Back to index

php5  5.3.10
Defines | Functions | Variables
sendmail.c File Reference
#include "php.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include "time.h"
#include <string.h>
#include <math.h>
#include <malloc.h>
#include <memory.h>
#include <winbase.h>
#include "sendmail.h"
#include "php_ini.h"
#include "inet.h"
#include "ext/standard/php_string.h"
#include "ext/date/php_date.h"

Go to the source code of this file.

Defines

#define SMTP_ERROR_RESPONSE_SPEC   "SMTP server response: %s"
#define SMTP_ERROR_RESPONSE(response)
#define SMTP_SKIP_SPACE(str)   { while (isspace(*str)) { str++; } }
#define PHP_WIN32_MAIL_UNIFY_PATTERN   "/(\r\n?)|\n/"
#define PHP_WIN32_MAIL_UNIFY_REPLACE   "\r\n"
#define PHP_WIN32_MAIL_RMVDBL_PATTERN   "/^\r\n|(\r\n)+$/m"
#define PHP_WIN32_MAIL_RMVDBL_REPLACE   ""
#define PHP_WIN32_MAIL_DOT_PATTERN   "\n."
#define PHP_WIN32_MAIL_DOT_REPLACE   "\n.."

Functions

static char * php_win32_mail_trim_header (char *header TSRMLS_DC)
PHPAPI int TSendMail (char *host, int *error, char **error_message, char *headers, char *Subject, char *mailTo, char *data, char *mailCc, char *mailBcc, char *mailRPath TSRMLS_DC)
PHPAPI void TSMClose ()
PHPAPI char * GetSMErrorText (int index)
static int SendText (char *RPath, char *Subject, char *mailTo, char *mailCc, char *mailBcc, char *data, char *headers, char *headers_lc, char **error_message TSRMLS_DC)
static int addToHeader (char **header_buffer, const char *specifier, char *string)
static int PostHeader (char *RPath, char *Subject, char *mailTo, char *xheaders TSRMLS_DC)
static int MailConnect ()
static int Post (LPCSTR msg)
static int Ack (char **server_response)
static unsigned long GetAddr (LPSTR szHost)
static int FormatEmailAddress (char *Buf, char *EmailAddress, char *FormatString)

Variables

char Buffer [MAIL_BUFFER_SIZE]
SOCKET sc
WSADATA Data
struct hostent * adr
int WinsockStarted
char * AppName
SOCKADDR_IN sock_in
char MailHost [HOST_NAME_LEN]
char LocalHost [HOST_NAME_LEN]
char seps [] = " ,\t\n"
char * php_mailer = "PHP 5 WIN32"
static char * ErrorMessages []

Define Documentation

#define PHP_WIN32_MAIL_DOT_PATTERN   "\n."

Definition at line 140 of file sendmail.c.

#define PHP_WIN32_MAIL_DOT_REPLACE   "\n.."

Definition at line 141 of file sendmail.c.

#define PHP_WIN32_MAIL_RMVDBL_PATTERN   "/^\r\n|(\r\n)+$/m"

Definition at line 133 of file sendmail.c.

Definition at line 134 of file sendmail.c.

#define PHP_WIN32_MAIL_UNIFY_PATTERN   "/(\r\n?)|\n/"

Definition at line 126 of file sendmail.c.

#define PHP_WIN32_MAIL_UNIFY_REPLACE   "\r\n"

Definition at line 127 of file sendmail.c.

#define SMTP_ERROR_RESPONSE (   response)
Value:
{ \
                                                                             if (response && error_message) { \
                                                                                    if (NULL != (*error_message = ecalloc(1, sizeof(SMTP_ERROR_RESPONSE_SPEC) + strlen(response)))) { \
                                                                                           snprintf(*error_message, sizeof(SMTP_ERROR_RESPONSE_SPEC) + strlen(response), SMTP_ERROR_RESPONSE_SPEC, response); \
                                                                                    } \
                                                                                    efree(response); \
                                                                             } \
                                                                      }

Definition at line 60 of file sendmail.c.

#define SMTP_ERROR_RESPONSE_SPEC   "SMTP server response: %s"

Definition at line 56 of file sendmail.c.

