ID: 14983
Updated by: [EMAIL PROTECTED]
Reported By: [EMAIL PROTECTED]
Status: Feedback
Bug Type: Reproducible crash
Operating System: Windows 2000
PHP Version: 4.1.1
New Comment:

No feedback was provided for this bug, so it is being suspended.
If you are able to provide the information that was requested,
please do so and change the status of the bug back to "Open".


Previous Comments:
------------------------------------------------------------------------

[2002-01-11 11:31:01] [EMAIL PROTECTED]

Here is the diff.

-Enrico

--- sendmail-old.c      Mon Sep  4 18:26:16 2000
+++ sendmail.c  Thu Jan 10 20:20:56 2002
@@ -16,6 +16,8 @@
  *  The complete wSendmail package with source code can be located
  *  from http://www.jgaa.com
  *
+
+ modified by Enrico Demarin Jan 2001
  */
 
 #include "php.h"                               /*php specific */
@@ -217,7 +219,7 @@
        if (strchr(mailTo, '@') == NULL)
                return (BAD_MSG_DESTINATION);
 
-       sprintf(Buffer, "HELO %s\r\n", LocalHost);
+       snprintf(Buffer, MAIL_BUFFER_SIZE, "HELO %s\r\n", LocalHost);
 
        /* in the beggining of the dialog */
        /* attempt reconnect if the first Post fail */
@@ -229,7 +231,7 @@
        if ((res = Ack()) != SUCCESS)
                return (res);
 
-       sprintf(Buffer, "MAIL FROM:<%s>\r\n", RPath);
+       snprintf(Buffer, MAIL_BUFFER_SIZE,"MAIL FROM:<%s>\r\n", RPath);
        if ((res = Post(Buffer)) != SUCCESS)
                return (res);
        if ((res = Ack()) != SUCCESS)
@@ -242,7 +244,7 @@
        token = strtok(tempMailTo, ",");
        while(token != NULL)
        {
-               sprintf(Buffer, "RCPT TO:<%s>\r\n", token);
+               snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token);
                if ((res = Post(Buffer)) != SUCCESS)
                        return (res);
                if ((res = Ack()) != SUCCESS)
@@ -259,7 +261,7 @@
                token = strtok(tempMailTo, ",");
                while(token != NULL)
                {
-                       sprintf(Buffer, "RCPT TO:<%s>\r\n", token);
+                       snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token);
                        if ((res = Post(Buffer)) != SUCCESS)
                                return (res);
                        if ((res = Ack()) != SUCCESS)
@@ -341,14 +343,15 @@
        struct tm *tm = localtime(&tNow);
        int zoneh = abs(_timezone);
        int zonem, res;
+       int i;
+
        char *p;
 
-       p = Buffer;
        zoneh /= (60 * 60);
        zonem = (abs(_timezone) / 60) - (zoneh * 60);
 
        if(!xheaders || !strstr(xheaders, "Date:")){
-               p += sprintf(p, "Date: %s, %02d %s %04d %02d:%02d:%02d
%s%02d%02d\r\n",
+               snprintf(Buffer, MAIL_BUFFER_SIZE, "Date: %s, %02d %s %04d
%02d:%02d:%02d %s%02d%02d\r\n",
                                         days[tm->tm_wday],
                                         tm->tm_mday,
                                         months[tm->tm_mon],
@@ -359,21 +362,56 @@
                                         (_timezone > 0) ? "+" : (_timezone < 0) ? "-" 
: "",
                                         zoneh,
                                         zonem);
+
+                                       if ((res = Post(Buffer)) != SUCCESS)
+                                       return (res);
        }
 
        if(!xheaders || !strstr(xheaders, "From:")){
-               p += sprintf(p, "From: %s\r\n", RPath);
+               snprintf(Buffer, MAIL_BUFFER_SIZE, "From: %s\r\n", RPath);
+               if ((res = Post(Buffer)) != SUCCESS)
+               return (res);
        }
-       p += sprintf(p, "Subject: %s\r\n", Subject);
+
+       snprintf(Buffer, MAIL_BUFFER_SIZE, "Subject: %s\r\n", Subject);
+       if ((res = Post(Buffer)) != SUCCESS)
+       return (res);
+
        if(!xheaders || !strstr(xheaders, "To:")){
-               p += sprintf(p, "To: %s\r\n", mailTo);
+               snprintf(Buffer, MAIL_BUFFER_SIZE, "To: %s\r\n", mailTo);
+               if ((res = Post(Buffer)) != SUCCESS)
+               return (res);
        }
+
        if(xheaders){
-               p += sprintf(p, "%s\r\n", xheaders);
-       }
 
-       if ((res = Post(Buffer)) != SUCCESS)
-               return (res);
+                               /* send extre headers in 1024 chunks */
+                               if (strlen(xheaders) <= 1024) {
+                                               if ((res = Post(xheaders)) != SUCCESS)
+                                               return (res);
+                               } else {
+                                               p = xheaders;
+               
+                                               while (1) {
+                                               if (*p == '\0')
+                                                       break;
+                                               if (strlen(p) >= 1024)
+                                               i = 1024;
+                                                       else
+                                               i = strlen(p);
+
+                                               /* put next chunk in buffer */
+                                               strncpy(Buffer, p, i);
+                                               Buffer[i] = '\0';
+                                               p += i;
+
+                                               /* send chunk */
+                                               if ((res = Post(Buffer)) != SUCCESS)
+                                               return (res);
+                                               }
+                               }
+                               }
+
 
        if ((res = Post("\r\n")) != SUCCESS)
                return (res);

