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 - imap - php_imap.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 2157
Code covered: 46.0 % Executed lines: 993
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                 :    | Authors: Rex Logan           <veebert@dimensional.com>               |
      16                 :    |          Mark Musone         <musone@afterfive.com>                  |
      17                 :    |          Brian Wang          <brian@vividnet.com>                    |
      18                 :    |          Kaj-Michael Lang    <milang@tal.org>                        |
      19                 :    |          Antoni Pamies Olive <toni@readysoft.net>                    |
      20                 :    |          Rasmus Lerdorf      <rasmus@php.net>                        |
      21                 :    |          Chuck Hagenbuch     <chuck@horde.org>                       |
      22                 :    |          Andrew Skalski      <askalski@chekinc.com>                  |
      23                 :    |          Hartmut Holzgraefe  <hholzgra@php.net>                      |
      24                 :    |          Jani Taskinen       <sniper@iki.fi>                         |
      25                 :    |          Daniel R. Kalowsky  <kalowsky@php.net>                      |
      26                 :    | PHP 4.0 updates:  Zeev Suraski <zeev@zend.com>                       |
      27                 :    +----------------------------------------------------------------------+
      28                 :  */
      29                 : /* $Id: php_imap.c 288585 2009-09-22 18:18:57Z felipe $ */
      30                 : 
      31                 : #define IMAP41
      32                 : 
      33                 : #ifdef HAVE_CONFIG_H
      34                 : #include "config.h"
      35                 : #endif
      36                 : 
      37                 : #include "php.h"
      38                 : #include "php_ini.h"
      39                 : #include "php_streams.h"
      40                 : #include "ext/standard/php_string.h"
      41                 : #include "ext/standard/info.h"
      42                 : #include "ext/standard/file.h"
      43                 : #include "ext/standard/php_smart_str.h"
      44                 : 
      45                 : #ifdef ERROR
      46                 : #undef ERROR
      47                 : #endif
      48                 : #include "php_imap.h"
      49                 : 
      50                 : #include <time.h>
      51                 : #include <stdio.h>
      52                 : #include <ctype.h>
      53                 : #include <signal.h>
      54                 : 
      55                 : #ifdef PHP_WIN32
      56                 : #include <winsock2.h>
      57                 : #include <stdlib.h>
      58                 : #include "win32/sendmail.h"
      59                 : MAILSTREAM DEFAULTPROTO;
      60                 : #endif
      61                 : 
      62                 : #define CRLF     "\015\012"
      63                 : #define CRLF_LEN sizeof("\015\012") - 1
      64                 : #define PHP_EXPUNGE 32768
      65                 : #define PHP_IMAP_ADDRESS_SIZE_BUF 10
      66                 : #ifndef SENDBUFLEN
      67                 : #define SENDBUFLEN 16385
      68                 : #endif
      69                 : 
      70                 : 
      71                 : static void _php_make_header_object(zval *myzvalue, ENVELOPE *en TSRMLS_DC);
      72                 : static void _php_imap_add_body(zval *arg, BODY *body TSRMLS_DC);
      73                 : static char* _php_imap_parse_address(ADDRESS *addresslist, zval *paddress TSRMLS_DC);
      74                 : static char* _php_rfc822_write_address(ADDRESS *addresslist TSRMLS_DC);
      75                 : 
      76                 : /* the gets we use */
      77                 : static char *php_mail_gets(readfn_t f, void *stream, unsigned long size, GETS_DATA *md);
      78                 : 
      79                 : /* These function declarations are missing from the IMAP header files... */
      80                 : void rfc822_date(char *date);
      81                 : char *cpystr(const char *str);
      82                 : char *cpytxt(SIZEDTEXT *dst, char *text, unsigned long size);
      83                 : #ifndef HAVE_NEW_MIME2TEXT
      84                 : long utf8_mime2text(SIZEDTEXT *src, SIZEDTEXT *dst);
      85                 : #else
      86                 : long utf8_mime2text (SIZEDTEXT *src, SIZEDTEXT *dst, long flags);
      87                 : #endif
      88                 : unsigned long find_rightmost_bit(unsigned long *valptr);
      89                 : void fs_give(void **block);
      90                 : void *fs_get(size_t size);
      91                 : 
      92                 : ZEND_DECLARE_MODULE_GLOBALS(imap)
      93                 : static PHP_GINIT_FUNCTION(imap);
      94                 : 
      95                 : /* {{{ imap_functions[]
      96                 :  */
      97                 : zend_function_entry imap_functions[] = {
      98                 :         PHP_FE(imap_open,                                                               NULL)
      99                 :         PHP_FE(imap_reopen,                                                             NULL)
     100                 :         PHP_FE(imap_close,                                                              NULL)
     101                 :         PHP_FE(imap_num_msg,                                                    NULL)
     102                 :         PHP_FE(imap_num_recent,                                                 NULL)
     103                 :         PHP_FE(imap_headers,                                                    NULL)
     104                 :         PHP_FE(imap_headerinfo,                                                 NULL)
     105                 :         PHP_FE(imap_rfc822_parse_headers,                               NULL)
     106                 :         PHP_FE(imap_rfc822_write_address,                               NULL)
     107                 :         PHP_FE(imap_rfc822_parse_adrlist,                               NULL)
     108                 :         PHP_FE(imap_body,                                                               NULL)
     109                 :         PHP_FE(imap_bodystruct,                                                 NULL)
     110                 :         PHP_FE(imap_fetchbody,                                                  NULL)
     111                 :         PHP_FE(imap_savebody,                                                   NULL)
     112                 :         PHP_FE(imap_fetchheader,                                                NULL)
     113                 :         PHP_FE(imap_fetchstructure,                                             NULL)
     114                 :         PHP_FE(imap_expunge,                                                    NULL)
     115                 :         PHP_FE(imap_delete,                                                             NULL)
     116                 :         PHP_FE(imap_undelete,                                                   NULL)
     117                 :         PHP_FE(imap_check,                                                              NULL)
     118                 :         PHP_FE(imap_listscan,                                                   NULL)
     119                 :         PHP_FE(imap_mail_copy,                                                  NULL)
     120                 :         PHP_FE(imap_mail_move,                                                  NULL)
     121                 :         PHP_FE(imap_mail_compose,                                               NULL)
     122                 :         PHP_FE(imap_createmailbox,                                              NULL)
     123                 :         PHP_FE(imap_renamemailbox,                                              NULL)
     124                 :         PHP_FE(imap_deletemailbox,                                              NULL)
     125                 :         PHP_FE(imap_subscribe,                                                  NULL)
     126                 :         PHP_FE(imap_unsubscribe,                                                NULL)
     127                 :         PHP_FE(imap_append,                                                             NULL)
     128                 :         PHP_FE(imap_ping,                                                               NULL)
     129                 :         PHP_FE(imap_base64,                                                             NULL)
     130                 :         PHP_FE(imap_qprint,                                                             NULL)
     131                 :         PHP_FE(imap_8bit,                                                               NULL)
     132                 :         PHP_FE(imap_binary,                                                             NULL)
     133                 :         PHP_FE(imap_utf8,                                                               NULL)
     134                 :         PHP_FE(imap_status,                                                             NULL)
     135                 :         PHP_FE(imap_mailboxmsginfo,                                             NULL)
     136                 :         PHP_FE(imap_setflag_full,                                               NULL)
     137                 :         PHP_FE(imap_clearflag_full,                                             NULL)
     138                 :         PHP_FE(imap_sort,                                                               NULL)
     139                 :         PHP_FE(imap_uid,                                                                NULL)
     140                 :         PHP_FE(imap_msgno,                                                              NULL)
     141                 :         PHP_FE(imap_list,                                                               NULL)
     142                 :         PHP_FE(imap_lsub,                                                               NULL)
     143                 :         PHP_FE(imap_fetch_overview,                                             NULL)
     144                 :         PHP_FE(imap_alerts,                                                             NULL)
     145                 :         PHP_FE(imap_errors,                                                             NULL)
     146                 :         PHP_FE(imap_last_error,                                                 NULL)
     147                 :         PHP_FE(imap_search,                                                             NULL)
     148                 :         PHP_FE(imap_utf7_decode,                                                NULL)
     149                 :         PHP_FE(imap_utf7_encode,                                                NULL)
     150                 :         PHP_FE(imap_mime_header_decode,                                 NULL)
     151                 :         PHP_FE(imap_thread,                                                             NULL)
     152                 :         PHP_FE(imap_timeout,                                                            NULL)
     153                 : 
     154                 : #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
     155                 :         PHP_FE(imap_get_quota,                                                  NULL)
     156                 :         PHP_FE(imap_get_quotaroot,                                              NULL)
     157                 :         PHP_FE(imap_set_quota,                                                  NULL)
     158                 :         PHP_FE(imap_setacl,                                                             NULL)
     159                 :         PHP_FE(imap_getacl,                                                             NULL)
     160                 : #endif
     161                 : 
     162                 :         PHP_FE(imap_mail,                                                               NULL)
     163                 : 
     164                 :         PHP_FALIAS(imap_header,                 imap_headerinfo,        NULL)
     165                 :         PHP_FALIAS(imap_listmailbox,    imap_list,                      NULL)
     166                 :         PHP_FALIAS(imap_getmailboxes,   imap_list_full,         NULL)
     167                 :         PHP_FALIAS(imap_scanmailbox,    imap_listscan,          NULL)
     168                 :         PHP_FALIAS(imap_listsubscribed, imap_lsub,                      NULL)
     169                 :         PHP_FALIAS(imap_getsubscribed,  imap_lsub_full,         NULL)
     170                 :         PHP_FALIAS(imap_fetchtext,              imap_body,                      NULL)
     171                 :         PHP_FALIAS(imap_scan,                   imap_listscan,          NULL)
     172                 :         PHP_FALIAS(imap_create,                 imap_createmailbox,     NULL)
     173                 :         PHP_FALIAS(imap_rename,                 imap_renamemailbox,     NULL)
     174                 :         {NULL, NULL, NULL}
     175                 : };
     176                 : /* }}} */
     177                 : 
     178                 : /* {{{ imap dependencies */
     179                 : static zend_module_dep imap_deps[] = {
     180                 :         ZEND_MOD_REQUIRED("standard")
     181                 :         {NULL, NULL, NULL}
     182                 : };
     183                 : /* }}} */
     184                 : 
     185                 : /* {{{ imap_module_entry
     186                 :  */
     187                 : zend_module_entry imap_module_entry = {
     188                 :         STANDARD_MODULE_HEADER_EX, NULL,
     189                 :         imap_deps,
     190                 :         "imap",
     191                 :         imap_functions,
     192                 :         PHP_MINIT(imap),
     193                 :         NULL,
     194                 :         PHP_RINIT(imap),
     195                 :         PHP_RSHUTDOWN(imap),
     196                 :         PHP_MINFO(imap),
     197                 :         NO_VERSION_YET,
     198                 :         PHP_MODULE_GLOBALS(imap),
     199                 :         PHP_GINIT(imap),
     200                 :         NULL,
     201                 :         NULL,
     202                 :         STANDARD_MODULE_PROPERTIES_EX
     203                 : };
     204                 : /* }}} */
     205                 : 
     206                 : #ifdef COMPILE_DL_IMAP
     207                 : ZEND_GET_MODULE(imap)
     208                 : #endif
     209                 : 
     210                 : /* True globals, no need for thread safety */
     211                 : static int le_imap;
     212                 : 
     213                 : #define PHP_IMAP_CHECK_MSGNO(msgindex)  \
     214                 :         if ((msgindex < 1) || ((unsigned) msgindex > imap_le_struct->imap_stream->nmsgs)) { \
     215                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message number");    \
     216                 :                 RETURN_FALSE;   \
     217                 :         }       \
     218                 : 
     219                 : /* {{{ mail_close_it
     220                 :  */
     221                 : static void mail_close_it(zend_rsrc_list_entry *rsrc TSRMLS_DC)
     222             131 : {
     223             131 :         pils *imap_le_struct = (pils *)rsrc->ptr;
     224                 : 
     225                 :         /* Do not try to close prototype streams */
     226             131 :         if (!(imap_le_struct->flags & OP_PROTOTYPE)) {
     227             131 :                 mail_close_full(imap_le_struct->imap_stream, imap_le_struct->flags);
     228                 :         }
     229                 : 
     230             131 :         if (IMAPG(imap_user)) {
     231             131 :                 efree(IMAPG(imap_user));
     232             131 :                 IMAPG(imap_user) = 0;
     233                 :         }
     234             131 :         if (IMAPG(imap_password)) {
     235             131 :                 efree(IMAPG(imap_password));
     236             131 :                 IMAPG(imap_password) = 0;
     237                 :         }
     238                 : 
     239             131 :         efree(imap_le_struct);
     240             131 : }
     241                 : /* }}} */
     242                 : 
     243                 : /* {{{ add_assoc_object
     244                 :  */
     245                 : static int add_assoc_object(zval *arg, char *key, zval *tmp TSRMLS_DC)
     246               1 : {
     247                 :         HashTable *symtable;
     248                 : 
     249               1 :         if (Z_TYPE_P(arg) == IS_OBJECT) {
     250               1 :                 symtable = Z_OBJPROP_P(arg);
     251                 :         } else {
     252               0 :                 symtable = Z_ARRVAL_P(arg);
     253                 :         }
     254               1 :         return zend_hash_update(symtable, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
     255                 : }
     256                 : /* }}} */
     257                 : 
     258                 : /* {{{ add_next_index_object
     259                 :  */
     260                 : static inline int add_next_index_object(zval *arg, zval *tmp TSRMLS_DC)
     261              76 : {
     262                 :         HashTable *symtable;
     263                 : 
     264              76 :         if (Z_TYPE_P(arg) == IS_OBJECT) {
     265               0 :                 symtable = Z_OBJPROP_P(arg);
     266                 :         } else {
     267              76 :                 symtable = Z_ARRVAL_P(arg);
     268                 :         }
     269                 : 
     270              76 :         return zend_hash_next_index_insert(symtable, (void *) &tmp, sizeof(zval *), NULL);
     271                 : }
     272                 : /* }}} */
     273                 : 
     274                 : /* {{{ mail_newfolderobjectlist
     275                 :  *
     276                 :  * Mail instantiate FOBJECTLIST
     277                 :  * Returns: new FOBJECTLIST list
     278                 :  * Author: CJH
     279                 :  */
     280                 : FOBJECTLIST *mail_newfolderobjectlist(void)
     281              46 : {
     282              46 :         return (FOBJECTLIST *) memset(fs_get(sizeof(FOBJECTLIST)), 0, sizeof(FOBJECTLIST));
     283                 : }
     284                 : /* }}} */
     285                 : 
     286                 : /* {{{ mail_free_foblist
     287                 :  *
     288                 :  * Mail garbage collect FOBJECTLIST
     289                 :  * Accepts: pointer to FOBJECTLIST pointer
     290                 :  * Author: CJH
     291                 :  */
     292                 : void mail_free_foblist(FOBJECTLIST **foblist, FOBJECTLIST **tail)
     293              23 : {
     294                 :         FOBJECTLIST *cur, *next;
     295                 : 
     296              69 :         for (cur=*foblist, next=cur->next; cur; cur=next) {
     297              46 :                 next = cur->next;
     298                 : 
     299              46 :                 if(cur->text.data)
     300              46 :                         fs_give((void **)&(cur->text.data));
     301                 : 
     302              46 :                 fs_give((void **)&cur);
     303                 :         }
     304                 : 
     305              23 :         *tail = NIL;
     306              23 :         *foblist = NIL;
     307              23 : }
     308                 : /* }}} */
     309                 : 
     310                 : /* {{{ mail_newerrorlist
     311                 :  *
     312                 :  * Mail instantiate ERRORLIST
     313                 :  * Returns: new ERRORLIST list
     314                 :  * Author: CJH
     315                 :  */
     316                 : ERRORLIST *mail_newerrorlist(void)
     317              24 : {
     318              24 :         return (ERRORLIST *) memset(fs_get(sizeof(ERRORLIST)), 0, sizeof(ERRORLIST));
     319                 : }
     320                 : /* }}} */
     321                 : 
     322                 : /* {{{ mail_free_errorlist
     323                 :  *
     324                 :  * Mail garbage collect FOBJECTLIST
     325                 :  * Accepts: pointer to FOBJECTLIST pointer
     326                 :  * Author: CJH
     327                 :  */
     328                 : void mail_free_errorlist(ERRORLIST **errlist)
     329              30 : {
     330              30 :         if (*errlist) {         /* only free if exists */
     331              24 :                 if ((*errlist)->text.data) {
     332              24 :                         fs_give((void **) &(*errlist)->text.data);
     333                 :                 }
     334              24 :                 mail_free_errorlist (&(*errlist)->next);
     335              24 :                 fs_give((void **) errlist);     /* return string to free storage */
     336                 :         }
     337              30 : }
     338                 : /* }}} */
     339                 : 
     340                 : /* {{{ mail_newmessagelist
     341                 :  *
     342                 :  * Mail instantiate MESSAGELIST
     343                 :  * Returns: new MESSAGELIST list
     344                 :  * Author: CJH
     345                 :  */
     346                 : MESSAGELIST *mail_newmessagelist(void)
     347              21 : {
     348              21 :         return (MESSAGELIST *) memset(fs_get(sizeof(MESSAGELIST)), 0, sizeof(MESSAGELIST));
     349                 : }
     350                 : /* }}} */
     351                 : 
     352                 : /* {{{ mail_free_messagelist
     353                 :  *
     354                 :  * Mail garbage collect MESSAGELIST
     355                 :  * Accepts: pointer to MESSAGELIST pointer
     356                 :  * Author: CJH
     357                 :  */
     358                 : void mail_free_messagelist(MESSAGELIST **msglist, MESSAGELIST **tail)
     359               7 : {
     360                 :         MESSAGELIST *cur, *next;
     361                 : 
     362              28 :         for (cur = *msglist, next = cur->next; cur; cur = next) {
     363              21 :                 next = cur->next;
     364              21 :                 fs_give((void **)&cur);
     365                 :         }
     366                 : 
     367               7 :         *tail = NIL;
     368               7 :         *msglist = NIL;
     369               7 : }
     370                 : /* }}} */
     371                 : 
     372                 : #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
     373                 : /* {{{ mail_getquota
     374                 :  *
     375                 :  * Mail GET_QUOTA callback
     376                 :  * Called via the mail_parameter function in c-client:src/c-client/mail.c
     377                 :  * Author DRK
     378                 :  */
     379                 : 
     380                 : void mail_getquota(MAILSTREAM *stream, char *qroot, QUOTALIST *qlist)
     381               0 : {
     382                 :         zval *t_map, *return_value;
     383                 :         TSRMLS_FETCH();
     384                 : 
     385               0 :         return_value = *IMAPG(quota_return);
     386                 : 
     387                 : /* put parsing code here */
     388               0 :         for(; qlist; qlist = qlist->next) {
     389               0 :                 MAKE_STD_ZVAL(t_map);
     390               0 :                 array_init(t_map);
     391               0 :                 if (strncmp(qlist->name, "STORAGE", 7) == 0)
     392                 :                 {
     393                 :                         /* this is to add backwards compatibility */
     394               0 :                         add_assoc_long_ex(return_value, "usage", sizeof("usage"), qlist->usage);
     395               0 :                         add_assoc_long_ex(return_value, "limit", sizeof("limit"), qlist->limit);
     396                 :                 }
     397                 : 
     398               0 :                 add_assoc_long_ex(t_map, "usage", sizeof("usage"), qlist->usage);
     399               0 :                 add_assoc_long_ex(t_map, "limit", sizeof("limit"), qlist->limit);
     400               0 :                 add_assoc_zval_ex(return_value, qlist->name, strlen(qlist->name)+1, t_map);
     401                 :         }
     402               0 : }
     403                 : /* }}} */
     404                 : 
     405                 : 
     406                 : /* {{{ mail_getquota
     407                 :  *
     408                 :  * Mail GET_ACL callback
     409                 :  * Called via the mail_parameter function in c-client:src/c-client/mail.c
     410                 :  */
     411                 : void mail_getacl(MAILSTREAM *stream, char *mailbox, ACLLIST *alist)
     412               0 : {
     413                 :         TSRMLS_FETCH();
     414                 : 
     415                 :         /* walk through the ACLLIST */
     416               0 :         for(; alist; alist = alist->next) {
     417               0 :                 add_assoc_stringl(IMAPG(imap_acl_list), alist->identifier, alist->rights, strlen(alist->rights), 1);
     418                 :         }
     419               0 : }
     420                 : /* }}} */
     421                 : 
     422                 : #endif
     423                 : 
     424                 : 
     425                 : /* {{{ PHP_GINIT_FUNCTION
     426                 :  */
     427                 : static PHP_GINIT_FUNCTION(imap)
     428           13565 : {
     429           13565 :         imap_globals->imap_user = NIL;
     430           13565 :         imap_globals->imap_password = NIL;
     431                 : 
     432           13565 :         imap_globals->imap_alertstack = NIL;
     433           13565 :         imap_globals->imap_errorstack = NIL;
     434                 : 
     435           13565 :         imap_globals->imap_folders = NIL;
     436           13565 :         imap_globals->imap_folders_tail = NIL;
     437           13565 :         imap_globals->imap_sfolders = NIL;
     438           13565 :         imap_globals->imap_sfolders_tail = NIL;
     439           13565 :         imap_globals->imap_messages = NIL;
     440           13565 :         imap_globals->imap_messages_tail = NIL;
     441           13565 :         imap_globals->imap_folder_objects = NIL;
     442           13565 :         imap_globals->imap_folder_objects_tail = NIL;
     443           13565 :         imap_globals->imap_sfolder_objects = NIL;
     444           13565 :         imap_globals->imap_sfolder_objects_tail = NIL;
     445                 : 
     446           13565 :         imap_globals->folderlist_style = FLIST_ARRAY;
     447                 : #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
     448           13565 :         imap_globals->quota_return = NIL;
     449           13565 :         imap_globals->imap_acl_list = NIL;
     450                 : #endif
     451           13565 :         imap_globals->gets_stream = NIL;
     452           13565 : }
     453                 : /* }}} */
     454                 : 
     455                 : /* {{{ PHP_MINIT_FUNCTION
     456                 :  */
     457                 : PHP_MINIT_FUNCTION(imap)
     458           13565 : {
     459           13565 :         unsigned long sa_all =  SA_MESSAGES | SA_RECENT | SA_UNSEEN | SA_UIDNEXT | SA_UIDVALIDITY;
     460                 : 
     461                 : #ifndef PHP_WIN32
     462           13565 :         mail_link(&unixdriver);             /* link in the unix driver */
     463           13565 :         mail_link(&mhdriver);               /* link in the mh driver */
     464                 :         /* mail_link(&mxdriver); */ /* According to c-client docs (internal.txt) this shouldn't be used. */
     465           13565 :         mail_link(&mmdfdriver);             /* link in the mmdf driver */
     466           13565 :         mail_link(&newsdriver);             /* link in the news driver */
     467           13565 :         mail_link(&philedriver);    /* link in the phile driver */
     468                 : #endif
     469           13565 :         mail_link(&imapdriver);             /* link in the imap driver */
     470           13565 :         mail_link(&nntpdriver);             /* link in the nntp driver */
     471           13565 :         mail_link(&pop3driver);             /* link in the pop3 driver */
     472           13565 :         mail_link(&mbxdriver);              /* link in the mbx driver */
     473           13565 :         mail_link(&tenexdriver);    /* link in the tenex driver */
     474           13565 :         mail_link(&mtxdriver);              /* link in the mtx driver */
     475           13565 :         mail_link(&dummydriver);    /* link in the dummy driver */
     476                 : 
     477                 : #ifndef PHP_WIN32
     478           13565 :         auth_link(&auth_log);               /* link in the log authenticator */
     479           13565 :         auth_link(&auth_md5);       /* link in the cram-md5 authenticator */
     480                 : #if HAVE_IMAP_KRB && defined(HAVE_IMAP_AUTH_GSS)
     481           13565 :         auth_link(&auth_gss);               /* link in the gss authenticator */
     482                 : #endif
     483           13565 :         auth_link(&auth_pla);               /* link in the plain authenticator */
     484                 : #endif
     485                 : 
     486                 : #ifdef HAVE_IMAP_SSL
     487           13565 :         ssl_onceonlyinit ();
     488                 : #endif
     489                 : 
     490                 :         /* lets allow NIL */
     491           13565 :         REGISTER_LONG_CONSTANT("NIL", NIL, CONST_PERSISTENT | CONST_CS);
     492                 : 
     493                 :         /* plug in our gets */
     494           13565 :         mail_parameters(NIL, SET_GETS, (void *) NIL);
     495                 : 
     496                 :         /* set default timeout values */
     497           13565 :         mail_parameters(NIL, SET_OPENTIMEOUT, (void *) FG(default_socket_timeout));
     498           13565 :         mail_parameters(NIL, SET_READTIMEOUT, (void *) FG(default_socket_timeout));
     499           13565 :         mail_parameters(NIL, SET_WRITETIMEOUT, (void *) FG(default_socket_timeout));
     500           13565 :         mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) FG(default_socket_timeout));
     501                 : 
     502                 :         /* timeout constants */
     503           13565 :         REGISTER_LONG_CONSTANT("IMAP_OPENTIMEOUT", 1, CONST_PERSISTENT | CONST_CS);
     504           13565 :         REGISTER_LONG_CONSTANT("IMAP_READTIMEOUT", 2, CONST_PERSISTENT | CONST_CS);
     505           13565 :         REGISTER_LONG_CONSTANT("IMAP_WRITETIMEOUT", 3, CONST_PERSISTENT | CONST_CS);
     506           13565 :         REGISTER_LONG_CONSTANT("IMAP_CLOSETIMEOUT", 4, CONST_PERSISTENT | CONST_CS);
     507                 : 
     508                 :         /* Open Options */
     509                 : 
     510           13565 :         REGISTER_LONG_CONSTANT("OP_DEBUG", OP_DEBUG, CONST_PERSISTENT | CONST_CS);
     511                 :         /* debug protocol negotiations */
     512           13565 :         REGISTER_LONG_CONSTANT("OP_READONLY", OP_READONLY, CONST_PERSISTENT | CONST_CS);
     513                 :         /* read-only open */
     514           13565 :         REGISTER_LONG_CONSTANT("OP_ANONYMOUS", OP_ANONYMOUS, CONST_PERSISTENT | CONST_CS);
     515                 :         /* anonymous open of newsgroup */
     516           13565 :         REGISTER_LONG_CONSTANT("OP_SHORTCACHE", OP_SHORTCACHE, CONST_PERSISTENT | CONST_CS);
     517                 :         /* short (elt-only) caching */
     518           13565 :         REGISTER_LONG_CONSTANT("OP_SILENT", OP_SILENT, CONST_PERSISTENT | CONST_CS);
     519                 :         /* don't pass up events (internal use) */
     520           13565 :         REGISTER_LONG_CONSTANT("OP_PROTOTYPE", OP_PROTOTYPE, CONST_PERSISTENT | CONST_CS);
     521                 :         /* return driver prototype */
     522           13565 :         REGISTER_LONG_CONSTANT("OP_HALFOPEN", OP_HALFOPEN, CONST_PERSISTENT | CONST_CS);
     523                 :         /* half-open (IMAP connect but no select) */
     524           13565 :         REGISTER_LONG_CONSTANT("OP_EXPUNGE", OP_EXPUNGE, CONST_PERSISTENT | CONST_CS);
     525                 :         /* silently expunge recycle stream */
     526           13565 :         REGISTER_LONG_CONSTANT("OP_SECURE", OP_SECURE, CONST_PERSISTENT | CONST_CS);
     527                 :         /* don't do non-secure authentication */
     528                 : 
     529                 :         /*
     530                 :         PHP re-assigns CL_EXPUNGE a custom value that can be used as part of the imap_open() bitfield
     531                 :         because it seems like a good idea to be able to indicate that the mailbox should be
     532                 :         automatically expunged during imap_open in case the script get interrupted and it doesn't get
     533                 :         to the imap_close() where this option is normally placed.  If the c-client library adds other
     534                 :         options and the value for this one conflicts, simply make PHP_EXPUNGE higher at the top of
     535                 :         this file
     536                 :         */
     537           13565 :         REGISTER_LONG_CONSTANT("CL_EXPUNGE", PHP_EXPUNGE, CONST_PERSISTENT | CONST_CS);
     538                 :         /* expunge silently */
     539                 : 
     540                 : 
     541                 :         /* Fetch options */
     542                 : 
     543           13565 :         REGISTER_LONG_CONSTANT("FT_UID", FT_UID, CONST_PERSISTENT | CONST_CS);
     544                 :         /* argument is a UID */
     545           13565 :         REGISTER_LONG_CONSTANT("FT_PEEK", FT_PEEK, CONST_PERSISTENT | CONST_CS);
     546                 :         /* peek at data */
     547           13565 :         REGISTER_LONG_CONSTANT("FT_NOT", FT_NOT, CONST_PERSISTENT | CONST_CS);
     548                 :         /* NOT flag for header lines fetch */
     549           13565 :         REGISTER_LONG_CONSTANT("FT_INTERNAL", FT_INTERNAL, CONST_PERSISTENT | CONST_CS);
     550                 :         /* text can be internal strings */
     551           13565 :         REGISTER_LONG_CONSTANT("FT_PREFETCHTEXT", FT_PREFETCHTEXT, CONST_PERSISTENT | CONST_CS);
     552                 :         /* IMAP prefetch text when fetching header */
     553                 : 
     554                 : 
     555                 :         /* Flagging options */
     556                 : 
     557           13565 :         REGISTER_LONG_CONSTANT("ST_UID", ST_UID, CONST_PERSISTENT | CONST_CS);
     558                 :         /* argument is a UID sequence */
     559           13565 :         REGISTER_LONG_CONSTANT("ST_SILENT", ST_SILENT, CONST_PERSISTENT | CONST_CS);
     560                 :         /* don't return results */
     561           13565 :         REGISTER_LONG_CONSTANT("ST_SET", ST_SET, CONST_PERSISTENT | CONST_CS);
     562                 :         /* set vs. clear */
     563                 : 
     564                 : 
     565                 :         /* Copy options */
     566                 : 
     567           13565 :         REGISTER_LONG_CONSTANT("CP_UID", CP_UID, CONST_PERSISTENT | CONST_CS);
     568                 :         /* argument is a UID sequence */
     569           13565 :         REGISTER_LONG_CONSTANT("CP_MOVE", CP_MOVE, CONST_PERSISTENT | CONST_CS);
     570                 :         /* delete from source after copying */
     571                 : 
     572                 : 
     573                 :         /* Search/sort options */
     574                 : 
     575           13565 :         REGISTER_LONG_CONSTANT("SE_UID", SE_UID, CONST_PERSISTENT | CONST_CS);
     576                 :         /* return UID */
     577           13565 :         REGISTER_LONG_CONSTANT("SE_FREE", SE_FREE, CONST_PERSISTENT | CONST_CS);
     578                 :         /* free search program after finished */
     579           13565 :         REGISTER_LONG_CONSTANT("SE_NOPREFETCH", SE_NOPREFETCH, CONST_PERSISTENT | CONST_CS);
     580                 :         /* no search prefetching */
     581           13565 :         REGISTER_LONG_CONSTANT("SO_FREE", SO_FREE, CONST_PERSISTENT | CONST_CS);
     582                 :         /* free sort program after finished */
     583           13565 :         REGISTER_LONG_CONSTANT("SO_NOSERVER", SO_NOSERVER, CONST_PERSISTENT | CONST_CS);
     584                 :         /* don't do server-based sort */
     585                 : 
     586                 : 
     587                 :         /* Status options */
     588                 : 
     589           13565 :         REGISTER_LONG_CONSTANT("SA_MESSAGES", SA_MESSAGES , CONST_PERSISTENT | CONST_CS);
     590                 :         /* number of messages */
     591           13565 :         REGISTER_LONG_CONSTANT("SA_RECENT", SA_RECENT, CONST_PERSISTENT | CONST_CS);
     592                 :         /* number of recent messages */
     593           13565 :         REGISTER_LONG_CONSTANT("SA_UNSEEN", SA_UNSEEN , CONST_PERSISTENT | CONST_CS);
     594                 :         /* number of unseen messages */
     595           13565 :         REGISTER_LONG_CONSTANT("SA_UIDNEXT", SA_UIDNEXT, CONST_PERSISTENT | CONST_CS);
     596                 :         /* next UID to be assigned */
     597           13565 :         REGISTER_LONG_CONSTANT("SA_UIDVALIDITY", SA_UIDVALIDITY , CONST_PERSISTENT | CONST_CS);
     598                 :         /* UID validity value */
     599           13565 :         REGISTER_LONG_CONSTANT("SA_ALL", sa_all, CONST_PERSISTENT | CONST_CS);
     600                 :         /* get all status information */
     601                 : 
     602                 : 
     603                 :         /* Bits for mm_list() and mm_lsub() */
     604                 : 
     605           13565 :         REGISTER_LONG_CONSTANT("LATT_NOINFERIORS", LATT_NOINFERIORS , CONST_PERSISTENT | CONST_CS);
     606           13565 :         REGISTER_LONG_CONSTANT("LATT_NOSELECT", LATT_NOSELECT, CONST_PERSISTENT | CONST_CS);
     607           13565 :         REGISTER_LONG_CONSTANT("LATT_MARKED", LATT_MARKED, CONST_PERSISTENT | CONST_CS);
     608           13565 :         REGISTER_LONG_CONSTANT("LATT_UNMARKED", LATT_UNMARKED , CONST_PERSISTENT | CONST_CS);
     609                 : 
     610                 : #ifdef LATT_REFERRAL
     611           13565 :         REGISTER_LONG_CONSTANT("LATT_REFERRAL", LATT_REFERRAL, CONST_PERSISTENT | CONST_CS);
     612                 : #endif
     613                 : 
     614                 : #ifdef LATT_HASCHILDREN
     615           13565 :         REGISTER_LONG_CONSTANT("LATT_HASCHILDREN", LATT_HASCHILDREN, CONST_PERSISTENT | CONST_CS);
     616                 : #endif
     617                 : 
     618                 : #ifdef LATT_HASNOCHILDREN
     619           13565 :         REGISTER_LONG_CONSTANT("LATT_HASNOCHILDREN", LATT_HASNOCHILDREN, CONST_PERSISTENT | CONST_CS);
     620                 : #endif
     621                 : 
     622                 :         /* Sort functions */
     623                 : 
     624           13565 :         REGISTER_LONG_CONSTANT("SORTDATE", SORTDATE , CONST_PERSISTENT | CONST_CS);
     625                 :         /* date */
     626           13565 :         REGISTER_LONG_CONSTANT("SORTARRIVAL", SORTARRIVAL , CONST_PERSISTENT | CONST_CS);
     627                 :         /* arrival date */
     628           13565 :         REGISTER_LONG_CONSTANT("SORTFROM", SORTFROM , CONST_PERSISTENT | CONST_CS);
     629                 :         /* from */
     630           13565 :         REGISTER_LONG_CONSTANT("SORTSUBJECT", SORTSUBJECT , CONST_PERSISTENT | CONST_CS);
     631                 :         /* subject */
     632           13565 :         REGISTER_LONG_CONSTANT("SORTTO", SORTTO , CONST_PERSISTENT | CONST_CS);
     633                 :         /* to */
     634           13565 :         REGISTER_LONG_CONSTANT("SORTCC", SORTCC , CONST_PERSISTENT | CONST_CS);
     635                 :         /* cc */
     636           13565 :         REGISTER_LONG_CONSTANT("SORTSIZE", SORTSIZE , CONST_PERSISTENT | CONST_CS);
     637                 :         /* size */
     638                 : 
     639           13565 :         REGISTER_LONG_CONSTANT("TYPETEXT", TYPETEXT , CONST_PERSISTENT | CONST_CS);
     640           13565 :         REGISTER_LONG_CONSTANT("TYPEMULTIPART", TYPEMULTIPART , CONST_PERSISTENT | CONST_CS);
     641           13565 :         REGISTER_LONG_CONSTANT("TYPEMESSAGE", TYPEMESSAGE , CONST_PERSISTENT | CONST_CS);
     642           13565 :         REGISTER_LONG_CONSTANT("TYPEAPPLICATION", TYPEAPPLICATION , CONST_PERSISTENT | CONST_CS);
     643           13565 :         REGISTER_LONG_CONSTANT("TYPEAUDIO", TYPEAUDIO , CONST_PERSISTENT | CONST_CS);
     644           13565 :         REGISTER_LONG_CONSTANT("TYPEIMAGE", TYPEIMAGE , CONST_PERSISTENT | CONST_CS);
     645           13565 :         REGISTER_LONG_CONSTANT("TYPEVIDEO", TYPEVIDEO , CONST_PERSISTENT | CONST_CS);
     646           13565 :         REGISTER_LONG_CONSTANT("TYPEMODEL", TYPEMODEL , CONST_PERSISTENT | CONST_CS);
     647           13565 :         REGISTER_LONG_CONSTANT("TYPEOTHER", TYPEOTHER , CONST_PERSISTENT | CONST_CS);
     648                 :         /*
     649                 :         TYPETEXT                unformatted text
     650                 :         TYPEMULTIPART           multiple part
     651                 :         TYPEMESSAGE             encapsulated message
     652                 :         TYPEAPPLICATION         application data
     653                 :         TYPEAUDIO               audio
     654                 :         TYPEIMAGE               static image (GIF, JPEG, etc.)
     655                 :         TYPEVIDEO               video
     656                 :         TYPEMODEL               model
     657                 :         TYPEOTHER               unknown
     658                 :         */
     659                 : 
     660           13565 :         REGISTER_LONG_CONSTANT("ENC7BIT", ENC7BIT , CONST_PERSISTENT | CONST_CS);
     661           13565 :         REGISTER_LONG_CONSTANT("ENC8BIT", ENC8BIT , CONST_PERSISTENT | CONST_CS);
     662           13565 :         REGISTER_LONG_CONSTANT("ENCBINARY", ENCBINARY , CONST_PERSISTENT | CONST_CS);
     663           13565 :         REGISTER_LONG_CONSTANT("ENCBASE64", ENCBASE64, CONST_PERSISTENT | CONST_CS);
     664           13565 :         REGISTER_LONG_CONSTANT("ENCQUOTEDPRINTABLE", ENCQUOTEDPRINTABLE , CONST_PERSISTENT | CONST_CS);
     665           13565 :         REGISTER_LONG_CONSTANT("ENCOTHER", ENCOTHER , CONST_PERSISTENT | CONST_CS);
     666                 :         /*
     667                 :         ENC7BIT                 7 bit SMTP semantic data
     668                 :         ENC8BIT                 8 bit SMTP semantic data
     669                 :         ENCBINARY               8 bit binary data
     670                 :         ENCBASE64               base-64 encoded data
     671                 :         ENCQUOTEDPRINTABLE      human-readable 8-as-7 bit data
     672                 :         ENCOTHER                unknown
     673                 :         */
     674                 : 
     675           13565 :         le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, "imap", module_number);
     676           13565 :         return SUCCESS;
     677                 : }
     678                 : /* }}} */
     679                 : 
     680                 : /* {{{ PHP_RINIT_FUNCTION
     681                 :  */
     682                 : PHP_RINIT_FUNCTION(imap)
     683           13551 : {
     684           13551 :         IMAPG(imap_errorstack) = NIL;
     685           13551 :         IMAPG(imap_alertstack) = NIL;
     686           13551 :         IMAPG(gets_stream) = NIL;
     687           13551 :         return SUCCESS;
     688                 : }
     689                 : /* }}} */
     690                 : 
     691                 : /* {{{ PHP_RSHUTDOWN_FUNCTION
     692                 :  */
     693                 : PHP_RSHUTDOWN_FUNCTION(imap)
     694           13584 : {
     695           13584 :         ERRORLIST *ecur = NIL;
     696           13584 :         STRINGLIST *acur = NIL;
     697                 : 
     698           13584 :         if (IMAPG(imap_errorstack) != NIL) {
     699                 :                 /* output any remaining errors at their original error level */
     700               2 :                 if (EG(error_reporting) & E_NOTICE) {
     701               2 :                         ecur = IMAPG(imap_errorstack);
     702               6 :                         while (ecur != NIL) {
     703               2 :                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s (errflg=%ld)", ecur->LTEXT, ecur->errflg);
     704               2 :                                 ecur = ecur->next;
     705                 :                         }
     706                 :                 }
     707               2 :                 mail_free_errorlist(&IMAPG(imap_errorstack));
     708                 :         }
     709                 : 
     710           13584 :         if (IMAPG(imap_alertstack) != NIL) {
     711                 :                 /* output any remaining alerts at E_NOTICE level */
     712               0 :                 if (EG(error_reporting) & E_NOTICE) {
     713               0 :                         acur = IMAPG(imap_alertstack);
     714               0 :                         while (acur != NIL) {
     715               0 :                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", acur->LTEXT);
     716               0 :                                 acur = acur->next;
     717                 :                         }
     718                 :                 }
     719               0 :                 mail_free_stringlist(&IMAPG(imap_alertstack));
     720               0 :                 IMAPG(imap_alertstack) = NIL;
     721                 :         }
     722           13584 :         return SUCCESS;
     723                 : }
     724                 : /* }}} */
     725                 : 
     726                 : 
     727                 : #if !defined(CCLIENTVERSION)
     728                 : #if HAVE_IMAP2007e
     729                 : #define CCLIENTVERSION "2007e"
     730                 : #elif HAVE_IMAP2007d
     731                 : #define CCLIENTVERSION "2007d"
     732                 : #elif HAVE_IMAP2007b
     733                 : #define CCLIENTVERSION "2007b"
     734                 : #elif HAVE_IMAP2007a
     735                 : #define CCLIENTVERSION "2007a"
     736                 : #elif HAVE_IMAP2004
     737                 : #define CCLIENTVERSION "2004"
     738                 : #elif HAVE_IMAP2001
     739                 : #define CCLIENTVERSION "2001"
     740                 : #elif HAVE_IMAP2000
     741                 : #define CCLIENTVERSION "2000"
     742                 : #elif defined(IMAP41)
     743                 : #define CCLIENTVERSION "4.1"
     744                 : #else
     745                 : #define CCLIENTVERSION "4.0"
     746                 : #endif
     747                 : #endif
     748                 : 
     749                 : /* {{{ PHP_MINFO_FUNCTION
     750                 :  */
     751                 : PHP_MINFO_FUNCTION(imap)
     752               6 : {
     753               6 :         php_info_print_table_start();
     754               6 :         php_info_print_table_row(2, "IMAP c-Client Version", CCLIENTVERSION);
     755                 : #if HAVE_IMAP_SSL
     756               6 :         php_info_print_table_row(2, "SSL Support", "enabled");
     757                 : #endif
     758                 : #if HAVE_IMAP_KRB && HAVE_IMAP_AUTH_GSS
     759               6 :         php_info_print_table_row(2, "Kerberos Support", "enabled");
     760                 : #endif
     761               6 :         php_info_print_table_end();
     762               6 : }
     763                 : /* }}} */
     764                 : 
     765                 : /* {{{ imap_do_open
     766                 :  */
     767                 : static void php_imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
     768             140 : {
     769                 :         zval **mailbox, **user, **passwd, **options, **retries;
     770                 :         MAILSTREAM *imap_stream;
     771                 :         pils *imap_le_struct;
     772             140 :         long flags=NIL;
     773             140 :         long cl_flags=NIL;
     774             140 :         int myargc = ZEND_NUM_ARGS();
     775                 : 
     776             140 :         if (myargc < 3 || myargc > 5 || zend_get_parameters_ex(myargc, &mailbox, &user, &passwd, &options, &retries) == FAILURE) {
     777               5 :                 ZEND_WRONG_PARAM_COUNT();
     778                 :         }
     779                 : 
     780             135 :         convert_to_string_ex(mailbox);
     781             135 :         convert_to_string_ex(user);
     782             135 :         convert_to_string_ex(passwd);
     783             135 :         if (myargc >= 4) {
     784              38 :                 convert_to_long_ex(options);
     785              38 :                 flags = Z_LVAL_PP(options);
     786              38 :                 if (flags & PHP_EXPUNGE) {
     787               1 :                         cl_flags = CL_EXPUNGE;
     788               1 :                         flags ^= PHP_EXPUNGE;
     789                 :                 }
     790              38 :                 if (flags & OP_PROTOTYPE) {
     791               1 :                         cl_flags |= OP_PROTOTYPE;
     792                 :                 }
     793                 :         }
     794                 : 
     795             135 :         if (IMAPG(imap_user)) {
     796               0 :                 efree(IMAPG(imap_user));
     797                 :         }
     798                 : 
     799             135 :         if (IMAPG(imap_password)) {
     800               0 :                 efree(IMAPG(imap_password));
     801                 :         }
     802                 : 
     803                 :         /* local filename, need to perform open_basedir and safe_mode checks */
     804             135 :         if (Z_STRVAL_PP(mailbox)[0] != '{' &&
     805                 :                         (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) ||
     806                 :                         (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) {
     807               0 :                 RETURN_FALSE;
     808                 :         }
     809                 : 
     810             135 :         IMAPG(imap_user)     = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user));
     811             135 :         IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd));
     812                 : 
     813                 : #ifdef SET_MAXLOGINTRIALS
     814             135 :         if (myargc == 5) {
     815              37 :                 convert_to_long_ex(retries);
     816              37 :                 if (Z_LVAL_PP(retries) < 0) {
     817               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING ,"Retries must be greater or equal to 0");
     818                 :                 } else {
     819              37 :                         mail_parameters(NIL, SET_MAXLOGINTRIALS, (void *) Z_LVAL_PP(retries));
     820                 :                 }
     821                 :         }
     822                 : #endif
     823                 : 
     824             135 :         imap_stream = mail_open(NIL, Z_STRVAL_PP(mailbox), flags);
     825                 : 
     826             135 :         if (imap_stream == NIL) {
     827               4 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't open stream %s", Z_STRVAL_PP(mailbox));
     828               4 :                 efree(IMAPG(imap_user)); IMAPG(imap_user) = 0;
     829               4 :                 efree(IMAPG(imap_password)); IMAPG(imap_password) = 0;
     830               4 :                 RETURN_FALSE;
     831                 :         }
     832                 : 
     833             131 :         imap_le_struct = emalloc(sizeof(pils));
     834             131 :         imap_le_struct->imap_stream = imap_stream;
     835             131 :         imap_le_struct->flags = cl_flags;
     836                 : 
     837             131 :         ZEND_REGISTER_RESOURCE(return_value, imap_le_struct, le_imap);
     838                 : }
     839                 : /* }}} */
     840                 : 
     841                 : /* {{{ proto resource imap_open(string mailbox, string user, string password [, int options [, int n_retries]])
     842                 :    Open an IMAP stream to a mailbox */
     843                 : PHP_FUNCTION(imap_open)
     844             140 : {
     845             140 :         php_imap_do_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     846             140 : }
     847                 : /* }}} */
     848                 : 
     849                 : /* {{{ proto bool imap_reopen(resource stream_id, string mailbox [, int options [, int n_retries]])
     850                 :    Reopen an IMAP stream to a new mailbox */
     851                 : PHP_FUNCTION(imap_reopen)
     852              23 : {
     853                 :         zval **streamind, **mailbox, **options, **retries;
     854                 :         pils *imap_le_struct;
     855                 :         MAILSTREAM *imap_stream;
     856              23 :         long flags=NIL;
     857              23 :         long cl_flags=NIL;
     858              23 :         int myargc=ZEND_NUM_ARGS();
     859                 : 
     860              23 :         if (myargc < 2 || myargc > 4 || zend_get_parameters_ex(myargc, &streamind, &mailbox, &options, &retries) == FAILURE) {
     861               0 :                 ZEND_WRONG_PARAM_COUNT();
     862                 :         }
     863                 : 
     864              23 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
     865                 : 
     866              23 :         convert_to_string_ex(mailbox);
     867                 : 
     868              23 :         if (myargc >= 3) {
     869               0 :                 convert_to_long_ex(options);
     870               0 :                 flags = Z_LVAL_PP(options);
     871               0 :                 if (flags & PHP_EXPUNGE) {
     872               0 :                         cl_flags = CL_EXPUNGE;
     873               0 :                         flags ^= PHP_EXPUNGE;
     874                 :                 }
     875               0 :                 imap_le_struct->flags = cl_flags;
     876                 :         }
     877                 : #ifdef SET_MAXLOGINTRIALS
     878              23 :         if (myargc == 4) {
     879               0 :                 convert_to_long_ex(retries);
     880               0 :                 mail_parameters(NIL, SET_MAXLOGINTRIALS, (void *) Z_LVAL_PP(retries));
     881                 :         }
     882                 : #endif
     883                 :         /* local filename, need to perform open_basedir and safe_mode checks */
     884              23 :         if (Z_STRVAL_PP(mailbox)[0] != '{' &&
     885                 :                         (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) ||
     886                 :                         (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) {
     887               0 :                 RETURN_FALSE;
     888                 :         }
     889                 : 
     890              23 :         imap_stream = mail_open(imap_le_struct->imap_stream, Z_STRVAL_PP(mailbox), flags);
     891              23 :         if (imap_stream == NIL) {
     892               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't re-open stream");
     893               0 :                 RETURN_FALSE;
     894                 :         }
     895              23 :         imap_le_struct->imap_stream = imap_stream;
     896              23 :         RETURN_TRUE;
     897                 : }
     898                 : /* }}} */
     899                 : 
     900                 : /* {{{ proto bool imap_append(resource stream_id, string folder, string message [, string options])
     901                 :    Append a new message to a specified mailbox */
     902                 : PHP_FUNCTION(imap_append)
     903             135 : {
     904                 :         zval **streamind, **folder, **message, **flags;
     905                 :         pils *imap_le_struct;
     906                 :         STRING st;
     907             135 :         int myargc=ZEND_NUM_ARGS();
     908                 : 
     909             135 :         if (myargc < 3 || myargc > 4 || zend_get_parameters_ex(myargc, &streamind, &folder, &message, &flags) == FAILURE) {
     910               0 :                 ZEND_WRONG_PARAM_COUNT();
     911                 :         }
     912                 : 
     913             135 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
     914                 : 
     915             135 :         convert_to_string_ex(folder);
     916             135 :         convert_to_string_ex(message);
     917                 : 
     918             135 :         if (myargc == 4) {
     919               0 :                 convert_to_string_ex(flags);
     920                 :         }
     921                 : 
     922             135 :         INIT (&st, mail_string, (void *) Z_STRVAL_PP(message), Z_STRLEN_PP(message));
     923                 : 
     924             135 :         if (mail_append_full(imap_le_struct->imap_stream, Z_STRVAL_PP(folder), myargc==4 ? Z_STRVAL_PP(flags) : NIL, NIL, &st)) {
     925             135 :                 RETURN_TRUE;
     926                 :         } else {
     927               0 :                 RETURN_FALSE;
     928                 :         }
     929                 : }
     930                 : /* }}} */
     931                 : 
     932                 : /* {{{ proto int imap_num_msg(resource stream_id)
     933                 :    Gives the number of messages in the current mailbox */
     934                 : PHP_FUNCTION(imap_num_msg)
     935              22 : {
     936                 :         zval **streamind;
     937                 :         pils *imap_le_struct;
     938                 : 
     939              22 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
     940               1 :                 ZEND_WRONG_PARAM_COUNT();
     941                 :         }
     942                 : 
     943              21 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
     944                 : 
     945              19 :         RETURN_LONG(imap_le_struct->imap_stream->nmsgs);
     946                 : }
     947                 : /* }}} */
     948                 : 
     949                 : /* {{{ proto bool imap_ping(resource stream_id)
     950                 :    Check if the IMAP stream is still active */
     951                 : PHP_FUNCTION(imap_ping)
     952               3 : {
     953                 :         zval **streamind;
     954                 :         pils *imap_le_struct;
     955                 : 
     956               3 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
     957               1 :                 ZEND_WRONG_PARAM_COUNT();
     958                 :         }
     959                 : 
     960               2 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
     961                 : 
     962               0 :         RETURN_BOOL(mail_ping(imap_le_struct->imap_stream));
     963                 : }
     964                 : /* }}} */
     965                 : 
     966                 : /* {{{ proto int imap_num_recent(resource stream_id)
     967                 :    Gives the number of recent messages in current mailbox */
     968                 : PHP_FUNCTION(imap_num_recent)
     969               3 : {
     970                 :         zval **streamind;
     971                 :         pils *imap_le_struct;
     972                 : 
     973               3 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
     974               1 :                 ZEND_WRONG_PARAM_COUNT();
     975                 :         }
     976                 : 
     977               2 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
     978                 : 
     979               0 :         RETURN_LONG(imap_le_struct->imap_stream->recent);
     980                 : }
     981                 : /* }}} */
     982                 : 
     983                 : #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
     984                 : /* {{{ proto array imap_get_quota(resource stream_id, string qroot)
     985                 :         Returns the quota set to the mailbox account qroot */
     986                 : PHP_FUNCTION(imap_get_quota)
     987               0 : {
     988                 :         zval **streamind, **qroot;
     989                 :         pils *imap_le_struct;
     990                 : 
     991               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &qroot) == FAILURE) {
     992               0 :                 ZEND_WRONG_PARAM_COUNT();
     993                 :         }
     994                 : 
     995               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
     996                 : 
     997               0 :         convert_to_string_ex(qroot);
     998                 : 
     999               0 :         array_init(return_value);
    1000               0 :         IMAPG(quota_return) = &return_value;
    1001                 : 
    1002                 :         /* set the callback for the GET_QUOTA function */
    1003               0 :         mail_parameters(NIL, SET_QUOTA, (void *) mail_getquota);
    1004               0 :         if(!imap_getquota(imap_le_struct->imap_stream, Z_STRVAL_PP(qroot))) {
    1005               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "c-client imap_getquota failed");
    1006               0 :                 zval_dtor(return_value);
    1007               0 :                 RETURN_FALSE;
    1008                 :         }
    1009                 : }
    1010                 : /* }}} */
    1011                 : 
    1012                 : /* {{{ proto array imap_get_quotaroot(resource stream_id, string mbox)
    1013                 :         Returns the quota set to the mailbox account mbox */
    1014                 : PHP_FUNCTION(imap_get_quotaroot)
    1015               0 : {
    1016                 :         zval **streamind, **mbox;
    1017                 :         pils *imap_le_struct;
    1018                 : 
    1019               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &mbox) == FAILURE) {
    1020               0 :                 ZEND_WRONG_PARAM_COUNT();
    1021                 :         }
    1022                 : 
    1023               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1024                 : 
    1025               0 :         convert_to_string_ex(mbox);
    1026                 : 
    1027               0 :         array_init(return_value);
    1028               0 :         IMAPG(quota_return) = &return_value;
    1029                 : 
    1030                 :         /* set the callback for the GET_QUOTAROOT function */
    1031               0 :         mail_parameters(NIL, SET_QUOTA, (void *) mail_getquota);
    1032               0 :         if(!imap_getquotaroot(imap_le_struct->imap_stream, Z_STRVAL_PP(mbox))) {
    1033               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "c-client imap_getquotaroot failed");
    1034               0 :                 zval_dtor(return_value);
    1035               0 :                 RETURN_FALSE;
    1036                 :         }
    1037                 : }
    1038                 : /* }}} */
    1039                 : 
    1040                 : /* {{{ proto bool imap_set_quota(resource stream_id, string qroot, int mailbox_size)
    1041                 :    Will set the quota for qroot mailbox */
    1042                 : PHP_FUNCTION(imap_set_quota)
    1043               0 : {
    1044                 :         zval **streamind, **qroot, **mailbox_size;
    1045                 :         pils *imap_le_struct;
    1046                 :         STRINGLIST      limits;
    1047                 : 
    1048               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &qroot, &mailbox_size) == FAILURE) {
    1049               0 :                 ZEND_WRONG_PARAM_COUNT();
    1050                 :         }
    1051                 : 
    1052               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1053                 : 
    1054               0 :         convert_to_string_ex(qroot);
    1055               0 :         convert_to_long_ex(mailbox_size);
    1056                 : 
    1057               0 :         limits.text.data = "STORAGE";
    1058               0 :         limits.text.size = Z_LVAL_PP(mailbox_size);
    1059               0 :         limits.next = NIL;
    1060                 : 
    1061               0 :         RETURN_BOOL(imap_setquota(imap_le_struct->imap_stream, Z_STRVAL_PP(qroot), &limits));
    1062                 : }
    1063                 : /* }}} */
    1064                 : 
    1065                 : /* {{{ proto bool imap_setacl(resource stream_id, string mailbox, string id, string rights)
    1066                 :         Sets the ACL for a given mailbox */
    1067                 : PHP_FUNCTION(imap_setacl)
    1068               0 : {
    1069                 :         zval **streamind, **mailbox, **id, **rights;
    1070                 :         pils *imap_le_struct;
    1071                 : 
    1072               0 :         if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &streamind, &mailbox, &id, &rights) == FAILURE) {
    1073               0 :                 ZEND_WRONG_PARAM_COUNT();
    1074                 :         }
    1075                 : 
    1076               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1077                 : 
    1078               0 :         convert_to_string_ex(mailbox);
    1079               0 :         convert_to_string_ex(id);
    1080               0 :         convert_to_string_ex(rights);
    1081                 : 
    1082               0 :         RETURN_BOOL(imap_setacl(imap_le_struct->imap_stream, Z_STRVAL_PP(mailbox), Z_STRVAL_PP(id), Z_STRVAL_PP(rights)));
    1083                 : }
    1084                 : /* }}} */
    1085                 : 
    1086                 : 
    1087                 : /* {{{ proto array imap_getacl(resource stream_id, string mailbox)
    1088                 :         Gets the ACL for a given mailbox */
    1089                 : PHP_FUNCTION(imap_getacl)
    1090               0 : {
    1091                 :         zval **streamind, **mailbox;
    1092                 :         pils *imap_le_struct;
    1093                 : 
    1094               0 :         if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &mailbox) == FAILURE) {
    1095               0 :                 ZEND_WRONG_PARAM_COUNT();
    1096                 :         }
    1097                 : 
    1098               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1099                 : 
    1100               0 :         convert_to_string_ex(mailbox);
    1101                 : 
    1102                 :         /* initializing the special array for the return values */
    1103               0 :         array_init(return_value);
    1104                 : 
    1105               0 :         IMAPG(imap_acl_list) = return_value;
    1106                 : 
    1107                 :         /* set the callback for the GET_ACL function */
    1108               0 :         mail_parameters(NIL, SET_ACL, (void *) mail_getacl);
    1109               0 :         if(!imap_getacl(imap_le_struct->imap_stream, Z_STRVAL_PP(mailbox))) {
    1110               0 :                 php_error(E_WARNING, "c-client imap_getacl failed");
    1111               0 :                 zval_dtor(return_value);
    1112               0 :                 RETURN_FALSE;
    1113                 :         }
    1114                 : 
    1115               0 :         IMAPG(imap_acl_list) = NIL;
    1116                 : }
    1117                 : /* }}} */
    1118                 : 
    1119                 : #endif /* HAVE_IMAP2000 || HAVE_IMAP2001 */
    1120                 : 
    1121                 : 
    1122                 : /* {{{ proto bool imap_expunge(resource stream_id)
    1123                 :    Permanently delete all messages marked for deletion */
    1124                 : PHP_FUNCTION(imap_expunge)
    1125               3 : {
    1126                 :         zval **streamind;
    1127                 :         pils *imap_le_struct;
    1128                 : 
    1129               3 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
    1130               1 :                 ZEND_WRONG_PARAM_COUNT();
    1131                 :         }
    1132                 : 
    1133               2 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1134                 : 
    1135               0 :         mail_expunge (imap_le_struct->imap_stream);
    1136                 : 
    1137               0 :         RETURN_TRUE;
    1138                 : }
    1139                 : /* }}} */
    1140                 : 
    1141                 : /* {{{ proto bool imap_close(resource stream_id [, int options])
    1142                 :    Close an IMAP stream */
    1143                 : PHP_FUNCTION(imap_close)
    1144             151 : {
    1145             151 :         zval **options, **streamind=NULL;
    1146             151 :         pils *imap_le_struct=NULL;
    1147             151 :         long flags = NIL;
    1148             151 :         int myargcount=ZEND_NUM_ARGS();
    1149                 : 
    1150             151 :         if (myargcount < 1 || myargcount > 2 || zend_get_parameters_ex(myargcount, &streamind, &options) == FAILURE) {
    1151               2 :                 ZEND_WRONG_PARAM_COUNT();
    1152                 :         }
    1153                 : 
    1154             149 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1155                 : 
    1156             123 :         if (myargcount == 2) {
    1157              80 :                 convert_to_long_ex(options);
    1158              80 :                 flags = Z_LVAL_PP(options);
    1159                 : 
    1160                 :                 /* Check that flags is exactly equal to PHP_EXPUNGE or Zero*/
    1161              80 :                 if (flags && ((flags & ~PHP_EXPUNGE) != 0)) {
    1162              10 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid value for the flags parameter");
    1163              10 :                         RETURN_FALSE;
    1164                 :                 }
    1165                 : 
    1166                 :                 /* Do the translation from PHP's internal PHP_EXPUNGE define to c-client's CL_EXPUNGE */
    1167              70 :                 if (flags & PHP_EXPUNGE) {
    1168              57 :                         flags ^= PHP_EXPUNGE;
    1169              57 :                         flags |= CL_EXPUNGE;
    1170                 :                 }
    1171              70 :                 imap_le_struct->flags = flags;
    1172                 :         }
    1173                 : 
    1174             113 :         zend_list_delete(Z_RESVAL_PP(streamind));
    1175                 : 
    1176             113 :         RETURN_TRUE;
    1177                 : }
    1178                 : /* }}} */
    1179                 : 
    1180                 : /* {{{ proto array imap_headers(resource stream_id)
    1181                 :    Returns headers for all messages in a mailbox */
    1182                 : PHP_FUNCTION(imap_headers)
    1183               4 : {
    1184                 :         zval **streamind;
    1185                 :         pils *imap_le_struct;
    1186                 :         unsigned long i;
    1187                 :         char *t;
    1188                 :         unsigned int msgno;
    1189                 :         char tmp[MAILTMPLEN];
    1190                 : 
    1191               4 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
    1192               1 :                 ZEND_WRONG_PARAM_COUNT();
    1193                 :         }
    1194                 : 
    1195               3 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1196                 : 
    1197                 :         /* Initialize return array */
    1198               1 :         array_init(return_value);
    1199                 : 
    1200               3 :         for (msgno = 1; msgno <= imap_le_struct->imap_stream->nmsgs; msgno++) {
    1201               2 :                 MESSAGECACHE * cache = mail_elt (imap_le_struct->imap_stream, msgno);
    1202               2 :                 mail_fetchstructure(imap_le_struct->imap_stream, msgno, NIL);
    1203               2 :                 tmp[0] = cache->recent ? (cache->seen ? 'R': 'N') : ' ';
    1204               2 :                 tmp[1] = (cache->recent | cache->seen) ? ' ' : 'U';
    1205               2 :                 tmp[2] = cache->flagged ? 'F' : ' ';
    1206               2 :                 tmp[3] = cache->answered ? 'A' : ' ';
    1207               2 :                 tmp[4] = cache->deleted ? 'D' : ' ';
    1208               2 :                 tmp[5] = cache->draft ? 'X' : ' ';
    1209               2 :                 snprintf(tmp + 6, sizeof(tmp) - 6, "%4ld) ", cache->msgno);
    1210               2 :                 mail_date(tmp+11, cache);
    1211               2 :                 tmp[22] = ' ';
    1212               2 :                 tmp[23] = '\0';
    1213               2 :                 mail_fetchfrom(tmp+23, imap_le_struct->imap_stream, msgno, (long)20);
    1214               2 :                 strcat(tmp, " ");
    1215               2 :                 if ((i = cache->user_flags)) {
    1216               0 :                         strcat(tmp, "{");
    1217               0 :                         while (i) {
    1218               0 :                                 strlcat(tmp, imap_le_struct->imap_stream->user_flags[find_rightmost_bit (&i)], sizeof(tmp));
    1219               0 :                                 if (i) strlcat(tmp, " ", sizeof(tmp));
    1220                 :                         }
    1221               0 :                         strlcat(tmp, "} ", sizeof(tmp));
    1222                 :                 }
    1223               2 :                 mail_fetchsubject(t = tmp + strlen(tmp), imap_le_struct->imap_stream, msgno, (long)25);
    1224               2 :                 snprintf(t += strlen(t), sizeof(tmp) - strlen(tmp),  " (%ld chars)", cache->rfc822_size);
    1225               2 :                 add_next_index_string(return_value, tmp, 1);
    1226                 :         }
    1227                 : }
    1228                 : /* }}} */
    1229                 : 
    1230                 : /* {{{ proto string imap_body(resource stream_id, int msg_no [, int options])
    1231                 :    Read the message body */
    1232                 : PHP_FUNCTION(imap_body)
    1233               4 : {
    1234                 :         zval **streamind, **msgno, **pflags;
    1235                 :         pils *imap_le_struct;
    1236               4 :         int msgindex, myargc=ZEND_NUM_ARGS();
    1237               4 :         long flags=0L;
    1238                 :         char *body;
    1239               4 :         unsigned long body_len = 0;
    1240                 : 
    1241               4 :         if (myargc < 2 || myargc > 3 || zend_get_parameters_ex(myargc, &streamind, &msgno, &pflags) == FAILURE) {
    1242               3 :                 ZEND_WRONG_PARAM_COUNT();
    1243                 :         }
    1244                 : 
    1245                 : 
    1246               1 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1247                 : 
    1248               1 :         convert_to_long_ex(msgno);
    1249               1 :         if (myargc == 3) {
    1250               0 :                 convert_to_long_ex(pflags);
    1251               0 :                 flags = Z_LVAL_PP(pflags);
    1252               0 :                 if (flags && ((flags & ~(FT_UID|FT_PEEK|FT_INTERNAL)) != 0)) {
    1253               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid value for the options parameter");
    1254               0 :                         RETURN_FALSE;
    1255                 :                 }
    1256                 :         }
    1257                 : 
    1258               1 :         if ((myargc == 3) && (flags & FT_UID)) {
    1259                 :                 /* This should be cached; if it causes an extra RTT to the
    1260                 :                    IMAP server, then that's the price we pay for making
    1261                 :                    sure we don't crash. */
    1262               0 :                 msgindex = mail_msgno(imap_le_struct->imap_stream, Z_LVAL_PP(msgno));
    1263                 :         } else {
    1264               1 :                 msgindex = Z_LVAL_PP(msgno);
    1265                 :         }
    1266               1 :         if ((msgindex < 1) || ((unsigned) msgindex > imap_le_struct->imap_stream->nmsgs)) {
    1267               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message number");
    1268               0 :                 RETURN_FALSE;
    1269                 :         }
    1270               1 :         body = mail_fetchtext_full (imap_le_struct->imap_stream, Z_LVAL_PP(msgno), &body_len, (myargc==3 ? Z_LVAL_PP(pflags) : NIL));
    1271               1 :         if (body_len == 0) {
    1272               0 :                 RETVAL_EMPTY_STRING();
    1273                 :         } else {
    1274               1 :                 RETVAL_STRINGL(body, body_len, 1);
    1275                 :         }
    1276                 : }
    1277                 : /* }}} */
    1278                 : 
    1279                 : /* {{{ proto bool imap_mail_copy(resource stream_id, int msg_no, string mailbox [, int options])
    1280                 :    Copy specified message to a mailbox */
    1281                 : PHP_FUNCTION(imap_mail_copy)
    1282               0 : {
    1283                 :         zval **streamind, **seq, **folder, **options;
    1284                 :         pils *imap_le_struct;
    1285               0 :         int myargcount = ZEND_NUM_ARGS();
    1286                 : 
    1287               0 :         if (myargcount > 4 || myargcount < 3 || zend_get_parameters_ex(myargcount, &streamind, &seq, &folder, &options) == FAILURE) {
    1288               0 :                 ZEND_WRONG_PARAM_COUNT();
    1289                 :         }
    1290                 : 
    1291               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1292                 : 
    1293               0 :         convert_to_string_ex(seq);
    1294               0 :         convert_to_string_ex(folder);
    1295               0 :         if (myargcount == 4) {
    1296               0 :                 convert_to_long_ex(options);
    1297                 :         }
    1298                 : 
    1299               0 :         if (mail_copy_full(imap_le_struct->imap_stream, Z_STRVAL_PP(seq), Z_STRVAL_PP(folder), myargcount==4 ? Z_LVAL_PP(options) : NIL)==T) {
    1300               0 :                 RETURN_TRUE;
    1301                 :         } else {
    1302               0 :                 RETURN_FALSE;
    1303                 :         }
    1304                 : }
    1305                 : /* }}} */
    1306                 : 
    1307                 : /* {{{ proto bool imap_mail_move(resource stream_id, int msg_no, string mailbox [, int options])
    1308                 :    Move specified message to a mailbox */
    1309                 : PHP_FUNCTION(imap_mail_move)
    1310               0 : {
    1311                 :         zval **streamind, **seq, **folder, **options;
    1312                 :         pils *imap_le_struct;
    1313               0 :         int myargcount = ZEND_NUM_ARGS();
    1314                 : 
    1315               0 :         if (myargcount > 4 || myargcount < 3 || zend_get_parameters_ex(myargcount, &streamind, &seq, &folder, &options) == FAILURE) {
    1316               0 :                 ZEND_WRONG_PARAM_COUNT();
    1317                 :         }
    1318                 : 
    1319               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1320                 : 
    1321               0 :         convert_to_string_ex(seq);
    1322               0 :         convert_to_string_ex(folder);
    1323               0 :         if (myargcount == 4) {
    1324               0 :                 convert_to_long_ex(options);
    1325                 :         }
    1326                 : 
    1327               0 :         if (mail_copy_full(imap_le_struct->imap_stream, Z_STRVAL_PP(seq), Z_STRVAL_PP(folder), myargcount == 4 ? (Z_LVAL_PP(options) | CP_MOVE) : CP_MOVE) == T) {
    1328               0 :                 RETURN_TRUE;
    1329                 :         } else {
    1330               0 :                 RETURN_FALSE;
    1331                 :         }
    1332                 : }
    1333                 : /* }}} */
    1334                 : 
    1335                 : /* {{{ proto bool imap_createmailbox(resource stream_id, string mailbox)
    1336                 :    Create a new mailbox */
    1337                 : PHP_FUNCTION(imap_createmailbox)
    1338              24 : {
    1339                 :         zval **streamind, **folder;
    1340                 :         pils *imap_le_struct;
    1341                 : 
    1342              24 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &folder) == FAILURE) {
    1343               0 :                 ZEND_WRONG_PARAM_COUNT();
    1344                 :         }
    1345                 : 
    1346              24 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1347                 : 
    1348              24 :         convert_to_string_ex(folder);
    1349                 : 
    1350              24 :         if (mail_create(imap_le_struct->imap_stream, Z_STRVAL_PP(folder)) == T) {
    1351              24 :                 RETURN_TRUE;
    1352                 :         } else {
    1353               0 :                 RETURN_FALSE;
    1354                 :         }
    1355                 : }
    1356                 : /* }}} */
    1357                 : 
    1358                 : /* {{{ proto bool imap_renamemailbox(resource stream_id, string old_name, string new_name)
    1359                 :    Rename a mailbox */
    1360                 : PHP_FUNCTION(imap_renamemailbox)
    1361               0 : {
    1362                 :         zval **streamind, **old_mailbox, **new_mailbox;
    1363                 :         pils *imap_le_struct;
    1364                 : 
    1365               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &old_mailbox, &new_mailbox) == FAILURE) {
    1366               0 :                 ZEND_WRONG_PARAM_COUNT();
    1367                 :         }
    1368                 : 
    1369               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1370                 : 
    1371               0 :         convert_to_string_ex(old_mailbox);
    1372               0 :         convert_to_string_ex(new_mailbox);
    1373                 : 
    1374               0 :         if (mail_rename(imap_le_struct->imap_stream, Z_STRVAL_PP(old_mailbox), Z_STRVAL_PP(new_mailbox))==T) {
    1375               0 :                 RETURN_TRUE;
    1376                 :         } else {
    1377               0 :                 RETURN_FALSE;
    1378                 :         }
    1379                 : }
    1380                 : /* }}} */
    1381                 : 
    1382                 : /* {{{ proto bool imap_deletemailbox(resource stream_id, string mailbox)
    1383                 :    Delete a mailbox */
    1384                 : PHP_FUNCTION(imap_deletemailbox)
    1385              24 : {
    1386                 :         zval **streamind, **folder;
    1387                 :         pils *imap_le_struct;
    1388                 : 
    1389              24 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &folder) == FAILURE) {
    1390               0 :                 ZEND_WRONG_PARAM_COUNT();
    1391                 :         }
    1392                 : 
    1393              24 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1394                 : 
    1395              24 :         convert_to_string_ex(folder);
    1396                 : 
    1397              24 :         if (mail_delete(imap_le_struct->imap_stream, Z_STRVAL_PP(folder))==T) {
    1398              24 :                 RETURN_TRUE;
    1399                 :         } else {
    1400               0 :                 RETURN_FALSE;
    1401                 :         }
    1402                 : }
    1403                 : /* }}} */
    1404                 : 
    1405                 : /* {{{ proto array imap_list(resource stream_id, string ref, string pattern)
    1406                 :    Read the list of mailboxes */
    1407                 : PHP_FUNCTION(imap_list)
    1408               0 : {
    1409                 :         zval **streamind, **ref, **pat;
    1410                 :         pils *imap_le_struct;
    1411               0 :         STRINGLIST *cur=NIL;
    1412                 : 
    1413               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &ref, &pat) == FAILURE) {
    1414               0 :                 ZEND_WRONG_PARAM_COUNT();
    1415                 :         }
    1416                 : 
    1417               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1418                 : 
    1419               0 :         convert_to_string_ex(ref);
    1420               0 :         convert_to_string_ex(pat);
    1421                 : 
    1422                 :         /* set flag for normal, old mailbox list */
    1423               0 :         IMAPG(folderlist_style) = FLIST_ARRAY;
    1424                 : 
    1425               0 :         IMAPG(imap_folders) = IMAPG(imap_folders_tail) = NIL;
    1426               0 :         mail_list(imap_le_struct->imap_stream, Z_STRVAL_PP(ref), Z_STRVAL_PP(pat));
    1427               0 :         if (IMAPG(imap_folders) == NIL) {
    1428               0 :                 RETURN_FALSE;
    1429                 :         }
    1430                 : 
    1431               0 :         array_init(return_value);
    1432               0 :         cur=IMAPG(imap_folders);
    1433               0 :         while (cur != NIL) {
    1434               0 :                 add_next_index_string(return_value, cur->LTEXT, 1);
    1435               0 :                 cur=cur->next;
    1436                 :         }
    1437               0 :         mail_free_stringlist (&IMAPG(imap_folders));
    1438               0 :         IMAPG(imap_folders) = IMAPG(imap_folders_tail) = NIL;
    1439                 : }
    1440                 : 
    1441                 : /* }}} */
    1442                 : 
    1443                 : /* {{{ proto array imap_getmailboxes(resource stream_id, string ref, string pattern)
    1444                 :    Reads the list of mailboxes and returns a full array of objects containing name, attributes, and delimiter */
    1445                 : /* Author: CJH */
    1446                 : PHP_FUNCTION(imap_list_full)
    1447              46 : {
    1448                 :         zval **streamind, **ref, **pat, *mboxob;
    1449                 :         pils *imap_le_struct;
    1450              46 :         FOBJECTLIST *cur=NIL;
    1451              46 :         char *delim=NIL;
    1452                 : 
    1453              46 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &ref, &pat) == FAILURE) {
    1454               0 :                 ZEND_WRONG_PARAM_COUNT();
    1455                 :         }
    1456                 : 
    1457              46 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1458                 : 
    1459              46 :         convert_to_string_ex(ref);
    1460              46 :         convert_to_string_ex(pat);
    1461                 : 
    1462                 :         /* set flag for new, improved array of objects mailbox list */
    1463              46 :         IMAPG(folderlist_style) = FLIST_OBJECT;
    1464                 : 
    1465              46 :         IMAPG(imap_folder_objects) = IMAPG(imap_folder_objects_tail) = NIL;
    1466              46 :         mail_list(imap_le_struct->imap_stream, Z_STRVAL_PP(ref), Z_STRVAL_PP(pat));
    1467              46 :         if (IMAPG(imap_folder_objects) == NIL) {
    1468              23 :                 RETURN_FALSE;
    1469                 :         }
    1470                 : 
    1471              23 :         array_init(return_value);
    1472              23 :         delim = safe_emalloc(2, sizeof(char), 0);
    1473              23 :         cur=IMAPG(imap_folder_objects);
    1474              92 :         while (cur != NIL) {
    1475              46 :                 MAKE_STD_ZVAL(mboxob);
    1476              46 :                 object_init(mboxob);
    1477              46 :                 add_property_string(mboxob, "name", cur->LTEXT, 1);
    1478              46 :                 add_property_long(mboxob, "attributes", cur->attributes);
    1479                 : #ifdef IMAP41
    1480              46 :                 delim[0] = (char)cur->delimiter;
    1481              46 :                 delim[1] = 0;
    1482              46 :                 add_property_string(mboxob, "delimiter", delim, 1);
    1483                 : #else
    1484                 :                 add_property_string(mboxob, "delimiter", cur->delimiter, 1);
    1485                 : #endif
    1486              46 :                 add_next_index_object(return_value, mboxob TSRMLS_CC);
    1487              46 :                 cur=cur->next;
    1488                 :         }
    1489              23 :         mail_free_foblist(&IMAPG(imap_folder_objects), &IMAPG(imap_folder_objects_tail));
    1490              23 :         efree(delim);
    1491              23 :         IMAPG(folderlist_style) = FLIST_ARRAY;          /* reset to default */
    1492                 : }
    1493                 : /* }}} */
    1494                 : 
    1495                 : /* {{{ proto array imap_listscan(resource stream_id, string ref, string pattern, string content)
    1496                 :    Read list of mailboxes containing a certain string */
    1497                 : PHP_FUNCTION(imap_listscan)
    1498               0 : {
    1499                 :         zval **streamind, **ref, **pat, **content;
    1500                 :         pils *imap_le_struct;
    1501               0 :         STRINGLIST *cur=NIL;
    1502                 : 
    1503               0 :         if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &streamind, &ref, &pat, &content) == FAILURE) {
    1504               0 :                 ZEND_WRONG_PARAM_COUNT();
    1505                 :         }
    1506                 : 
    1507               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1508                 : 
    1509               0 :         convert_to_string_ex(ref);
    1510               0 :         convert_to_string_ex(pat);
    1511               0 :         convert_to_string_ex(content);
    1512                 : 
    1513               0 :         IMAPG(imap_folders) = NIL;
    1514               0 :         mail_scan(imap_le_struct->imap_stream, Z_STRVAL_PP(ref), Z_STRVAL_PP(pat), Z_STRVAL_PP(content));
    1515               0 :         if (IMAPG(imap_folders) == NIL) {
    1516               0 :                 RETURN_FALSE;
    1517                 :         }
    1518                 : 
    1519               0 :         array_init(return_value);
    1520               0 :         cur=IMAPG(imap_folders);
    1521               0 :         while (cur != NIL) {
    1522               0 :                 add_next_index_string(return_value, cur->LTEXT, 1);
    1523               0 :                 cur=cur->next;
    1524                 :         }
    1525               0 :         mail_free_stringlist (&IMAPG(imap_folders));
    1526               0 :         IMAPG(imap_folders) = IMAPG(imap_folders_tail) = NIL;
    1527                 : }
    1528                 : 
    1529                 : /* }}} */
    1530                 : 
    1531                 : /* {{{ proto object imap_check(resource stream_id)
    1532                 :    Get mailbox properties */
    1533                 : PHP_FUNCTION(imap_check)
    1534              30 : {
    1535                 :         zval **streamind;
    1536                 :         pils *imap_le_struct;
    1537                 :         char date[100];
    1538                 : 
    1539              30 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
    1540               0 :                 ZEND_WRONG_PARAM_COUNT();
    1541                 :         }
    1542                 : 
    1543              30 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1544                 : 
    1545              30 :         if (mail_ping (imap_le_struct->imap_stream) == NIL) {
    1546               0 :                 RETURN_FALSE;
    1547                 :         }
    1548                 : 
    1549              60 :         if (imap_le_struct->imap_stream && imap_le_struct->imap_stream->mailbox) {
    1550              30 :                 rfc822_date(date);
    1551              30 :                 object_init(return_value);
    1552              30 :                 add_property_string(return_value, "Date", date, 1);
    1553              30 :                 add_property_string(return_value, "Driver", imap_le_struct->imap_stream->dtb->name, 1);
    1554              30 :                 add_property_string(return_value, "Mailbox", imap_le_struct->imap_stream->mailbox, 1);
    1555              30 :                 add_property_long(return_value, "Nmsgs", imap_le_struct->imap_stream->nmsgs);
    1556              30 :                 add_property_long(return_value, "Recent", imap_le_struct->imap_stream->recent);
    1557                 :         } else {
    1558               0 :                 RETURN_FALSE;
    1559                 :         }
    1560                 : }
    1561                 : /* }}} */
    1562                 : 
    1563                 : /* {{{ proto bool imap_delete(resource stream_id, int msg_no [, int options])
    1564                 :    Mark a message for deletion */
    1565                 : PHP_FUNCTION(imap_delete)
    1566              87 : {
    1567                 :         zval **streamind, **sequence, **flags;
    1568                 :         pils *imap_le_struct;
    1569              87 :         int myargc=ZEND_NUM_ARGS();
    1570                 : 
    1571              87 :         if (myargc < 2 || myargc > 3 || zend_get_parameters_ex(myargc, &streamind, &sequence, &flags) == FAILURE) {
    1572               0 :                 ZEND_WRONG_PARAM_COUNT();
    1573                 :         }
    1574                 : 
    1575              87 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1576                 : 
    1577              87 :         convert_to_string_ex(sequence);
    1578              87 :         if (myargc == 3) {
    1579               0 :                 convert_to_long_ex(flags);
    1580                 :         }
    1581                 : 
    1582              87 :         mail_setflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), "\\DELETED", myargc==3 ? Z_LVAL_PP(flags) : NIL);
    1583              87 :         RETVAL_TRUE;
    1584                 : }
    1585                 : /* }}} */
    1586                 : 
    1587                 : /* {{{ proto bool imap_undelete(resource stream_id, int msg_no)
    1588                 :    Remove the delete flag from a message */
    1589                 : PHP_FUNCTION(imap_undelete)
    1590               0 : {
    1591                 :         zval **streamind, **sequence, **flags;
    1592                 :         pils *imap_le_struct;
    1593               0 :         int myargc=ZEND_NUM_ARGS();
    1594                 : 
    1595               0 :         if (myargc < 2 || myargc > 3 || zend_get_parameters_ex(myargc, &streamind, &sequence, &flags) == FAILURE) {
    1596               0 :                 ZEND_WRONG_PARAM_COUNT();
    1597                 :         }
    1598                 : 
    1599               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1600                 : 
    1601               0 :         convert_to_string_ex(sequence);
    1602               0 :         if (myargc == 3) {
    1603               0 :                 convert_to_long_ex(flags);
    1604                 :         }
    1605                 : 
    1606               0 :         mail_clearflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), "\\DELETED", myargc==3 ? Z_LVAL_PP(flags) : NIL);
    1607               0 :         RETVAL_TRUE;
    1608                 : }
    1609                 : /* }}} */
    1610                 : 
    1611                 : /* {{{ proto object imap_headerinfo(resource stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
    1612                 :    Read the headers of the message */
    1613                 : PHP_FUNCTION(imap_headerinfo)
    1614               0 : {
    1615                 :         zval **streamind, **msgno, **fromlength, **subjectlength, **defaulthost;
    1616                 :         pils *imap_le_struct;
    1617                 :         MESSAGECACHE *cache;
    1618                 :         ENVELOPE *en;
    1619                 :         char dummy[2000], fulladdress[MAILTMPLEN + 1];
    1620               0 :         int myargc = ZEND_NUM_ARGS();
    1621                 : 
    1622               0 :         if (myargc < 2 || myargc > 5 || zend_get_parameters_ex(myargc, &streamind, &msgno, &fromlength, &subjectlength, &defaulthost) == FAILURE) {
    1623               0 :                 ZEND_WRONG_PARAM_COUNT();
    1624                 :         }
    1625                 : 
    1626               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1627                 : 
    1628               0 :         convert_to_long_ex(msgno);
    1629               0 :         if (myargc >= 3) {
    1630               0 :                 convert_to_long_ex(fromlength);
    1631               0 :                 if (Z_LVAL_PP(fromlength) < 0 || Z_LVAL_PP(fromlength) > MAILTMPLEN) {
    1632               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "From length has to be between 0 and %d", MAILTMPLEN);
    1633               0 :                         RETURN_FALSE;
    1634                 :                 }
    1635                 :         } else {
    1636               0 :                 fromlength = 0x00;
    1637                 :         }
    1638               0 :         if (myargc >= 4) {
    1639               0 :                 convert_to_long_ex(subjectlength);
    1640               0 :                 if (Z_LVAL_PP(subjectlength) < 0 || Z_LVAL_PP(subjectlength) > MAILTMPLEN) {
    1641               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Subject length has to be between 0 and %d", MAILTMPLEN);
    1642               0 :                         RETURN_FALSE;
    1643                 :                 }
    1644                 :         } else {
    1645               0 :                 subjectlength = 0x00;
    1646                 :         }
    1647               0 :         if (myargc == 5) {
    1648               0 :                 convert_to_string_ex(defaulthost);
    1649                 :         }
    1650                 : 
    1651               0 :         PHP_IMAP_CHECK_MSGNO(Z_LVAL_PP(msgno));
    1652                 : 
    1653               0 :         if (mail_fetchstructure(imap_le_struct->imap_stream, Z_LVAL_PP(msgno), NIL)) {
    1654               0 :                 cache = mail_elt(imap_le_struct->imap_stream, Z_LVAL_PP(msgno));
    1655                 :         } else {
    1656               0 :                 RETURN_FALSE;
    1657                 :         }
    1658                 : 
    1659               0 :         en = mail_fetchenvelope(imap_le_struct->imap_stream, Z_LVAL_PP(msgno));
    1660                 : 
    1661                 :         /* call a function to parse all the text, so that we can use the
    1662                 :            same function to parse text from other sources */
    1663               0 :         _php_make_header_object(return_value, en TSRMLS_CC);
    1664                 : 
    1665                 :         /* now run through properties that are only going to be returned
    1666                 :            from a server, not text headers */
    1667               0 :         add_property_string(return_value, "Recent", cache->recent ? (cache->seen ? "R": "N") : " ", 1);
    1668               0 :         add_property_string(return_value, "Unseen", (cache->recent | cache->seen) ? " " : "U", 1);
    1669               0 :         add_property_string(return_value, "Flagged", cache->flagged ? "F" : " ", 1);
    1670               0 :         add_property_string(return_value, "Answered", cache->answered ? "A" : " ", 1);
    1671               0 :         add_property_string(return_value, "Deleted", cache->deleted ? "D" : " ", 1);
    1672               0 :         add_property_string(return_value, "Draft", cache->draft ? "X" : " ", 1);
    1673                 : 
    1674               0 :         snprintf(dummy, sizeof(dummy), "%4ld", cache->msgno);
    1675               0 :         add_property_string(return_value, "Msgno", dummy, 1);
    1676                 : 
    1677               0 :         mail_date(dummy, cache);
    1678               0 :         add_property_string(return_value, "MailDate", dummy, 1);
    1679                 : 
    1680               0 :         snprintf(dummy, sizeof(dummy), "%ld", cache->rfc822_size);
    1681               0 :         add_property_string(return_value, "Size", dummy, 1);
    1682                 : 
    1683               0 :         add_property_long(return_value, "udate", mail_longdate(cache));
    1684                 : 
    1685               0 :         if (en->from && fromlength) {
    1686               0 :                 fulladdress[0] = 0x00;
    1687               0 :                 mail_fetchfrom(fulladdress, imap_le_struct->imap_stream, Z_LVAL_PP(msgno), Z_LVAL_PP(fromlength));
    1688               0 :                 add_property_string(return_value, "fetchfrom", fulladdress, 1);
    1689                 :         }
    1690               0 :         if (en->subject && subjectlength) {
    1691               0 :                 fulladdress[0] = 0x00;
    1692               0 :                 mail_fetchsubject(fulladdress, imap_le_struct->imap_stream, Z_LVAL_PP(msgno), Z_LVAL_PP(subjectlength));
    1693               0 :                 add_property_string(return_value, "fetchsubject", fulladdress, 1);
    1694                 :         }
    1695                 : }
    1696                 : /* }}} */
    1697                 : 
    1698                 : /* {{{ proto object imap_rfc822_parse_headers(string headers [, string default_host])
    1699                 :    Parse a set of mail headers contained in a string, and return an object similar to imap_headerinfo() */
    1700                 : PHP_FUNCTION(imap_rfc822_parse_headers)
    1701               0 : {
    1702                 :         zval **headers, **defaulthost;
    1703                 :         ENVELOPE *en;
    1704               0 :         int myargc = ZEND_NUM_ARGS();
    1705                 : 
    1706               0 :         if (myargc < 1 || myargc > 2 || zend_get_parameters_ex(myargc, &headers, &defaulthost) == FAILURE) {
    1707               0 :                 ZEND_WRONG_PARAM_COUNT();
    1708                 :         }
    1709                 : 
    1710               0 :         convert_to_string_ex(headers);
    1711               0 :         if (myargc == 2) {
    1712               0 :                 convert_to_string_ex(defaulthost);
    1713                 :         }
    1714                 : 
    1715               0 :         if (myargc == 2) {
    1716               0 :                 rfc822_parse_msg(&en, NULL, Z_STRVAL_PP(headers), Z_STRLEN_PP(headers), NULL, Z_STRVAL_PP(defaulthost), NIL);
    1717                 :         } else {
    1718               0 :                 rfc822_parse_msg(&en, NULL, Z_STRVAL_PP(headers), Z_STRLEN_PP(headers), NULL, "UNKNOWN", NIL);
    1719                 :         }
    1720                 : 
    1721                 :         /* call a function to parse all the text, so that we can use the
    1722                 :            same function no matter where the headers are from */
    1723               0 :         _php_make_header_object(return_value, en TSRMLS_CC);
    1724               0 :         mail_free_envelope(&en);
    1725                 : }
    1726                 : /* }}} */
    1727                 : 
    1728                 : 
    1729                 : /* KMLANG */
    1730                 : /* {{{ proto array imap_lsub(resource stream_id, string ref, string pattern)
    1731                 :    Return a list of subscribed mailboxes */
    1732                 : PHP_FUNCTION(imap_lsub)
    1733               0 : {
    1734                 :         zval **streamind, **ref, **pat;
    1735                 :         pils *imap_le_struct;
    1736               0 :         STRINGLIST *cur=NIL;
    1737                 : 
    1738               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &ref, &pat) == FAILURE) {
    1739               0 :                 ZEND_WRONG_PARAM_COUNT();
    1740                 :         }
    1741                 : 
    1742               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1743                 : 
    1744               0 :         convert_to_string_ex(ref);
    1745               0 :         convert_to_string_ex(pat);
    1746                 : 
    1747                 :         /* set flag for normal, old mailbox list */
    1748               0 :         IMAPG(folderlist_style) = FLIST_ARRAY;
    1749                 : 
    1750               0 :         IMAPG(imap_sfolders) = NIL;
    1751               0 :         mail_lsub(imap_le_struct->imap_stream, Z_STRVAL_PP(ref), Z_STRVAL_PP(pat));
    1752               0 :         if (IMAPG(imap_sfolders) == NIL) {
    1753               0 :                 RETURN_FALSE;
    1754                 :         }
    1755                 : 
    1756               0 :         array_init(return_value);
    1757               0 :         cur=IMAPG(imap_sfolders);
    1758               0 :         while (cur != NIL) {
    1759               0 :                 add_next_index_string(return_value, cur->LTEXT, 1);
    1760               0 :                 cur=cur->next;
    1761                 :         }
    1762               0 :         mail_free_stringlist (&IMAPG(imap_sfolders));
    1763               0 :         IMAPG(imap_sfolders) = IMAPG(imap_sfolders_tail) = NIL;
    1764                 : }
    1765                 : /* }}} */
    1766                 : 
    1767                 : /* {{{ proto array imap_getsubscribed(resource stream_id, string ref, string pattern)
    1768                 :    Return a list of subscribed mailboxes, in the same format as imap_getmailboxes() */
    1769                 : /* Author: CJH */
    1770                 : PHP_FUNCTION(imap_lsub_full)
    1771               0 : {
    1772                 :         zval **streamind, **ref, **pat, *mboxob;
    1773                 :         pils *imap_le_struct;
    1774               0 :         FOBJECTLIST *cur=NIL;
    1775               0 :         char *delim=NIL;
    1776                 : 
    1777               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &ref, &pat) == FAILURE) {
    1778               0 :                 ZEND_WRONG_PARAM_COUNT();
    1779                 :         }
    1780                 : 
    1781               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1782                 : 
    1783               0 :         convert_to_string_ex(ref);
    1784               0 :         convert_to_string_ex(pat);
    1785                 : 
    1786                 :         /* set flag for new, improved array of objects list */
    1787               0 :         IMAPG(folderlist_style) = FLIST_OBJECT;
    1788                 : 
    1789               0 :         IMAPG(imap_sfolder_objects) = IMAPG(imap_sfolder_objects_tail) = NIL;
    1790               0 :         mail_lsub(imap_le_struct->imap_stream, Z_STRVAL_PP(ref), Z_STRVAL_PP(pat));
    1791               0 :         if (IMAPG(imap_sfolder_objects) == NIL) {
    1792               0 :                 RETURN_FALSE;
    1793                 :         }
    1794                 : 
    1795               0 :         array_init(return_value);
    1796               0 :         delim = safe_emalloc(2, sizeof(char), 0);
    1797               0 :         cur=IMAPG(imap_sfolder_objects);
    1798               0 :         while (cur != NIL) {
    1799               0 :                 MAKE_STD_ZVAL(mboxob);
    1800               0 :                 object_init(mboxob);
    1801               0 :                 add_property_string(mboxob, "name", cur->LTEXT, 1);
    1802               0 :                 add_property_long(mboxob, "attributes", cur->attributes);
    1803                 : #ifdef IMAP41
    1804               0 :                 delim[0] = (char)cur->delimiter;
    1805               0 :                 delim[1] = 0;
    1806               0 :                 add_property_string(mboxob, "delimiter", delim, 1);
    1807                 : #else
    1808                 :                 add_property_string(mboxob, "delimiter", cur->delimiter, 1);
    1809                 : #endif
    1810               0 :                 add_next_index_object(return_value, mboxob TSRMLS_CC);
    1811               0 :                 cur=cur->next;
    1812                 :         }
    1813               0 :         mail_free_foblist (&IMAPG(imap_sfolder_objects), &IMAPG(imap_sfolder_objects_tail));
    1814               0 :         efree(delim);
    1815               0 :         IMAPG(folderlist_style) = FLIST_ARRAY; /* reset to default */
    1816                 : }
    1817                 : /* }}} */
    1818                 : 
    1819                 : /* {{{ proto bool imap_subscribe(resource stream_id, string mailbox)
    1820                 :    Subscribe to a mailbox */
    1821                 : PHP_FUNCTION(imap_subscribe)
    1822               0 : {
    1823                 :         zval **streamind, **folder;
    1824                 :         pils *imap_le_struct;
    1825                 : 
    1826               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &folder) == FAILURE) {
    1827               0 :                 ZEND_WRONG_PARAM_COUNT();
    1828                 :         }
    1829                 : 
    1830               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1831                 : 
    1832               0 :         convert_to_string_ex(folder);
    1833                 : 
    1834               0 :         if (mail_subscribe(imap_le_struct->imap_stream, Z_STRVAL_PP(folder))==T) {
    1835               0 :                 RETURN_TRUE;
    1836                 :         } else {
    1837               0 :                 RETURN_FALSE;
    1838                 :         }
    1839                 : }
    1840                 : /* }}} */
    1841                 : 
    1842                 : /* {{{ proto bool imap_unsubscribe(resource stream_id, string mailbox)
    1843                 :    Unsubscribe from a mailbox */
    1844                 : PHP_FUNCTION(imap_unsubscribe)
    1845               0 : {
    1846                 :         zval **streamind, **folder;
    1847                 :         pils *imap_le_struct;
    1848                 : 
    1849               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &folder) == FAILURE) {
    1850               0 :                 ZEND_WRONG_PARAM_COUNT();
    1851                 :         }
    1852                 : 
    1853               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1854                 : 
    1855               0 :         convert_to_string_ex(folder);
    1856                 : 
    1857               0 :         if (mail_unsubscribe(imap_le_struct->imap_stream, Z_STRVAL_PP(folder))==T) {
    1858               0 :                 RETURN_TRUE;
    1859                 :         } else {
    1860               0 :                 RETURN_FALSE;
    1861                 :         }
    1862                 : }
    1863                 : /* }}} */
    1864                 : 
    1865                 : /* {{{ proto object imap_fetchstructure(resource stream_id, int msg_no [, int options])
    1866                 :    Read the full structure of a message */
    1867                 : PHP_FUNCTION(imap_fetchstructure)
    1868               0 : {
    1869                 :         zval **streamind, **msgno, **pflags;
    1870                 :         pils *imap_le_struct;
    1871                 :         BODY *body;
    1872               0 :         int msgindex, myargc=ZEND_NUM_ARGS();
    1873               0 :         long flags=0L;
    1874                 : 
    1875               0 :         if (myargc < 2  || myargc > 3 || zend_get_parameters_ex(myargc, &streamind, &msgno, &pflags) == FAILURE) {
    1876               0 :                 ZEND_WRONG_PARAM_COUNT();
    1877                 :         }
    1878                 : 
    1879                 : 
    1880               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1881                 : 
    1882               0 :         convert_to_long_ex(msgno);
    1883               0 :         if (Z_LVAL_PP(msgno) < 1) {
    1884               0 :                 RETURN_FALSE;
    1885                 :         }
    1886               0 :         if (myargc == 3) {
    1887               0 :                 convert_to_long_ex(pflags);
    1888               0 :                 flags = Z_LVAL_PP(pflags);
    1889                 : 
    1890               0 :                 if (flags && ((flags & ~FT_UID) != 0)) {
    1891               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid value for the options parameter");
    1892               0 :                         RETURN_FALSE;
    1893                 :                 }
    1894                 :         }
    1895                 : 
    1896               0 :         object_init(return_value);
    1897                 : 
    1898               0 :         if ((myargc == 3) && (flags & FT_UID)) {
    1899                 :                 /* This should be cached; if it causes an extra RTT to the
    1900                 :                    IMAP server, then that's the price we pay for making
    1901                 :                    sure we don't crash. */
    1902               0 :                 msgindex = mail_msgno(imap_le_struct->imap_stream, Z_LVAL_PP(msgno));
    1903                 :         } else {
    1904               0 :                 msgindex = Z_LVAL_PP(msgno);
    1905                 :         }
    1906               0 :         PHP_IMAP_CHECK_MSGNO(msgindex);
    1907                 : 
    1908               0 :         mail_fetchstructure_full(imap_le_struct->imap_stream, Z_LVAL_PP(msgno), &body , myargc == 3 ? Z_LVAL_PP(pflags) : NIL);
    1909                 : 
    1910               0 :         if (!body) {
    1911               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No body information available");
    1912               0 :                 RETURN_FALSE;
    1913                 :         }
    1914                 : 
    1915               0 :         _php_imap_add_body(return_value, body TSRMLS_CC);
    1916                 : }
    1917                 : /* }}} */
    1918                 : 
    1919                 : /* {{{ proto string imap_fetchbody(resource stream_id, int msg_no, string section [, int options])
    1920                 :    Get a specific body section */
    1921                 : PHP_FUNCTION(imap_fetchbody)
    1922              90 : {
    1923                 :         zval **streamind, **msgno, **sec, **pflags;
    1924                 :         pils *imap_le_struct;
    1925                 :         char *body;
    1926              90 :         long flags=0L;
    1927                 :         unsigned long len;
    1928              90 :         int myargc=ZEND_NUM_ARGS();
    1929                 : 
    1930              90 :         if (myargc < 3 || myargc > 4 || zend_get_parameters_ex(myargc, &streamind, &msgno, &sec, &pflags) == FAILURE) {
    1931               4 :                 ZEND_WRONG_PARAM_COUNT();
    1932                 :         }
    1933                 : 
    1934                 : 
    1935              86 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    1936                 : 
    1937              62 :         convert_to_long_ex(msgno);
    1938              62 :         convert_to_string_ex(sec);
    1939              62 :         if (myargc == 4) {
    1940               9 :                 convert_to_long_ex(pflags);
    1941               9 :                 flags = Z_LVAL_PP(pflags);
    1942               9 :                 if (flags && ((flags & ~(FT_UID|FT_PEEK|FT_INTERNAL)) != 0)) {
    1943               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid value for the options parameter");
    1944               2 :                         RETURN_FALSE;
    1945                 :                 }
    1946                 :         }
    1947                 : 
    1948              60 :         if (myargc < 4 || !(flags & FT_UID)) {
    1949                 :                 /* only perform the check if the msgno is a message number and not a UID */
    1950              55 :                 PHP_IMAP_CHECK_MSGNO(Z_LVAL_PP(msgno));
    1951                 :         }
    1952                 : 
    1953              38 :         body = mail_fetchbody_full(imap_le_struct->imap_stream, Z_LVAL_PP(msgno), Z_STRVAL_PP(sec), &len, myargc==4 ? Z_LVAL_PP(pflags) : NIL);
    1954                 : 
    1955              38 :         if (!body) {
    1956               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No body information available");
    1957               0 :                 RETURN_FALSE;
    1958                 :         }
    1959              38 :         RETVAL_STRINGL(body, len, 1);
    1960                 : }
    1961                 : 
    1962                 : /* }}} */
    1963                 : 
    1964                 : /* {{{ proto bool imap_savebody(resource stream_id, string|resource file, int msg_no[, string section = ""[, int options = 0]])
    1965                 :         Save a specific body section to a file */
    1966                 : PHP_FUNCTION(imap_savebody)
    1967               0 : {
    1968                 :         zval *stream, **out;
    1969               0 :         pils *imap_ptr = NULL;
    1970               0 :         php_stream *writer = NULL;
    1971               0 :         char *section = "";
    1972               0 :         int section_len = 0, close_stream = 1;
    1973               0 :         long msgno, flags = 0;
    1974                 : 
    1975               0 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZl|sl", &stream, &out, &msgno, &section, &section_len, &flags)) {
    1976               0 :                 RETURN_FALSE;
    1977                 :         }
    1978                 : 
    1979               0 :         ZEND_FETCH_RESOURCE(imap_ptr, pils *, &stream, -1, "imap", le_imap);
    1980                 : 
    1981               0 :         if (!imap_ptr) {
    1982               0 :                 RETURN_FALSE;
    1983                 :         }
    1984                 : 
    1985               0 :         switch (Z_TYPE_PP(out))
    1986                 :         {
    1987                 :                 case IS_LONG:
    1988                 :                 case IS_RESOURCE:
    1989               0 :                         close_stream = 0;
    1990               0 :                         php_stream_from_zval(writer, out);
    1991               0 :                 break;
    1992                 : 
    1993                 :                 default:
    1994               0 :                         convert_to_string_ex(out);
    1995               0 :                         writer = php_stream_open_wrapper(Z_STRVAL_PP(out), "wb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
    1996                 :                 break;
    1997                 :         }
    1998                 : 
    1999               0 :         if (!writer) {
    2000               0 :                 RETURN_FALSE;
    2001                 :         }
    2002                 : 
    2003               0 :         IMAPG(gets_stream) = writer;
    2004               0 :         mail_parameters(NIL, SET_GETS, (void *) php_mail_gets);
    2005               0 :         mail_fetchbody_full(imap_ptr->imap_stream, msgno, section, NULL, flags);
    2006               0 :         mail_parameters(NIL, SET_GETS, (void *) NIL);
    2007               0 :         IMAPG(gets_stream) = NULL;
    2008                 : 
    2009               0 :         if (close_stream) {
    2010               0 :                 php_stream_close(writer);
    2011                 :         }
    2012                 : 
    2013               0 :         RETURN_TRUE;
    2014                 : }
    2015                 : /* }}} */
    2016                 : 
    2017                 : /* {{{ proto string imap_base64(string text)
    2018                 :    Decode BASE64 encoded text */
    2019                 : PHP_FUNCTION(imap_base64)
    2020               3 : {
    2021                 :         zval **text;
    2022                 :         char *decode;
    2023                 :         unsigned long newlength;
    2024                 : 
    2025               3 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &text) == FAILURE) {
    2026               0 :                 ZEND_WRONG_PARAM_COUNT();
    2027                 :         }
    2028                 : 
    2029               3 :         convert_to_string_ex(text);
    2030                 : 
    2031               3 :         decode = (char *) rfc822_base64((unsigned char *) Z_STRVAL_PP(text), Z_STRLEN_PP(text), &newlength);
    2032                 : 
    2033               3 :         if (decode == NULL) {
    2034               0 :                 RETURN_FALSE;
    2035                 :         }
    2036                 : 
    2037               3 :         RETVAL_STRINGL(decode, newlength, 1);
    2038               3 :         fs_give((void**) &decode);
    2039                 : }
    2040                 : /* }}} */
    2041                 : 
    2042                 : /* {{{ proto string imap_qprint(string text)
    2043                 :    Convert a quoted-printable string to an 8-bit string */
    2044                 : PHP_FUNCTION(imap_qprint)
    2045               0 : {
    2046                 :         zval **text;
    2047                 :         char *decode;
    2048                 :         unsigned long newlength;
    2049                 : 
    2050               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &text) == FAILURE) {
    2051               0 :                 ZEND_WRONG_PARAM_COUNT();
    2052                 :         }
    2053                 : 
    2054               0 :         convert_to_string_ex(text);
    2055                 : 
    2056               0 :         decode = (char *) rfc822_qprint((unsigned char *) Z_STRVAL_PP(text), Z_STRLEN_PP(text), &newlength);
    2057                 : 
    2058               0 :         if (decode == NULL) {
    2059               0 :                 RETURN_FALSE;
    2060                 :         }
    2061                 : 
    2062               0 :         RETVAL_STRINGL(decode, newlength, 1);
    2063               0 :         fs_give((void**) &decode);
    2064                 : }
    2065                 : /* }}} */
    2066                 : 
    2067                 : /* {{{ proto string imap_8bit(string text)
    2068                 :    Convert an 8-bit string to a quoted-printable string */
    2069                 : PHP_FUNCTION(imap_8bit)
    2070               6 : {
    2071                 :         zval **text;
    2072                 :         char *decode;
    2073                 :         unsigned long newlength;
    2074                 : 
    2075               6 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &text) == FAILURE) {
    2076               0 :                 ZEND_WRONG_PARAM_COUNT();
    2077                 :         }
    2078                 : 
    2079               6 :         convert_to_string_ex(text);
    2080                 : 
    2081               6 :         decode = (char *) rfc822_8bit((unsigned char *) Z_STRVAL_PP(text), Z_STRLEN_PP(text), &newlength);
    2082                 : 
    2083               6 :         if (decode == NULL) {
    2084               0 :                 RETURN_FALSE;
    2085                 :         }
    2086                 : 
    2087               6 :         RETVAL_STRINGL(decode, newlength, 1);
    2088               6 :         fs_give((void**) &decode);
    2089                 : }
    2090                 : /* }}} */
    2091                 : 
    2092                 : /* {{{ proto string imap_binary(string text)
    2093                 :    Convert an 8bit string to a base64 string */
    2094                 : PHP_FUNCTION(imap_binary)
    2095               4 : {
    2096                 :         zval **text;
    2097                 :         char *decode;
    2098                 :         unsigned long newlength;
    2099                 : 
    2100               4 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &text) == FAILURE) {
    2101               0 :                 ZEND_WRONG_PARAM_COUNT();
    2102                 :         }
    2103                 : 
    2104               4 :         convert_to_string_ex(text);
    2105                 : 
    2106               4 :         decode = rfc822_binary(Z_STRVAL_PP(text), Z_STRLEN_PP(text), &newlength);
    2107                 : 
    2108               4 :         if (decode == NULL) {
    2109               0 :                 RETURN_FALSE;
    2110                 :         }
    2111                 : 
    2112               4 :         RETVAL_STRINGL(decode, newlength, 1);
    2113               4 :         fs_give((void**) &decode);
    2114                 : }
    2115                 : /* }}} */
    2116                 : 
    2117                 : /* {{{ proto object imap_mailboxmsginfo(resource stream_id)
    2118                 :    Returns info about the current mailbox */
    2119                 : PHP_FUNCTION(imap_mailboxmsginfo)
    2120               1 : {
    2121                 :         zval **streamind;
    2122                 :         pils *imap_le_struct;
    2123                 :         char date[100];
    2124                 :         unsigned int msgno, unreadmsg, deletedmsg, msize;
    2125                 : 
    2126               1 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &streamind) == FAILURE) {
    2127               0 :                 ZEND_WRONG_PARAM_COUNT();
    2128                 :         }
    2129                 : 
    2130               1 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2131                 : 
    2132                 :         /* Initialize return object */
    2133               1 :         object_init(return_value);
    2134                 : 
    2135               1 :         unreadmsg = 0;
    2136               1 :         deletedmsg = 0;
    2137               1 :         msize = 0;
    2138                 : 
    2139               1 :         for (msgno = 1; msgno <= imap_le_struct->imap_stream->nmsgs; msgno++) {
    2140               0 :                 MESSAGECACHE * cache = mail_elt (imap_le_struct->imap_stream, msgno);
    2141               0 :                 mail_fetchstructure (imap_le_struct->imap_stream, msgno, NIL);
    2142                 : 
    2143               0 :                 if (!cache->seen || cache->recent) {
    2144               0 :                         unreadmsg++;
    2145                 :                 }
    2146                 : 
    2147               0 :                 if (cache->deleted) {
    2148               0 :                         deletedmsg++;
    2149                 :                 }
    2150               0 :                 msize = msize + cache->rfc822_size;
    2151                 :         }
    2152               1 :         add_property_long(return_value, "Unread", unreadmsg);
    2153               1 :         add_property_long(return_value, "Deleted", deletedmsg);
    2154               1 :         add_property_long(return_value, "Nmsgs", imap_le_struct->imap_stream->nmsgs);
    2155               1 :         add_property_long(return_value, "Size", msize);
    2156               1 :         rfc822_date(date);
    2157               1 :         add_property_string(return_value, "Date", date, 1);
    2158               1 :         add_property_string(return_value, "Driver", imap_le_struct->imap_stream->dtb->name, 1);
    2159               1 :         add_property_string(return_value, "Mailbox", imap_le_struct->imap_stream->mailbox, 1);
    2160               1 :         add_property_long(return_value, "Recent", imap_le_struct->imap_stream->recent);
    2161                 : }
    2162                 : /* }}} */
    2163                 : 
    2164                 : /* {{{ proto string imap_rfc822_write_address(string mailbox, string host, string personal)
    2165                 :    Returns a properly formatted email address given the mailbox, host, and personal info */
    2166                 : PHP_FUNCTION(imap_rfc822_write_address)
    2167               0 : {
    2168                 :         zval **mailbox, **host, **personal;
    2169                 :         ADDRESS *addr;
    2170                 :         char *string;
    2171                 : 
    2172               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &mailbox, &host, &personal) == FAILURE) {
    2173               0 :                 ZEND_WRONG_PARAM_COUNT();
    2174                 :         }
    2175                 : 
    2176               0 :         convert_to_string_ex(mailbox);
    2177               0 :         convert_to_string_ex(host);
    2178               0 :         convert_to_string_ex(personal);
    2179                 : 
    2180               0 :         addr=mail_newaddr();
    2181                 : 
    2182               0 :         if (mailbox) {
    2183               0 :                 addr->mailbox = cpystr(Z_STRVAL_PP(mailbox));
    2184                 :         }
    2185                 : 
    2186               0 :         if (host) {
    2187               0 :                 addr->host = cpystr(Z_STRVAL_PP(host));
    2188                 :         }
    2189                 : 
    2190               0 :         if (personal) {
    2191               0 :                 addr->personal = cpystr(Z_STRVAL_PP(personal));
    2192                 :         }
    2193                 : 
    2194               0 :         addr->next=NIL;
    2195               0 :         addr->error=NIL;
    2196               0 :         addr->adl=NIL;
    2197                 : 
    2198               0 :         string = _php_rfc822_write_address(addr TSRMLS_CC);
    2199               0 :         if (string) {
    2200               0 :                 RETVAL_STRING(string, 0);
    2201                 :         } else {
    2202               0 :                 RETURN_FALSE;
    2203                 :         }
    2204                 : }
    2205                 : /* }}} */
    2206                 : 
    2207                 : /* {{{ proto array imap_rfc822_parse_adrlist(string address_string, string default_host)
    2208                 :    Parses an address string */
    2209                 : PHP_FUNCTION(imap_rfc822_parse_adrlist)
    2210               2 : {
    2211                 :         zval **str, **defaulthost, *tovals;
    2212                 :         ADDRESS *addresstmp;
    2213                 :         ENVELOPE *env;
    2214                 :         char *str_copy;
    2215                 : 
    2216               2 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &str, &defaulthost) == FAILURE) {
    2217               0 :                 ZEND_WRONG_PARAM_COUNT();
    2218                 :         }
    2219                 : 
    2220               2 :         SEPARATE_ZVAL(str);
    2221               2 :         convert_to_string_ex(str);
    2222               2 :         convert_to_string_ex(defaulthost);
    2223                 : 
    2224               2 :         env = mail_newenvelope();
    2225                 : 
    2226                 :         /* rfc822_parse_adrlist() modifies passed string. Copy it. */
    2227               2 :         str_copy = estrndup(Z_STRVAL_PP(str), Z_STRLEN_PP(str));
    2228               2 :         rfc822_parse_adrlist(&env->to, str_copy, Z_STRVAL_PP(defaulthost));
    2229               2 :         efree(str_copy);
    2230                 : 
    2231               2 :         array_init(return_value);
    2232                 : 
    2233               2 :         addresstmp = env->to;
    2234                 : 
    2235               2 :         if (addresstmp) do {
    2236              10 :                 MAKE_STD_ZVAL(tovals);
    2237              10 :                 object_init(tovals);
    2238              10 :                 if (addresstmp->mailbox) {
    2239              10 :                         add_property_string(tovals, "mailbox", addresstmp->mailbox, 1);
    2240                 :                 }
    2241              10 :                 if (addresstmp->host) {
    2242              10 :                         add_property_string(tovals, "host", addresstmp->host, 1);
    2243                 :                 }
    2244              10 :                 if (addresstmp->personal) {
    2245               3 :                         add_property_string(tovals, "personal", addresstmp->personal, 1);
    2246                 :                 }
    2247              10 :                 if (addresstmp->adl) {
    2248               1 :                         add_property_string(tovals, "adl", addresstmp->adl, 1);
    2249                 :                 }
    2250              10 :                 add_next_index_object(return_value, tovals TSRMLS_CC);
    2251              10 :         } while ((addresstmp = addresstmp->next));
    2252                 : 
    2253               2 :         mail_free_envelope(&env);
    2254                 : }
    2255                 : /* }}} */
    2256                 : 
    2257                 : /* {{{ proto string imap_utf8(string mime_encoded_text)
    2258                 :    Convert a mime-encoded text to UTF-8 */
    2259                 : PHP_FUNCTION(imap_utf8)
    2260               4 : {
    2261                 :         zval **str;
    2262                 :         SIZEDTEXT src, dest;
    2263                 : 
    2264               4 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
    2265               0 :                 ZEND_WRONG_PARAM_COUNT();
    2266                 :         }
    2267                 : 
    2268               4 :         convert_to_string_ex(str);
    2269                 : 
    2270               4 :         src.data  = NULL;
    2271               4 :         src.size  = 0;
    2272               4 :         dest.data = NULL;
    2273               4 :         dest.size = 0;
    2274                 : 
    2275               4 :         cpytxt(&src, Z_STRVAL_PP(str), Z_STRLEN_PP(str));
    2276                 : 
    2277                 : #ifndef HAVE_NEW_MIME2TEXT
    2278               4 :         utf8_mime2text(&src, &dest);
    2279                 : #else
    2280                 :         utf8_mime2text(&src, &dest, U8T_CANONICAL);
    2281                 : #endif
    2282               4 :         RETVAL_STRINGL(dest.data, dest.size, 1);
    2283               4 :         if (dest.data) {
    2284               4 :                 free(dest.data);
    2285                 :         }
    2286               4 :         if (src.data && src.data != dest.data) {
    2287               0 :                 free(src.data);
    2288                 :         }
    2289                 : }
    2290                 : /* }}} */
    2291                 : 
    2292                 : 
    2293                 : /* {{{ macros for the modified utf7 conversion functions
    2294                 :  *
    2295                 :  * author: Andrew Skalski <askalski@chek.com>
    2296                 :  */
    2297                 : 
    2298                 : /* tests `c' and returns true if it is a special character */
    2299                 : #define SPECIAL(c) ((c) <= 0x1f || (c) >= 0x7f)
    2300                 : 
    2301                 : /* validate a modified-base64 character */
    2302                 : #define B64CHAR(c) (isalnum(c) || (c) == '+' || (c) == ',')
    2303                 : 
    2304                 : /* map the low 64 bits of `n' to the modified-base64 characters */
    2305                 : #define B64(n)  ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
    2306                 :                 "abcdefghijklmnopqrstuvwxyz0123456789+,"[(n) & 0x3f])
    2307                 : 
    2308                 : /* map the modified-base64 character `c' to its 64 bit value */
    2309                 : #define UNB64(c)        ((c) == '+' ? 62 : (c) == ',' ? 63 : (c) >= 'a' ? \
    2310                 :                         (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4)
    2311                 : /* }}} */
    2312                 : 
    2313                 : /* {{{ proto string imap_utf7_decode(string buf)
    2314                 :    Decode a modified UTF-7 string */
    2315                 : PHP_FUNCTION(imap_utf7_decode)
    2316               0 : {
    2317                 :         /* author: Andrew Skalski <askalski@chek.com> */
    2318                 :         zval **arg;
    2319                 :         const unsigned char *in, *inp, *endp;
    2320                 :         unsigned char *out, *outp;
    2321                 :         unsigned char c;
    2322                 :         int inlen, outlen;
    2323                 :         enum {
    2324                 :                 ST_NORMAL,      /* printable text */
    2325                 :                 ST_DECODE0,     /* encoded text rotation... */
    2326                 :                 ST_DECODE1,
    2327                 :                 ST_DECODE2,
    2328                 :                 ST_DECODE3
    2329                 :         } state;
    2330                 : 
    2331               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
    2332               0 :                 ZEND_WRONG_PARAM_COUNT();
    2333                 :         }
    2334                 : 
    2335               0 :         convert_to_string_ex(arg);              /*      Is this string really modified?
    2336                 :                                                                                 If it is use and you don't want it to be seen outside of the function
    2337                 :                                                                                 then use zend_get_parameters() */
    2338                 : 
    2339               0 :         in = (const unsigned char *) Z_STRVAL_PP(arg);
    2340               0 :         inlen = Z_STRLEN_PP(arg);
    2341                 : 
    2342                 :         /* validate and compute length of output string */
    2343               0 :         outlen = 0;
    2344               0 :         state = ST_NORMAL;
    2345               0 :         for (endp = (inp = in) + inlen; inp < endp; inp++) {
    2346               0 :                 if (state == ST_NORMAL) {
    2347                 :                         /* process printable character */
    2348               0 :                         if (SPECIAL(*inp)) {
    2349               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid modified UTF-7 character: `%c'", *inp);
    2350               0 :                                 RETURN_FALSE;
    2351               0 :                         } else if (*inp != '&') {
    2352               0 :                                 outlen++;
    2353               0 :                         } else if (inp + 1 == endp) {
    2354               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected end of string");
    2355               0 :                                 RETURN_FALSE;
    2356               0 :                         } else if (inp[1] != '-') {
    2357               0 :                                 state = ST_DECODE0;
    2358                 :                         } else {
    2359               0 :                                 outlen++;
    2360               0 :                                 inp++;
    2361                 :                         }
    2362               0 :                 } else if (*inp == '-') {
    2363                 :                         /* return to NORMAL mode */
    2364               0 :                         if (state == ST_DECODE1) {
    2365               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Stray modified base64 character: `%c'", *--inp);
    2366               0 :                                 RETURN_FALSE;
    2367                 :                         }
    2368               0 :                         state = ST_NORMAL;
    2369               0 :                 } else if (!B64CHAR(*inp)) {
    2370               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid modified base64 character: `%c'", *inp);
    2371               0 :                         RETURN_FALSE;
    2372                 :                 } else {
    2373               0 :                         switch (state) {
    2374                 :                                 case ST_DECODE3:
    2375               0 :                                         outlen++;
    2376               0 :                                         state = ST_DECODE0;
    2377               0 :                                         break;
    2378                 :                                 case ST_DECODE2:
    2379                 :                                 case ST_DECODE1:
    2380               0 :                                         outlen++;
    2381                 :                                 case ST_DECODE0:
    2382               0 :                                         state++;
    2383                 :                                 case ST_NORMAL:
    2384                 :                                         break;
    2385                 :                         }
    2386                 :                 }
    2387                 :         }
    2388                 : 
    2389                 :         /* enforce end state */
    2390               0 :         if (state != ST_NORMAL) {
    2391               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected end of string");
    2392               0 :                 RETURN_FALSE;
    2393                 :         }
    2394                 : 
    2395                 :         /* allocate output buffer */
    2396               0 :         out = emalloc(outlen + 1);
    2397                 : 
    2398                 :         /* decode input string */
    2399               0 :         outp = out;
    2400               0 :         state = ST_NORMAL;
    2401               0 :         for (endp = (inp = in) + inlen; inp < endp; inp++) {
    2402               0 :                 if (state == ST_NORMAL) {
    2403               0 :                         if (*inp == '&' && inp[1] != '-') {
    2404               0 :                                 state = ST_DECODE0;
    2405                 :                         }
    2406               0 :                         else if ((*outp++ = *inp) == '&') {
    2407               0 :                                 inp++;
    2408                 :                         }
    2409                 :                 }
    2410               0 :                 else if (*inp == '-') {
    2411               0 :                         state = ST_NORMAL;
    2412                 :                 }
    2413                 :                 else {
    2414                 :                         /* decode input character */
    2415               0 :                         switch (state) {
    2416                 :                         case ST_DECODE0:
    2417               0 :                                 *outp = UNB64(*inp) << 2;
    2418               0 :                                 state = ST_DECODE1;
    2419               0 :                                 break;
    2420                 :                         case ST_DECODE1:
    2421               0 :                                 outp[1] = UNB64(*inp);
    2422               0 :                                 c = outp[1] >> 4;
    2423               0 :                                 *outp++ |= c;
    2424               0 :                                 *outp <<= 4;
    2425               0 :                                 state = ST_DECODE2;
    2426               0 :                                 break;
    2427                 :                         case ST_DECODE2:
    2428               0 :                                 outp[1] = UNB64(*inp);
    2429               0 :                                 c = outp[1] >> 2;
    2430               0 :                                 *outp++ |= c;
    2431               0 :                                 *outp <<= 6;
    2432               0 :                                 state = ST_DECODE3;
    2433               0 :                                 break;
    2434                 :                         case ST_DECODE3:
    2435               0 :                                 *outp++ |= UNB64(*inp);
    2436               0 :                                 state = ST_DECODE0;
    2437                 :                         case ST_NORMAL:
    2438                 :                                 break;
    2439                 :                         }
    2440                 :                 }
    2441                 :         }
    2442                 : 
    2443               0 :         *outp = 0;
    2444                 : 
    2445                 : #if PHP_DEBUG
    2446                 :         /* warn if we computed outlen incorrectly */
    2447                 :         if (outp - out != outlen) {
    2448                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "outp - out [%ld] != outlen [%d]", outp - out, outlen);
    2449                 :         }
    2450                 : #endif
    2451                 : 
    2452               0 :         RETURN_STRINGL(out, outlen, 0);
    2453                 : }
    2454                 : /* }}} */
    2455                 : 
    2456                 : /* {{{ proto string imap_utf7_encode(string buf)
    2457                 :    Encode a string in modified UTF-7 */
    2458                 : PHP_FUNCTION(imap_utf7_encode)
    2459               1 : {
    2460                 :         /* author: Andrew Skalski <askalski@chek.com> */
    2461                 :         zval **arg;
    2462                 :         const unsigned char *in, *inp, *endp;
    2463                 :         unsigned char *out, *outp;
    2464                 :         unsigned char c;
    2465                 :         int inlen, outlen;
    2466                 :         enum {
    2467                 :                 ST_NORMAL,      /* printable text */
    2468                 :                 ST_ENCODE0,     /* encoded text rotation... */
    2469                 :                 ST_ENCODE1,
    2470                 :                 ST_ENCODE2
    2471                 :         } state;
    2472                 : 
    2473               1 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
    2474               0 :                 ZEND_WRONG_PARAM_COUNT();
    2475                 :         }
    2476                 : 
    2477               1 :         convert_to_string_ex(arg);
    2478                 : 
    2479               1 :         in = (const unsigned char *) Z_STRVAL_PP(arg);
    2480               1 :         inlen = Z_STRLEN_PP(arg);
    2481                 : 
    2482                 :         /* compute the length of the result string */
    2483               1 :         outlen = 0;
    2484               1 :         state = ST_NORMAL;
    2485               1 :         endp = (inp = in) + inlen;
    2486              28 :         while (inp < endp) {
    2487              26 :                 if (state == ST_NORMAL) {
    2488              26 :                         if (SPECIAL(*inp)) {
    2489               0 :                                 state = ST_ENCODE0;
    2490               0 :                                 outlen++;
    2491              26 :                         } else if (*inp++ == '&') {
    2492               0 :                                 outlen++;
    2493                 :                         }
    2494              26 :                         outlen++;
    2495               0 :                 } else if (!SPECIAL(*inp)) {
    2496               0 :                         state = ST_NORMAL;
    2497                 :                 } else {
    2498                 :                         /* ST_ENCODE0 -> ST_ENCODE1  - two chars
    2499                 :                          * ST_ENCODE1 -> ST_ENCODE2  - one char
    2500                 :                          * ST_ENCODE2 -> ST_ENCODE0  - one char
    2501                 :                          */
    2502               0 :                         if (state == ST_ENCODE2) {
    2503               0 :                                 state = ST_ENCODE0;
    2504                 :                         }
    2505               0 :                         else if (state++ == ST_ENCODE0) {
    2506               0 :                                 outlen++;
    2507                 :                         }
    2508               0 :                         outlen++;
    2509               0 :                         inp++;
    2510                 :                 }
    2511                 :         }
    2512                 : 
    2513                 :         /* allocate output buffer */
    2514               1 :         out = emalloc(outlen + 1);
    2515                 : 
    2516                 :         /* encode input string */
    2517               1 :         outp = out;
    2518               1 :         state = ST_NORMAL;
    2519               1 :         endp = (inp = in) + inlen;
    2520              28 :         while (inp < endp || state != ST_NORMAL) {
    2521              26 :                 if (state == ST_NORMAL) {
    2522              26 :                         if (SPECIAL(*inp)) {
    2523                 :                                 /* begin encoding */
    2524               0 :                                 *outp++ = '&';
    2525               0 :                                 state = ST_ENCODE0;
    2526              26 :                         } else if ((*outp++ = *inp++) == '&') {
    2527               0 :                                 *outp++ = '-';
    2528                 :                         }
    2529               0 :                 } else if (inp == endp || !SPECIAL(*inp)) {
    2530                 :                         /* flush overflow and terminate region */
    2531               0 :                         if (state != ST_ENCODE0) {
    2532               0 :                                 c = B64(*outp);
    2533               0 :                                 *outp++ = c;
    2534                 :                         }
    2535               0 :                         *outp++ = '-';
    2536               0 :                         state = ST_NORMAL;
    2537                 :                 } else {
    2538                 :                         /* encode input character */
    2539               0 :                         switch (state) {
    2540                 :                                 case ST_ENCODE0:
    2541               0 :                                         *outp++ = B64(*inp >> 2);
    2542               0 :                                         *outp = *inp++ << 4;
    2543               0 :                                         state = ST_ENCODE1;
    2544               0 :                                         break;
    2545                 :                                 case ST_ENCODE1:
    2546               0 :                                         c = B64(*outp | *inp >> 4);
    2547               0 :                                         *outp++ = c;
    2548               0 :                                         *outp = *inp++ << 2;
    2549               0 :                                         state = ST_ENCODE2;
    2550               0 :                                         break;
    2551                 :                                 case ST_ENCODE2:
    2552               0 :                                         c = B64(*outp | *inp >> 6);
    2553               0 :                                         *outp++ = c;
    2554               0 :                                         *outp++ = B64(*inp++);
    2555               0 :                                         state = ST_ENCODE0;
    2556                 :                                 case ST_NORMAL:
    2557                 :                                         break;
    2558                 :                         }
    2559                 :                 }
    2560                 :         }
    2561                 : 
    2562               1 :         *outp = 0;
    2563                 : 
    2564                 : #if PHP_DEBUG
    2565                 :         /* warn if we computed outlen incorrectly */
    2566                 :         if (outp - out != outlen) {
    2567                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "outp - out [%ld] != outlen [%d]", outp - out, outlen);
    2568                 :         }
    2569                 : #endif
    2570                 : 
    2571               1 :         RETURN_STRINGL(out, outlen, 0);
    2572                 : }
    2573                 : /* }}} */
    2574                 : 
    2575                 : #undef SPECIAL
    2576                 : #undef B64CHAR
    2577                 : #undef B64
    2578                 : #undef UNB64
    2579                 : 
    2580                 : /* {{{ proto bool imap_setflag_full(resource stream_id, string sequence, string flag [, int options])
    2581                 :    Sets flags on messages */
    2582                 : PHP_FUNCTION(imap_setflag_full)
    2583               5 : {
    2584                 :         zval **streamind, **sequence, **flag, **flags;
    2585                 :         pils *imap_le_struct;
    2586               5 :         int myargc = ZEND_NUM_ARGS();
    2587                 : 
    2588               5 :         if (myargc < 3 || myargc > 4 || zend_get_parameters_ex(myargc, &streamind, &sequence, &flag, &flags) == FAILURE) {
    2589               0 :                 ZEND_WRONG_PARAM_COUNT();
    2590                 :         }
    2591                 : 
    2592               5 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2593                 : 
    2594               5 :         convert_to_string_ex(sequence);
    2595               5 :         convert_to_string_ex(flag);
    2596               5 :         if (myargc==4) {
    2597               0 :                 convert_to_long_ex(flags);
    2598                 :         }
    2599                 : 
    2600               5 :         mail_setflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), Z_STRVAL_PP(flag), myargc==4 ? Z_LVAL_PP(flags) : NIL);
    2601               5 :         RETURN_TRUE;
    2602                 : }
    2603                 : /* }}} */
    2604                 : 
    2605                 : /* {{{ proto bool imap_clearflag_full(resource stream_id, string sequence, string flag [, int options])
    2606                 :    Clears flags on messages */
    2607                 : PHP_FUNCTION(imap_clearflag_full)
    2608               3 : {
    2609                 :         zval **streamind, **sequence, **flag, **flags;
    2610                 :         pils *imap_le_struct;
    2611               3 :         int myargc = ZEND_NUM_ARGS();
    2612                 : 
    2613               3 :         if (myargc < 3 || myargc > 4 || zend_get_parameters_ex(myargc, &streamind, &sequence, &flag, &flags) ==FAILURE) {
    2614               0 :                 ZEND_WRONG_PARAM_COUNT();
    2615                 :         }
    2616                 : 
    2617               3 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2618                 : 
    2619               3 :         convert_to_string_ex(sequence);
    2620               3 :         convert_to_string_ex(flag);
    2621               3 :         if (myargc==4) {
    2622               0 :                 convert_to_long_ex(flags);
    2623                 :         }
    2624                 : 
    2625               3 :         mail_clearflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), Z_STRVAL_PP(flag), myargc==4 ? Z_LVAL_PP(flags) : NIL);
    2626               3 :         RETURN_TRUE;
    2627                 : }
    2628                 : /* }}} */
    2629                 : 
    2630                 : /* {{{ proto array imap_sort(resource stream_id, int criteria, int reverse [, int options [, string search_criteria [, string charset]]])
    2631                 :    Sort an array of message headers, optionally including only messages that meet specified criteria. */
    2632                 : PHP_FUNCTION(imap_sort)
    2633               0 : {
    2634                 :         zval **streamind, **pgm, **rev, **flags, **criteria, **charset;
    2635                 :         pils *imap_le_struct;
    2636                 :         unsigned long *slst, *sl;
    2637                 :         char *search_criteria;
    2638               0 :         SORTPGM *mypgm=NIL;
    2639               0 :         SEARCHPGM *spg=NIL;
    2640               0 :         int myargc = ZEND_NUM_ARGS();
    2641                 : 
    2642               0 :         if (myargc < 3 || myargc > 6 || zend_get_parameters_ex(myargc, &streamind, &pgm, &rev, &flags, &criteria, &charset) == FAILURE) {
    2643               0 :                 ZEND_WRONG_PARAM_COUNT();
    2644                 :         }
    2645                 : 
    2646               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2647                 : 
    2648               0 :         convert_to_long_ex(rev);
    2649               0 :         convert_to_long_ex(pgm);
    2650               0 :         if (Z_LVAL_PP(pgm) > SORTSIZE) {
    2651               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized sort criteria");
    2652               0 :                 RETURN_FALSE;
    2653                 :         }
    2654               0 :         if (myargc >= 4) {
    2655               0 :                 convert_to_long_ex(flags);
    2656               0 :                 if (Z_LVAL_PP(flags) < 0) {
    2657               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Search options parameter has to be greater than or equal to 0");
    2658               0 :                         RETURN_FALSE;
    2659                 :                 }
    2660                 :         }
    2661               0 :         if (myargc >= 5) {
    2662               0 :                 convert_to_string_ex(criteria);
    2663               0 :                 search_criteria = estrndup(Z_STRVAL_PP(criteria), Z_STRLEN_PP(criteria));
    2664               0 :                 spg = mail_criteria(search_criteria);
    2665               0 :                 efree(search_criteria);
    2666               0 :                 if (myargc == 6) {
    2667               0 :                         convert_to_string_ex(charset);
    2668                 :                 }
    2669                 :         } else {
    2670               0 :                 spg = mail_newsearchpgm();
    2671                 :         }
    2672                 : 
    2673               0 :         mypgm = mail_newsortpgm();
    2674               0 :         mypgm->reverse = Z_LVAL_PP(rev);
    2675               0 :         mypgm->function = (short) Z_LVAL_PP(pgm);
    2676               0 :         mypgm->next = NIL;
    2677                 : 
    2678               0 :         slst = mail_sort(imap_le_struct->imap_stream, (myargc == 6 ? Z_STRVAL_PP(charset) : NIL), spg, mypgm, (myargc >= 4 ? Z_LVAL_PP(flags) : NIL));
    2679                 : 
    2680               0 :         if (spg && myargc >= 4 && !(Z_LVAL_PP(flags) & SE_FREE)) {
    2681               0 :                 mail_free_searchpgm(&spg);
    2682                 :         }
    2683                 : 
    2684               0 :         array_init(return_value);
    2685               0 :         if (slst != NIL && slst != 0) {
    2686               0 :                 for (sl = slst; *sl; sl++) {
    2687               0 :                         add_next_index_long(return_value, *sl);
    2688                 :                 }
    2689               0 :                 fs_give ((void **) &slst);
    2690                 :         }
    2691                 : }
    2692                 : /* }}} */
    2693                 : 
    2694                 : /* {{{ proto string imap_fetchheader(resource stream_id, int msg_no [, int options])
    2695                 :    Get the full unfiltered header for a message */
    2696                 : PHP_FUNCTION(imap_fetchheader)
    2697              73 : {
    2698                 :         zval **streamind, **msgno, **pflags;
    2699                 :         pils *imap_le_struct;
    2700              73 :         int msgindex, myargc = ZEND_NUM_ARGS();
    2701              73 :         long flags=0L;
    2702                 : 
    2703              73 :         if (myargc < 2 || myargc > 3 || zend_get_parameters_ex(myargc, &streamind, &msgno, &pflags) == FAILURE) {
    2704               2 :                 ZEND_WRONG_PARAM_COUNT();
    2705                 :         }
    2706                 : 
    2707              71 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2708                 : 
    2709              42 :         convert_to_long_ex(msgno);
    2710              42 :         if (myargc == 3) {
    2711               9 :                 convert_to_long_ex(pflags);
    2712               9 :                 flags =  Z_LVAL_PP(pflags);
    2713               9 :                 if (flags && ((flags & ~(FT_UID|FT_INTERNAL|FT_PREFETCHTEXT)) != 0)) {
    2714               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid value for the options parameter");
    2715               2 :                         RETURN_FALSE;
    2716                 :                 }
    2717                 :         }
    2718                 : 
    2719                 : 
    2720              45 :         if ((myargc == 3) && (flags & FT_UID)) {
    2721                 :                 /* This should be cached; if it causes an extra RTT to the
    2722                 :                    IMAP server, then that's the price we pay for making sure
    2723                 :                    we don't crash. */
    2724               5 :                 msgindex = mail_msgno(imap_le_struct->imap_stream, Z_LVAL_PP(msgno));
    2725                 :         } else {
    2726              35 :                 msgindex = Z_LVAL_PP(msgno);
    2727                 :         }
    2728                 : 
    2729              40 :         PHP_IMAP_CHECK_MSGNO(msgindex);
    2730                 : 
    2731              17 :         RETVAL_STRING(mail_fetchheader_full(imap_le_struct->imap_stream, Z_LVAL_PP(msgno), NIL, NIL, (myargc == 3 ? Z_LVAL_PP(pflags) : NIL)), 1);
    2732                 : }
    2733                 : /* }}} */
    2734                 : 
    2735                 : /* {{{ proto int imap_uid(resource stream_id, int msg_no)
    2736                 :    Get the unique message id associated with a standard sequential message number */
    2737                 : PHP_FUNCTION(imap_uid)
    2738               6 : {
    2739                 :         zval **streamind, **msgno;
    2740                 :         pils *imap_le_struct;
    2741                 :         int msgindex;
    2742                 : 
    2743               6 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &msgno) == FAILURE) {
    2744               0 :                 ZEND_WRONG_PARAM_COUNT();
    2745                 :         }
    2746                 : 
    2747               6 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2748                 : 
    2749               6 :         convert_to_long_ex(msgno);
    2750                 : 
    2751               6 :         msgindex = Z_LVAL_PP(msgno);
    2752               6 :         if ((msgindex < 1) || ((unsigned) msgindex > imap_le_struct->imap_stream->nmsgs)) {
    2753               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message number");
    2754               0 :                 RETURN_FALSE;
    2755                 :         }
    2756                 : 
    2757               6 :         RETURN_LONG(mail_uid(imap_le_struct->imap_stream, Z_LVAL_PP(msgno)));
    2758                 : }
    2759                 : /* }}} */
    2760                 : 
    2761                 : /* {{{ proto int imap_msgno(resource stream_id, int unique_msg_id)
    2762                 :    Get the sequence number associated with a UID */
    2763                 : PHP_FUNCTION(imap_msgno)
    2764               0 : {
    2765                 :         zval **streamind, **msgno;
    2766                 :         pils *imap_le_struct;
    2767                 : 
    2768               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &msgno) == FAILURE) {
    2769               0 :                 ZEND_WRONG_PARAM_COUNT();
    2770                 :         }
    2771                 : 
    2772               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2773                 : 
    2774               0 :         convert_to_long_ex(msgno);
    2775                 : 
    2776               0 :         RETURN_LONG(mail_msgno(imap_le_struct->imap_stream, Z_LVAL_PP(msgno)));
    2777                 : }
    2778                 : /* }}} */
    2779                 : 
    2780                 : /* {{{ proto object imap_status(resource stream_id, string mailbox, int options)
    2781                 :    Get status info from a mailbox */
    2782                 : PHP_FUNCTION(imap_status)
    2783               1 : {
    2784                 :         zval **streamind, **mbx, **flags;
    2785                 :         pils *imap_le_struct;
    2786                 : 
    2787               1 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &mbx, &flags) == FAILURE) {
    2788               0 :                 ZEND_WRONG_PARAM_COUNT();
    2789                 :         }
    2790                 : 
    2791               1 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2792                 : 
    2793               1 :         convert_to_string_ex(mbx);
    2794               1 :         convert_to_long_ex(flags);
    2795                 : 
    2796               1 :         object_init(return_value);
    2797                 : 
    2798               1 :         if (mail_status(imap_le_struct->imap_stream, Z_STRVAL_PP(mbx), Z_LVAL_PP(flags))) {
    2799               1 :                 add_property_long(return_value, "flags", IMAPG(status_flags));
    2800               1 :                 if (IMAPG(status_flags) & SA_MESSAGES) {
    2801               1 :                         add_property_long(return_value, "messages", IMAPG(status_messages));
    2802                 :                 }
    2803               1 :                 if (IMAPG(status_flags) & SA_RECENT) {
    2804               1 :                         add_property_long(return_value, "recent", IMAPG(status_recent));
    2805                 :                 }
    2806               1 :                 if (IMAPG(status_flags) & SA_UNSEEN) {
    2807               1 :                         add_property_long(return_value, "unseen", IMAPG(status_unseen));
    2808                 :                 }
    2809               1 :                 if (IMAPG(status_flags) & SA_UIDNEXT) {
    2810               1 :                         add_property_long(return_value, "uidnext", IMAPG(status_uidnext));
    2811                 :                 }
    2812               1 :                 if (IMAPG(status_flags) & SA_UIDVALIDITY) {
    2813               1 :                         add_property_long(return_value, "uidvalidity", IMAPG(status_uidvalidity));
    2814                 :                 }
    2815                 :         } else {
    2816               0 :                 RETURN_FALSE;
    2817                 :         }
    2818                 : }
    2819                 : /* }}} */
    2820                 : 
    2821                 : /* {{{ proto object imap_bodystruct(resource stream_id, int msg_no, string section)
    2822                 :    Read the structure of a specified body section of a specific message */
    2823                 : PHP_FUNCTION(imap_bodystruct)
    2824               2 : {
    2825                 :         zval **streamind, **msg, **section;
    2826                 :         pils *imap_le_struct;
    2827                 :         zval *parametres, *param, *dparametres, *dparam;
    2828                 :         PARAMETER *par, *dpar;
    2829                 :         BODY *body;
    2830                 : 
    2831               2 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &streamind, &msg, &section) == FAILURE) {
    2832               0 :                 ZEND_WRONG_PARAM_COUNT();
    2833                 :         }
    2834                 : 
    2835               2 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2836                 : 
    2837               2 :         convert_to_long_ex(msg);
    2838               2 :         convert_to_string_ex(section);
    2839                 : 
    2840               2 :         if (!Z_LVAL_PP(msg) || Z_LVAL_PP(msg) < 1 || (unsigned) Z_LVAL_PP(msg) > imap_le_struct->imap_stream->nmsgs) {
    2841               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message number");
    2842               0 :                 RETURN_FALSE;
    2843                 :         }
    2844                 : 
    2845               2 :         object_init(return_value);
    2846                 : 
    2847               2 :         body=mail_body(imap_le_struct->imap_stream, Z_LVAL_PP(msg), Z_STRVAL_PP(section));
    2848               2 :         if (body == NULL) {
    2849               1 :                 zval_dtor(return_value);
    2850               1 :                 RETURN_FALSE;
    2851                 :         }
    2852               1 :         if (body->type <= TYPEMAX) {
    2853               1 :                 add_property_long(return_value, "type", body->type);
    2854                 :         }
    2855               1 :         if (body->encoding <= ENCMAX) {
    2856               1 :                 add_property_long(return_value, "encoding", body->encoding);
    2857                 :         }
    2858                 : 
    2859               1 :         if (body->subtype) {
    2860               1 :                 add_property_long(return_value, "ifsubtype", 1);
    2861               1 :                 add_property_string(return_value, "subtype",  body->subtype, 1);
    2862                 :         } else {
    2863               0 :                 add_property_long(return_value, "ifsubtype", 0);
    2864                 :         }
    2865                 : 
    2866               1 :         if (body->description) {
    2867               1 :                 add_property_long(return_value, "ifdescription", 1);
    2868               1 :                 add_property_string(return_value, "description",  body->description, 1);
    2869                 :         } else {
    2870               0 :                 add_property_long(return_value, "ifdescription", 0);
    2871                 :         }
    2872               1 :         if (body->id) {
    2873               0 :                 add_property_long(return_value, "ifid", 1);
    2874               0 :                 add_property_string(return_value, "id",  body->id, 1);
    2875                 :         } else {
    2876               1 :                 add_property_long(return_value, "ifid", 0);
    2877                 :         }
    2878                 : 
    2879                 : 
    2880               1 :         if (body->size.lines) {
    2881               0 :                 add_property_long(return_value, "lines", body->size.lines);
    2882                 :         }
    2883               1 :         if (body->size.bytes) {
    2884               1 :                 add_property_long(return_value, "bytes", body->size.bytes);
    2885                 :         }
    2886                 : #ifdef IMAP41
    2887               1 :         if (body->disposition.type) {
    2888               0 :                 add_property_long(return_value, "ifdisposition", 1);
    2889               0 :                 add_property_string(return_value, "disposition", body->disposition.type, 1);
    2890                 :         } else {
    2891               1 :                 add_property_long(return_value, "ifdisposition", 0);
    2892                 :         }
    2893                 : 
    2894               1 :         if (body->disposition.parameter) {
    2895               0 :                 dpar = body->disposition.parameter;
    2896               0 :                 add_property_long(return_value, "ifdparameters", 1);
    2897               0 :                 MAKE_STD_ZVAL(dparametres);
    2898               0 :                 array_init(dparametres);
    2899                 :                 do {
    2900               0 :                         MAKE_STD_ZVAL(dparam);
    2901               0 :                         object_init(dparam);
    2902               0 :                         add_property_string(dparam, "attribute", dpar->attribute, 1);
    2903               0 :                         add_property_string(dparam, "value", dpar->value, 1);
    2904               0 :                         add_next_index_object(dparametres, dparam TSRMLS_CC);
    2905               0 :                 } while ((dpar = dpar->next));
    2906               0 :                 add_assoc_object(return_value, "dparameters", dparametres TSRMLS_CC);
    2907                 :         } else {
    2908               1 :                 add_property_long(return_value, "ifdparameters", 0);
    2909                 :         }
    2910                 : #endif
    2911                 : 
    2912               1 :         if ((par = body->parameter)) {
    2913               1 :                 add_property_long(return_value, "ifparameters", 1);
    2914                 : 
    2915               1 :                 MAKE_STD_ZVAL(parametres);
    2916               1 :                 array_init(parametres);
    2917                 :                 do {
    2918               1 :                         MAKE_STD_ZVAL(param);
    2919               1 :                         object_init(param);
    2920               1 :                         if (par->attribute) {
    2921               1 :                                 add_property_string(param, "attribute", par->attribute, 1);
    2922                 :                         }
    2923               1 :                         if (par->value) {
    2924               1 :                                 add_property_string(param, "value", par->value, 1);
    2925                 :                         }
    2926                 : 
    2927               1 :                         add_next_index_object(parametres, param TSRMLS_CC);
    2928               1 :                 } while ((par = par->next));
    2929                 :         } else {
    2930               0 :                 MAKE_STD_ZVAL(parametres);
    2931               0 :                 object_init(parametres);
    2932               0 :                 add_property_long(return_value, "ifparameters", 0);
    2933                 :         }
    2934               1 :         add_assoc_object(return_value, "parameters", parametres TSRMLS_CC);
    2935                 : }
    2936                 : 
    2937                 : /* }}} */
    2938                 : 
    2939                 : /* {{{ proto array imap_fetch_overview(resource stream_id, int msg_no [, int options])
    2940                 :    Read an overview of the information in the headers of the given message sequence */
    2941                 : PHP_FUNCTION(imap_fetch_overview)
    2942              71 : {
    2943                 :         zval **streamind, **sequence, **pflags;
    2944                 :         pils *imap_le_struct;
    2945                 :         zval *myoverview;
    2946                 :         char *address;
    2947              71 :         long status, flags=0L;
    2948              71 :         int myargc = ZEND_NUM_ARGS();
    2949                 : 
    2950              71 :         if (myargc < 2 || myargc > 3 || zend_get_parameters_ex(myargc, &streamind, &sequence, &pflags) == FAILURE) {
    2951               2 :                 ZEND_WRONG_PARAM_COUNT();
    2952                 :         }
    2953                 : 
    2954                 : 
    2955              69 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    2956                 : 
    2957              43 :         convert_to_string_ex(sequence);
    2958              43 :         if(myargc == 3) {
    2959               7 :                 convert_to_long_ex(pflags);
    2960               7 :                 flags = Z_LVAL_PP(pflags);
    2961               7 :                 if (flags && ((flags & ~FT_UID) != 0)) {
    2962               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid value for the options parameter");
    2963               2 :                         RETURN_FALSE;
    2964                 :                 }
    2965                 :         }
    2966                 : 
    2967              41 :         array_init(return_value);
    2968                 : 
    2969              41 :         status = (flags & FT_UID)
    2970                 :                 ? mail_uid_sequence (imap_le_struct->imap_stream, Z_STRVAL_PP(sequence))
    2971                 :                 : mail_sequence (imap_le_struct->imap_stream, Z_STRVAL_PP(sequence));
    2972                 : 
    2973              41 :         if (status) {
    2974                 :                 MESSAGECACHE *elt;
    2975                 :                 ENVELOPE *env;
    2976                 :                 unsigned long i;
    2977                 : 
    2978              58 :                 for (i = 1; i <= imap_le_struct->imap_stream->nmsgs; i++) {
    2979              35 :                         if (((elt = mail_elt (imap_le_struct->imap_stream, i))->sequence) &&
    2980                 :                                 (env = mail_fetch_structure (imap_le_struct->imap_stream, i, NIL, NIL))) {
    2981              19 :                                 MAKE_STD_ZVAL(myoverview);
    2982              19 :                                 object_init(myoverview);
    2983              19 :                                 if (env->subject) {
    2984              19 :                                         add_property_string(myoverview, "subject", env->subject, 1);
    2985                 :                                 }
    2986              19 :                                 if (env->from) {
    2987              19 :                                         env->from->next=NULL;
    2988              19 :                                         address =_php_rfc822_write_address(env->from TSRMLS_CC);
    2989              19 :                                         if (address) {
    2990              19 :                                                 add_property_string(myoverview, "from", address, 0);
    2991                 :                                         }
    2992                 :                                 }
    2993              19 :                                 if (env->to) {
    2994              19 :                                         env->to->next = NULL;
    2995              19 :                                         address = _php_rfc822_write_address(env->to TSRMLS_CC);
    2996              19 :                                         if (address) {
    2997              19 :                                                 add_property_string(myoverview, "to", address, 0);
    2998                 :                                         }
    2999                 :                                 }
    3000              19 :                                 if (env->date) {
    3001               0 :                                         add_property_string(myoverview, "date", env->date, 1);
    3002                 :                                 }
    3003              19 :                                 if (env->message_id) {
    3004               0 :                                         add_property_string(myoverview, "message_id", env->message_id, 1);
    3005                 :                                 }
    3006              19 :                                 if (env->references) {
    3007               0 :                                         add_property_string(myoverview, "references", env->references, 1);
    3008                 :                                 }
    3009              19 :                                 if (env->in_reply_to) {
    3010               0 :                                         add_property_string(myoverview, "in_reply_to", env->in_reply_to, 1);
    3011                 :                                 }
    3012              19 :                                 add_property_long(myoverview, "size", elt->rfc822_size);
    3013              19 :                                 add_property_long(myoverview, "uid", mail_uid(imap_le_struct->imap_stream, i));
    3014              19 :                                 add_property_long(myoverview, "msgno", i);
    3015              19 :                                 add_property_long(myoverview, "recent", elt->recent);
    3016              19 :                                 add_property_long(myoverview, "flagged", elt->flagged);
    3017              19 :                                 add_property_long(myoverview, "answered", elt->answered);
    3018              19 :                                 add_property_long(myoverview, "deleted", elt->deleted);
    3019              19 :                                 add_property_long(myoverview, "seen", elt->seen);
    3020              19 :                                 add_property_long(myoverview, "draft", elt->draft);
    3021              19 :                                 add_next_index_object(return_value, myoverview TSRMLS_CC);
    3022                 :                         }
    3023                 :                 }
    3024                 :         }
    3025                 : }
    3026                 : /* }}} */
    3027                 : 
    3028                 : /* {{{ proto string imap_mail_compose(array envelope, array body)
    3029                 :    Create a MIME message based on given envelope and body sections */
    3030                 : PHP_FUNCTION(imap_mail_compose)
    3031              24 : {
    3032                 :         zval **envelope, **body;
    3033                 :         char *key;
    3034                 :         zval **data, **pvalue, **disp_data, **env_data;
    3035                 :         ulong ind;
    3036              24 :         char *cookie = NIL;
    3037                 :         ENVELOPE *env;
    3038              24 :         BODY *bod=NULL, *topbod=NULL;
    3039              24 :         PART *mypart=NULL, *part;
    3040              24 :         PARAMETER *param, *disp_param = NULL, *custom_headers_param = NULL, *tmp_param = NULL;
    3041              24 :         char *tmp=NULL, *mystring=NULL, *t=NULL, *tempstring=NULL, *str_copy = NULL;
    3042              24 :         int toppart = 0;
    3043                 : 
    3044              24 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &envelope, &body) == FAILURE) {
    3045               0 :                 ZEND_WRONG_PARAM_COUNT();
    3046                 :         }
    3047                 : 
    3048              24 :         if (Z_TYPE_PP(envelope) != IS_ARRAY) {
    3049               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as envelope parameter");
    3050               0 :                 RETURN_FALSE;
    3051                 :         }
    3052                 : 
    3053              24 :         if (Z_TYPE_PP(body) != IS_ARRAY) {
    3054               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as body parameter");
    3055               0 :                 RETURN_FALSE;
    3056                 :         }
    3057                 : 
    3058                 : #define PHP_RFC822_PARSE_ADRLIST(target, value) \
    3059                 :         str_copy = estrndup(Z_STRVAL_PP(value), Z_STRLEN_PP(value)); \
    3060                 :         rfc822_parse_adrlist(target, str_copy, "NO HOST"); \
    3061                 :         efree(str_copy);
    3062                 : 
    3063              24 :         env = mail_newenvelope();
    3064              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "remail", sizeof("remail"), (void **) &pvalue)== SUCCESS) {
    3065               0 :                 convert_to_string_ex(pvalue);
    3066               0 :                 env->remail = cpystr(Z_STRVAL_PP(pvalue));
    3067                 :         }
    3068              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "return_path", sizeof("return_path"), (void **) &pvalue)== SUCCESS) {
    3069               2 :                 convert_to_string_ex(pvalue)
    3070               2 :                 PHP_RFC822_PARSE_ADRLIST(&env->return_path, pvalue);
    3071                 :         }
    3072              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "date", sizeof("date"), (void **) &pvalue)== SUCCESS) {
    3073               1 :                 convert_to_string_ex(pvalue);
    3074               1 :                 env->date = cpystr(Z_STRVAL_PP(pvalue));
    3075                 :         }
    3076              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "from", sizeof("from"), (void **) &pvalue)== SUCCESS) {
    3077              23 :                 convert_to_string_ex(pvalue);
    3078              23 :                 PHP_RFC822_PARSE_ADRLIST(&env->from, pvalue);
    3079                 :         }
    3080              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "reply_to", sizeof("reply_to"), (void **) &pvalue)== SUCCESS) {
    3081               1 :                 convert_to_string_ex(pvalue);
    3082               1 :                 PHP_RFC822_PARSE_ADRLIST(&env->reply_to, pvalue);
    3083                 :         }
    3084              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "in_reply_to", sizeof("in_reply_to"), (void **) &pvalue)== SUCCESS) {
    3085               0 :                 convert_to_string_ex(pvalue);
    3086               0 :                 env->in_reply_to = cpystr(Z_STRVAL_PP(pvalue));
    3087                 :         }
    3088              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "subject", sizeof("subject"), (void **) &pvalue)== SUCCESS) {
    3089              18 :                 convert_to_string_ex(pvalue);
    3090              18 :                 env->subject = cpystr(Z_STRVAL_PP(pvalue));
    3091                 :         }
    3092              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "to", sizeof("to"), (void **) &pvalue)== SUCCESS) {
    3093              22 :                 convert_to_string_ex(pvalue);
    3094              22 :                 PHP_RFC822_PARSE_ADRLIST(&env->to, pvalue);
    3095                 :         }
    3096              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "cc", sizeof("cc"), (void **) &pvalue)== SUCCESS) {
    3097               3 :                 convert_to_string_ex(pvalue);
    3098               3 :                 PHP_RFC822_PARSE_ADRLIST(&env->cc, pvalue);
    3099                 :         }
    3100              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "bcc", sizeof("bcc"), (void **) &pvalue)== SUCCESS) {
    3101               1 :                 convert_to_string_ex(pvalue);
    3102               1 :                 PHP_RFC822_PARSE_ADRLIST(&env->bcc, pvalue);
    3103                 :         }
    3104              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "message_id", sizeof("message_id"), (void **) &pvalue)== SUCCESS) {
    3105               0 :                 convert_to_string_ex(pvalue);
    3106               0 :                 env->message_id = cpystr(Z_STRVAL_PP(pvalue));
    3107                 :         }
    3108                 : 
    3109              24 :         if (zend_hash_find(Z_ARRVAL_PP(envelope), "custom_headers", sizeof("custom_headers"), (void **) &pvalue)== SUCCESS) {
    3110               0 :                 if (Z_TYPE_PP(pvalue) == IS_ARRAY) {
    3111               0 :                         custom_headers_param = tmp_param = NULL;
    3112               0 :                         while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &env_data) == SUCCESS) {
    3113               0 :                                 custom_headers_param = mail_newbody_parameter();
    3114               0 :                                 convert_to_string_ex(env_data);
    3115               0 :                                 custom_headers_param->value = (char *) fs_get(Z_STRLEN_PP(env_data) + 1);
    3116               0 :                                 custom_headers_param->attribute = NULL;
    3117               0 :                                 memcpy(custom_headers_param->value, Z_STRVAL_PP(env_data), Z_STRLEN_PP(env_data) + 1);
    3118               0 :                                 zend_hash_move_forward(Z_ARRVAL_PP(pvalue));
    3119               0 :                                 custom_headers_param->next = tmp_param;
    3120               0 :                                 tmp_param = custom_headers_param;
    3121                 :                         }
    3122                 :                 }
    3123                 :         }
    3124                 : 
    3125              24 :         zend_hash_internal_pointer_reset(Z_ARRVAL_PP(body));
    3126              24 :         if (zend_hash_get_current_data(Z_ARRVAL_PP(body), (void **) &data) != SUCCESS || Z_TYPE_PP(data) != IS_ARRAY) {
    3127               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "body parameter must be a non-empty array");
    3128               0 :                 RETURN_FALSE;
    3129                 :         }
    3130                 : 
    3131              24 :         if (Z_TYPE_PP(data) == IS_ARRAY) {
    3132              24 :                 bod = mail_newbody();
    3133              24 :                 topbod = bod;
    3134                 : 
    3135              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &pvalue)== SUCCESS) {
    3136              23 :                         convert_to_long_ex(pvalue);
    3137              23 :                         bod->type = (short) Z_LVAL_PP(pvalue);
    3138                 :                 }
    3139              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "encoding", sizeof("encoding"), (void **) &pvalue)== SUCCESS) {
    3140               1 :                         convert_to_long_ex(pvalue);
    3141               1 :                         bod->encoding = (short) Z_LVAL_PP(pvalue);
    3142                 :                 }
    3143              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "charset", sizeof("charset"), (void **) &pvalue)== SUCCESS) {
    3144               1 :                         convert_to_string_ex(pvalue);
    3145               1 :                         tmp_param = mail_newbody_parameter();
    3146               1 :                         tmp_param->value = cpystr(Z_STRVAL_PP(pvalue));
    3147               1 :                         tmp_param->attribute = cpystr("CHARSET");
    3148               1 :                         tmp_param->next = bod->parameter;
    3149               1 :                         bod->parameter = tmp_param;
    3150                 :                 }
    3151              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "type.parameters", sizeof("type.parameters"), (void **) &pvalue)== SUCCESS) {
    3152               0 :                         if(Z_TYPE_PP(pvalue) == IS_ARRAY) {
    3153               0 :                                 disp_param = tmp_param = NULL;
    3154               0 :                                 while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) {
    3155               0 :                                         disp_param = mail_newbody_parameter();
    3156               0 :                                         zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0);
    3157               0 :                                         disp_param->attribute = cpystr(key);
    3158               0 :                                         convert_to_string_ex(disp_data);
    3159               0 :                                         disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1);
    3160               0 :                                         memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1);
    3161               0 :                                         zend_hash_move_forward(Z_ARRVAL_PP(pvalue));
    3162               0 :                                         disp_param->next = tmp_param;
    3163               0 :                                         tmp_param = disp_param;
    3164                 :                                 }
    3165               0 :                         bod->parameter = disp_param;
    3166                 :                         }
    3167                 :                 }
    3168              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "subtype", sizeof("subtype"), (void **) &pvalue)== SUCCESS) {
    3169              23 :                         convert_to_string_ex(pvalue);
    3170              23 :                         bod->subtype = cpystr(Z_STRVAL_PP(pvalue));
    3171                 :                 }
    3172              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "id", sizeof("id"), (void **) &pvalue)== SUCCESS) {
    3173               0 :                         convert_to_string_ex(pvalue);
    3174               0 :                         bod->id = cpystr(Z_STRVAL_PP(pvalue));
    3175                 :                 }
    3176              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "description", sizeof("description"), (void **) &pvalue)== SUCCESS) {
    3177               0 :                         convert_to_string_ex(pvalue);
    3178               0 :                         bod->description = cpystr(Z_STRVAL_PP(pvalue));
    3179                 :                 }
    3180              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "disposition.type", sizeof("disposition.type"), (void **) &pvalue)== SUCCESS) {
    3181               0 :                         convert_to_string_ex(pvalue);
    3182               0 :                         bod->disposition.type = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1);
    3183               0 :                         memcpy(bod->disposition.type, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue)+1);
    3184                 :                 }
    3185              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "disposition", sizeof("disposition"), (void **) &pvalue)== SUCCESS) {
    3186               0 :                         if (Z_TYPE_PP(pvalue) == IS_ARRAY) {
    3187               0 :                                 disp_param = tmp_param = NULL;
    3188               0 :                                 while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) {
    3189               0 :                                         disp_param = mail_newbody_parameter();
    3190               0 :                                         zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0);
    3191               0 :                                         disp_param->attribute = cpystr(key);
    3192               0 :                                         convert_to_string_ex(disp_data);
    3193               0 :                                         disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1);
    3194               0 :                                         memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1);
    3195               0 :                                         zend_hash_move_forward(Z_ARRVAL_PP(pvalue));
    3196               0 :                                         disp_param->next = tmp_param;
    3197               0 :                                         tmp_param = disp_param;
    3198                 :                                 }
    3199               0 :                                 bod->disposition.parameter = disp_param;
    3200                 :                         }
    3201                 :                 }
    3202              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "contents.data", sizeof("contents.data"), (void **) &pvalue)== SUCCESS) {
    3203               1 :                         convert_to_string_ex(pvalue);
    3204               1 :                         bod->contents.text.data = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1);
    3205               1 :                         memcpy(bod->contents.text.data, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue)+1);
    3206               1 :                         bod->contents.text.size = Z_STRLEN_PP(pvalue);
    3207                 :                 } else {
    3208              23 :                         bod->contents.text.data = (char *) fs_get(1);
    3209              23 :                         memcpy(bod->contents.text.data, "", 1);
    3210              23 :                         bod->contents.text.size = 0;
    3211                 :                 }
    3212              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "lines", sizeof("lines"), (void **) &pvalue)== SUCCESS) {
    3213               0 :                         convert_to_long_ex(pvalue);
    3214               0 :                         bod->size.lines = Z_LVAL_PP(pvalue);
    3215                 :                 }
    3216              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "bytes", sizeof("bytes"), (void **) &pvalue)== SUCCESS) {
    3217               0 :                         convert_to_long_ex(pvalue);
    3218               0 :                         bod->size.bytes = Z_LVAL_PP(pvalue);
    3219                 :                 }
    3220              24 :                 if (zend_hash_find(Z_ARRVAL_PP(data), "md5", sizeof("md5"), (void **) &pvalue)== SUCCESS) {
    3221               0 :                         convert_to_string_ex(pvalue);
    3222               0 :                         bod->md5 = cpystr(Z_STRVAL_PP(pvalue));
    3223                 :                 }
    3224                 :         }
    3225                 : 
    3226              24 :         zend_hash_move_forward(Z_ARRVAL_PP(body));
    3227                 : 
    3228             110 :         while (zend_hash_get_current_data(Z_ARRVAL_PP(body), (void **) &data) == SUCCESS) {
    3229              62 :                 if (Z_TYPE_PP(data) == IS_ARRAY) {
    3230              62 :                         short type = -1;
    3231              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &pvalue)== SUCCESS) {
    3232              62 :                                 convert_to_long_ex(pvalue);
    3233              62 :                                 type = (short) Z_LVAL_PP(pvalue);
    3234                 :                         }
    3235                 : 
    3236              62 :                         if (!toppart) {
    3237              22 :                                 bod->nested.part = mail_newbody_part();
    3238              22 :                                 mypart = bod->nested.part;
    3239              22 :                                 toppart = 1;
    3240                 :                         } else {
    3241              40 :                                 mypart->next = mail_newbody_part();
    3242              40 :                                 mypart = mypart->next;
    3243                 :                         }
    3244                 : 
    3245              62 :                         bod = &mypart->body;
    3246                 : 
    3247              62 :                         if (type != TYPEMULTIPART) {
    3248              61 :                                 bod->type = type;
    3249                 :                         }
    3250                 : 
    3251              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "encoding", sizeof("encoding"), (void **) &pvalue)== SUCCESS) {
    3252               5 :                                 convert_to_long_ex(pvalue);
    3253               5 :                                 bod->encoding = (short) Z_LVAL_PP(pvalue);
    3254                 :                         }
    3255              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "charset", sizeof("charset"), (void **) &pvalue)== SUCCESS) {
    3256               3 :                                 convert_to_string_ex(pvalue);
    3257               3 :                                 tmp_param = mail_newbody_parameter();
    3258               3 :                                 tmp_param->value = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1);
    3259               3 :                                 memcpy(tmp_param->value, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue) + 1);
    3260               3 :                                 tmp_param->attribute = cpystr("CHARSET");
    3261               3 :                                 tmp_param->next = bod->parameter;
    3262               3 :                                 bod->parameter = tmp_param;
    3263                 :                         }
    3264              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "type.parameters", sizeof("type.parameters"), (void **) &pvalue)== SUCCESS) {
    3265               1 :                                 if(Z_TYPE_PP(pvalue) == IS_ARRAY) {
    3266               1 :                                         disp_param = tmp_param = NULL;
    3267               3 :                                         while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) {
    3268               1 :                                                 disp_param = mail_newbody_parameter();
    3269               1 :                                                 zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0);
    3270               1 :                                                 disp_param->attribute = cpystr(key);
    3271               1 :                                                 convert_to_string_ex(disp_data);
    3272               1 :                                                 disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1);
    3273               1 :                                                 memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1);
    3274               1 :                                                 zend_hash_move_forward(Z_ARRVAL_PP(pvalue));
    3275               1 :                                                 disp_param->next = tmp_param;
    3276               1 :                                                 tmp_param = disp_param;
    3277                 :                                         }
    3278               1 :                                         bod->parameter = disp_param;
    3279                 :                                 }
    3280                 :                         }
    3281              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "subtype", sizeof("subtype"), (void **) &pvalue)== SUCCESS) {
    3282              62 :                                 convert_to_string_ex(pvalue);
    3283              62 :                                 bod->subtype = cpystr(Z_STRVAL_PP(pvalue));
    3284                 :                         }
    3285              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "id", sizeof("id"), (void **) &pvalue)== SUCCESS) {
    3286               0 :                                 convert_to_string_ex(pvalue);
    3287               0 :                                 bod->id = cpystr(Z_STRVAL_PP(pvalue));
    3288                 :                         }
    3289              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "description", sizeof("description"), (void **) &pvalue)== SUCCESS) {
    3290              61 :                                 convert_to_string_ex(pvalue);
    3291              61 :                                 bod->description = cpystr(Z_STRVAL_PP(pvalue));
    3292                 :                         }
    3293              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "disposition.type", sizeof("disposition.type"), (void **) &pvalue)== SUCCESS) {
    3294               1 :                                 convert_to_string_ex(pvalue);
    3295               1 :                                 bod->disposition.type = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1);
    3296               1 :                                 memcpy(bod->disposition.type, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue)+1);
    3297                 :                         }
    3298              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "disposition", sizeof("disposition"), (void **) &pvalue)== SUCCESS) {
    3299               3 :                                 if (Z_TYPE_PP(pvalue) == IS_ARRAY) {
    3300               1 :                                         disp_param = tmp_param = NULL;
    3301               3 :                                         while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) {
    3302               1 :                                                 disp_param = mail_newbody_parameter();
    3303               1 :                                                 zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0);
    3304               1 :                                                 disp_param->attribute = cpystr(key);
    3305               1 :                                                 convert_to_string_ex(disp_data);
    3306               1 :                                                 disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1);
    3307               1 :                                                 memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1);
    3308               1 :                                                 zend_hash_move_forward(Z_ARRVAL_PP(pvalue));
    3309               1 :                                                 disp_param->next = tmp_param;
    3310               1 :                                                 tmp_param = disp_param;
    3311                 :                                         }
    3312               1 :                                         bod->disposition.parameter = disp_param;
    3313                 :                                 }
    3314                 :                         }
    3315              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "contents.data", sizeof("contents.data"), (void **) &pvalue)== SUCCESS) {
    3316              61 :                                 convert_to_string_ex(pvalue);
    3317              61 :                                 bod->contents.text.data = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1);
    3318              61 :                                 memcpy(bod->contents.text.data, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue) + 1);
    3319              61 :                                 bod->contents.text.size = Z_STRLEN_PP(pvalue);
    3320                 :                         } else {
    3321               1 :                                 bod->contents.text.data = (char *) fs_get(1);
    3322               1 :                                 memcpy(bod->contents.text.data, "", 1);
    3323               1 :                                 bod->contents.text.size = 0;
    3324                 :                         }
    3325              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "lines", sizeof("lines"), (void **) &pvalue)== SUCCESS) {
    3326               0 :                                 convert_to_long_ex(pvalue);
    3327               0 :                                 bod->size.lines = Z_LVAL_PP(pvalue);
    3328                 :                         }
    3329              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "bytes", sizeof("bytes"), (void **) &pvalue)== SUCCESS) {
    3330               0 :                                 convert_to_long_ex(pvalue);
    3331               0 :                                 bod->size.bytes = Z_LVAL_PP(pvalue);
    3332                 :                         }
    3333              62 :                         if (zend_hash_find(Z_ARRVAL_PP(data), "md5", sizeof("md5"), (void **) &pvalue)== SUCCESS) {
    3334               0 :                                 convert_to_string_ex(pvalue);
    3335               0 :                                 bod->md5 = cpystr(Z_STRVAL_PP(pvalue));
    3336                 :                         }
    3337                 :                 }
    3338              62 :                 zend_hash_move_forward(Z_ARRVAL_PP(body));
    3339                 :         }
    3340                 : 
    3341              24 :         if (bod && bod->type == TYPEMULTIPART && (!bod->nested.part || !bod->nested.part->next)) {
    3342               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot generate multipart e-mail without components.");
    3343               0 :                 RETVAL_FALSE;
    3344               0 :                 goto done;
    3345                 :         }
    3346                 : 
    3347              24 :         rfc822_encode_body_7bit(env, topbod);
    3348                 : 
    3349              24 :         tmp = emalloc(SENDBUFLEN + 1);
    3350                 : 
    3351              24 :         rfc822_header(tmp, env, topbod);
    3352                 : 
    3353                 :         /* add custom envelope headers */
    3354              24 :         if (custom_headers_param) {
    3355               0 :                 int l = strlen(tmp) - 2, l2;
    3356               0 :                 PARAMETER *tp = custom_headers_param;
    3357                 : 
    3358                 :                 /* remove last CRLF from tmp */
    3359               0 :                 tmp[l] = '\0';
    3360               0 :                 tempstring = emalloc(l);
    3361               0 :                 memcpy(tempstring, tmp, l);
    3362                 : 
    3363                 :                 do {
    3364               0 :                         l2 = strlen(custom_headers_param->value);
    3365               0 :                         tempstring = erealloc(tempstring, l + l2 + CRLF_LEN + 1);
    3366               0 :                         memcpy(tempstring + l, custom_headers_param->value, l2);
    3367               0 :                         memcpy(tempstring + l + l2, CRLF, CRLF_LEN);
    3368               0 :                         l += l2 + CRLF_LEN;
    3369               0 :                 } while ((custom_headers_param = custom_headers_param->next));
    3370                 : 
    3371               0 :                 mail_free_body_parameter(&tp);
    3372                 : 
    3373               0 :                 mystring = emalloc(l + CRLF_LEN + 1);
    3374               0 :                 memcpy(mystring, tempstring, l);
    3375               0 :                 memcpy(mystring + l , CRLF, CRLF_LEN);
    3376               0 :                 mystring[l + CRLF_LEN] = '\0';
    3377                 : 
    3378               0 :                 efree(tempstring);
    3379                 :         } else {
    3380              24 :                 mystring = estrdup(tmp);
    3381                 :         }
    3382                 : 
    3383              24 :         bod = topbod;
    3384                 : 
    3385              46 :         if (bod && bod->type == TYPEMULTIPART) {
    3386                 : 
    3387                 :                 /* first body part */
    3388              22 :                         part = bod->nested.part;
    3389                 : 
    3390                 :                 /* find cookie */
    3391              44 :                         for (param = bod->parameter; param && !cookie; param = param->next) {
    3392              22 :                                 if (!strcmp (param->attribute, "BOUNDARY")) {
    3393              22 :                                         cookie = param->value;
    3394                 :                                 }
    3395                 :                         }
    3396                 : 
    3397                 :                 /* yucky default */
    3398              22 :                         if (!cookie) {
    3399               0 :                                 cookie = "-";
    3400              22 :                         } else if (strlen(cookie) > (SENDBUFLEN - 2 - 2 - 2)) {  /* validate cookie length -- + CRLF * 2 */
    3401               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The boudary should be no longer then 4kb");
    3402               0 :                                 RETVAL_FALSE;
    3403               0 :                                 goto done;
    3404                 :                         }
    3405                 : 
    3406                 :                 /* for each part */
    3407                 :                         do {
    3408              62 :                                 t = tmp;
    3409                 : 
    3410                 :                         /* append mini-header */
    3411              62 :                                 *t = '\0';
    3412              62 :                                 rfc822_write_body_header(&t, &part->body);
    3413                 : 
    3414                 :                         /* output cookie, mini-header, and contents */
    3415              62 :                                 spprintf(&tempstring, 0, "%s--%s%s%s%s", mystring, cookie, CRLF, tmp, CRLF);
    3416              62 :                                 efree(mystring);
    3417              62 :                                 mystring=tempstring;
    3418                 : 
    3419              62 :                                 bod=&part->body;
    3420                 : 
    3421              62 :                                 spprintf(&tempstring, 0, "%s%s%s", mystring, bod->contents.text.data, CRLF);
    3422              62 :                                 efree(mystring);
    3423              62 :                                 mystring=tempstring;
    3424              62 :                         } while ((part = part->next)); /* until done */
    3425                 : 
    3426                 :                         /* output trailing cookie */
    3427              22 :                         spprintf(&tempstring, 0, "%s--%s--%s", mystring, cookie, CRLF);
    3428              22 :                         efree(mystring);
    3429              22 :                         mystring=tempstring;
    3430               2 :         } else if (bod) {
    3431               2 :                 spprintf(&tempstring, 0, "%s%s%s", mystring, bod->contents.text.data, CRLF);
    3432               2 :                 efree(mystring);
    3433               2 :                 mystring=tempstring;
    3434                 :         } else {
    3435               0 :                 efree(mystring);
    3436               0 :                 RETVAL_FALSE;
    3437               0 :                 goto done;
    3438                 :         }
    3439                 : 
    3440              24 :         RETVAL_STRING(tempstring, 0);
    3441              24 : done:
    3442              24 :         if (tmp) {
    3443              24 :                 efree(tmp);
    3444                 :         }
    3445              24 :         mail_free_body(&topbod);
    3446              24 :         mail_free_envelope(&env);
    3447                 : }
    3448                 : /* }}} */
    3449                 : 
    3450                 : 
    3451                 : /* {{{ _php_imap_mail
    3452                 :  */
    3453                 : int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *cc, char *bcc, char* rpath TSRMLS_DC)
    3454               0 : {
    3455                 : #ifdef PHP_WIN32
    3456                 :         int tsm_err;
    3457                 : #else
    3458                 :         FILE *sendmail;
    3459                 :         int ret;
    3460                 : #endif
    3461                 : 
    3462                 : #ifdef PHP_WIN32
    3463                 :         char *tempMailTo;
    3464                 :         char *tsm_errmsg = NULL;
    3465                 :         ADDRESS *addr;
    3466                 :         char *bufferTo = NULL, *bufferCc = NULL, *bufferBcc = NULL, *bufferHeader = NULL;
    3467                 :         int offset, bufferLen = 0;
    3468                 :         size_t bt_len;
    3469                 : 
    3470                 :         if (headers) {
    3471                 :                 bufferLen += strlen(headers);
    3472                 :         }
    3473                 :         if (to) {
    3474                 :                 bufferLen += strlen(to) + 6;
    3475                 :         }
    3476                 :         if (cc) {
    3477                 :                 bufferLen += strlen(cc) + 6;
    3478                 :         }
    3479                 : 
    3480                 : #define PHP_IMAP_CLEAN  if (bufferTo) efree(bufferTo); if (bufferCc) efree(bufferCc); if (bufferBcc) efree(bufferBcc); if (bufferHeader) efree(bufferHeader);
    3481                 : #define PHP_IMAP_BAD_DEST PHP_IMAP_CLEAN; efree(tempMailTo); return (BAD_MSG_DESTINATION);
    3482                 : 
    3483                 :         bufferHeader = (char *)emalloc(bufferLen + 1);
    3484                 :         memset(bufferHeader, 0, bufferLen);
    3485                 :         if (to && *to) {
    3486                 :                 strlcat(bufferHeader, "To: ", bufferLen + 1);
    3487                 :                 strlcat(bufferHeader, to, bufferLen + 1);
    3488                 :                 strlcat(bufferHeader, "\r\n", bufferLen + 1);
    3489                 :                 tempMailTo = estrdup(to);
    3490                 :                 bt_len = strlen(to);
    3491                 :                 bufferTo = (char *)safe_emalloc(bt_len, 1, 1);
    3492                 :                 bt_len++;
    3493                 :                 offset = 0;
    3494                 :                 addr = NULL;
    3495                 :                 rfc822_parse_adrlist(&addr, tempMailTo, NULL);
    3496                 :                 while (addr) {
    3497                 :                         if (addr->host == NULL || strcmp(addr->host, ERRHOST) == 0) {
    3498                 :                                 PHP_IMAP_BAD_DEST;
    3499                 :                         } else {
    3500                 :                                 bufferTo = safe_erealloc(bufferTo, bt_len, 1, strlen(addr->mailbox));
    3501                 :                                 bt_len += strlen(addr->mailbox);
    3502                 :                                 bufferTo = safe_erealloc(bufferTo, bt_len, 1, strlen(addr->host));
    3503                 :                                 bt_len += strlen(addr->host);
    3504                 :                                 offset += slprintf(bufferTo + offset, bt_len - offset, "%s@%s,", addr->mailbox, addr->host);
    3505                 :                         }
    3506                 :                         addr = addr->next;
    3507                 :                 }
    3508                 :                 efree(tempMailTo);
    3509                 :                 if (offset>0) {
    3510                 :                         bufferTo[offset-1] = 0;
    3511                 :                 }
    3512                 :         }
    3513                 : 
    3514                 :         if (cc && *cc) {
    3515                 :                 strlcat(bufferHeader, "Cc: ", bufferLen + 1);
    3516                 :                 strlcat(bufferHeader, cc, bufferLen + 1);
    3517                 :                 strlcat(bufferHeader, "\r\n", bufferLen + 1);
    3518                 :                 tempMailTo = estrdup(cc);
    3519                 :                 bt_len = strlen(cc);
    3520                 :                 bufferCc = (char *)safe_emalloc(bt_len, 1, 1);
    3521                 :                 bt_len++;
    3522                 :                 offset = 0;
    3523                 :                 addr = NULL;
    3524                 :                 rfc822_parse_adrlist(&addr, tempMailTo, NULL);
    3525                 :                 while (addr) {
    3526                 :                         if (addr->host == NULL || strcmp(addr->host, ERRHOST) == 0) {
    3527                 :                                 PHP_IMAP_BAD_DEST;
    3528                 :                         } else {
    3529                 :                                 bufferCc = safe_erealloc(bufferCc, bt_len, 1, strlen(addr->mailbox));
    3530                 :                                 bt_len += strlen(addr->mailbox);
    3531                 :                                 bufferCc = safe_erealloc(bufferCc, bt_len, 1, strlen(addr->host));
    3532                 :                                 bt_len += strlen(addr->host);
    3533                 :                                 offset += slprintf(bufferCc + offset, bt_len - offset, "%s@%s,", addr->mailbox, addr->host);
    3534                 :                         }
    3535                 :                         addr = addr->next;
    3536                 :                 }
    3537                 :                 efree(tempMailTo);
    3538                 :                 if (offset>0) {
    3539                 :                         bufferCc[offset-1] = 0;
    3540                 :                 }
    3541                 :         }
    3542                 : 
    3543                 :         if (bcc && *bcc) {
    3544                 :                 tempMailTo = estrdup(bcc);
    3545                 :                 bt_len = strlen(bcc);
    3546                 :                 bufferBcc = (char *)safe_emalloc(bt_len, 1, 1);
    3547                 :                 bt_len++;
    3548                 :                 offset = 0;
    3549                 :                 addr = NULL;
    3550                 :                 rfc822_parse_adrlist(&addr, tempMailTo, NULL);
    3551                 :                 while (addr) {
    3552                 :                         if (addr->host == NULL || strcmp(addr->host, ERRHOST) == 0) {
    3553                 :                                 PHP_IMAP_BAD_DEST;
    3554                 :                         } else {
    3555                 :                                 bufferBcc = safe_erealloc(bufferBcc, bt_len, 1, strlen(addr->mailbox));
    3556                 :                                 bt_len += strlen(addr->mailbox);
    3557                 :                                 bufferBcc = safe_erealloc(bufferBcc, bt_len, 1, strlen(addr->host));
    3558                 :                                 bt_len += strlen(addr->host);
    3559                 :                                 offset += slprintf(bufferBcc + offset, bt_len - offset, "%s@%s,", addr->mailbox, addr->host);
    3560                 :                         }
    3561                 :                         addr = addr->next;
    3562                 :                 }
    3563                 :                 efree(tempMailTo);
    3564                 :                 if (offset>0) {
    3565                 :                         bufferBcc[offset-1] = 0;
    3566                 :                 }
    3567                 :         }
    3568                 : 
    3569                 :         if (headers && *headers) {
    3570                 :                 strlcat(bufferHeader, headers, bufferLen + 1);
    3571                 :         }
    3572                 : 
    3573                 :         if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, bufferHeader, subject, bufferTo, message, bufferCc, bufferBcc, rpath TSRMLS_CC) != SUCCESS) {
    3574                 :                 if (tsm_errmsg) {
    3575                 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tsm_errmsg);
    3576                 :                         efree(tsm_errmsg);
    3577                 :                 } else {
    3578                 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", GetSMErrorText(tsm_err));
    3579                 :                 }
    3580                 :                 PHP_IMAP_CLEAN;
    3581                 :                 return 0;
    3582                 :         }
    3583                 :         PHP_IMAP_CLEAN;
    3584                 : #else
    3585               0 :         if (!INI_STR("sendmail_path")) {
    3586               0 :                 return 0;
    3587                 :         }
    3588               0 :         sendmail = popen(INI_STR("sendmail_path"), "w");
    3589               0 :         if (sendmail) {
    3590               0 :                 if (rpath && rpath[0]) fprintf(sendmail, "From: %s\n", rpath);
    3591               0 :                 fprintf(sendmail, "To: %s\n", to);
    3592               0 :                 if (cc && cc[0]) fprintf(sendmail, "Cc: %s\n", cc);
    3593               0 :                 if (bcc && bcc[0]) fprintf(sendmail, "Bcc: %s\n", bcc);
    3594               0 :                 fprintf(sendmail, "Subject: %s\n", subject);
    3595               0 :                 if (headers != NULL) {
    3596               0 :                         fprintf(sendmail, "%s\n", headers);
    3597                 :                 }
    3598               0 :                 fprintf(sendmail, "\n%s\n", message);
    3599               0 :                 ret = pclose(sendmail);
    3600               0 :                 if (ret == -1) {
    3601               0 :                         return 0;
    3602                 :                 } else {
    3603               0 :                         return 1;
    3604                 :                 }
    3605                 :         } else {
    3606               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute mail delivery program");
    3607               0 :                 return 0;
    3608                 :         }
    3609                 : #endif
    3610                 :         return 1;
    3611                 : }
    3612                 : /* }}} */
    3613                 : 
    3614                 : /* {{{ proto bool imap_mail(string to, string subject, string message [, string additional_headers [, string cc [, string bcc [, string rpath]]]])
    3615                 :    Send an email message */
    3616                 : PHP_FUNCTION(imap_mail)
    3617               0 : {
    3618                 :         zval **argv[7];
    3619               0 :         char *to=NULL, *message=NULL, *headers=NULL, *subject=NULL, *cc=NULL, *bcc=NULL, *rpath=NULL;
    3620               0 :         int argc = ZEND_NUM_ARGS();
    3621                 : 
    3622               0 :         if (argc < 3 || argc > 7 || zend_get_parameters_array_ex(argc, argv) == FAILURE) {
    3623               0 :                 ZEND_WRONG_PARAM_COUNT();
    3624                 :         }
    3625                 : 
    3626                 :         /* To: */
    3627               0 :         convert_to_string_ex(argv[0]);
    3628               0 :         if (Z_STRVAL_PP(argv[0])) {
    3629               0 :                 to = Z_STRVAL_PP(argv[0]);
    3630                 :         } else {
    3631               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No to field in mail command");
    3632               0 :                 RETURN_FALSE;
    3633                 :         }
    3634                 : 
    3635                 :         /* Subject: */
    3636               0 :         convert_to_string_ex(argv[1]);
    3637               0 :         if (Z_STRVAL_PP(argv[1])) {
    3638               0 :                 subject = Z_STRVAL_PP(argv[1]);
    3639                 :         } else {
    3640               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No subject field in mail command");
    3641               0 :                 RETURN_FALSE;
    3642                 :         }
    3643                 : 
    3644                 :         /* message body */
    3645               0 :         convert_to_string_ex(argv[2]);
    3646               0 :         if (Z_STRVAL_PP(argv[2])) {
    3647               0 :                 message = Z_STRVAL_PP(argv[2]);
    3648                 :         } else {
    3649                 :                 /* this is not really an error, so it is allowed. */
    3650               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message string in mail command");
    3651               0 :                 message = NULL;
    3652                 :         }
    3653                 : 
    3654                 :         /* other headers */
    3655               0 :         if (argc > 3) {
    3656               0 :                 convert_to_string_ex(argv[3]);
    3657               0 :                 headers = Z_STRVAL_PP(argv[3]);
    3658                 :         }
    3659                 : 
    3660                 :         /* cc */
    3661               0 :         if (argc > 4) {
    3662               0 :                 convert_to_string_ex(argv[4]);
    3663               0 :                 cc = Z_STRVAL_PP(argv[4]);
    3664                 :         }
    3665                 : 
    3666                 :         /* bcc */
    3667               0 :         if (argc > 5) {
    3668               0 :                 convert_to_string_ex(argv[5]);
    3669               0 :                 bcc = Z_STRVAL_PP(argv[5]);
    3670                 :         }
    3671                 : 
    3672                 :         /* rpath */
    3673               0 :         if (argc > 6) {
    3674               0 :                 convert_to_string_ex(argv[6]);
    3675               0 :                 rpath = Z_STRVAL_PP(argv[6]);
    3676                 :         }
    3677                 : 
    3678               0 :         if (_php_imap_mail(to, subject, message, headers, cc, bcc, rpath TSRMLS_CC)) {
    3679               0 :                 RETURN_TRUE;
    3680                 :         } else {
    3681               0 :                 RETURN_FALSE;
    3682                 :         }
    3683                 : }
    3684                 : /* }}} */
    3685                 : 
    3686                 : /* {{{ proto array imap_search(resource stream_id, string criteria [, int options [, string charset]])
    3687                 :    Return a list of messages matching the given criteria */
    3688                 : PHP_FUNCTION(imap_search)
    3689               8 : {
    3690                 :         zval **streamind, **criteria, **search_flags, **charset;
    3691                 :         pils *imap_le_struct;
    3692                 :         long flags;
    3693                 :         char *search_criteria;
    3694                 :         MESSAGELIST *cur;
    3695               8 :         int argc = ZEND_NUM_ARGS();
    3696               8 :         SEARCHPGM *pgm = NIL;
    3697                 : 
    3698               8 :         if (argc < 2 || argc > 4 || zend_get_parameters_ex(argc, &streamind, &criteria, &search_flags, &charset) == FAILURE) {
    3699               0 :                 ZEND_WRONG_PARAM_COUNT();
    3700                 :         }
    3701                 : 
    3702               8 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    3703                 : 
    3704               8 :         convert_to_string_ex(criteria);
    3705               8 :         search_criteria = estrndup(Z_STRVAL_PP(criteria), Z_STRLEN_PP(criteria));
    3706                 : 
    3707               8 :         if (argc == 2) {
    3708               8 :                 flags = SE_FREE;
    3709                 :         } else {
    3710               0 :                 convert_to_long_ex(search_flags);
    3711               0 :                 flags = Z_LVAL_PP(search_flags);
    3712               0 :                 if (argc == 4) {
    3713               0 :                         convert_to_string_ex(charset);
    3714                 :                 }
    3715                 :         }
    3716                 : 
    3717               8 :         pgm = mail_criteria(search_criteria);
    3718               8 :         IMAPG(imap_messages) = IMAPG(imap_messages_tail) = NIL;
    3719                 : 
    3720               8 :         mail_search_full(imap_le_struct->imap_stream, (argc == 4 ? Z_STRVAL_PP(charset) : NIL), pgm, flags);
    3721                 : 
    3722               8 :         if (pgm && !(flags & SE_FREE)) {
    3723               0 :                 mail_free_searchpgm(&pgm);
    3724                 :         }
    3725                 : 
    3726               8 :         if (IMAPG(imap_messages) == NIL) {
    3727               1 :                 efree(search_criteria);
    3728               1 :                 RETURN_FALSE;
    3729                 :         }
    3730                 : 
    3731               7 :         array_init(return_value);
    3732                 : 
    3733               7 :         cur = IMAPG(imap_messages);
    3734              35 :         while (cur != NIL) {
    3735              21 :                 add_next_index_long(return_value, cur->msgid);
    3736              21 :                 cur = cur->next;
    3737                 :         }
    3738               7 :         mail_free_messagelist(&IMAPG(imap_messages), &IMAPG(imap_messages_tail));
    3739               7 :         efree(search_criteria);
    3740                 : }
    3741                 : /* }}} */
    3742                 : 
    3743                 : /* {{{ proto array imap_alerts(void)
    3744                 :    Returns an array of all IMAP alerts that have been generated 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. */
    3745                 : /* Author: CJH */
    3746                 : PHP_FUNCTION(imap_alerts)
    3747               1 : {
    3748               1 :         STRINGLIST *cur=NIL;
    3749                 : 
    3750               1 :         if (ZEND_NUM_ARGS() > 0) {
    3751               1 :                 ZEND_WRONG_PARAM_COUNT();
    3752                 :         }
    3753                 : 
    3754               0 :         if (IMAPG(imap_alertstack) == NIL) {
    3755               0 :                 RETURN_FALSE;
    3756                 :         }
    3757                 : 
    3758               0 :         array_init(return_value);
    3759                 : 
    3760               0 :         cur = IMAPG(imap_alertstack);
    3761               0 :         while (cur != NIL) {
    3762               0 :                 add_next_index_string(return_value, cur->LTEXT, 1);
    3763               0 :                 cur = cur->next;
    3764                 :         }
    3765               0 :         mail_free_stringlist(&IMAPG(imap_alertstack));
    3766               0 :         IMAPG(imap_alertstack) = NIL;
    3767                 : }
    3768                 : /* }}} */
    3769                 : 
    3770                 : /* {{{ proto array imap_errors(void)
    3771                 :    Returns an array of all IMAP errors generated 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. */
    3772                 : /* Author: CJH */
    3773                 : PHP_FUNCTION(imap_errors)
    3774               5 : {
    3775               5 :         ERRORLIST *cur=NIL;
    3776                 : 
    3777               5 :         if (ZEND_NUM_ARGS() > 0) {
    3778               0 :                 ZEND_WRONG_PARAM_COUNT();
    3779                 :         }
    3780                 : 
    3781               5 :         if (IMAPG(imap_errorstack) == NIL) {
    3782               1 :                 RETURN_FALSE;
    3783                 :         }
    3784                 : 
    3785               4 :         array_init(return_value);
    3786                 : 
    3787               4 :         cur = IMAPG(imap_errorstack);
    3788              30 :         while (cur != NIL) {
    3789              22 :                 add_next_index_string(return_value, cur->LTEXT, 1);
    3790              22 :                 cur = cur->next;
    3791                 :         }
    3792               4 :         mail_free_errorlist(&IMAPG(imap_errorstack));
    3793               4 :         IMAPG(imap_errorstack) = NIL;
    3794                 : }
    3795                 : /* }}} */
    3796                 : 
    3797                 : /* {{{ proto string imap_last_error(void)
    3798                 :    Returns the last error that was generated by an IMAP function. The error stack is NOT cleared after this call. */
    3799                 : /* Author: CJH */
    3800                 : PHP_FUNCTION(imap_last_error)
    3801              30 : {
    3802              30 :         ERRORLIST *cur=NIL;
    3803                 : 
    3804              30 :         if (ZEND_NUM_ARGS() > 0) {
    3805               0 :                 ZEND_WRONG_PARAM_COUNT();
    3806                 :         }
    3807                 : 
    3808              30 :         if (IMAPG(imap_errorstack) == NIL) {
    3809               4 :                 RETURN_FALSE;
    3810                 :         }
    3811                 : 
    3812              26 :         cur = IMAPG(imap_errorstack);
    3813             215 :         while (cur != NIL) {
    3814             189 :                 if (cur->next == NIL) {
    3815              26 :                         RETURN_STRING(cur->LTEXT, 1);
    3816                 :                 }
    3817             163 :                 cur = cur->next;
    3818                 :         }
    3819                 : }
    3820                 : /* }}} */
    3821                 : 
    3822                 : /* {{{ proto array imap_mime_header_decode(string str)
    3823                 :    Decode mime header element in accordance with RFC 2047 and return array of objects containing 'charset' encoding and decoded 'text' */
    3824                 : PHP_FUNCTION(imap_mime_header_decode)
    3825               0 : {
    3826                 :         /* Author: Ted Parnefors <ted@mtv.se> */
    3827                 :         zval **str, *myobject;
    3828                 :         char *string, *charset, encoding, *text, *decode;
    3829               0 :         long charset_token, encoding_token, end_token, end, offset=0, i;
    3830                 :         unsigned long newlength;
    3831                 : 
    3832               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
    3833               0 :                 ZEND_WRONG_PARAM_COUNT();
    3834                 :         }
    3835                 : 
    3836               0 :         convert_to_string_ex(str);
    3837                 : 
    3838               0 :         array_init(return_value);
    3839                 : 
    3840               0 :         string = Z_STRVAL_PP(str);
    3841               0 :         end = Z_STRLEN_PP(str);
    3842                 : 
    3843               0 :         charset = (char *) safe_emalloc((end + 1), 2, 0);
    3844               0 :         text = &charset[end + 1];
    3845               0 :         while (offset < end) {       /* Reached end of the string? */
    3846               0 :                 if ((charset_token = (long)php_memnstr(&string[offset], "=?", 2, string + end))) {        /* Is there anything encoded in the string? */
    3847               0 :                         charset_token -= (long)string;
    3848               0 :                         if (offset != charset_token) {  /* Is there anything before the encoded data? */
    3849                 :                                 /* Retrieve unencoded data that is found before encoded data */
    3850               0 :                                 memcpy(text, &string[offset], charset_token-offset);
    3851               0 :                                 text[charset_token - offset] = 0x00;
    3852               0 :                                 MAKE_STD_ZVAL(myobject);
    3853               0 :                                 object_init(myobject);
    3854               0 :                                 add_property_string(myobject, "charset", "default", 1);
    3855               0 :                                 add_property_string(myobject, "text", text, 1);
    3856               0 :                                 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), (void *)&myobject, sizeof(zval *), NULL);
    3857                 :                         }
    3858               0 :                         if ((encoding_token = (long)php_memnstr(&string[charset_token+2], "?", 1, string+end))) {         /* Find token for encoding */
    3859               0 :                                 encoding_token -= (long)string;
    3860               0 :                                 if ((end_token = (long)php_memnstr(&string[encoding_token+3], "?=", 2, string+end))) {    /* Find token for end of encoded data */
    3861               0 :                                         end_token -= (long)string;
    3862               0 :                                         memcpy(charset, &string[charset_token + 2], encoding_token - (charset_token + 2));  /* Extract charset encoding */
    3863               0 :                                         charset[encoding_token-(charset_token + 2)] = 0x00;
    3864               0 :                                         encoding=string[encoding_token + 1];    /* Extract encoding from string */
    3865               0 :                                         memcpy(text, &string[encoding_token + 3], end_token - (encoding_token + 3));        /* Extract text */
    3866               0 :                                         text[end_token - (encoding_token + 3)] = 0x00;
    3867               0 :                                         decode = text;
    3868               0 :                                         if (encoding == 'q' || encoding == 'Q') {       /* Decode 'q' encoded data */
    3869               0 :                                                 for(i=0; text[i] != 0x00; i++) if (text[i] == '_') text[i] = ' ';       /* Replace all *_' with space. */
    3870               0 :                                                 decode = (char *)rfc822_qprint((unsigned char *) text, strlen(text), &newlength);
    3871               0 :                                         } else if (encoding == 'b' || encoding == 'B') {
    3872               0 :                                                 decode = (char *)rfc822_base64((unsigned char *) text, strlen(text), &newlength); /* Decode 'B' encoded data */
    3873                 :                                         }
    3874               0 :                                         if (decode == NULL) {
    3875               0 :                                                 efree(charset);
    3876               0 :                                                 zval_dtor(return_value);
    3877               0 :                                                 RETURN_FALSE;
    3878                 :                                         }
    3879               0 :                                         MAKE_STD_ZVAL(myobject);
    3880               0 :                                         object_init(myobject);
    3881               0 :                                         add_property_string(myobject, "charset", charset, 1);
    3882               0 :                                         add_property_string(myobject, "text", decode, 1);
    3883               0 :                                         zend_hash_next_index_insert(Z_ARRVAL_P(return_value), (void *)&myobject, sizeof(zval *), NULL);
    3884                 : 
    3885                 :                                         /* only free decode if it was allocated by rfc822_qprint or rfc822_base64 */
    3886               0 :                                         if (decode != text) {
    3887               0 :                                                 fs_give((void**)&decode);
    3888                 :                                         }
    3889                 : 
    3890               0 :                                         offset = end_token+2;
    3891               0 :                                         for (i = 0; (string[offset + i] == ' ') || (string[offset + i] == 0x0a) || (string[offset + i] == 0x0d); i++);
    3892               0 :                                         if ((string[offset + i] == '=') && (string[offset + i + 1] == '?') && (offset + i < end)) {
    3893               0 :                                                 offset += i;
    3894                 :                                         }
    3895               0 :                                         continue;       /*/ Iterate the loop again please. */
    3896                 :                                 }
    3897                 :                         }
    3898                 :                 } else {
    3899                 :                         /* Just some tweaking to optimize the code, and get the end statements work in a general manner.
    3900                 :                          * If we end up here we didn't find a position for "charset_token",
    3901                 :                          * so we need to set it to the start of the yet unextracted data.
    3902                 :                          */
    3903               0 :                         charset_token = offset;
    3904                 :                 }
    3905                 :                 /* Return the rest of the data as unencoded, as it was either unencoded or was missing separators
    3906                 :                    which rendered the the remainder of the string impossible for us to decode. */
    3907               0 :                 memcpy(text, &string[charset_token], end - charset_token);  /* Extract unencoded text from string */
    3908               0 :                 text[end - charset_token] = 0x00;
    3909               0 :                 MAKE_STD_ZVAL(myobject);
    3910               0 :                 object_init(myobject);
    3911               0 :                 add_property_string(myobject, "charset", "default", 1);
    3912               0 :                 add_property_string(myobject, "text", text, 1);
    3913               0 :                 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), (void *)&myobject, sizeof(zval *), NULL);
    3914                 : 
    3915               0 :                 offset = end;   /* We have reached the end of the string. */
    3916                 :         }
    3917               0 :         efree(charset);
    3918                 : }
    3919                 : /* }}} */
    3920                 : 
    3921                 : 
    3922                 : /* Support Functions */
    3923                 : 
    3924                 : #ifdef HAVE_RFC822_OUTPUT_ADDRESS_LIST
    3925                 : 
    3926                 : /* {{{ _php_rfc822_soutr
    3927                 :  */
    3928                 : static long _php_rfc822_soutr (void *stream, char *string)
    3929                 : {
    3930                 :         smart_str *ret = (smart_str*)stream;
    3931                 :         int len = strlen(string);
    3932                 : 
    3933                 :         smart_str_appendl(ret, string, len);
    3934                 :         return LONGT;
    3935                 : }
    3936                 : 
    3937                 : /* }}} */
    3938                 : 
    3939                 : /* {{{ _php_rfc822_write_address
    3940                 :  */
    3941                 : static char* _php_rfc822_write_address(ADDRESS *addresslist TSRMLS_DC)
    3942                 : {
    3943                 :         char address[MAILTMPLEN];
    3944                 :         smart_str ret = {0};
    3945                 :         RFC822BUFFER buf;
    3946                 : 
    3947                 :         buf.beg = address;
    3948                 :         buf.cur = buf.beg;
    3949                 :         buf.end = buf.beg + sizeof(address) - 1;
    3950                 :         buf.s = &ret;
    3951                 :         buf.f = _php_rfc822_soutr;
    3952                 :         rfc822_output_address_list(&buf, addresslist, 0, NULL);
    3953                 :         rfc822_output_flush(&buf);
    3954                 :         smart_str_0(&ret);
    3955                 :         return ret.c;
    3956                 : }
    3957                 : /* }}} */
    3958                 : 
    3959                 : #else
    3960                 : 
    3961                 : /* {{{ _php_rfc822_len
    3962                 :  * Calculate string length based on imap's rfc822_cat function.
    3963                 :  */
    3964                 : static int _php_rfc822_len(char *str)
    3965             152 : {
    3966                 :         int len;
    3967                 :         char *p;
    3968                 : 
    3969             152 :         if (!str || !*str) {
    3970              76 :                 return 0;
    3971                 :         }
    3972                 : 
    3973                 :         /* strings with special characters will need to be quoted, as a safety measure we
    3974                 :          * add 2 bytes for the quotes just in case.
    3975                 :          */
    3976              76 :         len = strlen(str) + 2;
    3977              76 :         p = str;
    3978                 :         /* rfc822_cat() will escape all " and \ characters, therefor we need to increase
    3979                 :          * our buffer length to account for these characters.
    3980                 :          */
    3981             152 :         while ((p = strpbrk(p, "\\\""))) {
    3982               0 :                 p++;
    3983               0 :                 len++;
    3984                 :         }
    3985                 : 
    3986              76 :         return len;
    3987                 : }
    3988                 : /* }}} */
    3989                 : 
    3990                 : 
    3991                 : /* {{{ _php_imap_get_address_size
    3992                 :  */
    3993                 : static int _php_imap_address_size (ADDRESS *addresslist)
    3994              38 : {
    3995                 :         ADDRESS *tmp;
    3996              38 :         int ret=0, num_ent=0;
    3997                 : 
    3998              38 :         tmp = addresslist;
    3999                 : 
    4000              38 :         if (tmp) do {
    4001              38 :                 ret += _php_rfc822_len(tmp->personal);
    4002              38 :                 ret += _php_rfc822_len(tmp->adl);
    4003              38 :                 ret += _php_rfc822_len(tmp->mailbox);
    4004              38 :                 ret += _php_rfc822_len(tmp->host);
    4005              38 :                 num_ent++;
    4006              38 :         } while ((tmp = tmp->next));
    4007                 : 
    4008                 :         /*
    4009                 :          * rfc822_write_address_full() needs some extra space for '<>,', etc.
    4010                 :          * for this perpouse we allocate additional PHP_IMAP_ADDRESS_SIZE_BUF bytes
    4011                 :          * by default this buffer is 10 bytes long
    4012                 :         */
    4013              38 :         ret += (ret) ? num_ent*PHP_IMAP_ADDRESS_SIZE_BUF : 0;
    4014                 : 
    4015              38 :         return ret;
    4016                 : }
    4017                 : 
    4018                 : /* }}} */
    4019                 : 
    4020                 : /* {{{ _php_rfc822_write_address
    4021                 :  */
    4022                 : static char* _php_rfc822_write_address(ADDRESS *addresslist TSRMLS_DC)
    4023              38 : {
    4024                 :         char address[SENDBUFLEN];
    4025                 : 
    4026              38 :         if (_php_imap_address_size(addresslist) >= SENDBUFLEN) {
    4027               0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Address buffer overflow");
    4028               0 :                 return NULL;
    4029                 :         }
    4030              38 :         address[0] = 0;
    4031              38 :         rfc822_write_address(address, addresslist);
    4032              38 :         return estrdup(address);
    4033                 : }
    4034                 : /* }}} */
    4035                 : #endif
    4036                 : /* {{{ _php_imap_parse_address
    4037                 :  */
    4038                 : static char* _php_imap_parse_address (ADDRESS *addresslist, zval *paddress TSRMLS_DC)
    4039               0 : {
    4040                 :         char *fulladdress;
    4041                 :         ADDRESS *addresstmp;
    4042                 :         zval *tmpvals;
    4043                 : 
    4044               0 :         addresstmp = addresslist;
    4045                 : 
    4046               0 :         fulladdress = _php_rfc822_write_address(addresstmp TSRMLS_CC);
    4047                 : 
    4048               0 :         addresstmp = addresslist;
    4049                 :         do {
    4050               0 :                 MAKE_STD_ZVAL(tmpvals);
    4051               0 :                 object_init(tmpvals);
    4052               0 :                 if (addresstmp->personal) add_property_string(tmpvals, "personal", addresstmp->personal, 1);
    4053               0 :                 if (addresstmp->adl) add_property_string(tmpvals, "adl", addresstmp->adl, 1);
    4054               0 :                 if (addresstmp->mailbox) add_property_string(tmpvals, "mailbox", addresstmp->mailbox, 1);
    4055               0 :                 if (addresstmp->host) add_property_string(tmpvals, "host", addresstmp->host, 1);
    4056               0 :                 add_next_index_object(paddress, tmpvals TSRMLS_CC);
    4057               0 :         } while ((addresstmp = addresstmp->next));
    4058               0 :         return fulladdress;
    4059                 : }
    4060                 : /* }}} */
    4061                 : 
    4062                 : /* {{{ _php_make_header_object
    4063                 :  */
    4064                 : static void _php_make_header_object(zval *myzvalue, ENVELOPE *en TSRMLS_DC)
    4065               0 : {
    4066                 :         zval *paddress;
    4067               0 :         char *fulladdress=NULL;
    4068                 : 
    4069               0 :         object_init(myzvalue);
    4070                 : 
    4071               0 :         if (en->remail) add_property_string(myzvalue, "remail", en->remail, 1);
    4072               0 :         if (en->date) add_property_string(myzvalue, "date", en->date, 1);
    4073               0 :         if (en->date) add_property_string(myzvalue, "Date", en->date, 1);
    4074               0 :         if (en->subject) add_property_string(myzvalue, "subject", en->subject, 1);
    4075               0 :         if (en->subject) add_property_string(myzvalue, "Subject", en->subject, 1);
    4076               0 :         if (en->in_reply_to) add_property_string(myzvalue, "in_reply_to", en->in_reply_to, 1);
    4077               0 :         if (en->message_id) add_property_string(myzvalue, "message_id", en->message_id, 1);
    4078               0 :         if (en->newsgroups) add_property_string(myzvalue, "newsgroups", en->newsgroups, 1);
    4079               0 :         if (en->followup_to) add_property_string(myzvalue, "followup_to", en->followup_to, 1);
    4080               0 :         if (en->references) add_property_string(myzvalue, "references", en->references, 1);
    4081                 : 
    4082               0 :         if (en->to) {
    4083               0 :                 MAKE_STD_ZVAL(paddress);
    4084               0 :                 array_init(paddress);
    4085               0 :                 fulladdress = _php_imap_parse_address(en->to, paddress TSRMLS_CC);
    4086               0 :                 if (fulladdress) {
    4087               0 :                         add_property_string(myzvalue, "toaddress", fulladdress, 0);
    4088                 :                 }
    4089               0 :                 add_assoc_object(myzvalue, "to", paddress TSRMLS_CC);
    4090                 :         }
    4091                 : 
    4092               0 :         if (en->from) {
    4093               0 :                 MAKE_STD_ZVAL(paddress);
    4094               0 :                 array_init(paddress);
    4095               0 :                 fulladdress = _php_imap_parse_address(en->from, paddress TSRMLS_CC);
    4096               0 :                 if (fulladdress) {
    4097               0 :                         add_property_string(myzvalue, "fromaddress", fulladdress, 0);
    4098                 :                 }
    4099               0 :                 add_assoc_object(myzvalue, "from", paddress TSRMLS_CC);
    4100                 :         }
    4101                 : 
    4102               0 :         if (en->cc) {
    4103               0 :                 MAKE_STD_ZVAL(paddress);
    4104               0 :                 array_init(paddress);
    4105               0 :                 fulladdress = _php_imap_parse_address(en->cc, paddress TSRMLS_CC);
    4106               0 :                 if (fulladdress) {
    4107               0 :                         add_property_string(myzvalue, "ccaddress", fulladdress, 0);
    4108                 :                 }
    4109               0 :                 add_assoc_object(myzvalue, "cc", paddress TSRMLS_CC);
    4110                 :         }
    4111                 : 
    4112               0 :         if (en->bcc) {
    4113               0 :                 MAKE_STD_ZVAL(paddress);
    4114               0 :                 array_init(paddress);
    4115               0 :                 fulladdress = _php_imap_parse_address(en->bcc, paddress TSRMLS_CC);
    4116               0 :                 if (fulladdress) {
    4117               0 :                         add_property_string(myzvalue, "bccaddress", fulladdress, 0);
    4118                 :                 }
    4119               0 :                 add_assoc_object(myzvalue, "bcc", paddress TSRMLS_CC);
    4120                 :         }
    4121                 : 
    4122               0 :         if (en->reply_to) {
    4123               0 :                 MAKE_STD_ZVAL(paddress);
    4124               0 :                 array_init(paddress);
    4125               0 :                 fulladdress = _php_imap_parse_address(en->reply_to, paddress TSRMLS_CC);
    4126               0 :                 if (fulladdress) {
    4127               0 :                         add_property_string(myzvalue, "reply_toaddress", fulladdress, 0);
    4128                 :                 }
    4129               0 :                 add_assoc_object(myzvalue, "reply_to", paddress TSRMLS_CC);
    4130                 :         }
    4131                 : 
    4132               0 :         if (en->sender) {
    4133               0 :                 MAKE_STD_ZVAL(paddress);
    4134               0 :                 array_init(paddress);
    4135               0 :                 fulladdress = _php_imap_parse_address(en->sender, paddress TSRMLS_CC);
    4136               0 :                 if (fulladdress) {
    4137               0 :                         add_property_string(myzvalue, "senderaddress", fulladdress, 0);
    4138                 :                 }
    4139               0 :                 add_assoc_object(myzvalue, "sender", paddress TSRMLS_CC);
    4140                 :         }
    4141                 : 
    4142               0 :         if (en->return_path) {
    4143               0 :                 MAKE_STD_ZVAL(paddress);
    4144               0 :                 array_init(paddress);
    4145               0 :                 fulladdress = _php_imap_parse_address(en->return_path, paddress TSRMLS_CC);
    4146               0 :                 if (fulladdress) {
    4147               0 :                         add_property_string(myzvalue, "return_pathaddress", fulladdress, 0);
    4148                 :                 }
    4149               0 :                 add_assoc_object(myzvalue, "return_path", paddress TSRMLS_CC);
    4150                 :         }
    4151               0 : }
    4152                 : /* }}} */
    4153                 : 
    4154                 : /* {{{ _php_imap_add_body
    4155                 :  */
    4156                 : void _php_imap_add_body(zval *arg, BODY *body TSRMLS_DC)
    4157               0 : {
    4158                 :         zval *parametres, *param, *dparametres, *dparam;
    4159                 :         PARAMETER *par, *dpar;
    4160                 :         PART *part;
    4161                 : 
    4162               0 :         if (body->type <= TYPEMAX) {
    4163               0 :                 add_property_long(arg, "type", body->type);
    4164                 :         }
    4165                 : 
    4166               0 :         if (body->encoding <= ENCMAX) {
    4167               0 :                 add_property_long(arg, "encoding", body->encoding);
    4168                 :         }
    4169                 : 
    4170               0 :         if (body->subtype) {
    4171               0 :                 add_property_long(arg, "ifsubtype", 1);
    4172               0 :                 add_property_string(arg, "subtype",  body->subtype, 1);
    4173                 :         } else {
    4174               0 :                 add_property_long(arg, "ifsubtype", 0);
    4175                 :         }
    4176                 : 
    4177               0 :         if (body->description) {
    4178               0 :                 add_property_long(arg, "ifdescription", 1);
    4179               0 :                 add_property_string(arg, "description",  body->description, 1);
    4180                 :         } else {
    4181               0 :                 add_property_long(arg, "ifdescription", 0);
    4182                 :         }
    4183                 : 
    4184               0 :         if (body->id) {
    4185               0 :                 add_property_long(arg, "ifid", 1);
    4186               0 :                 add_property_string(arg, "id",  body->id, 1);
    4187                 :         } else {
    4188               0 :                 add_property_long(arg, "ifid", 0);
    4189                 :         }
    4190                 : 
    4191               0 :         if (body->size.lines) {
    4192               0 :                 add_property_long(arg, "lines", body->size.lines);
    4193                 :         }
    4194                 : 
    4195               0 :         if (body->size.bytes) {
    4196               0 :                 add_property_long(arg, "bytes", body->size.bytes);
    4197                 :         }
    4198                 : 
    4199                 : #ifdef IMAP41
    4200               0 :         if (body->disposition.type) {
    4201               0 :                 add_property_long(arg, "ifdisposition", 1);
    4202               0 :                 add_property_string(arg, "disposition", body->disposition.type, 1);
    4203                 :         } else {
    4204               0 :                 add_property_long(arg, "ifdisposition", 0);
    4205                 :         }
    4206                 : 
    4207               0 :         if (body->disposition.parameter) {
    4208               0 :                 dpar = body->disposition.parameter;
    4209               0 :                 add_property_long(arg, "ifdparameters", 1);
    4210               0 :                 MAKE_STD_ZVAL(dparametres);
    4211               0 :                 array_init(dparametres);
    4212                 :                 do {
    4213               0 :                         MAKE_STD_ZVAL(dparam);
    4214               0 :                         object_init(dparam);
    4215               0 :                         add_property_string(dparam, "attribute", dpar->attribute, 1);
    4216               0 :                         add_property_string(dparam, "value", dpar->value, 1);
    4217               0 :                         add_next_index_object(dparametres, dparam TSRMLS_CC);
    4218               0 :                 } while ((dpar = dpar->next));
    4219               0 :                 add_assoc_object(arg, "dparameters", dparametres TSRMLS_CC);
    4220                 :         } else {
    4221               0 :                 add_property_long(arg, "ifdparameters", 0);
    4222                 :         }
    4223                 : #endif
    4224                 : 
    4225               0 :         if ((par = body->parameter)) {
    4226               0 :                 add_property_long(arg, "ifparameters", 1);
    4227                 : 
    4228               0 :                 MAKE_STD_ZVAL(parametres);
    4229               0 :                 array_init(parametres);
    4230                 :                 do {
    4231               0 :                         MAKE_STD_ZVAL(param);
    4232               0 :                         object_init(param);
    4233               0 :                         if (par->attribute) {
    4234               0 :                                 add_property_string(param, "attribute", par->attribute, 1);
    4235                 :                         }
    4236               0 :                         if (par->value) {
    4237               0 :                                 add_property_string(param, "value", par->value, 1);
    4238                 :                         }
    4239                 : 
    4240               0 :                         add_next_index_object(parametres, param TSRMLS_CC);
    4241               0 :                 } while ((par = par->next));
    4242                 :         } else {
    4243               0 :                 MAKE_STD_ZVAL(parametres);
    4244               0 :                 object_init(parametres);
    4245               0 :                 add_property_long(arg, "ifparameters", 0);
    4246                 :         }
    4247               0 :         add_assoc_object(arg, "parameters", parametres TSRMLS_CC);
    4248                 : 
    4249                 :         /* multipart message ? */
    4250               0 :         if (body->type == TYPEMULTIPART) {
    4251               0 :                 MAKE_STD_ZVAL(parametres);
    4252               0 :                 array_init(parametres);
    4253               0 :                 for (part = body->CONTENT_PART; part; part = part->next) {
    4254               0 :                         MAKE_STD_ZVAL(param);
    4255               0 :                         object_init(param);
    4256               0 :                         _php_imap_add_body(param, &part->body TSRMLS_CC);
    4257               0 :                         add_next_index_object(parametres, param TSRMLS_CC);
    4258                 :                 }
    4259               0 :                 add_assoc_object(arg, "parts", parametres TSRMLS_CC);
    4260                 :         }
    4261                 : 
    4262                 :         /* encapsulated message ? */
    4263               0 :         if ((body->type == TYPEMESSAGE) && (!strcasecmp(body->subtype, "rfc822"))) {
    4264               0 :                 body = body->CONTENT_MSG_BODY;
    4265               0 :                 MAKE_STD_ZVAL(parametres);
    4266               0 :                 array_init(parametres);
    4267               0 :                 MAKE_STD_ZVAL(param);
    4268               0 :                 object_init(param);
    4269               0 :                 _php_imap_add_body(param, body TSRMLS_CC);
    4270               0 :                 add_next_index_object(parametres, param TSRMLS_CC);
    4271               0 :                 add_assoc_object(arg, "parts", parametres TSRMLS_CC);
    4272                 :         }
    4273               0 : }
    4274                 : /* }}} */
    4275                 : 
    4276                 : 
    4277                 : /* imap_thread, stealing this from header cclient -rjs3 */
    4278                 : /* {{{ build_thread_tree_helper
    4279                 :  */
    4280                 : static void build_thread_tree_helper(THREADNODE *cur, zval *tree, long *numNodes, char *buf)
    4281               0 : {
    4282               0 :         unsigned long thisNode = *numNodes;
    4283                 : 
    4284                 :         /* define "#.num" */
    4285               0 :         snprintf(buf, 25, "%ld.num", thisNode);
    4286                 : 
    4287               0 :         add_assoc_long(tree, buf, cur->num);
    4288                 : 
    4289               0 :         snprintf(buf, 25, "%ld.next", thisNode);
    4290               0 :         if(cur->next) {
    4291               0 :                 (*numNodes)++;
    4292               0 :                 add_assoc_long(tree, buf, *numNodes);
    4293               0 :                 build_thread_tree_helper(cur->next, tree, numNodes, buf);
    4294                 :         } else { /* "null pointer" */
    4295               0 :                 add_assoc_long(tree, buf, 0);
    4296                 :         }
    4297                 : 
    4298               0 :         snprintf(buf, 25, "%ld.branch", thisNode);
    4299               0 :         if(cur->branch) {
    4300               0 :                 (*numNodes)++;
    4301               0 :                 add_assoc_long(tree, buf, *numNodes);
    4302               0 :                 build_thread_tree_helper(cur->branch, tree, numNodes, buf);
    4303                 :         } else { /* "null pointer" */
    4304               0 :                 add_assoc_long(tree, buf, 0);
    4305                 :         }
    4306               0 : }
    4307                 : /* }}} */
    4308                 : 
    4309                 : /* {{{ build_thread_tree
    4310                 :  */
    4311                 : static int build_thread_tree(THREADNODE *top, zval **tree)
    4312               0 : {
    4313               0 :         long numNodes = 0;
    4314                 :         char buf[25];
    4315                 : 
    4316               0 :         array_init(*tree);
    4317                 : 
    4318               0 :         build_thread_tree_helper(top, *tree, &numNodes, buf);
    4319                 : 
    4320               0 :         return SUCCESS;
    4321                 : }
    4322                 : /* }}} */
    4323                 : 
    4324                 : /* {{{ proto array imap_thread(resource stream_id [, int options])
    4325                 :    Return threaded by REFERENCES tree */
    4326                 : PHP_FUNCTION(imap_thread)
    4327               0 : {
    4328                 :         zval **streamind, **search_flags;
    4329                 :         pils *imap_le_struct;
    4330                 :         long flags;
    4331               0 :         char criteria[] = "ALL";
    4332                 :         THREADNODE *top;
    4333               0 :         int argc = ZEND_NUM_ARGS();
    4334               0 :         SEARCHPGM *pgm = NIL;
    4335                 : 
    4336               0 :         if ( argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &streamind, &search_flags) == FAILURE) {
    4337               0 :                 ZEND_WRONG_PARAM_COUNT();
    4338                 :         }
    4339                 : 
    4340               0 :         ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
    4341                 : 
    4342               0 :         if (argc == 1) {
    4343               0 :                 flags = SE_FREE;
    4344                 :         } else {
    4345               0 :                 convert_to_long_ex(search_flags);
    4346               0 :                 flags = Z_LVAL_PP(search_flags);
    4347                 :         }
    4348                 : 
    4349               0 :         pgm = mail_criteria(criteria);
    4350               0 :         top = mail_thread(imap_le_struct->imap_stream, "REFERENCES", NIL, pgm, flags);
    4351               0 :         if (pgm && !(flags & SE_FREE)) {
    4352               0 :                 mail_free_searchpgm(&pgm);
    4353                 :         }
    4354                 : 
    4355               0 :         if(top == NIL) {
    4356               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function returned an empty tree");
    4357               0 :                 RETURN_FALSE;
    4358                 :         }
    4359                 : 
    4360                 :         /* Populate our return value data structure here. */
    4361               0 :         if(build_thread_tree(top, &return_value) == FAILURE) {
    4362               0 :                 mail_free_threadnode(&top);
    4363               0 :                 RETURN_FALSE;
    4364                 :         }
    4365               0 :         mail_free_threadnode(&top);
    4366                 : }
    4367                 : /* }}} */
    4368                 : 
    4369                 : /* {{{ proto mixed imap_timeout(int timeout_type [, int timeout])
    4370                 :    Set or fetch imap timeout */
    4371                 : PHP_FUNCTION(imap_timeout)
    4372               0 : {
    4373               0 :         long ttype, timeout=-1;
    4374                 :         int timeout_type;
    4375                 : 
    4376               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &ttype, &timeout) == FAILURE) {
    4377               0 :                 RETURN_FALSE;
    4378                 :         }
    4379                 : 
    4380               0 :         if (timeout == -1) {
    4381               0 :                 switch (ttype) {
    4382                 :                         case 1:
    4383               0 :                                 timeout_type = GET_OPENTIMEOUT;
    4384               0 :                                 break;
    4385                 :                         case 2:
    4386               0 :                                 timeout_type = GET_READTIMEOUT;
    4387               0 :                                 break;
    4388                 :                         case 3:
    4389               0 :                                 timeout_type = GET_WRITETIMEOUT;
    4390               0 :                                 break;
    4391                 :                         case 4:
    4392               0 :                                 timeout_type = GET_CLOSETIMEOUT;
    4393               0 :                                 break;
    4394                 :                         default:
    4395               0 :                                 RETURN_FALSE;
    4396                 :                                 break;
    4397                 :                 }
    4398                 : 
    4399               0 :                 timeout = (long) mail_parameters(NIL, timeout_type, NIL);
    4400               0 :                 RETURN_LONG(timeout);
    4401               0 :         } else if (timeout >= 0) {
    4402               0 :                 switch (ttype) {
    4403                 :                         case 1:
    4404               0 :                                 timeout_type = SET_OPENTIMEOUT;
    4405               0 :                                 break;
    4406                 :                         case 2:
    4407               0 :                                 timeout_type = SET_READTIMEOUT;
    4408               0 :                                 break;
    4409                 :                         case 3:
    4410               0 :                                 timeout_type = SET_WRITETIMEOUT;
    4411               0 :                                 break;
    4412                 :                         case 4:
    4413               0 :                                 timeout_type = SET_CLOSETIMEOUT;
    4414               0 :                                 break;
    4415                 :                         default:
    4416               0 :                                 RETURN_FALSE;
    4417                 :                                 break;
    4418                 :                 }
    4419                 : 
    4420               0 :                 timeout = (long) mail_parameters(NIL, timeout_type, (void *) timeout);
    4421               0 :                 RETURN_TRUE;
    4422                 :         } else {
    4423               0 :                 RETURN_FALSE;
    4424                 :         }
    4425                 : }
    4426                 : /* }}} */
    4427                 : 
    4428                 : #define GETS_FETCH_SIZE 8196LU
    4429                 : /* {{{ php_mail_gets */
    4430                 : static char *php_mail_gets(readfn_t f, void *stream, unsigned long size, GETS_DATA *md)
    4431               0 : {
    4432                 :         TSRMLS_FETCH();
    4433                 : 
    4434                 :         /*      write to the gets stream if it is set,
    4435                 :                 otherwise forward to c-clients gets */
    4436               0 :         if (IMAPG(gets_stream)) {
    4437                 :                 char buf[GETS_FETCH_SIZE];
    4438                 : 
    4439               0 :                 while (size) {
    4440                 :                         unsigned long read;
    4441                 : 
    4442               0 :                         if (size > GETS_FETCH_SIZE) {
    4443               0 :                                 read = GETS_FETCH_SIZE;
    4444               0 :                                 size -=GETS_FETCH_SIZE;
    4445                 :                         } else {
    4446               0 :                                 read = size;
    4447               0 :                                 size = 0;
    4448                 :                         }
    4449                 : 
    4450               0 :                         if (!f(stream, read, buf)) {
    4451               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to read from socket");
    4452               0 :                                 break;
    4453               0 :                         } else if (read != php_stream_write(IMAPG(gets_stream), buf, read)) {
    4454               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write to stream");
    4455               0 :                                 break;
    4456                 :                         }
    4457                 :                 }
    4458               0 :                 return NULL;
    4459                 :         } else {
    4460               0 :                 char *buf = pemalloc(size + 1, 1);
    4461                 : 
    4462               0 :                 if (f(stream, size, buf)) {
    4463               0 :                         buf[size] = '\0';
    4464                 :                 } else {
    4465               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to read from socket");
    4466               0 :                         free(buf);
    4467               0 :                         buf = NULL;
    4468                 :                 }
    4469               0 :                 return buf;
    4470                 :         }
    4471                 : }
    4472                 : /* }}} */
    4473                 : 
    4474                 : /* {{{ Interfaces to C-client
    4475                 :  */
    4476                 : void mm_searched(MAILSTREAM *stream, unsigned long number)
    4477              21 : {
    4478              21 :         MESSAGELIST *cur = NIL;
    4479                 :         TSRMLS_FETCH();
    4480                 : 
    4481              21 :         if (IMAPG(imap_messages) == NIL) {
    4482               7 :                 IMAPG(imap_messages) = mail_newmessagelist();
    4483               7 :                 IMAPG(imap_messages)->msgid = number;
    4484               7 :                 IMAPG(imap_messages)->next = NIL;
    4485               7 :                 IMAPG(imap_messages_tail) = IMAPG(imap_messages);
    4486                 :         } else {
    4487              14 :                 cur = IMAPG(imap_messages_tail);
    4488              14 :                 cur->next = mail_newmessagelist();
    4489              14 :                 cur = cur->next;
    4490              14 :                 cur->msgid = number;
    4491              14 :                 cur->next = NIL;
    4492              14 :                 IMAPG(imap_messages_tail) = cur;
    4493                 :         }
    4494              21 : }
    4495                 : 
    4496                 : void mm_exists(MAILSTREAM *stream, unsigned long number)
    4497             241 : {
    4498             241 : }
    4499                 : 
    4500                 : void mm_expunged(MAILSTREAM *stream, unsigned long number)
    4501               0 : {
    4502               0 : }
    4503                 : 
    4504                 : void mm_flags(MAILSTREAM *stream, unsigned long number)
    4505             130 : {
    4506             130 : }
    4507                 : 
    4508                 : /* Author: CJH */
    4509                 : void mm_notify(MAILSTREAM *stream, char *str, long errflg)
    4510             325 : {
    4511             325 :         STRINGLIST *cur = NIL;
    4512                 :         TSRMLS_FETCH();
    4513                 : 
    4514             325 :         if (strncmp(str, "[ALERT] ", 8) == 0) {
    4515               0 :                 if (IMAPG(imap_alertstack) == NIL) {
    4516               0 :                         IMAPG(imap_alertstack) = mail_newstringlist();
    4517               0 :                         IMAPG(imap_alertstack)->LSIZE = strlen(IMAPG(imap_alertstack)->LTEXT = cpystr(str));
    4518               0 :                         IMAPG(imap_alertstack)->next = NIL;
    4519                 :                 } else {
    4520               0 :                         cur = IMAPG(imap_alertstack);
    4521               0 :                         while (cur->next != NIL) {
    4522               0 :                                 cur = cur->next;
    4523                 :                         }
    4524               0 :                         cur->next = mail_newstringlist ();
    4525               0 :                         cur = cur->next;
    4526               0 :                         cur->LSIZE = strlen(cur->LTEXT = cpystr(str));
    4527               0 :                         cur->next = NIL;
    4528                 :                 }
    4529                 :         }
    4530             325 : }
    4531                 : 
    4532                 : void mm_list(MAILSTREAM *stream, DTYPE delimiter, char *mailbox, long attributes)
    4533              46 : {
    4534              46 :         STRINGLIST *cur=NIL;
    4535              46 :         FOBJECTLIST *ocur=NIL;
    4536                 :         TSRMLS_FETCH();
    4537                 : 
    4538              46 :         if (IMAPG(folderlist_style) == FLIST_OBJECT) {
    4539                 :                 /* build up a the new array of objects */
    4540                 :                 /* Author: CJH */
    4541              46 :                 if (IMAPG(imap_folder_objects) == NIL) {
    4542              23 :                         IMAPG(imap_folder_objects) = mail_newfolderobjectlist();
    4543              23 :                         IMAPG(imap_folder_objects)->LSIZE=strlen(IMAPG(imap_folder_objects)->LTEXT=cpystr(mailbox));
    4544              23 :                         IMAPG(imap_folder_objects)->delimiter = delimiter;
    4545              23 :                         IMAPG(imap_folder_objects)->attributes = attributes;
    4546              23 :                         IMAPG(imap_folder_objects)->next = NIL;
    4547              23 :                         IMAPG(imap_folder_objects_tail) = IMAPG(imap_folder_objects);
    4548                 :                 } else {
    4549              23 :                         ocur=IMAPG(imap_folder_objects_tail);
    4550              23 :                         ocur->next=mail_newfolderobjectlist();
    4551              23 :                         ocur=ocur->next;
    4552              23 :                         ocur->LSIZE = strlen(ocur->LTEXT = cpystr(mailbox));
    4553              23 :                         ocur->delimiter = delimiter;
    4554              23 :                         ocur->attributes = attributes;
    4555              23 :                         ocur->next = NIL;
    4556              23 :                         IMAPG(imap_folder_objects_tail) = ocur;
    4557                 :                 }
    4558                 : 
    4559                 :         } else {
    4560                 :                 /* build the old IMAPG(imap_folders) variable to allow old imap_listmailbox() to work */
    4561               0 :                 if (!(attributes & LATT_NOSELECT)) {
    4562               0 :                         if (IMAPG(imap_folders) == NIL) {
    4563               0 :                                 IMAPG(imap_folders)=mail_newstringlist();
    4564               0 :                                 IMAPG(imap_folders)->LSIZE=strlen(IMAPG(imap_folders)->LTEXT=cpystr(mailbox));
    4565               0 :                                 IMAPG(imap_folders)->next=NIL;
    4566               0 :                                 IMAPG(imap_folders_tail) = IMAPG(imap_folders);
    4567                 :                         } else {
    4568               0 :                                 cur=IMAPG(imap_folders_tail);
    4569               0 :                                 cur->next=mail_newstringlist ();
    4570               0 :                                 cur=cur->next;
    4571               0 :                                 cur->LSIZE = strlen (cur->LTEXT = cpystr (mailbox));
    4572               0 :                                 cur->next = NIL;
    4573               0 :                                 IMAPG(imap_folders_tail) = cur;
    4574                 :                         }
    4575                 :                 }
    4576                 :         }
    4577              46 : }
    4578                 : 
    4579                 : void mm_lsub(MAILSTREAM *stream, DTYPE delimiter, char *mailbox, long attributes)
    4580               0 : {
    4581               0 :         STRINGLIST *cur=NIL;
    4582               0 :         FOBJECTLIST *ocur=NIL;
    4583                 :         TSRMLS_FETCH();
    4584                 : 
    4585               0 :         if (IMAPG(folderlist_style) == FLIST_OBJECT) {
    4586                 :                 /* build the array of objects */
    4587                 :                 /* Author: CJH */
    4588               0 :                 if (IMAPG(imap_sfolder_objects) == NIL) {
    4589               0 :                         IMAPG(imap_sfolder_objects) = mail_newfolderobjectlist();
    4590               0 :                         IMAPG(imap_sfolder_objects)->LSIZE=strlen(IMAPG(imap_sfolder_objects)->LTEXT=cpystr(mailbox));
    4591               0 :                         IMAPG(imap_sfolder_objects)->delimiter = delimiter;
    4592               0 :                         IMAPG(imap_sfolder_objects)->attributes = attributes;
    4593               0 :                         IMAPG(imap_sfolder_objects)->next = NIL;
    4594               0 :                         IMAPG(imap_sfolder_objects_tail) = IMAPG(imap_sfolder_objects);
    4595                 :                 } else {
    4596               0 :                         ocur=IMAPG(imap_sfolder_objects_tail);
    4597               0 :                         ocur->next=mail_newfolderobjectlist();
    4598               0 :                         ocur=ocur->next;
    4599               0 :                         ocur->LSIZE=strlen(ocur->LTEXT = cpystr(mailbox));
    4600               0 :                         ocur->delimiter = delimiter;
    4601               0 :                         ocur->attributes = attributes;
    4602               0 :                         ocur->next = NIL;
    4603               0 :                         IMAPG(imap_sfolder_objects_tail) = ocur;
    4604                 :                 }
    4605                 :         } else {
    4606                 :                 /* build the old simple array for imap_listsubscribed() */
    4607               0 :                 if (IMAPG(imap_sfolders) == NIL) {
    4608               0 :                         IMAPG(imap_sfolders)=mail_newstringlist();
    4609               0 :                         IMAPG(imap_sfolders)->LSIZE=strlen(IMAPG(imap_sfolders)->LTEXT=cpystr(mailbox));
    4610               0 :                         IMAPG(imap_sfolders)->next=NIL;
    4611               0 :                         IMAPG(imap_sfolders_tail) = IMAPG(imap_sfolders);
    4612                 :                 } else {
    4613               0 :                         cur=IMAPG(imap_sfolders_tail);
    4614               0 :                         cur->next=mail_newstringlist ();
    4615               0 :                         cur=cur->next;
    4616               0 :                         cur->LSIZE = strlen (cur->LTEXT = cpystr (mailbox));
    4617               0 :                         cur->next = NIL;
    4618               0 :                         IMAPG(imap_sfolders_tail) = cur;
    4619                 :                 }
    4620                 :         }
    4621               0 : }
    4622                 : 
    4623                 : void mm_status(MAILSTREAM *stream, char *mailbox, MAILSTATUS *status)
    4624               1 : {
    4625                 :         TSRMLS_FETCH();
    4626                 : 
    4627               1 :         IMAPG(status_flags)=status->flags;
    4628               1 :         if (IMAPG(status_flags) & SA_MESSAGES) {
    4629               1 :                 IMAPG(status_messages)=status->messages;
    4630                 :         }
    4631               1 :         if (IMAPG(status_flags) & SA_RECENT) {
    4632               1 :                 IMAPG(status_recent)=status->recent;
    4633                 :         }
    4634               1 :         if (IMAPG(status_flags) & SA_UNSEEN) {
    4635               1 :                 IMAPG(status_unseen)=status->unseen;
    4636                 :         }
    4637               1 :         if (IMAPG(status_flags) & SA_UIDNEXT) {
    4638               1 :                 IMAPG(status_uidnext)=status->uidnext;
    4639                 :         }
    4640               1 :         if (IMAPG(status_flags) & SA_UIDVALIDITY) {
    4641               1 :                 IMAPG(status_uidvalidity)=status->uidvalidity;
    4642                 :         }
    4643               1 : }
    4644                 : 
    4645                 : void mm_log(char *str, long errflg)
    4646             313 : {
    4647             313 :         ERRORLIST *cur = NIL;
    4648                 :         TSRMLS_FETCH();
    4649                 : 
    4650                 :         /* Author: CJH */
    4651             313 :         if (errflg != NIL) { /* CJH: maybe put these into a more comprehensive log for debugging purposes? */
    4652              24 :                 if (IMAPG(imap_errorstack) == NIL) {
    4653               6 :                         IMAPG(imap_errorstack) = mail_newerrorlist();
    4654               6 :                         IMAPG(imap_errorstack)->LSIZE = strlen(IMAPG(imap_errorstack)->LTEXT = cpystr(str));
    4655               6 :                         IMAPG(imap_errorstack)->errflg = errflg;
    4656               6 :                         IMAPG(imap_errorstack)->next = NIL;
    4657                 :                 } else {
    4658              18 :                         cur = IMAPG(imap_errorstack);
    4659             118 :                         while (cur->next != NIL) {
    4660              82 :                                 cur = cur->next;
    4661                 :                         }
    4662              18 :                         cur->next = mail_newerrorlist();
    4663              18 :                         cur = cur->next;
    4664              18 :                         cur->LSIZE = strlen(cur->LTEXT = cpystr(str));
    4665              18 :                         cur->errflg = errflg;
    4666              18 :                         cur->next = NIL;
    4667                 :                 }
    4668                 :         }
    4669             313 : }
    4670                 : 
    4671                 : void mm_dlog(char *str)
    4672               0 : {
    4673                 :         /* CJH: this is for debugging; it might be useful to allow setting
    4674                 :            the stream to debug mode and capturing this somewhere - syslog?
    4675                 :            php debugger? */
    4676               0 : }
    4677                 : 
    4678                 : void mm_login(NETMBX *mb, char *user, char *pwd, long trial)
    4679             135 : {