mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
fix thread safety for win32/sendmail
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -69,22 +71,6 @@
|
||||
#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;
|
||||
|
||||
Reference in New Issue
Block a user