------------------------------------------------------------------------

[2002-01-11 11:00:08] [EMAIL PROTECTED]

It would be nice if you post a diff instead of the whole file...

------------------------------------------------------------------------

[2002-01-10 21:07:29] [EMAIL PROTECTED]


this is what i came up with to fix the behaviour. It's a quick fix
cause i needed PHP working for a demo tomorrow, but it appears to fix
the problem.

- Enrico

/* 
 *    PHP Sendmail for Windows.
 *
 *  This file is rewriten specificly for PHPFI.  Some functionality
 *  has been removed (MIME and file attachments).  This code was 
 *  modified from code based on code writen by Jarle Aase.
 *
 *  This class is based on the original code by Jarle Aase, see
bellow:
 *  wSendmail.cpp  It has been striped of some functionality to match
 *  the requirements of phpfi.
 *
 *  Very simple SMTP Send-mail program for sending command-line level
 *  emails and CGI-BIN form response for the Windows platform.
 *
 *  The complete wSendmail package with source code can be located
 *  from http://www.jgaa.com
 *

 modified by Enrico Demarin Jan 2001
 */

#include "php.h"                                /*php specific */
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#include "time.h"
#include <string.h>
#include <malloc.h>
#include <memory.h>
#include <winbase.h>
#include "sendmail.h"
#include "php_ini.h"

/*
   extern int _daylight;
   extern long _timezone;
 */
/*enum
   {
   DO_CONNECT = WM_USER +1
   };
 */

static char *days[] =
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static char *months[] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
"Nov", "Dec"};

#ifndef THREAD_SAFE
char Buffer[MAIL_BUFFER_SIZE];

/* socket related data */
SOCKET sc;
WSADATA Data;
struct hostent *adr;
SOCKADDR_IN sock_in;
int WinsockStarted;
/* values set by the constructor */
char *AppName;
char MailHost[HOST_NAME_LEN];
char LocalHost[HOST_NAME_LEN];
#endif
char seps[] = " ,\t\n";
char *php_mailer = "PHP 4.0 WIN32";

char *get_header(char *h, char *headers);

/* Error messages */
static char *ErrorMessages[] =
{
        {"Success"},
        {"Bad arguments from form"},
        {"Unable to open temporary mailfile for read"},
        {"Failed to Start Sockets"},
        {"Failed to Resolve Host"},
        {"Failed to obtain socket handle"},
        {"Failed to Connect"},
        {"Failed to Send"},
        {"Failed to Receive"},
        {"Server Error"},
        {"Failed to resolve the host IP name"},
        {"Out of memory"},
        {"Unknown error"},
        {"Bad Message Contents"},
        {"Bad Message Subject"},
        {"Bad Message destination"},
        {"Bad Message Return Path"},
        {"Bad Mail Host"},
        {"Bad Message File"},
        {"PHP Internal error: php.ini sendmail from variable not set!"}
};



