PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - standard - mail.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 112
Code covered: 72.3 % Executed lines: 81
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Rasmus Lerdorf <rasmus@php.net>                              |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: mail.c 282505 2009-06-21 15:30:23Z iliaa $ */
      20                 : 
      21                 : #include <stdlib.h>
      22                 : #include <ctype.h>
      23                 : #include <stdio.h>
      24                 : #include "php.h"
      25                 : #include "ext/standard/info.h"
      26                 : #include "ext/standard/php_string.h"
      27                 : #include "ext/standard/basic_functions.h"
      28                 : 
      29                 : #if HAVE_SYSEXITS_H
      30                 : #include <sysexits.h>
      31                 : #endif
      32                 : #if HAVE_SYS_SYSEXITS_H
      33                 : #include <sys/sysexits.h>
      34                 : #endif
      35                 : 
      36                 : #if PHP_SIGCHILD
      37                 : #if HAVE_SIGNAL_H
      38                 : #include <signal.h>
      39                 : #endif
      40                 : #endif
      41                 : 
      42                 : #include "php_mail.h"
      43                 : #include "php_ini.h"
      44                 : #include "exec.h"
      45                 : 
      46                 : #ifdef PHP_WIN32
      47                 : #include "win32/sendmail.h"
      48                 : #endif
      49                 : 
      50                 : #ifdef NETWARE
      51                 : #define EX_OK           0       /* successful termination */
      52                 : #define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
      53                 : #endif
      54                 : 
      55                 : #define SKIP_LONG_HEADER_SEP(str, pos)                                                                                                                                  \
      56                 :         if (str[pos] == '\r' && str[pos + 1] == '\n' && (str[pos + 2] == ' ' || str[pos + 2] == '\t')) {        \
      57                 :                 pos += 2;                                                                                                                                                                               \
      58                 :                 while (str[pos + 1] == ' ' || str[pos + 1] == '\t') {                                                                                   \
      59                 :                         pos++;                                                                                                                                                                          \
      60                 :                 }                                                                                                                                                                                               \
      61                 :                 continue;                                                                                                                                                                               \
      62                 :         }                                                                                                                                                                                                       \
      63                 : 
      64                 : #define MAIL_ASCIIZ_CHECK(str, len)                             \
      65                 :         p = str;                                                                        \
      66                 :         e = p + len;                                                            \
      67                 :         while ((p = memchr(p, '\0', (e - p)))) {        \
      68                 :                 *p = ' ';                                                               \
      69                 :         }                                                                                       \
      70                 : 
      71                 : extern long php_getuid(void);
      72                 : 
      73                 : /* {{{ proto int ezmlm_hash(string addr) U
      74                 :    Calculate EZMLM list hash value. */
      75                 : PHP_FUNCTION(ezmlm_hash)
      76               7 : {
      77               7 :         char *str = NULL;
      78               7 :         unsigned int h = 5381;
      79                 :         int j, str_len;
      80                 : 
      81               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &str, &str_len, UG(ascii_conv)) == FAILURE) {
      82               5 :                 return;
      83                 :         }
      84                 : 
      85              42 :         for (j = 0; j < str_len; j++) {
      86              40 :                 h = (h + (h << 5)) ^ (unsigned long) (unsigned char) tolower(str[j]);
      87                 :         }
      88                 : 
      89               2 :         h = (h % 53);
      90                 : 
      91               2 :         RETURN_LONG((int) h);
      92                 : }
      93                 : /* }}} */
      94                 : 
      95                 : /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])
      96                 :    Send an email message */
      97                 : PHP_FUNCTION(mail)
      98              10 : {
      99              10 :         char *to=NULL, *message=NULL, *headers=NULL;
     100              10 :         char *subject=NULL, *extra_cmd=NULL;
     101              10 :         int to_len, message_len, headers_len = 0;
     102              10 :         int subject_len, extra_cmd_len = 0, i;
     103              10 :         char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
     104                 :         char *to_r, *subject_r;
     105                 :         char *p, *e;
     106                 : 
     107              10 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss",        &to, &to_len, &subject, &subject_len, &message, &message_len,
     108                 :                                                                                                                                         &headers, &headers_len, &extra_cmd, &extra_cmd_len) == FAILURE
     109                 :         ) {
     110               2 :                 return;
     111                 :         }
     112                 : 
     113                 :         /* ASCIIZ check */
     114               8 :         MAIL_ASCIIZ_CHECK(to, to_len);
     115               8 :         MAIL_ASCIIZ_CHECK(subject, subject_len);
     116               8 :         MAIL_ASCIIZ_CHECK(message, message_len);
     117               8 :         if (headers) {
     118               2 :                 MAIL_ASCIIZ_CHECK(headers, headers_len);
     119                 :         }
     120               8 :         if (extra_cmd) {
     121               1 :                 MAIL_ASCIIZ_CHECK(extra_cmd, extra_cmd_len);
     122                 :         }
     123                 : 
     124               8 :         if (to_len > 0) {
     125               8 :                 to_r = estrndup(to, to_len);
     126               8 :                 for (; to_len; to_len--) {
     127               8 :                         if (!isspace((unsigned char) to_r[to_len - 1])) {
     128               8 :                                 break;
     129                 :                         }
     130               0 :                         to_r[to_len - 1] = '\0';
     131                 :                 }
     132             136 :                 for (i = 0; to_r[i]; i++) {
     133             128 :                         if (iscntrl((unsigned char) to_r[i])) {
     134                 :                                 /* According to RFC 822, section 3.1.1 long headers may be separated into
     135                 :                                  * parts using CRLF followed at least one linear-white-space character ('\t' or ' ').
     136                 :                                  * To prevent these separators from being replaced with a space, we use the
     137                 :                                  * SKIP_LONG_HEADER_SEP to skip over them. */
     138               0 :                                 SKIP_LONG_HEADER_SEP(to_r, i);
     139               0 :                                 to_r[i] = ' ';
     140                 :                         }
     141                 :                 }
     142                 :         } else {
     143               0 :                 to_r = to;
     144                 :         }
     145                 : 
     146               8 :         if (subject_len > 0) {
     147               8 :                 subject_r = estrndup(subject, subject_len);
     148               8 :                 for (; subject_len; subject_len--) {
     149               8 :                         if (!isspace((unsigned char) subject_r[subject_len - 1])) {
     150               8 :                                 break;
     151                 :                         }
     152               0 :                         subject_r[subject_len - 1] = '\0';
     153                 :                 }
     154             104 :                 for (i = 0; subject_r[i]; i++) {
     155              96 :                         if (iscntrl((unsigned char) subject_r[i])) {
     156               0 :                                 SKIP_LONG_HEADER_SEP(subject_r, i);
     157               0 :                                 subject_r[i] = ' ';
     158                 :                         }
     159                 :                 }
     160                 :         } else {
     161               0 :                 subject_r = subject;
     162                 :         }
     163                 : 
     164               8 :         if (force_extra_parameters) {
     165               1 :                 extra_cmd = php_escape_shell_cmd(force_extra_parameters);
     166               7 :         } else if (extra_cmd) {
     167               1 :                 extra_cmd = php_escape_shell_cmd(extra_cmd);
     168                 :         }
     169                 : 
     170               8 :         if (php_mail(to_r, subject_r, message, headers, extra_cmd TSRMLS_CC)) {
     171               4 :                 RETVAL_TRUE;
     172                 :         } else {
     173               4 :                 RETVAL_FALSE;
     174                 :         }
     175                 : 
     176               8 :         if (extra_cmd) {
     177               2 :                 efree (extra_cmd);
     178                 :         }
     179               8 :         if (to_r != to) {
     180               8 :                 efree(to_r);
     181                 :         }
     182               8 :         if (subject_r != subject) {
     183               8 :                 efree(subject_r);
     184                 :         }
     185                 : }
     186                 : /* }}} */
     187                 : 
     188                 : /* {{{ php_mail
     189                 :  */
     190                 : PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC)
     191              12 : {
     192                 : #if (defined PHP_WIN32 || defined NETWARE)
     193                 :         int tsm_err;
     194                 :         char *tsm_errmsg = NULL;
     195                 : #endif
     196                 :         FILE *sendmail;
     197                 :         int ret;
     198              12 :         char *sendmail_path = INI_STR("sendmail_path");
     199              12 :         char *sendmail_cmd = NULL;
     200              12 :         char *mail_log = INI_STR("mail.log");
     201              12 :         char *hdr = headers;
     202                 : #if PHP_SIGCHILD
     203                 :         void (*sig_handler)() = NULL;
     204                 : #endif
     205                 : 
     206                 : #define MAIL_RET(val) \
     207                 :         if (hdr != headers) {   \
     208                 :                 efree(hdr);     \
     209                 :         }       \
     210                 :         return val;     \
     211                 : 
     212              12 :         if (mail_log) {
     213                 :                 char *tmp;
     214               0 :                 int l = spprintf(&tmp, 0, "mail() on [%s:%d]: To: %s -- Headers: %s\n", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), to, hdr ? hdr : "");
     215               0 :                 php_stream *stream = php_stream_open_wrapper(mail_log, "a", IGNORE_URL_WIN | REPORT_ERRORS | STREAM_DISABLE_OPEN_BASEDIR, NULL);
     216                 : 
     217               0 :                 if (hdr) { /* find all \r\n instances and replace them with spaces, so a log line is always one line long */ 
     218               0 :                         char *p = tmp;
     219               0 :                         while ((p = strpbrk(p, "\r\n"))) {
     220               0 :                                 *p = ' ';
     221                 :                         }
     222               0 :                         tmp[l - 1] = '\n';
     223                 :                 }
     224               0 :                 if (stream) {
     225               0 :                         php_stream_write(stream, tmp, l);
     226               0 :                         php_stream_close(stream);
     227                 :                 }
     228               0 :                 efree(tmp);
     229                 :         }
     230              12 :         if (PG(mail_x_header)) {
     231               0 :                 char *tmp = zend_get_executed_filename(TSRMLS_C);
     232                 :                 char *f;
     233                 :                 size_t f_len;
     234                 : 
     235               0 :                 php_basename(tmp, strlen(tmp), NULL, 0, &f, &f_len TSRMLS_CC);
     236                 : 
     237               0 :                 if (headers != NULL) {
     238               0 :                         spprintf(&hdr, 0, "X-PHP-Originating-Script: %ld:%s\r\n%s", php_getuid(), f, headers);
     239                 :                 } else {
     240               0 :                         spprintf(&hdr, 0, "X-PHP-Originating-Script: %ld:%s\n", php_getuid(), f);
     241                 :                 }
     242               0 :                 efree(f);
     243                 :         }
     244                 : 
     245              12 :         if (!sendmail_path) {
     246                 : #if (defined PHP_WIN32 || defined NETWARE)
     247                 :                 /* handle old style win smtp sending */
     248                 :                 if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message, NULL, NULL, NULL TSRMLS_CC) == FAILURE) {
     249                 :                         if (tsm_errmsg) {
     250                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tsm_errmsg);
     251                 :                                 efree(tsm_errmsg);
     252                 :                         } else {
     253                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", GetSMErrorText(tsm_err));
     254                 :                         }
     255                 :                         MAIL_RET(0);
     256                 :                 }
     257                 :                 MAIL_RET(1);
     258                 : #else
     259               0 :                 MAIL_RET(0);
     260                 : #endif
     261                 :         }
     262              12 :         if (extra_cmd != NULL) {
     263               2 :                 spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd);
     264                 :         } else {
     265              10 :                 sendmail_cmd = sendmail_path;
     266                 :         }
     267                 : 
     268                 : #if PHP_SIGCHILD
     269                 :         /* Set signal handler of SIGCHLD to default to prevent other signal handlers
     270                 :          * from being called and reaping the return code when our child exits.
     271                 :          * The original handler needs to be restored after pclose() */
     272                 :         sig_handler = (void *)signal(SIGCHLD, SIG_DFL);
     273                 :         if (sig_handler == SIG_ERR) {
     274                 :                 sig_handler = NULL;
     275                 :         }
     276                 : #endif
     277                 : 
     278                 : #ifdef PHP_WIN32
     279                 :         sendmail = popen(sendmail_cmd, "wb");
     280                 : #else
     281                 :         /* Since popen() doesn't indicate if the internal fork() doesn't work
     282                 :          * (e.g. the shell can't be executed) we explicitely set it to 0 to be
     283                 :          * sure we don't catch any older errno value. */
     284              12 :         errno = 0;
     285              12 :         sendmail = popen(sendmail_cmd, "w");
     286                 : #endif
     287              12 :         if (extra_cmd != NULL) {
     288               2 :                 efree (sendmail_cmd);
     289                 :         }
     290                 : 
     291              12 :         if (sendmail) {
     292                 : #ifndef PHP_WIN32
     293              12 :                 if (EACCES == errno) {
     294               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Permission denied: unable to execute shell to run mail delivery binary '%s'", sendmail_path);
     295               0 :                         pclose(sendmail);
     296                 : #if PHP_SIGCHILD
     297                 :                         /* Restore handler in case of error on Windows
     298                 :                            Not sure if this applicable on Win but just in case. */
     299                 :                         if (sig_handler) {
     300                 :                                 signal(SIGCHLD, sig_handler);
     301                 :                         }
     302                 : #endif
     303               0 :                         MAIL_RET(0);
     304                 :                 }
     305                 : #endif
     306              12 :                 fprintf(sendmail, "To: %s\n", to);
     307              12 :                 fprintf(sendmail, "Subject: %s\n", subject);
     308              12 :                 if (hdr != NULL) {
     309               6 :                         fprintf(sendmail, "%s\n", hdr);
     310                 :                 }
     311              12 :                 fprintf(sendmail, "\n%s\n", message);
     312              12 :                 ret = pclose(sendmail);
     313                 : 
     314                 : #if PHP_SIGCHILD
     315                 :                 if (sig_handler) {
     316                 :                         signal(SIGCHLD, sig_handler);
     317                 :                 }
     318                 : #endif
     319                 : 
     320                 : #ifdef PHP_WIN32
     321                 :                 if (ret == -1)
     322                 : #else
     323                 : #if defined(EX_TEMPFAIL)
     324              12 :                 if ((ret != EX_OK)&&(ret != EX_TEMPFAIL))
     325                 : #elif defined(EX_OK)
     326                 :                 if (ret != EX_OK)
     327                 : #else
     328                 :                 if (ret != 0)
     329                 : #endif
     330                 : #endif
     331                 :                 {
     332               4 :                         MAIL_RET(0);
     333                 :                 } else {
     334               8 :                         MAIL_RET(1);
     335                 :                 }
     336                 :         } else {
     337               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute mail delivery program '%s'", sendmail_path);
     338                 : #if PHP_SIGCHILD
     339                 :                 if (sig_handler) {
     340                 :                         signal(SIGCHLD, sig_handler);                                           
     341                 :                 }
     342                 : #endif
     343               0 :                 MAIL_RET(0);
     344                 :         }
     345                 : 
     346                 :         MAIL_RET(1); /* never reached */
     347                 : }
     348                 : /* }}} */
     349                 : 
     350                 : /* {{{ PHP_MINFO_FUNCTION
     351                 :  */
     352                 : PHP_MINFO_FUNCTION(mail)
     353              44 : {
     354              44 :         char *sendmail_path = INI_STR("sendmail_path");
     355                 : 
     356                 : #ifdef PHP_WIN32
     357                 :         if (!sendmail_path) {
     358                 :                 php_info_print_table_row(2, "Internal Sendmail Support for Windows", "enabled");
     359                 :         } else {
     360                 :                 php_info_print_table_row(2, "Path to sendmail", sendmail_path);
     361                 :         }
     362                 : #else
     363              44 :         php_info_print_table_row(2, "Path to sendmail", sendmail_path);
     364                 : #endif
     365              44 : }
     366                 : /* }}} */
     367                 : 
     368                 : /*
     369                 :  * Local variables:
     370                 :  * tab-width: 4
     371                 :  * c-basic-offset: 4
     372                 :  * End:
     373                 :  * vim600: sw=4 ts=4 fdm=marker
     374                 :  * vim<600: sw=4 ts=4
     375                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:43 +0000 (34 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.