]> granicus.if.org Git - php/commitdiff
fix thread safety for win32/sendmail
authorAnatol Belski <ab@php.net>
Tue, 3 Mar 2015 19:42:28 +0000 (20:42 +0100)
committerAnatol Belski <ab@php.net>
Tue, 3 Mar 2015 19:42:28 +0000 (20:42 +0100)
win32/php_win32_globals.h
win32/sendmail.c

index ad2435d99c0440605cf9fcbc04b3af7fe4976c94..b22c227eda9f320cb0eca5d63cf546cfef6392ac 100644 (file)
@@ -23,6 +23,8 @@
 
 /* misc globals for thread-safety under win32 */
 
+#include "win32/sendmail.h"
+
 typedef struct _php_win32_core_globals php_win32_core_globals;
 
 #ifdef ZTS
@@ -41,6 +43,11 @@ struct _php_win32_core_globals {
        HKEY       registry_key;
        HANDLE     registry_event;
        HashTable *registry_directories;
+
+       char   mail_buffer[MAIL_BUFFER_SIZE];
+       SOCKET mail_socket;
+       char   mail_host[HOST_NAME_LEN];
+       char   mail_local_host[HOST_NAME_LEN];
 };
 
 void php_win32_core_globals_ctor(void *vg);
index 7dacf5ce419a9ecb7b903576b85184fe7de1f3de..b8d18d195ea2cfd4818373c8900b612fbed7c013 100644 (file)
@@ -40,6 +40,8 @@
 #include "php_ini.h"
 #include "inet.h"
 
+#include "php_win32_globals.h"
+
 #if HAVE_PCRE || HAVE_BUNDLED_PCRE
 #include "ext/pcre/php_pcre.h"
 #endif
 #define SMTP_SKIP_SPACE(str)   { while (isspace(*str)) { str++; } }
 
 
-#ifndef THREAD_SAFE
-char Buffer[MAIL_BUFFER_SIZE];
-
-/* socket related data */
-SOCKET sc;
-#ifndef NETWARE
-WSADATA Data;
-struct hostent *adr;
-int WinsockStarted;
-/* values set by the constructor */
-char *AppName;
-#endif /* NETWARE */
-SOCKADDR_IN sock_in;
-char MailHost[HOST_NAME_LEN];
-char LocalHost[HOST_NAME_LEN];
-#endif
 char seps[] = " ,\t\n";
 #ifndef NETWARE
 char *php_mailer = "PHP 7 WIN32";
@@ -223,10 +209,6 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message,
        zend_string *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;
@@ -234,7 +216,7 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message,
                *error = BAD_MAIL_HOST;
                return FAILURE;
        } else {
-               strcpy(MailHost, host);
+               strcpy(PW32G(mail_host), host);
        }
 
        if (headers) {
@@ -296,7 +278,7 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message,
                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"));
+                       PW32G(mail_host), !INI_INT("smtp_port") ? 25 : INI_INT("smtp_port"));
                return FAILURE;
        } else {
                ret = SendText(RPath, Subject, mailTo, mailCc, mailBcc, data, headers, headers_lc->val, error_message);
@@ -332,8 +314,8 @@ PHPAPI void TSMClose()
           elesewhere
        */
 
-       shutdown(sc, 0);
-       closesocket(sc);
+       shutdown(PW32G(mail_socket), 0);
+       closesocket(PW32G(mail_socket));
 }
 
 
@@ -405,17 +387,17 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
                return (BAD_MSG_DESTINATION);
        */
 
-       snprintf(Buffer, sizeof(Buffer), "HELO %s\r\n", LocalHost);
+       snprintf(PW32G(mail_buffer), sizeof(PW32G(mail_buffer)), "HELO %s\r\n", PW32G(mail_local_host));
 
        /* in the beginning of the dialog */
        /* attempt reconnect if the first Post fail */
-       if ((res = Post(Buffer)) != SUCCESS) {
+       if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                int err = MailConnect();
                if (0 != err) {
                        return (FAILED_TO_SEND);
                }
 
-               if ((res = Post(Buffer)) != SUCCESS) {
+               if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                        return (res);
                }
        }
@@ -425,8 +407,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
        }
 
        SMTP_SKIP_SPACE(RPath);