/*********************************************************************
// Name:  TSendMail
// Input:   1) host:    Name of the mail host where the SMTP server
resides
//                      max accepted length of name = 256
//          2) appname: Name of the application to use in the X-mailer
//                      field of the message. if NULL is given the
application
//                      name is used as given by the GetCommandLine()
function
//                      max accespted length of name = 100
// Output:  1) error:   Returns the error code if something went wrong
or
//                      SUCCESS otherwise.
//
//  See SendText() for additional args!
//********************************************************************/
int TSendMail(char *host, int *error,
                          char *headers, char *Subject, char *mailTo, char *data)
{
        int ret;
        char *RPath = NULL;

        WinsockStarted = FALSE;

        if (host == NULL) {
                *error = BAD_MAIL_HOST;
                return BAD_MAIL_HOST;
        } else if (strlen(host) >= HOST_NAME_LEN) {
                *error = BAD_MAIL_HOST;
                return BAD_MAIL_HOST;
        } else {
                strcpy(MailHost, host);
        }

        if (INI_STR("sendmail_from")){
                RPath = estrdup(INI_STR("sendmail_from"));
                } else {
                        return 19;
        }

        /* attempt to connect with mail host */
        *error = MailConnect();
        if (*error != 0) {
                if(RPath)efree(RPath);
                return *error;
        } else {
                ret = SendText(RPath, Subject, mailTo, data, headers);
                TSMClose();
                if (ret != SUCCESS) {
                        *error = ret;
                }
                if(RPath)efree(RPath);
                return ret;
        }
}

//********************************************************************
// Name:  TSendMail::~TSendMail
// Input:
// Output:
// Description: DESTRUCTOR
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
void TSMClose()
{
        Post("QUIT\r\n");
        Ack();
        /* to guarantee that the cleanup is not made twice and 
           compomise the rest of the application if sockets are used
           elesewhere 
        */

        shutdown(sc, 0); 
        closesocket(sc);
}


/*********************************************************************
// Name:  char *GetSMErrorText
// Input:   Error index returned by the menber functions
// Output:  pointer to a string containing the error description
// Description:
// Author/Date:  jcar 20/9/96
// History:
//*******************************************************************/
char *GetSMErrorText(int index)
{

        if ((index > MAX_ERROR_INDEX) || (index < MIN_ERROR_INDEX))
                return (ErrorMessages[UNKNOWN_ERROR]);
        else
                return (ErrorMessages[index]);
}


/*********************************************************************
// Name:  TSendText
// Input:       1) RPath:   return path of the message
//                                  Is used to fill the "Return-Path"
and the
//                                  "X-Sender" fields of the message.
//                  2) Subject: Subject field of the message. If NULL
is given
//                                  the subject is set to "No Subject"
//                  3) mailTo:  Destination address
//                  4) data:        Null terminated string containing
the data to be send.
// Output:      Error code or SUCCESS
// Description:
// Author/Date:  jcar 20/9/96
// History:
//*******************************************************************/
int SendText(char *RPath, char *Subject, char *mailTo, char *data, char
*headers)
{
        int res, i;
        char *p;
        char *tempMailTo, *token, *pos1, *pos2;

        /* check for NULL parameters */
        if (data == NULL)
                return (BAD_MSG_CONTENTS);
        if (mailTo == NULL)
                return (BAD_MSG_DESTINATION);
        if (RPath == NULL)
                return (BAD_MSG_RPATH);

        /* simple checks for the mailto address */
        /* have ampersand ? */
        if (strchr(mailTo, '@') == NULL)
                return (BAD_MSG_DESTINATION);

        snprintf(Buffer, MAIL_BUFFER_SIZE, "HELO %s\r\n", LocalHost);

        /* in the beggining of the dialog */
        /* attempt reconnect if the first Post fail */
        if ((res = Post(Buffer)) != SUCCESS) {
                MailConnect();
                if ((res = Post(Buffer)) != SUCCESS)
                        return (res);
        }
        if ((res = Ack()) != SUCCESS)
                return (res);

        snprintf(Buffer, MAIL_BUFFER_SIZE,"MAIL FROM:<%s>\r\n", RPath);
        if ((res = Post(Buffer)) != SUCCESS)
                return (res);
        if ((res = Ack()) != SUCCESS)
                return (res);


        tempMailTo = estrdup(mailTo);
        
        /* Send mail to all rcpt's */
        token = strtok(tempMailTo, ",");
        while(token != NULL)
        {
                snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token);
                if ((res = Post(Buffer)) != SUCCESS)
                        return (res);
                if ((res = Ack()) != SUCCESS)
                        return (res);
                token = strtok(NULL, ",");
        }

        /* Send mail to all Cc rcpt's */
        efree(tempMailTo);
        if (headers && (pos1 = strstr(headers, "Cc:"))) {
                pos2 = strstr(pos1, "\r\n");
                tempMailTo = estrndup(pos1, pos2-pos1);

                token = strtok(tempMailTo, ",");
                while(token != NULL)
                {
                        snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token);
                        if ((res = Post(Buffer)) != SUCCESS)
                                return (res);
                        if ((res = Ack()) != SUCCESS)
                                return (res);
                        token = strtok(NULL, ",");
                }
                efree(tempMailTo);
        }

        if ((res = Post("DATA\r\n")) != SUCCESS)
                return (res);
        if ((res = Ack()) != SUCCESS)
                return (res);


        /* send message header */
        if (Subject == NULL)
                res = PostHeader(RPath, "No Subject", mailTo, headers);
        else
                res = PostHeader(RPath, Subject, mailTo, headers);
        if (res != SUCCESS)
                return (res);


        /* send message contents in 1024 chunks */
        if (strlen(data) <= 1024) {
                if ((res = Post(data)) != SUCCESS)
                        return (res);
        } else {
                p = data;
                while (1) {
                        if (*p == '\0')
                                break;
                        if (strlen(p) >= 1024)
                                i = 1024;
                        else
                                i = strlen(p);

                        /* put next chunk in buffer */
                        strncpy(Buffer, p, i);
                        Buffer[i] = '\0';
                        p += i;

                        /* send chunk */
                        if ((res = Post(Buffer)) != SUCCESS)
                                return (res);
                }
        }

        /*send termination dot */
        if ((res = Post("\r\n.\r\n")) != SUCCESS)
                return (res);
        if ((res = Ack()) != SUCCESS)
                return (res);

        return (SUCCESS);
}



