From: Hartmut Holzgraefe Date: Mon, 7 Feb 2000 15:52:47 +0000 (+0000) Subject: another re-sync with the PHP3 tree X-Git-Tag: BEFORE_SAPIFICATION_FEB_10_2000~52 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce62bbb67403280ecafde565aff203b24ea05145;p=php another re-sync with the PHP3 tree imap_mail deactivated for win builds, as the files win32/imap_sendmail.c win32/imap_sendmail.h from PHP3 are still missing --- diff --git a/ext/imap/imap.c b/ext/imap/imap.c index 7438cdde0c..9962f18dd7 100644 --- a/ext/imap/imap.c +++ b/ext/imap/imap.c @@ -30,6 +30,7 @@ #endif #include "php.h" +#include "php_ini.h" #ifdef COMPILE_DL_IMAP #include "dl/phpdl.h" @@ -79,6 +80,7 @@ void *fs_get (size_t size); static int add_assoc_object(pval *arg, char *key, pval *tmp); int add_next_index_object(pval *arg, pval *tmp); void imap_add_body( pval *arg, BODY *body ); +int imap_mail(char *to, char *subject, char *message, char *headers, char *cc, char *bcc, char *rpath); typedef struct php_imap_le_struct { MAILSTREAM *imap_stream; @@ -173,8 +175,12 @@ function_entry imap_functions[] = { PHP_FE(imap_alerts, NULL) PHP_FE(imap_errors, NULL) PHP_FE(imap_last_error, NULL) +#if !(WIN32|WINNT) + PHP_FE(imap_mail, NULL) +#endif PHP_FE(imap_search, NULL) - PHP_FE(imap_utf8, NULL) + PHP_FE(imap_utf7_decode, NULL) + PHP_FE(imap_utf7_encode, NULL) {NULL, NULL, NULL} }; @@ -1487,13 +1493,14 @@ PHP_FUNCTION(imap_listscan) /* }}} */ /* {{{ proto object imap_check(int stream_id) + Get mailbox properties */ PHP_FUNCTION(imap_check) { pval *streamind; int ind, ind_type; pils *imap_le_struct; - char date[50]; + char date[100]; if (ARG_COUNT(ht)!=1 || getParameters(ht,1,&streamind) == FAILURE) { WRONG_PARAM_COUNT; @@ -2344,7 +2351,7 @@ PHP_FUNCTION(imap_binary) PHP_FUNCTION(imap_mailboxmsginfo) { pval *streamind; - char date[50]; + char date[100]; int ind, ind_type; unsigned int msgno; pils *imap_le_struct; @@ -2455,7 +2462,7 @@ PHP_FUNCTION(imap_rfc822_parse_adrlist) /* {{{ proto string imap_utf8(string string) - Convert a string to UTF8 */ + Convert a string to UTF-8 */ PHP_FUNCTION(imap_utf8) { pval *string; @@ -2477,6 +2484,311 @@ PHP_FUNCTION(imap_utf8) } /* }}} */ + +/* macros for the modified utf7 conversion functions */ +/* author: Andrew Skalski */ + +/* tests `c' and returns true if it is a special character */ +#define SPECIAL(c) ((c) <= 0x1f || (c) >= 0x7f) +/* validate a modified-base64 character */ +#define B64CHAR(c) (isalnum(c) || (c) == '+' || (c) == ',') +/* map the low 64 bits of `n' to the modified-base64 characters */ +#define B64(n) ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefghijklmnopqrstuvwxyz0123456789+,"[(n) & 0x3f]) +/* map the modified-base64 character `c' to its 64 bit value */ +#define UNB64(c) ((c) == '+' ? 62 : (c) == ',' ? 63 : (c) >= 'a' ? \ + (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4) + +/* {{{ proto string imap_utf7_decode(string buf) + Decode a modified UTF-7 string */ +PHP_FUNCTION(imap_utf7_decode) +{ + /* author: Andrew Skalski */ + int argc; + pval *arg; + const unsigned char *in, *inp, *endp; + unsigned char *out, *outp; + int inlen, outlen; + enum { ST_NORMAL, /* printable text */ + ST_DECODE0, /* encoded text rotation... */ + ST_DECODE1, + ST_DECODE2, + ST_DECODE3 + } state; + + /* collect arguments */ + argc = ARG_COUNT(ht); + if (argc != 1 || getParameters(ht, argc, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + in = (const unsigned char*) arg->value.str.val; + inlen = arg->value.str.len; + + /* validate and compute length of output string */ + outlen = 0; + state = ST_NORMAL; + for (endp = (inp = in) + inlen; inp < endp; inp++) { + if (state == ST_NORMAL) { + /* process printable character */ + if (SPECIAL(*inp)) { + php_error(E_WARNING, "imap_utf7_decode: " + "Invalid modified UTF-7 character: " + "`%c'", *inp); + RETURN_FALSE; + } + else if (*inp != '&') { + outlen++; + } + else if (inp + 1 == endp) { + php_error(E_WARNING, "imap_utf7_decode: " + "Unexpected end of string"); + RETURN_FALSE; + } + else if (inp[1] != '-') { + state = ST_DECODE0; + } + else { + outlen++; + inp++; + } + } + else if (*inp == '-') { + /* return to NORMAL mode */ + if (state == ST_DECODE1) { + php_error(E_WARNING, "imap_utf7_decode: " + "Stray modified base64 character: " + "`%c'", *--inp); + RETURN_FALSE; + } + state = ST_NORMAL; + } + else if (!B64CHAR(*inp)) { + php_error(E_WARNING, "imap_utf7_decode: " + "Invalid modified base64 character: " + "`%c'", *inp); + RETURN_FALSE; + } + else { + switch (state) { + case ST_DECODE3: + outlen++; + state = ST_DECODE0; + break; + case ST_DECODE2: + case ST_DECODE1: + outlen++; + case ST_DECODE0: + state++; + case ST_NORMAL: + } + } + } + + /* enforce end state */ + if (state != ST_NORMAL) { + php_error(E_WARNING, "imap_utf7_decode: " + "Unexpected end of string"); + RETURN_FALSE; + } + + /* allocate output buffer */ + if ((out = emalloc(outlen + 1)) == NULL) { + php_error(E_WARNING, "imap_utf7_decode: " + "Unable to allocate result string"); + RETURN_FALSE; + } + + /* decode input string */ + outp = out; + state = ST_NORMAL; + for (endp = (inp = in) + inlen; inp < endp; inp++) { + if (state == ST_NORMAL) { + if (*inp == '&' && inp[1] != '-') { + state = ST_DECODE0; + } + else if ((*outp++ = *inp) == '&') { + inp++; + } + } + else if (*inp == '-') { + state = ST_NORMAL; + } + else { + /* decode input character */ + switch (state) { + case ST_DECODE0: + *outp = UNB64(*inp) << 2; + state = ST_DECODE1; + break; + case ST_DECODE1: + outp[1] = UNB64(*inp); + *outp++ |= outp[1] >> 4; + *outp <<= 4; + state = ST_DECODE2; + break; + case ST_DECODE2: + outp[1] = UNB64(*inp); + *outp++ |= outp[1] >> 2; + *outp <<= 6; + state = ST_DECODE3; + break; + case ST_DECODE3: + *outp++ |= UNB64(*inp); + state = ST_DECODE0; + case ST_NORMAL: + } + } + } + + *outp = 0; + +#if DEBUG + /* warn if we computed outlen incorrectly */ + if (outp - out != outlen) { + php_error(E_WARNING, + "imap_utf7_decode: outp - out [%d] != outlen [%d]", + outp - out, outlen); + } +#endif + + RETURN_STRINGL(out, outlen, 0); +} +/* }}} */ + +/* {{{ proto string imap_utf7_encode(string buf) + Encode a string in modified UTF-7 */ +PHP_FUNCTION(imap_utf7_encode) +{ + /* author: Andrew Skalski */ + int argc; + pval *arg; + const unsigned char *in, *inp, *endp; + unsigned char *out, *outp; + int inlen, outlen; + enum { ST_NORMAL, /* printable text */ + ST_ENCODE0, /* encoded text rotation... */ + ST_ENCODE1, + ST_ENCODE2 + } state; + + /* collect arguments */ + argc = ARG_COUNT(ht); + if (argc != 1 || getParameters(ht, argc, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + in = (const unsigned char*) arg->value.str.val; + inlen = arg->value.str.len; + + /* compute the length of the result string */ + outlen = 0; + state = ST_NORMAL; + endp = (inp = in) + inlen; + while (inp < endp) { + if (state == ST_NORMAL) { + if (SPECIAL(*inp)) { + state = ST_ENCODE0; + outlen++; + } + else if (*inp++ == '&') { + outlen++; + } + outlen++; + } + else if (!SPECIAL(*inp)) { + state = ST_NORMAL; + } + else { + /* ST_ENCODE0 -> ST_ENCODE1 - two chars + * ST_ENCODE1 -> ST_ENCODE2 - one char + * ST_ENCODE2 -> ST_ENCODE0 - one char + */ + if (state == ST_ENCODE2) { + state = ST_ENCODE0; + } + else if (state++ == ST_ENCODE0) { + outlen++; + } + outlen++; + inp++; + } + } + + /* allocate output buffer */ + if ((out = emalloc(outlen + 1)) == NULL) { + php_error(E_WARNING, "imap_utf7_encode: " + "Unable to allocate result string"); + RETURN_FALSE; + } + + /* encode input string */ + outp = out; + state = ST_NORMAL; + endp = (inp = in) + inlen; + while (inp < endp || state != ST_NORMAL) { + if (state == ST_NORMAL) { + if (SPECIAL(*inp)) { + /* begin encoding */ + *outp++ = '&'; + state = ST_ENCODE0; + } + else if ((*outp++ = *inp++) == '&') { + *outp++ = '-'; + } + } + else if (inp == endp || !SPECIAL(*inp)) { + /* flush overflow and terminate region */ + if (state != ST_ENCODE0) { + *outp++ = B64(*outp); + } + *outp++ = '-'; + state = ST_NORMAL; + } + else { + /* encode input character */ + switch (state) { + case ST_ENCODE0: + *outp++ = B64(*inp >> 2); + *outp = *inp++ << 4; + state = ST_ENCODE1; + break; + case ST_ENCODE1: + *outp++ = B64(*outp | *inp >> 4); + *outp = *inp++ << 2; + state = ST_ENCODE2; + break; + case ST_ENCODE2: + *outp++ = B64(*outp | *inp >> 6); + *outp++ = B64(*inp++); + state = ST_ENCODE0; + case ST_NORMAL: + } + } + } + + *outp = 0; + +#if DEBUG + /* warn if we computed outlen incorrectly */ + if (outp - out != outlen) { + php_error(E_WARNING, + "imap_utf7_encode: outp - out [%d] != outlen [%d]", + outp - out, outlen); + } +#endif + + RETURN_STRINGL(out, outlen, 0); +} +/* }}} */ + +#undef SPECIAL +#undef B64CHAR +#undef B64 +#undef UNB64 + + + /* {{{ proto int imap_setflag_full(int stream_id, string sequence, string flag [, int options]) Sets flags on messages */ PHP_FUNCTION(imap_setflag_full) @@ -3126,6 +3438,123 @@ PHP_FUNCTION(imap_mail_compose) } /* }}} */ +#if !(WIN32|WINNT) +int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *cc, char *bcc, char* rpath) +{ +#if MSVC5 + int tsm_err; +#else + FILE *sendmail; + int ret; +#endif + +#if MSVC5 + if (imap_TSendMail(INI_STR("smtp"),&tsm_err,headers,subject,to,message,cc,bcc,rpath) != SUCCESS){ + php_error(E_WARNING, GetSMErrorText(tsm_err)); + return 0; + } +#else + if (!INI_STR("sendmail_path")) { + return 0; + } + sendmail = popen(INI_STR("sendmail_path"), "w"); + if (sendmail) { + fprintf(sendmail, "To: %s\n", to); + if (cc && cc[0]) fprintf(sendmail, "Cc: %s\n", cc); + if (bcc && bcc[0]) fprintf(sendmail, "Bcc: %s\n", bcc); + fprintf(sendmail, "Subject: %s\n", subject); + if (headers != NULL) { + fprintf(sendmail, "%s\n", headers); + } + fprintf(sendmail, "\n%s\n", message); + ret = pclose(sendmail); + if (ret == -1) { + return 0; + } else { + return 1; + } + } else { + php_error(E_WARNING, "Could not execute mail delivery program"); + return 0; + } +#endif + return 1; +} + +/* {{{ proto int imap_mail(string to, string subject, string message [, string additional_headers [, string cc [, string bcc [, string rpath]]]]) + Send an email message */ +PHP_FUNCTION(imap_mail) +{ + pval *argv[6]; + char *to=NULL, *message=NULL, *headers=NULL, *subject=NULL, *cc=NULL, *bcc=NULL, *rpath=NULL; + int argc; + + argc = ARG_COUNT(ht); + if (argc < 3 || argc > 7 || getParametersArray(ht, argc, argv) == FAILURE) { + WRONG_PARAM_COUNT; + } + /* To: */ + convert_to_string(argv[0]); + if (argv[0]->value.str.val) { + to = argv[0]->value.str.val; + } else { + php_error(E_WARNING, "No to field in mail command"); + RETURN_FALSE; + } + + /* Subject: */ + convert_to_string(argv[1]); + if (argv[1]->value.str.val) { + subject = argv[1]->value.str.val; + } else { + php_error(E_WARNING, "No subject field in mail command"); + RETURN_FALSE; + } + + /* message body */ + convert_to_string(argv[2]); + if (argv[2]->value.str.val) { + message = argv[2]->value.str.val; + } else { + /* this is not really an error, so it is allowed. */ + php_error(E_WARNING, "No message string in mail command"); + message = NULL; + } + + /* other headers */ + if (argc > 3) { + convert_to_string(argv[3]); + headers = argv[3]->value.str.val; + } + + /* cc */ + if (argc > 4) { + convert_to_string(argv[4]); + cc = argv[4]->value.str.val; + } + + /* bcc */ + if (argc > 5) { + convert_to_string(argv[5]); + bcc = argv[5]->value.str.val; + } + + /* rpath */ + if (argc > 6) { + convert_to_string(argv[6]); + rpath = argv[6]->value.str.val; + } + + if (_php_imap_mail(to, subject, message, headers, cc, bcc, rpath)){ + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +#endif + /* {{{ proto array imap_search(int stream_id, string criteria [, long flags]) Return a list of messages matching the criteria */ PHP_FUNCTION(imap_search) @@ -3178,6 +3607,10 @@ PHP_FUNCTION(imap_search) /* {{{ proto array imap_alerts(void) Returns an array of all IMAP alerts that have been generated */ +/* Returns an array of all IMAP alerts that have been generated either + since the last page load, or since the last imap_alerts() call, + whichever came last. The alert stack is cleared after imap_alerts() + is called. */ /* Author: CJH */ PHP_FUNCTION(imap_alerts) { @@ -3207,6 +3640,9 @@ PHP_FUNCTION(imap_alerts) /* {{{ proto array imap_errors(void) Returns an array of all IMAP errors generated */ +/* Returns an array of all IMAP errors generated either since the last + page load, or since the last imap_errors() call, whichever came + last. The error stack is cleared after imap_errors() is called. */ /* Author: CJH */ PHP_FUNCTION(imap_errors) { diff --git a/ext/imap/imap.h b/ext/imap/imap.h index ce2e0fee4d..082751f442 100644 --- a/ext/imap/imap.h +++ b/ext/imap/imap.h @@ -74,8 +74,13 @@ PHP_FUNCTION(imap_mail_compose); PHP_FUNCTION(imap_alerts); PHP_FUNCTION(imap_errors); PHP_FUNCTION(imap_last_error); +#if !(WIN32|WINNT) +PHP_FUNCTION(imap_mail); +#endif PHP_FUNCTION(imap_search); PHP_FUNCTION(imap_utf8); +PHP_FUNCTION(imap_utf7_decode); +PHP_FUNCTION(imap_utf7_encode); #else #define imap_module_ptr NULL #endif /* HAVE_IMAP */