-       FormatEmailAddress(Buffer, RPath, "MAIL FROM:<%s>\r\n");
-       if ((res = Post(Buffer)) != SUCCESS) {
+       FormatEmailAddress(PW32G(mail_buffer), RPath, "MAIL FROM:<%s>\r\n");
+       if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                return (res);
        }
        if ((res = Ack(&server_response)) != SUCCESS) {
@@ -440,8 +422,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
        while (token != NULL)
        {
                SMTP_SKIP_SPACE(token);
-               FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
-               if ((res = Post(Buffer)) != SUCCESS) {
+               FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
+               if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                        efree(tempMailTo);
                        return (res);
                }
@@ -461,8 +443,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
                while (token != NULL)
                {
                        SMTP_SKIP_SPACE(token);
-                       FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
-                       if ((res = Post(Buffer)) != SUCCESS) {
+                       FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
+                       if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                                efree(tempMailTo);
                                return (res);
                        }
@@ -491,8 +473,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
                while (token != NULL)
                {
                        SMTP_SKIP_SPACE(token);
-                       FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
-                       if ((res = Post(Buffer)) != SUCCESS) {
+                       FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
+                       if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                                efree(tempMailTo);
                                return (res);
                        }
@@ -516,8 +498,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
                while (token != NULL)
                {
                        SMTP_SKIP_SPACE(token);
-                       FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
-                       if ((res = Post(Buffer)) != SUCCESS) {
+                       FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
+                       if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                                efree(tempMailTo);
                                return (res);
                        }
@@ -549,8 +531,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
                        while (token != NULL)
                        {
                                SMTP_SKIP_SPACE(token);
-                               FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
-                               if ((res = Post(Buffer)) != SUCCESS) {
+                               FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
+                               if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
                                        efree(tempMailTo);
                                        return (res);
                                }
@@ -775,22 +757,23 @@ static int MailConnect()
 #ifdef HAVE_IPV6
        IN6_ADDR addr6;
 #endif
+       SOCKADDR_IN sock_in;
 
        /* Create Socket */
-       if ((sc = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
+       if ((PW32G(mail_socket) = 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)) {
-               closesocket(sc);
+       if (gethostname(PW32G(mail_local_host), HOST_NAME_LEN)) {
+               closesocket(PW32G(mail_socket));
                return (FAILED_TO_GET_HOSTNAME);
        }
 
-       ent = gethostbyname(LocalHost);
+       ent = gethostbyname(PW32G(mail_local_host));
 
        if (!ent) {
-               closesocket(sc);
+               closesocket(PW32G(mail_socket));
                return (FAILED_TO_GET_HOSTNAME);
        }
 
@@ -803,25 +786,25 @@ static int MailConnect()
 #endif
        {
                if (namelen + 2 >= HOST_NAME_LEN) {
-                       closesocket(sc);
+                       closesocket(PW32G(mail_socket));
                        return (FAILED_TO_GET_HOSTNAME);
                }
 
-               strcpy(LocalHost, "[");
-               strcpy(LocalHost + 1, ent->h_name);
-               strcpy(LocalHost + namelen + 1, "]");
+               strcpy(PW32G(mail_local_host), "[");
+               strcpy(PW32G(mail_local_host) + 1, ent->h_name);
+               strcpy(PW32G(mail_local_host) + namelen + 1, "]");
        } else {
                if (namelen >= HOST_NAME_LEN) {
-                       closesocket(sc);
+                       closesocket(PW32G(mail_socket));
                        return (FAILED_TO_GET_HOSTNAME);
                }
 
-               strcpy(LocalHost, ent->h_name);
+               strcpy(PW32G(mail_local_host), ent->h_name);
        }
 
        /* Resolve the servers IP */
        /*
-       if (!isdigit(MailHost[0])||!gethostbyname(MailHost))
+       if (!isdigit(PW32G(mail_host)[0])||!gethostbyname(PW32G(mail_host)))
        {
                return (FAILED_TO_RESOLVE_HOST);
        }
@@ -835,10 +818,10 @@ static int MailConnect()
        /* 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);
+       sock_in.sin_addr.S_un.S_addr = GetAddr(PW32G(mail_host));
 
-       if (connect(sc, (LPSOCKADDR) & sock_in, sizeof(sock_in))) {
-               closesocket(sc);
+       if (connect(PW32G(mail_socket), (LPSOCKADDR) & sock_in, sizeof(sock_in))) {
+               closesocket(PW32G(mail_socket));
                return (FAILED_TO_CONNECT);
        }
 
@@ -863,7 +846,7 @@ static int Post(LPCSTR msg)
        int index = 0;
 
        while (len > 0) {
-               if ((slen = send(sc, msg + index, len, 0)) < 1)
+               if ((slen = send(PW32G(mail_socket), msg + index, len, 0)) < 1)
                        return (FAILED_TO_SEND);
                len -= slen;
                index += slen;
@@ -892,7 +875,7 @@ static int Ack(char **server_response)
 
 again:
 
-       if ((rlen = recv(sc, buf + Index, ((MAIL_BUFFER_SIZE) - 1) - Received, 0)) < 1) {
+       if ((rlen = recv(PW32G(mail_socket), buf + Index, ((MAIL_BUFFER_SIZE) - 1) - Received, 0)) < 1) {
                return (FAILED_TO_RECEIVE);
        }
        Received += rlen;