/*********************************************************************
// Name:  PostHeader
// Input:       1) return path
//                  2) Subject
//                  3) destination address
//                  4) DoMime flag
// Output:      Error code or Success
// Description:
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
int PostHeader(char *RPath, char *Subject, char *mailTo, char
*xheaders)
{

        /* Print message header according to RFC 822 */
        /* Return-path, Received, Date, From, Subject, Sender, To, cc */

        time_t tNow = time(NULL);
        struct tm *tm = localtime(&tNow);
        int zoneh = abs(_timezone);
        int zonem, res;
        int i;

        char *p;

        zoneh /= (60 * 60);
        zonem = (abs(_timezone) / 60) - (zoneh * 60);

        if(!xheaders || !strstr(xheaders, "Date:")){
                snprintf(Buffer, MAIL_BUFFER_SIZE, "Date: %s, %02d %s %04d
%02d:%02d:%02d %s%02d%02d\r\n",
                                         days[tm->tm_wday],
                                         tm->tm_mday,
                                         months[tm->tm_mon],
                                         tm->tm_year + 1900,
                                         tm->tm_hour,
                                         tm->tm_min,
                                         tm->tm_sec,
                                         (_timezone > 0) ? "+" : (_timezone < 0) ? "-" 
: "",
                                         zoneh,
                                         zonem);

                                        if ((res = Post(Buffer)) != SUCCESS)
                                        return (res);
        }

        if(!xheaders || !strstr(xheaders, "From:")){
                snprintf(Buffer, MAIL_BUFFER_SIZE, "From: %s\r\n", RPath);
                if ((res = Post(Buffer)) != SUCCESS)
                return (res);
        }

        snprintf(Buffer, MAIL_BUFFER_SIZE, "Subject: %s\r\n", Subject);
        if ((res = Post(Buffer)) != SUCCESS)
        return (res);

        if(!xheaders || !strstr(xheaders, "To:")){
                snprintf(Buffer, MAIL_BUFFER_SIZE, "To: %s\r\n", mailTo);
                if ((res = Post(Buffer)) != SUCCESS)
                return (res);
        }

        if(xheaders){

                                /* send extre headers in 1024 chunks */
                                if (strlen(xheaders) <= 1024) {
                                                if ((res = Post(xheaders)) != SUCCESS)
                                                return (res);
                                } else {
                                                p = xheaders;
                
                                                while (1) {
                                                if (*p == '\0')
                                                        break;
                                                if (strlen(p) >= 1024)
                                                i = 1024;
                                                        else
                                                i = strlen(p);

                                                /* put next chunk in buffer */
                                                strncpy(Buffer, p, i);
                                                Buffer[i] = '\0';
                                                p += i;

                                                /* send chunk */
                                                if ((res = Post(Buffer)) != SUCCESS)
                                                return (res);
                                                }
                                }
                                }


        if ((res = Post("\r\n")) != SUCCESS)
                return (res);

        return (SUCCESS);
}



