cvs: php4 /win32 sendmail.c sendmail.h
| From: | Markus Fischer | Date: | Wed, 05 Jun 2002 17:08:38 +0000 |
| Subject: | cvs: php4 /win32 sendmail.c sendmail.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-12235@lists.php.net to get a copy of this message | ||
mfischer Wed Jun 5 13:08:38 2002 EDT
Modified files:
/php4/win32 sendmail.c sendmail.h
Log:
- Headers are now rewritten to always have \r\n line endings for SMTP.
Also automatically removes superflous line breaks at
the start and end of the header.
# http://cr.yp.to/docs/smtplf.html is a good read
about this topic.
Index: php4/win32/sendmail.c
diff -u php4/win32/sendmail.c:1.39 php4/win32/sendmail.c:1.40
--- php4/win32/sendmail.c:1.39 Mon Jun 3 10:39:30 2002
+++ php4/win32/sendmail.c Wed Jun 5 13:08:38 2002
@@ -17,7 +17,7 @@
*
*/
-/* $Id: sendmail.c,v 1.39 2002/06/03 14:39:30 mfischer Exp $ */
+/* $Id: sendmail.c,v 1.40 2002/06/05 17:08:38 mfischer Exp $ */
#include "php.h" /*php specific */
#include <stdio.h>
@@ -30,6 +30,10 @@
#include <winbase.h>
#include "sendmail.h"
#include "php_ini.h"
+
+#if HAVE_PCRE || HAVE_BUNDLED_PCRE
+#include "ext/pcre/php_pcre.h"
+#endif
/*
extern int _daylight;
@@ -100,10 +104,78 @@
{"Bad Mail Host"},
{"Bad Message File"},
{"\"sendmail_from\" not set in php.ini or custom \"From:\" header
missing"},
- {"Mailserver rejected our \"sendmail_from\" setting"} /* 20 */
+ {"Mailserver rejected our \"sendmail_from\" setting"}, /* 20 */
+ {"Error while trimming mail header with PCRE, please file a bug report at http://bugs.php.net/"} /* 21 */
};
-
-
+
+/* This pattern converts all single occurences of \n (Unix)
+ * withour a leading \r to \r\n and all occurences of \r (Mac)
+ * without a trailing \n to \r\n
+ * Thx to Nibbler from ircnet/#linuxger
+ */
+#define PHP_WIN32_MAIL_UNIFY_PATTERN "/(\r\n?)|\n/"
+#define PHP_WIN32_MAIL_UNIFY_REPLACE "\r\n"
+
+/* This pattern removes \r\n from the start of the string,
+ * \r\n from the end of the string and also makes sure every line
+ * is only wrapped with a single \r\n (thus reduces multiple
+ * occurences of \r\n between lines to a single \r\n) */
+#define PHP_WIN32_MAIL_RMVDBL_PATTERN "/^\r\n|(\r\n)+$/m"
+#define PHP_WIN32_MAIL_RMVDBL_REPLACE ""
+
+/* This function is meant to unify the headers passed to to mail()
+ * This means, use PCRE to transform single occurences of \n or \r in \r\n
+ * As a second step we also eleminate all \r\n occurences which are:
+ * 1) At the start of the header
+ * 2) At the end of the header
+ * 3) Two or more occurences in the header are removed so only one is left
+ *
+ * Returns NULL on error, or the new char* buffer on success.
+ * You have to take care and efree() the buffer on your own.
+ */
+static char *php_win32_mail_trim_header(char *header TSRMLS_DC)
+{
+
+#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 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 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
+}
/*********************************************************************
// Name: TSendMail
@@ -123,7 +195,8 @@
{
int ret;
char *RPath = NULL;
- char *headers_lc = NULL; /* headers_lc is only created if we've a header at all */
+ char *headers_lc = NULL; /* headers_lc is only created if we've a header at all */
+ TSRMLS_FETCH();
WinsockStarted = FALSE;
@@ -139,10 +212,18 @@
if (headers) {
char *pos = NULL;
- size_t i;
+ 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))) {
+ if (NULL == (headers_lc = estrdup(headers))) {
+ efree(headers);
*error = OUT_OF_MEMORY;
return FAILURE;
}
@@ -155,7 +236,8 @@
if (INI_STR("sendmail_from")) {
RPath = estrdup(INI_STR("sendmail_from"));
} else {
- if (headers_lc) {
+ if (headers) {
+ efree(headers);
efree(headers_lc);
}
*error = W32_SM_SENDMAIL_FROM_NOT_SET;
@@ -168,7 +250,8 @@
if (RPath) {
efree(RPath);
}
- if (headers_lc) {
+ if (headers) {
+ efree(headers);
efree(headers_lc);
}
/* 128 is safe here, the specifier in snprintf isn't longer than that */
@@ -186,7 +269,8 @@
if (RPath) {
efree(RPath);
}
- if (headers_lc) {
+ if (headers) {
+ efree(headers);
efree(headers_lc);
}
if (ret != SUCCESS) {
@@ -311,10 +395,13 @@
while(token != NULL)
{
snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token);
- if ((res = Post(Buffer)) != SUCCESS)
- return (res);
+ if ((res = Post(Buffer)) != SUCCESS) {
+ efree(tempMailTo);
+ return (res);
+ }
if ((res = Ack(&server_response)) != SUCCESS) {
- SMTP_ERROR_RESPONSE(server_response);
+ SMTP_ERROR_RESPONSE(server_response);
+ efree(tempMailTo);
return (res);
}
token = strtok(NULL, ",");
Index: php4/win32/sendmail.h
diff -u php4/win32/sendmail.h:1.8 php4/win32/sendmail.h:1.9
--- php4/win32/sendmail.h:1.8 Fri May 17 12:16:27 2002
+++ php4/win32/sendmail.h Wed Jun 5 13:08:38 2002
@@ -27,8 +27,9 @@
#define BAD_MAIL_HOST 17
#define BAD_MSG_FILE 18
#define W32_SM_SENDMAIL_FROM_NOT_SET 19
-#define W32_SM_SENDMAIL_FROM_MALFORMED 20
-#define MAX_ERROR_INDEX 21 /* Always last error message + 1 */
+#define W32_SM_SENDMAIL_FROM_MALFORMED 20
+#define W32_SM_PCRE_ERROR 21
+#define MAX_ERROR_INDEX 22 /* Always last error message + 1 */
int TSendMail(char *smtpaddr, int *returnerror, char **error_message,