#define SMTP_SKIP_SPACE (   str)    { while (isspace(*str)) { str++; } }

Definition at line 68 of file sendmail.c.


Function Documentation

static int Ack ( char **  server_response) [static]

Definition at line 879 of file sendmail.c.

{
       static char buf[MAIL_BUFFER_SIZE];
       int rlen;
       int Index = 0;
       int Received = 0;

again:

       if ((rlen = recv(sc, buf + Index, ((MAIL_BUFFER_SIZE) - 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;
       
       /* SMPT RFC says \r\n is the only valid line ending, who are we to argue ;)
        * The response code must contain at least 5 characters ex. 220\r\n */
       if (Received < 5 || buf[Received - 1] != '\n' || buf[Received - 2] != '\r') {
              goto again;
       }

       if (buf[0] > '3') {
              /* If we've a valid pointer, return the SMTP server response so the error message contains more information */
              if (server_response) {
                     int dec = 0;
                     /* See if we have something like \r, \n, \r\n or \n\r at the end of the message and chop it off */
                     if (Received > 2) {
                            if (buf[Received-1] == '\n' || buf[Received-1] == '\r') {
                                   dec++;
                                   if (buf[Received-2] == '\r' || buf[Received-2] == '\n') {
                                          dec++;
                                   }
                            }

                     }
                     *server_response = estrndup(buf, Received - dec);
              }
              return (SMTP_SERVER_ERROR);
       }

       return (SUCCESS);
}

Here is the caller graph for this function:

static int addToHeader ( char **  header_buffer,
const char *  specifier,
char *  string 
) [static]

Definition at line 664 of file sendmail.c.

{
       if (NULL == (*header_buffer = erealloc(*header_buffer, strlen(*header_buffer) + strlen(specifier) + strlen(string) + 1))) {
              return 0;
       }
       sprintf(*header_buffer + strlen(*header_buffer), specifier, string);
       return 1;
}

Here is the caller graph for this function:

static int FormatEmailAddress ( char *  Buf,
char *  EmailAddress,
char *  FormatString 
) [static]

Definition at line 978 of file sendmail.c.

                                                                                 {
       char *tmpAddress1, *tmpAddress2;
       int result;

       if( (tmpAddress1 = strchr(EmailAddress, '<')) && (tmpAddress2 = strchr(tmpAddress1, '>'))  ) {
              *tmpAddress2 = 0; // terminate the string temporarily.
              result = snprintf(Buf, MAIL_BUFFER_SIZE, FormatString , tmpAddress1+1);
              *tmpAddress2 = '>'; // put it back the way it was.
              return result;
       } 
       return snprintf(Buf, MAIL_BUFFER_SIZE , FormatString , EmailAddress );
} /* end FormatEmailAddress() */

Here is the caller graph for this function:

static unsigned long GetAddr ( LPSTR  szHost) [static]

Definition at line 939 of file sendmail.c.

{
       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() */

Here is the caller graph for this function:

PHPAPI char* GetSMErrorText ( int  index)

Definition at line 351 of file sendmail.c.

{
       if (MIN_ERROR_INDEX <= index && index < MAX_ERROR_INDEX) {
              return (ErrorMessages[index]);

       } else {
              return (ErrorMessages[UNKNOWN_ERROR]);

       }
}

Here is the caller graph for this function:

static int MailConnect ( ) [static]

Definition at line 766 of file sendmail.c.

{

       int res, namelen;
       short portnum;
       struct hostent *ent;
       IN_ADDR addr;
#ifdef HAVE_IPV6
       IN6_ADDR addr6;
#endif

       /* 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);
       }

       ent = gethostbyname(LocalHost);

       if (!ent) {
              return (FAILED_TO_GET_HOSTNAME);
       }

       namelen = strlen(ent->h_name);

#ifdef HAVE_IPV6
       if (inet_pton(AF_INET, ent->h_name, &addr) == 1 || inet_pton(AF_INET6, ent->h_name, &addr6) == 1)
#else
       if (inet_pton(AF_INET, ent->h_name, &addr) == 1)
#endif
       {
              if (namelen + 2 >= HOST_NAME_LEN) {
                     return (FAILED_TO_GET_HOSTNAME);
              }

              strcpy(LocalHost, "[");
              strcpy(LocalHost + 1, ent->h_name);
              strcpy(LocalHost + namelen + 1, "]");
       } else {
              if (namelen >= HOST_NAME_LEN) {
                     return (FAILED_TO_GET_HOSTNAME);
              }

              strcpy(LocalHost, ent->h_name);
       }

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

       portnum = (short) INI_INT("smtp_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(NULL);
       return (res);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* php_win32_mail_trim_header ( char *header  TSRMLS_DC) [static]

Definition at line 153 of file sendmail.c.

{

#if HAVE_PCRE || HAVE_BUNDLED_PCRE
       
       char *result, *result2;
       int result_len;
       zval *replace;

       if (!header) {
              return NULL;
       }

       MAKE_STD_ZVAL(replace);
       ZVAL_STRING(replace, PHP_WIN32_MAIL_UNIFY_REPLACE, 0);

       result = php_pcre_replace(PHP_WIN32_MAIL_UNIFY_PATTERN, sizeof(PHP_WIN32_MAIL_UNIFY_PATTERN)-1,
                                                   header, strlen(header),
                                                   replace,
                                                   0,
                                                   &result_len,
                                                   -1,
                                                   NULL TSRMLS_CC);
       if (NULL == result) {
              FREE_ZVAL(replace);
              return NULL;
       }

       ZVAL_STRING(replace, PHP_WIN32_MAIL_RMVDBL_REPLACE, 0);

       result2 = php_pcre_replace(PHP_WIN32_MAIL_RMVDBL_PATTERN, sizeof(PHP_WIN32_MAIL_RMVDBL_PATTERN)-1,
                                                    result, result_len,
                                                    replace,
                                                    0,
                                                    &result_len,
                                                    -1,
                                                    NULL TSRMLS_CC);
       efree(result);
       FREE_ZVAL(replace);
       return result2;
#else
       /* In case we don't have PCRE support (for whatever reason...) simply do nothing and return the unmodified header */
       return estrdup(header);
#endif
}

Here is the caller graph for this function:

static int Post ( LPCSTR  msg) [static]

Definition at line 852 of file sendmail.c.

{
       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);
}

Here is the caller graph for this function:

static int PostHeader ( char *  RPath,
char *  Subject,
char *  mailTo,
char *xheaders  TSRMLS_DC 
) [static]

Definition at line 684 of file sendmail.c.

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

       int res;
       char *header_buffer;
       char *headers_lc = NULL;
       size_t i;

       if (xheaders) {
              if (NULL == (headers_lc = estrdup(xheaders))) {
                     return OUT_OF_MEMORY;
              }
              for (i = 0; i < strlen(headers_lc); i++) {
                     headers_lc[i] = tolower(headers_lc[i]);
              }
       }

       header_buffer = ecalloc(1, MAIL_BUFFER_SIZE);

       if (!xheaders || !strstr(headers_lc, "date:")) {
              time_t tNow = time(NULL);
              char *dt = php_format_date("r", 1, tNow, 1 TSRMLS_CC);

              snprintf(header_buffer, MAIL_BUFFER_SIZE, "Date: %s\r\n", dt);
              efree(dt);
       }

       if (!headers_lc || !strstr(headers_lc, "from:")) {
              if (!addToHeader(&header_buffer, "From: %s\r\n", RPath)) {
                     goto PostHeader_outofmem;
              }
       }
       if (!addToHeader(&header_buffer, "Subject: %s\r\n", Subject)) {
              goto PostHeader_outofmem;
       }

       /* Only add the To: field from the $to parameter if isn't in the custom headers */
       if ((headers_lc && (!strstr(headers_lc, "\r\nto:") && (strncmp(headers_lc, "to:", 3) != 0))) || !headers_lc) {
              if (!addToHeader(&header_buffer, "To: %s\r\n", mailTo)) {
                     goto PostHeader_outofmem;
              }
       }
       if (xheaders) {
              if (!addToHeader(&header_buffer, "%s\r\n", xheaders)) {
                     goto PostHeader_outofmem;
              }
       }

       if (headers_lc) {
              efree(headers_lc);
       }
       if ((res = Post(header_buffer)) != SUCCESS) {
              efree(header_buffer);
              return (res);
       }
       efree(header_buffer);

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

       return (SUCCESS);

PostHeader_outofmem:
       if (headers_lc) {
              efree(headers_lc);
       }
       return OUT_OF_MEMORY;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int SendText ( char *  RPath,
char *  Subject,
char *  mailTo,
char *  mailCc,
char *  mailBcc,
char *  data,
char *  headers,
char *  headers_lc,
char **error_message  TSRMLS_DC 
) [static]

Definition at line 381 of file sendmail.c.

{
       int res;
       char *p;
       char *tempMailTo, *token, *pos1, *pos2;
       char *server_response = NULL;
       char *stripped_header  = NULL;
       char *data_cln;
       int data_cln_len;

       /* 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 ? */
       /* mfischer, 20020514: I commented this out because it really
          seems bogus. Only a username for example may still be a
          valid address at the destination system.
       if (strchr(mailTo, '@') == NULL)
              return (BAD_MSG_DESTINATION);
       */

       snprintf(Buffer, sizeof(Buffer), "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(&server_response)) != SUCCESS) {
              SMTP_ERROR_RESPONSE(server_response);
              return (res);
       }

       SMTP_SKIP_SPACE(RPath);
       FormatEmailAddress(Buffer, RPath, "MAIL FROM:<%s>\r\n");
       if ((res = Post(Buffer)) != SUCCESS) {
              return (res);
       }
       if ((res = Ack(&server_response)) != SUCCESS) {
              SMTP_ERROR_RESPONSE(server_response);
              return W32_SM_SENDMAIL_FROM_MALFORMED;
       }

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

       if (mailCc && *mailCc) {
              tempMailTo = estrdup(mailCc);
              /* Send mail to all rcpt's */
              token = strtok(tempMailTo, ",");
              while (token != NULL)
              {
                     SMTP_SKIP_SPACE(token);
                     FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
                     if ((res = Post(Buffer)) != SUCCESS) {
                            efree(tempMailTo);
                            return (res);
                     }
                     if ((res = Ack(&server_response)) != SUCCESS) {
                            SMTP_ERROR_RESPONSE(server_response);
                            efree(tempMailTo);
                            return (res);
                     }
                     token = strtok(NULL, ",");
              }
              efree(tempMailTo);
       }
       /* Send mail to all Cc rcpt's */
       else if (headers && (pos1 = strstr(headers_lc, "cc:")) && ((pos1 == headers_lc) || (*(pos1-1) == '\n'))) {
              /* Real offset is memaddress from the original headers + difference of
               * string found in the lowercase headrs + 3 characters to jump over
               * the cc: */
              pos1 = headers + (pos1 - headers_lc) + 3;
              if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
                     tempMailTo = estrndup(pos1, strlen(pos1));
              } else {
                     tempMailTo = estrndup(pos1, pos2 - pos1);
              }

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

       /* Send mail to all Bcc rcpt's
          This is basically a rip of the Cc code above.
          Just don't forget to remove the Bcc: from the header afterwards. */
       if (mailBcc && *mailBcc) {
              tempMailTo = estrdup(mailBcc);
              /* Send mail to all rcpt's */
              token = strtok(tempMailTo, ",");
              while (token != NULL)
              {
                     SMTP_SKIP_SPACE(token);
                     FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
                     if ((res = Post(Buffer)) != SUCCESS) {
                            efree(tempMailTo);
                            return (res);
                     }
                     if ((res = Ack(&server_response)) != SUCCESS) {
                            SMTP_ERROR_RESPONSE(server_response);
                            efree(tempMailTo);
                            return (res);
                     }
                     token = strtok(NULL, ",");
              }
              efree(tempMailTo);
       }
       else if (headers) {
              if (pos1 = strstr(headers_lc, "bcc:")) {
                     /* Real offset is memaddress from the original headers + difference of
                      * string found in the lowercase headrs + 4 characters to jump over
                      * the bcc: */
                     pos1 = headers + (pos1 - headers_lc) + 4;
                     if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
                            tempMailTo = estrndup(pos1, strlen(pos1));
                            /* Later, when we remove the Bcc: out of the
                               header we know it was the last thing. */
                            pos2 = pos1;
                     } else {
                            tempMailTo = estrndup(pos1, pos2 - pos1);
                     }

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

                     /* Now that we've identified that we've a Bcc list,
                        remove it from the current header. */
                     if (NULL == (stripped_header = ecalloc(1, strlen(headers)))) {
                            return OUT_OF_MEMORY;
                     }
                     /* headers = point to string start of header
                        pos1    = pointer IN headers where the Bcc starts
                        '4'     = Length of the characters 'bcc:'
                        Because we've added +4 above for parsing the Emails
                        we've to substract them here. */
                     memcpy(stripped_header, headers, pos1 - headers - 4);
                     if (pos1 != pos2) {
                            /* if pos1 != pos2 , pos2 points to the rest of the headers.
                               Since pos1 != pos2 if "\r\n" was found, we know those characters
                               are there and so we jump over them (else we would generate a new header
                               which would look like "\r\n\r\n". */
                            memcpy(stripped_header + (pos1 - headers - 4), pos2 + 2, strlen(pos2) - 2);
                     }
              }
       }

       /* Simplify the code that we create a copy of stripped_header no matter if
          we actually strip something or not. So we've a single efree() later. */
       if (headers && !stripped_header) {
              if (NULL == (stripped_header = estrndup(headers, strlen(headers)))) {
                     return OUT_OF_MEMORY;
              }
       }

       if ((res = Post("DATA\r\n")) != SUCCESS) {
              if (stripped_header) {
                     efree(stripped_header);
              }
              return (res);
       }
       if ((res = Ack(&server_response)) != SUCCESS) {
              SMTP_ERROR_RESPONSE(server_response);
              if (stripped_header) {
                     efree(stripped_header);
              }
              return (res);
       }

       /* send message header */
       if (Subject == NULL) {
              res = PostHeader(RPath, "No Subject", mailTo, stripped_header TSRMLS_CC);
       } else {
              res = PostHeader(RPath, Subject, mailTo, stripped_header TSRMLS_CC);
       }
       if (stripped_header) {
              efree(stripped_header);
       }
       if (res != SUCCESS) {
              return (res);
       }

       /* Escape \n. sequences
        * We use php_str_to_str() and not php_str_replace_in_subject(), since the latter
        * uses ZVAL as it's parameters */
       data_cln = php_str_to_str(data, strlen(data), PHP_WIN32_MAIL_DOT_PATTERN, sizeof(PHP_WIN32_MAIL_DOT_PATTERN) - 1,
                                   PHP_WIN32_MAIL_DOT_REPLACE, sizeof(PHP_WIN32_MAIL_DOT_REPLACE) - 1, &data_cln_len);
       if (!data_cln) {
              data_cln = estrdup("");
              data_cln_len = 1;           
       }

       /* send message contents in 1024 chunks */
       {
              char c, *e2, *e = data_cln + data_cln_len;
              p = data_cln;

              while (e - p > 1024) {
                     e2 = p + 1024;
                     c = *e2;
                     *e2 = '\0';
                     if ((res = Post(p)) != SUCCESS) {
                            efree(data_cln);
                            return(res);
                     }
                     *e2 = c;
                     p = e2;
              }
              if ((res = Post(p)) != SUCCESS) {
                     efree(data_cln);
                     return(res);
              }
       }

       efree(data_cln);

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

       return (SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI int TSendMail ( char *  host,
int error,
char **  error_message,
char *  headers,
char *  Subject,
char *  mailTo,
char *  data,
char *  mailCc,
char *  mailBcc,
char *mailRPath  TSRMLS_DC 
)

Definition at line 212 of file sendmail.c.

{
       int ret;
       char *RPath = NULL;
       char *headers_lc = NULL; /* headers_lc is only created if we've a header at all */
       char *pos1 = NULL, *pos2 = NULL;

#ifndef NETWARE
       WinsockStarted = FALSE;
#endif

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

       if (headers) {
              char *pos = NULL;
              size_t i;

              /* Use PCRE to trim the header into the right format */
              if (NULL == (headers = php_win32_mail_trim_header(headers TSRMLS_CC))) {
                     *error = W32_SM_PCRE_ERROR;
                     return FAILURE;
              }

              /* Create a lowercased header for all the searches so we're finally case
               * insensitive when searching for a pattern. */
              if (NULL == (headers_lc = estrdup(headers))) {
                     efree(headers);
                     *error = OUT_OF_MEMORY;
                     return FAILURE;
              }
              for (i = 0; i < strlen(headers_lc); i++) {
                     headers_lc[i] = tolower(headers_lc[i]);
              }
       }
 
       /* Fall back to sendmail_from php.ini setting */
       if (mailRPath && *mailRPath) {
              RPath = estrdup(mailRPath);
       } else if (INI_STR("sendmail_from")) {
              RPath = estrdup(INI_STR("sendmail_from"));
       } else if (   headers_lc &&
                            (pos1 = strstr(headers_lc, "from:")) &&
                            ((pos1 == headers_lc) || (*(pos1-1) == '\n'))
       ) {
              /* Real offset is memaddress from the original headers + difference of
               * string found in the lowercase headrs + 5 characters to jump over   
               * the from: */
              pos1 = headers + (pos1 - headers_lc) + 5;
              if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
                     RPath = estrndup(pos1, strlen(pos1));
              } else {
                     RPath = estrndup(pos1, pos2 - pos1);
              }
       } else {
              if (headers) {
                     efree(headers);
                     efree(headers_lc);
              }
              *error = W32_SM_SENDMAIL_FROM_NOT_SET;
              return FAILURE;
       }

       /* attempt to connect with mail host */
       *error = MailConnect();
       if (*error != 0) {
              if (RPath) {
                     efree(RPath);
              }
              if (headers) {
                     efree(headers);
                     efree(headers_lc);
              }
              /* 128 is safe here, the specifier in snprintf isn't longer than that */
              if (NULL == (*error_message = ecalloc(1, HOST_NAME_LEN + 128))) {
                     return FAILURE;
              }
              snprintf(*error_message, HOST_NAME_LEN + 128,
                     "Failed to connect to mailserver at \"%s\" port %d, verify your \"SMTP\" "
                     "and \"smtp_port\" setting in php.ini or use ini_set()",
                     MailHost, !INI_INT("smtp_port") ? 25 : INI_INT("smtp_port"));
              return FAILURE;
       } else {
              ret = SendText(RPath, Subject, mailTo, mailCc, mailBcc, data, headers, headers_lc, error_message TSRMLS_CC);
              TSMClose();
              if (RPath) {
                     efree(RPath);
              }
              if (headers) {
                     efree(headers);
                     efree(headers_lc);
              }
              if (ret != SUCCESS) {
                     *error = ret;
                     return FAILURE;
              }
              return SUCCESS;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void TSMClose ( void  )

Definition at line 329 of file sendmail.c.

{
       Post("QUIT\r\n");
       Ack(NULL);
       /* 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);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct hostent* adr

Definition at line 78 of file sendmail.c.

char* AppName

Definition at line 81 of file sendmail.c.

Definition at line 72 of file sendmail.c.

WSADATA Data

Definition at line 77 of file sendmail.c.

char* ErrorMessages[] [static]
Initial value:
{
       {"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 to mailserver, verify your \"SMTP\" setting in php.ini"},
       {"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"},
       {"\"sendmail_from\" not set in php.ini or custom \"From:\" header missing"},
       {"Mailserver rejected our \"sendmail_from\" setting"}, 
       {"Error while trimming mail header with PCRE, please file a bug report at http://bugs.php.net/"} 
}

Definition at line 95 of file sendmail.c.

Definition at line 85 of file sendmail.c.

Definition at line 84 of file sendmail.c.

char* php_mailer = "PHP 5 WIN32"

Definition at line 89 of file sendmail.c.

Definition at line 75 of file sendmail.c.

char seps[] = " ,\t\n"

Definition at line 87 of file sendmail.c.

SOCKADDR_IN sock_in

Definition at line 83 of file sendmail.c.

Definition at line 79 of file sendmail.c.