/*********************************************************************
// Name:  MailConnect
// Input:   None
// Output:  None
// Description: Connect to the mail host and receive the welcome
message.
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
int MailConnect()
{

        int res;
        short portnum;

        /* Create Socket */
        if ((sc = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
                return (FAILED_TO_OBTAIN_SOCKET_HANDLE);

        /* Get our own host name */
        if (gethostname(LocalHost, HOST_NAME_LEN))
                return (FAILED_TO_GET_HOSTNAME);

        /* Resolve the servers IP */
        /*
        if (!isdigit(MailHost[0])||!gethostbyname(MailHost))
        {
                return (FAILED_TO_RESOLVE_HOST);
        }
        */

        portnum = (short) INI_INT("sendmail_port");
        if (!portnum) {
                portnum = 25;
        }

        /* Connect to server */
        sock_in.sin_family = AF_INET;
        sock_in.sin_port = htons(portnum);
        sock_in.sin_addr.S_un.S_addr = GetAddr(MailHost);

        if (connect(sc, (LPSOCKADDR) & sock_in, sizeof(sock_in)))
                return (FAILED_TO_CONNECT);

        /* receive Server welcome message */
        res = Ack();
        return (res);
}






/*********************************************************************
// Name:  Post
// Input:
// Output:
// Description:
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
int Post(LPCSTR msg)
{
        int len = strlen(msg);
        int slen;
        int index = 0;

        while (len > 0) {
                if ((slen = send(sc, msg + index, len, 0)) < 1)
                        return (FAILED_TO_SEND);
                len -= slen;
                index += slen;
        }
        return (SUCCESS);
}



/*********************************************************************
// Name:  Ack
// Input:
// Output:
// Description:
// Get the response from the server. We only want to know if the
// last command was successful.
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
int Ack()
{
        static char *buf;
        int rlen;
        int Index = 0;
        int Received = 0;

        if (!buf)
                if ((buf = (char *) malloc(1024 * 4)) == NULL)
                        return (OUT_OF_MEMORY);

  again:

        if ((rlen = recv(sc, buf + Index, ((1024 * 4) - 1) - Received, 0)) <
1)
                return (FAILED_TO_RECEIVE);

        Received += rlen;
        buf[Received] = 0;
        /*err_msg   fprintf(stderr,"Received: (%d bytes) %s", rlen, buf +
Index); */

        /* Check for newline */
        Index += rlen;
        
        if ((buf[Received - 4] == ' ' && buf[Received - 3] == '-') ||
            (buf[Received - 2] != '\r') || (buf[Received - 1] != '\n'))
                /* err_msg          fprintf(stderr,"Incomplete server message.
Awaiting CRLF\n"); */
                goto again;                             /* Incomplete data. Line must 
be terminated by CRLF
                                           And not contain a space followed by a '-'
*/

        if (buf[0] > '3')
                return (SMTP_SERVER_ERROR);

        return (SUCCESS);
}


/*********************************************************************
// Name:  unsigned long GetAddr (LPSTR szHost)
// Input:
// Output:
// Description: Given a string, it will return an IP address.
//   - first it tries to convert the string directly
//   - if that fails, it tries o resolve it as a hostname
//
// WARNING: gethostbyname() is a blocking function
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
unsigned long GetAddr(LPSTR szHost)
{
        LPHOSTENT lpstHost;
        u_long lAddr = INADDR_ANY;

        /* check that we have a string */
        if (*szHost) {

                /* check for a dotted-IP address string */
                lAddr = inet_addr(szHost);

                /* If not an address, then try to resolve it as a hostname */
                if ((lAddr == INADDR_NONE) && (strcmp(szHost, "255.255.255.255"))) {

                        lpstHost = gethostbyname(szHost);
                        if (lpstHost) {         /* success */
                                lAddr = *((u_long FAR *) (lpstHost->h_addr));
                        } else {
                                lAddr = INADDR_ANY;             /* failure */
                        }
                }
        }
        return (lAddr);
}                                                               /* end GetAddr() */


------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/?id=14983


Edit this bug report at http://bugs.php.net/?id=14983&edit=1


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to