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-19 Instrumented lines: 92
Code covered: 82.6 % Executed lines: 76
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       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 278756 2009-04-15 14:25:06Z 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                 : 
      27                 : #if HAVE_SYSEXITS_H
      28                 : #include <sysexits.h>
      29                 : #endif
      30                 : #if HAVE_SYS_SYSEXITS_H
      31                 : #include <sys/sysexits.h>
      32                 : #endif
      33                 : 
      34                 : #if PHP_SIGCHILD
      35                 : #if HAVE_SIGNAL_H
      36                 : #include <signal.h>
      37                 : #endif
      38                 : #endif
      39                 : 
      40                 : #include "php_mail.h"
      41                 : #include "php_ini.h"
      42                 : #include "safe_mode.h"
      43                 : #include "exec.h"
      44                 : 
      45                 : #ifdef PHP_WIN32
      46                 : #include "win32/sendmail.h"
      47                 : #endif
      48                 : 
      49                 : #ifdef NETWARE
      50                 : #define EX_OK           0       /* successful termination */
      51                 : #define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
      52                 : #endif
      53                 : 
      54                 : #define SKIP_LONG_HEADER_SEP(str, pos)                                                                          \
      55                 :         if (str[pos] == '\r' && str[pos + 1] == '\n' && (str[pos + 2] == ' ' || str[pos + 2] == '\t')) {        \
      56                 :                 pos += 2;                                                                                       \
      57                 :                 while (str[pos + 1] == ' ' || str[pos + 1] == '\t') {                                                   \
      58                 :                         pos++;                                                                                  \
      59                 :                 }                                                                                               \
      60                 :                 continue;                                                                                       \
      61                 :         }                                                                                                       \
      62                 : 
      63                 : #define MAIL_ASCIIZ_CHECK(str, len)                     \
      64                 :         p = str;                                        \
      65                 :         e = p + len;                                    \
      66                 :         while ((p = memchr(p, '\0', (e - p)))) {        \
      67                 :                 *p = ' ';                               \
      68                 :         }                                               \
      69                 : 
      70                 : 
      71                 : /* {{{ proto int ezmlm_hash(string addr)
      72                 :    Calculate EZMLM list hash value. */
      73                 : PHP_FUNCTION(ezmlm_hash)
      74               7 : {
      75               7 :         char *str = NULL;
      76               7 :         unsigned int h = 5381;
      77                 :         int j, str_len;
      78                 :         
      79               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
      80                 :                                                           &str, &str_len) == FAILURE) {
      81               5 :                 return;
      82                 :         }
      83                 : 
      84              42 :         for (j = 0; j < str_len; j++) {
      85              40 :                 h = (h + (h << 5)) ^ (unsigned long) (unsigned char) tolower(str[j]);
      86                 :         }
      87                 :         
      88               2 :         h = (h % 53);
      89                 :         
      90               2 :         RETURN_LONG((int) h);
      91                 : }
      92                 : /* }}} */
      93                 : 
      94                 : /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])
      95                 :    Send an email message */
      96                 : PHP_FUNCTION(mail)
      97              10 : {
      98              10 :         char *to=NULL, *message=NULL, *headers=NULL;
      99              10 :         char *subject=NULL, *extra_cmd=NULL;
     100                 :         int to_len, message_len, headers_len;
     101                 :         int subject_len, extra_cmd_len, i;
     102              10 :         char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
     103                 :         char *to_r, *subject_r;
     104                 :         char *p, *e;
     105                 : 
     106              10 :         if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) {
     107               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect.  The fifth parameter is disabled in SAFE MODE");
     108               0 :                 RETURN_FALSE;
     109                 :         }       
     110                 :         
     111              10 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss",
     112                 :                                                           &to, &to_len,
     113                 :                                                           &subject, &subject_len,
     114                 :                                                           &message, &message_len,
     115                 :                                                           &headers, &headers_len,
     116                 :                                                           &extra_cmd, &extra_cmd_len
     117                 :                                                           ) == FAILURE) {
     118               2 :                 return;
     119                 :         }
     120                 : 
     121                 :         /* ASCIIZ check */
     122               8 :         MAIL_ASCIIZ_CHECK(to, to_len);
     123               8 :         MAIL_ASCIIZ_CHECK(subject, subject_len);
     124               8 :         MAIL_ASCIIZ_CHECK(message, message_len);
     125               8 :         if (headers) {
     126               2 :                 MAIL_ASCIIZ_CHECK(headers, headers_len);
     127                 :         }
     128               8 :         if (extra_cmd) {
     129               1 :                 MAIL_ASCIIZ_CHECK(extra_cmd, extra_cmd_len);
     130                 :         }
     131                 : 
     132               8 :         if (to_len > 0) {
     133               8 :                 to_r = estrndup(to, to_len);
     134               8 :                 for (; to_len; to_len--) {
     135               8 :                         if (!isspace((unsigned char) to_r[to_len - 1])) {
     136               8 :                                 break;
     137                 :                         }
     138               0 :                         to_r[to_len - 1] = '\0';
     139                 :                 }
     140             136 :                 for (i = 0; to_r[i]; i++) {
     141             128 :                         if (iscntrl((unsigned char) to_r[i])) {
     142                 :                                 /* According to RFC 822, section 3.1.1 long headers may be separated into
     143                 :                                  * parts using CRLF followed at least one linear-white-space character ('\t' or ' ').
     144                 :                                  * To prevent these separators from being replaced with a space, we use the
     145                 :                                  * SKIP_LONG_HEADER_SEP to skip over them.
     146                 :                                  */
     147               0 :                                 SKIP_LONG_HEADER_SEP(to_r, i);
     148               0 :                                 to_r[i] = ' ';
     149                 :                         }
     150                 :                 }
     151                 :         } else {
     152               0 :                 to_r = to;
     153                 :         }
     154                 : 
     155               8 :         if (subject_len > 0) {
     156               8 :                 subject_r = estrndup(subject, subject_len);
     157               8 :                 for (; subject_len; subject_len--) {
     158               8 :                         if (!isspace((unsigned char) subject_r[subject_len - 1])) {
     159               8 :                                 break;
     160                 :                         }
     161               0 :                         subject_r[subject_len - 1] = '\0';
     162                 :                 }
     163             104 :                 for(i = 0; subject_r[i]; i++) {
     164              96 :                         if (iscntrl((unsigned char) subject_r[i])) {
     165               0 :                                 SKIP_LONG_HEADER_SEP(subject_r, i);
     166               0 :                                 subject_r[i] = ' ';
     167                 :                         }
     168                 :                 }
     169                 :         } else {
     170               0 :                 subject_r = subject;
     171                 :         }
     172                 : 
     173               8 :         if (force_extra_parameters) {
     174               1 :                 extra_cmd = php_escape_shell_cmd(force_extra_parameters);
     175               7 :         } else if (extra_cmd) {
     176               1 :                 extra_cmd = php_escape_shell_cmd(extra_cmd);
     177                 :         }
     178                 : 
     179               8 :         if (php_mail(to_r, subject_r, message, headers, extra_cmd TSRMLS_CC)) {
     180               4 :                 RETVAL_TRUE;
     181                 :         } else {
     182               4 :                 RETVAL_FALSE;
     183                 :         }
     184                 : 
     185               8 :         if (extra_cmd) {
     186               2 :                 efree (extra_cmd);
     187                 :         }
     188               8 :         if (to_r != to) {
     189               8 :                 efree(to_r);
     190                 :         }
     191               8 :         if (subject_r != subject) {
     192               8 :                 efree(subject_r);
     193                 :         }
     194                 : }
     195                 : /* }}} */
     196                 : 
     197                 : /* {{{ php_mail
     198                 :  */
     199                 : PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC)
     200              22 : {
     201                 : #if (defined PHP_WIN32 || defined NETWARE)
     202                 :         int tsm_err;
     203                 :         char *tsm_errmsg = NULL;
     204                 : #endif
     205                 :         FILE *sendmail;
     206                 :         int ret;
     207              22 :         char *sendmail_path = INI_STR("sendmail_path");
     208              22 :         char *sendmail_cmd = NULL;
     209                 : #if PHP_SIGCHILD
     210                 :         void (*sig_handler)() = NULL;
     211                 : #endif
     212                 : 
     213              22 :         if (!sendmail_path) {
     214                 : #if (defined PHP_WIN32 || defined NETWARE)
     215                 :                 /* handle old style win smtp sending */
     216                 :                 if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, headers, subject, to, message, NULL, NULL, NULL TSRMLS_CC) == FAILURE) {
     217                 :                         if (tsm_errmsg) {
     218                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tsm_errmsg);
     219                 :                                 efree(tsm_errmsg);
     220                 :                         } else {
     221                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", GetSMErrorText(tsm_err));
     222                 :                         }
     223                 :                         return 0;
     224                 :                 }
     225                 :                 return 1;
     226                 : #else
     227               0 :                 return 0;
     228                 : #endif
     229                 :         }
     230              22 :         if (extra_cmd != NULL) {
     231               2 :                 spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd);
     232                 :         } else {
     233              20 :                 sendmail_cmd = sendmail_path;
     234                 :         }
     235                 : 
     236                 : #if PHP_SIGCHILD
     237                 :         /* Set signal handler of SIGCHLD to default to prevent other signal handlers
     238                 :          * from being called and reaping the return code when our child exits.
     239                 :          * The original handler needs to be restored after pclose() */
     240                 :         sig_handler = (void *)signal(SIGCHLD, SIG_DFL);
     241                 :         if (sig_handler == SIG_ERR) {
     242                 :                 sig_handler = NULL;
     243                 :         }
     244                 : #endif
     245                 : 
     246                 : #ifdef PHP_WIN32
     247                 :         sendmail = popen(sendmail_cmd, "wb");
     248                 : #else
     249                 :         /* Since popen() doesn't indicate if the internal fork() doesn't work
     250                 :          * (e.g. the shell can't be executed) we explicitely set it to 0 to be
     251                 :          * sure we don't catch any older errno value. */
     252              22 :         errno = 0;
     253              22 :         sendmail = popen(sendmail_cmd, "w");
     254                 : #endif
     255              22 :         if (extra_cmd != NULL)
     256               2 :                 efree (sendmail_cmd);
     257                 : 
     258              22 :         if (sendmail) {
     259                 : #ifndef PHP_WIN32
     260              22 :                 if (EACCES == errno) {
     261               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Permission denied: unable to execute shell to run mail delivery binary '%s'", sendmail_path);
     262               0 :                         pclose(sendmail);
     263                 : #if PHP_SIGCHILD
     264                 :                         /* Restore handler in case of error on Windows
     265                 :                            Not sure if this applicable on Win but just in case. */
     266                 :                         if (sig_handler) {
     267                 :                                 signal(SIGCHLD, sig_handler);
     268                 :                         }
     269                 : #endif  
     270               0 :                         return 0;
     271                 :                 }
     272                 : #endif
     273              22 :                 fprintf(sendmail, "To: %s\n", to);
     274              22 :                 fprintf(sendmail, "Subject: %s\n", subject);
     275              22 :                 if (headers != NULL) {
     276              16 :                         fprintf(sendmail, "%s\n", headers);
     277                 :                 }
     278              22 :                 fprintf(sendmail, "\n%s\n", message);
     279              22 :                 ret = pclose(sendmail);
     280                 : #if PHP_SIGCHILD
     281                 :                 if (sig_handler) {
     282                 :                         signal(SIGCHLD, sig_handler);
     283                 :                 }
     284                 : #endif
     285                 : 
     286                 : #ifdef PHP_WIN32
     287                 :                 if (ret == -1)
     288                 : #else
     289                 : #if defined(EX_TEMPFAIL)
     290              22 :                 if ((ret != EX_OK)&&(ret != EX_TEMPFAIL))
     291                 : #elif defined(EX_OK)
     292                 :                 if (ret != EX_OK)
     293                 : #else
     294                 :                 if (ret != 0)
     295                 : #endif
     296                 : #endif
     297                 :                 {
     298               4 :                         return 0;
     299                 :                 } else {
     300              18 :                         return 1;
     301                 :                 }
     302                 :         } else {
     303               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute mail delivery program '%s'", sendmail_path);
     304                 : #if PHP_SIGCHILD
     305                 :                 if (sig_handler) {
     306                 :                         signal(SIGCHLD, sig_handler);                                           
     307                 :                 }
     308                 : #endif
     309               0 :                 return 0;
     310                 :         }
     311                 : 
     312                 :         return 1; /* never reached */
     313                 : }
     314                 : /* }}} */
     315                 : 
     316                 : /* {{{ PHP_MINFO_FUNCTION
     317                 :  */
     318                 : PHP_MINFO_FUNCTION(mail)
     319               6 : {
     320               6 :         char *sendmail_path = INI_STR("sendmail_path");
     321                 : 
     322                 : #ifdef PHP_WIN32
     323                 :         if (!sendmail_path) {
     324                 :                 php_info_print_table_row(2, "Internal Sendmail Support for Windows", "enabled");
     325                 :         } else {
     326                 :                 php_info_print_table_row(2, "Path to sendmail", sendmail_path);
     327                 :         }
     328                 : #else
     329               6 :         php_info_print_table_row(2, "Path to sendmail", sendmail_path);
     330                 : #endif
     331               6 : }
     332                 : /* }}} */
     333                 : 
     334                 : /*
     335                 :  * Local variables:
     336                 :  * tab-width: 4
     337                 :  * c-basic-offset: 4
     338                 :  * End:
     339                 :  * vim600: sw=4 ts=4 fdm=marker
     340                 :  * vim<600: sw=4 ts=4
     341                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:23 +0000 (5 days ago)

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