PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/imap/php_imap.c

http://github.com/php/php-src
C | 4653 lines | 3445 code | 639 blank | 569 comment | 984 complexity | fb2db4dbfd5ce1da0f43734fd7cba14b MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | http://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Rex Logan <veebert@dimensional.com> |
  14. | Mark Musone <musone@afterfive.com> |
  15. | Brian Wang <brian@vividnet.com> |
  16. | Kaj-Michael Lang <milang@tal.org> |
  17. | Antoni Pamies Olive <toni@readysoft.net> |
  18. | Rasmus Lerdorf <rasmus@php.net> |
  19. | Chuck Hagenbuch <chuck@horde.org> |
  20. | Andrew Skalski <askalski@chekinc.com> |
  21. | Hartmut Holzgraefe <hholzgra@php.net> |
  22. | Jani Taskinen <jani.taskinen@iki.fi> |
  23. | Daniel R. Kalowsky <kalowsky@php.net> |
  24. | PHP 4.0 updates: Zeev Suraski <zeev@php.net> |
  25. +----------------------------------------------------------------------+
  26. */
  27. #define IMAP41
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include "php.h"
  32. #include "php_ini.h"
  33. #include "php_streams.h"
  34. #include "ext/standard/php_string.h"
  35. #include "ext/standard/info.h"
  36. #include "ext/standard/file.h"
  37. #include "zend_smart_str.h"
  38. #include "ext/pcre/php_pcre.h"
  39. #ifdef ERROR
  40. #undef ERROR
  41. #endif
  42. #include "php_imap.h"
  43. #include "php_imap_arginfo.h"
  44. #include <time.h>
  45. #include <stdio.h>
  46. #include <ctype.h>
  47. #include <signal.h>
  48. #ifdef PHP_WIN32
  49. #include <winsock2.h>
  50. #include <stdlib.h>
  51. #include "win32/sendmail.h"
  52. MAILSTREAM DEFAULTPROTO;
  53. #endif
  54. #define CRLF "\015\012"
  55. #define CRLF_LEN sizeof("\015\012") - 1
  56. #define PHP_EXPUNGE 32768
  57. #define PHP_IMAP_ADDRESS_SIZE_BUF 10
  58. #ifndef SENDBUFLEN
  59. #define SENDBUFLEN 16385
  60. #endif
  61. #if defined(__GNUC__) && __GNUC__ >= 4
  62. # define PHP_IMAP_EXPORT __attribute__ ((visibility("default")))
  63. #else
  64. # define PHP_IMAP_EXPORT
  65. #endif
  66. static void _php_make_header_object(zval *myzvalue, ENVELOPE *en);
  67. static void _php_imap_add_body(zval *arg, BODY *body);
  68. static zend_string* _php_imap_parse_address(ADDRESS *addresslist, zval *paddress);
  69. static zend_string* _php_rfc822_write_address(ADDRESS *addresslist);
  70. /* the gets we use */
  71. static char *php_mail_gets(readfn_t f, void *stream, unsigned long size, GETS_DATA *md);
  72. /* These function declarations are missing from the IMAP header files... */
  73. void rfc822_date(char *date);
  74. char *cpystr(const char *str);
  75. char *cpytxt(SIZEDTEXT *dst, char *text, unsigned long size);
  76. #ifndef HAVE_NEW_MIME2TEXT
  77. long utf8_mime2text(SIZEDTEXT *src, SIZEDTEXT *dst);
  78. #else
  79. long utf8_mime2text (SIZEDTEXT *src, SIZEDTEXT *dst, long flags);
  80. #endif
  81. unsigned long find_rightmost_bit(unsigned long *valptr);
  82. void fs_give(void **block);
  83. void *fs_get(size_t size);
  84. ZEND_DECLARE_MODULE_GLOBALS(imap)
  85. static PHP_GINIT_FUNCTION(imap);
  86. /* {{{ imap dependencies */
  87. static const zend_module_dep imap_deps[] = {
  88. ZEND_MOD_REQUIRED("standard")
  89. ZEND_MOD_END
  90. };
  91. /* }}} */
  92. /* {{{ PHP_INI
  93. */
  94. PHP_INI_BEGIN()
  95. STD_PHP_INI_BOOLEAN("imap.enable_insecure_rsh", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_rsh, zend_imap_globals, imap_globals)
  96. PHP_INI_END()
  97. /* }}} */
  98. /* {{{ imap_module_entry
  99. */
  100. zend_module_entry imap_module_entry = {
  101. STANDARD_MODULE_HEADER_EX, NULL,
  102. imap_deps,
  103. "imap",
  104. ext_functions,
  105. PHP_MINIT(imap),
  106. NULL,
  107. PHP_RINIT(imap),
  108. PHP_RSHUTDOWN(imap),
  109. PHP_MINFO(imap),
  110. PHP_IMAP_VERSION,
  111. PHP_MODULE_GLOBALS(imap),
  112. PHP_GINIT(imap),
  113. NULL,
  114. NULL,
  115. STANDARD_MODULE_PROPERTIES_EX
  116. };
  117. /* }}} */
  118. #ifdef COMPILE_DL_IMAP
  119. #ifdef ZTS
  120. ZEND_TSRMLS_CACHE_DEFINE()
  121. #endif
  122. ZEND_GET_MODULE(imap)
  123. #endif
  124. /* True globals, no need for thread safety */
  125. static int le_imap;
  126. #define PHP_IMAP_CHECK_MSGNO(msgindex) \
  127. if ((msgindex < 1) || ((unsigned) msgindex > imap_le_struct->imap_stream->nmsgs)) { \
  128. php_error_docref(NULL, E_WARNING, "Bad message number"); \
  129. RETURN_FALSE; \
  130. } \
  131. /* {{{ mail_close_it
  132. */
  133. static void mail_close_it(zend_resource *rsrc)
  134. {
  135. pils *imap_le_struct = (pils *)rsrc->ptr;
  136. /* Do not try to close prototype streams */
  137. if (!(imap_le_struct->flags & OP_PROTOTYPE)) {
  138. mail_close_full(imap_le_struct->imap_stream, imap_le_struct->flags);
  139. }
  140. if (IMAPG(imap_user)) {
  141. efree(IMAPG(imap_user));
  142. IMAPG(imap_user) = 0;
  143. }
  144. if (IMAPG(imap_password)) {
  145. efree(IMAPG(imap_password));
  146. IMAPG(imap_password) = 0;
  147. }
  148. efree(imap_le_struct);
  149. }
  150. /* }}} */
  151. /* {{{ add_assoc_object
  152. */
  153. static zval *add_assoc_object(zval *arg, char *key, zval *tmp)
  154. {
  155. HashTable *symtable;
  156. if (Z_TYPE_P(arg) == IS_OBJECT) {
  157. symtable = Z_OBJPROP_P(arg);
  158. } else {
  159. symtable = Z_ARRVAL_P(arg);
  160. }
  161. return zend_hash_str_update(symtable, key, strlen(key), tmp);
  162. }
  163. /* }}} */
  164. /* {{{ add_next_index_object
  165. */
  166. static inline zval *add_next_index_object(zval *arg, zval *tmp)
  167. {
  168. HashTable *symtable;
  169. if (Z_TYPE_P(arg) == IS_OBJECT) {
  170. symtable = Z_OBJPROP_P(arg);
  171. } else {
  172. symtable = Z_ARRVAL_P(arg);
  173. }
  174. return zend_hash_next_index_insert(symtable, tmp);
  175. }
  176. /* }}} */
  177. /* {{{ mail_newfolderobjectlist
  178. *
  179. * Mail instantiate FOBJECTLIST
  180. * Returns: new FOBJECTLIST list
  181. * Author: CJH
  182. */
  183. FOBJECTLIST *mail_newfolderobjectlist(void)
  184. {
  185. return (FOBJECTLIST *) memset(fs_get(sizeof(FOBJECTLIST)), 0, sizeof(FOBJECTLIST));
  186. }
  187. /* }}} */
  188. /* {{{ mail_free_foblist
  189. *
  190. * Mail garbage collect FOBJECTLIST
  191. * Accepts: pointer to FOBJECTLIST pointer
  192. * Author: CJH
  193. */
  194. void mail_free_foblist(FOBJECTLIST **foblist, FOBJECTLIST **tail)
  195. {
  196. FOBJECTLIST *cur, *next;
  197. for (cur=*foblist, next=cur->next; cur; cur=next) {
  198. next = cur->next;
  199. if(cur->text.data)
  200. fs_give((void **)&(cur->text.data));
  201. fs_give((void **)&cur);
  202. }
  203. *tail = NIL;
  204. *foblist = NIL;
  205. }
  206. /* }}} */
  207. /* {{{ mail_newerrorlist
  208. *
  209. * Mail instantiate ERRORLIST
  210. * Returns: new ERRORLIST list
  211. * Author: CJH
  212. */
  213. ERRORLIST *mail_newerrorlist(void)
  214. {
  215. return (ERRORLIST *) memset(fs_get(sizeof(ERRORLIST)), 0, sizeof(ERRORLIST));
  216. }
  217. /* }}} */
  218. /* {{{ mail_free_errorlist
  219. *
  220. * Mail garbage collect FOBJECTLIST
  221. * Accepts: pointer to FOBJECTLIST pointer
  222. * Author: CJH
  223. */
  224. void mail_free_errorlist(ERRORLIST **errlist)
  225. {
  226. if (*errlist) { /* only free if exists */
  227. if ((*errlist)->text.data) {
  228. fs_give((void **) &(*errlist)->text.data);
  229. }
  230. mail_free_errorlist (&(*errlist)->next);
  231. fs_give((void **) errlist); /* return string to free storage */
  232. }
  233. }
  234. /* }}} */
  235. /* {{{ mail_newmessagelist
  236. *
  237. * Mail instantiate MESSAGELIST
  238. * Returns: new MESSAGELIST list
  239. * Author: CJH
  240. */
  241. MESSAGELIST *mail_newmessagelist(void)
  242. {
  243. return (MESSAGELIST *) memset(fs_get(sizeof(MESSAGELIST)), 0, sizeof(MESSAGELIST));
  244. }
  245. /* }}} */
  246. /* {{{ mail_free_messagelist
  247. *
  248. * Mail garbage collect MESSAGELIST
  249. * Accepts: pointer to MESSAGELIST pointer
  250. * Author: CJH
  251. */
  252. void mail_free_messagelist(MESSAGELIST **msglist, MESSAGELIST **tail)
  253. {
  254. MESSAGELIST *cur, *next;
  255. for (cur = *msglist, next = cur->next; cur; cur = next) {
  256. next = cur->next;
  257. fs_give((void **)&cur);
  258. }
  259. *tail = NIL;
  260. *msglist = NIL;
  261. }
  262. /* }}} */
  263. #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
  264. /* {{{ mail_getquota
  265. *
  266. * Mail GET_QUOTA callback
  267. * Called via the mail_parameter function in c-client:src/c-client/mail.c
  268. * Author DRK
  269. */
  270. void mail_getquota(MAILSTREAM *stream, char *qroot, QUOTALIST *qlist)
  271. {
  272. zval t_map, *return_value;
  273. return_value = *IMAPG(quota_return);
  274. /* put parsing code here */
  275. for(; qlist; qlist = qlist->next) {
  276. array_init(&t_map);
  277. if (strncmp(qlist->name, "STORAGE", 7) == 0)
  278. {
  279. /* this is to add backwards compatibility */
  280. add_assoc_long_ex(return_value, "usage", sizeof("usage") - 1, qlist->usage);
  281. add_assoc_long_ex(return_value, "limit", sizeof("limit") - 1, qlist->limit);
  282. }
  283. add_assoc_long_ex(&t_map, "usage", sizeof("usage") - 1, qlist->usage);
  284. add_assoc_long_ex(&t_map, "limit", sizeof("limit") - 1, qlist->limit);
  285. add_assoc_zval_ex(return_value, qlist->name, strlen(qlist->name), &t_map);
  286. }
  287. }
  288. /* }}} */
  289. /* {{{ mail_getquota
  290. *
  291. * Mail GET_ACL callback
  292. * Called via the mail_parameter function in c-client:src/c-client/mail.c
  293. */
  294. void mail_getacl(MAILSTREAM *stream, char *mailbox, ACLLIST *alist)
  295. {
  296. /* walk through the ACLLIST */
  297. for(; alist; alist = alist->next) {
  298. add_assoc_stringl(IMAPG(imap_acl_list), alist->identifier, alist->rights, strlen(alist->rights));
  299. }
  300. }
  301. /* }}} */
  302. #endif
  303. /* {{{ PHP_GINIT_FUNCTION
  304. */
  305. static PHP_GINIT_FUNCTION(imap)
  306. {
  307. #if defined(COMPILE_DL_IMAP) && defined(ZTS)
  308. ZEND_TSRMLS_CACHE_UPDATE();
  309. #endif
  310. imap_globals->imap_user = NIL;
  311. imap_globals->imap_password = NIL;
  312. imap_globals->imap_alertstack = NIL;
  313. imap_globals->imap_errorstack = NIL;
  314. imap_globals->imap_folders = NIL;
  315. imap_globals->imap_folders_tail = NIL;
  316. imap_globals->imap_sfolders = NIL;
  317. imap_globals->imap_sfolders_tail = NIL;
  318. imap_globals->imap_messages = NIL;
  319. imap_globals->imap_messages_tail = NIL;
  320. imap_globals->imap_folder_objects = NIL;
  321. imap_globals->imap_folder_objects_tail = NIL;
  322. imap_globals->imap_sfolder_objects = NIL;
  323. imap_globals->imap_sfolder_objects_tail = NIL;
  324. imap_globals->folderlist_style = FLIST_ARRAY;
  325. #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
  326. imap_globals->quota_return = NIL;
  327. imap_globals->imap_acl_list = NIL;
  328. #endif
  329. imap_globals->gets_stream = NIL;
  330. }
  331. /* }}} */
  332. /* {{{ PHP_MINIT_FUNCTION
  333. */
  334. PHP_MINIT_FUNCTION(imap)
  335. {
  336. unsigned long sa_all = SA_MESSAGES | SA_RECENT | SA_UNSEEN | SA_UIDNEXT | SA_UIDVALIDITY;
  337. REGISTER_INI_ENTRIES();
  338. #ifndef PHP_WIN32
  339. mail_link(&unixdriver); /* link in the unix driver */
  340. mail_link(&mhdriver); /* link in the mh driver */
  341. /* mail_link(&mxdriver); */ /* According to c-client docs (internal.txt) this shouldn't be used. */
  342. mail_link(&mmdfdriver); /* link in the mmdf driver */
  343. mail_link(&newsdriver); /* link in the news driver */
  344. mail_link(&philedriver); /* link in the phile driver */
  345. #endif
  346. mail_link(&imapdriver); /* link in the imap driver */
  347. mail_link(&nntpdriver); /* link in the nntp driver */
  348. mail_link(&pop3driver); /* link in the pop3 driver */
  349. mail_link(&mbxdriver); /* link in the mbx driver */
  350. mail_link(&tenexdriver); /* link in the tenex driver */
  351. mail_link(&mtxdriver); /* link in the mtx driver */
  352. mail_link(&dummydriver); /* link in the dummy driver */
  353. #ifndef PHP_WIN32
  354. auth_link(&auth_log); /* link in the log authenticator */
  355. auth_link(&auth_md5); /* link in the cram-md5 authenticator */
  356. #if HAVE_IMAP_KRB && defined(HAVE_IMAP_AUTH_GSS)
  357. auth_link(&auth_gss); /* link in the gss authenticator */
  358. #endif
  359. auth_link(&auth_pla); /* link in the plain authenticator */
  360. #endif
  361. #ifdef HAVE_IMAP_SSL
  362. ssl_onceonlyinit ();
  363. #endif
  364. /* lets allow NIL */
  365. REGISTER_LONG_CONSTANT("NIL", NIL, CONST_PERSISTENT | CONST_CS);
  366. /* plug in our gets */
  367. mail_parameters(NIL, SET_GETS, (void *) NIL);
  368. /* set default timeout values */
  369. mail_parameters(NIL, SET_OPENTIMEOUT, (void *) FG(default_socket_timeout));
  370. mail_parameters(NIL, SET_READTIMEOUT, (void *) FG(default_socket_timeout));
  371. mail_parameters(NIL, SET_WRITETIMEOUT, (void *) FG(default_socket_timeout));
  372. mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) FG(default_socket_timeout));
  373. /* timeout constants */
  374. REGISTER_LONG_CONSTANT("IMAP_OPENTIMEOUT", 1, CONST_PERSISTENT | CONST_CS);
  375. REGISTER_LONG_CONSTANT("IMAP_READTIMEOUT", 2, CONST_PERSISTENT | CONST_CS);
  376. REGISTER_LONG_CONSTANT("IMAP_WRITETIMEOUT", 3, CONST_PERSISTENT | CONST_CS);
  377. REGISTER_LONG_CONSTANT("IMAP_CLOSETIMEOUT", 4, CONST_PERSISTENT | CONST_CS);
  378. /* Open Options */
  379. REGISTER_LONG_CONSTANT("OP_DEBUG", OP_DEBUG, CONST_PERSISTENT | CONST_CS);
  380. /* debug protocol negotiations */
  381. REGISTER_LONG_CONSTANT("OP_READONLY", OP_READONLY, CONST_PERSISTENT | CONST_CS);
  382. /* read-only open */
  383. REGISTER_LONG_CONSTANT("OP_ANONYMOUS", OP_ANONYMOUS, CONST_PERSISTENT | CONST_CS);
  384. /* anonymous open of newsgroup */
  385. REGISTER_LONG_CONSTANT("OP_SHORTCACHE", OP_SHORTCACHE, CONST_PERSISTENT | CONST_CS);
  386. /* short (elt-only) caching */
  387. REGISTER_LONG_CONSTANT("OP_SILENT", OP_SILENT, CONST_PERSISTENT | CONST_CS);
  388. /* don't pass up events (internal use) */
  389. REGISTER_LONG_CONSTANT("OP_PROTOTYPE", OP_PROTOTYPE, CONST_PERSISTENT | CONST_CS);
  390. /* return driver prototype */
  391. REGISTER_LONG_CONSTANT("OP_HALFOPEN", OP_HALFOPEN, CONST_PERSISTENT | CONST_CS);
  392. /* half-open (IMAP connect but no select) */
  393. REGISTER_LONG_CONSTANT("OP_EXPUNGE", OP_EXPUNGE, CONST_PERSISTENT | CONST_CS);
  394. /* silently expunge recycle stream */
  395. REGISTER_LONG_CONSTANT("OP_SECURE", OP_SECURE, CONST_PERSISTENT | CONST_CS);
  396. /* don't do non-secure authentication */
  397. /*
  398. PHP re-assigns CL_EXPUNGE a custom value that can be used as part of the imap_open() bitfield
  399. because it seems like a good idea to be able to indicate that the mailbox should be
  400. automatically expunged during imap_open in case the script get interrupted and it doesn't get
  401. to the imap_close() where this option is normally placed. If the c-client library adds other
  402. options and the value for this one conflicts, simply make PHP_EXPUNGE higher at the top of
  403. this file
  404. */
  405. REGISTER_LONG_CONSTANT("CL_EXPUNGE", PHP_EXPUNGE, CONST_PERSISTENT | CONST_CS);
  406. /* expunge silently */
  407. /* Fetch options */
  408. REGISTER_LONG_CONSTANT("FT_UID", FT_UID, CONST_PERSISTENT | CONST_CS);
  409. /* argument is a UID */
  410. REGISTER_LONG_CONSTANT("FT_PEEK", FT_PEEK, CONST_PERSISTENT | CONST_CS);
  411. /* peek at data */
  412. REGISTER_LONG_CONSTANT("FT_NOT", FT_NOT, CONST_PERSISTENT | CONST_CS);
  413. /* NOT flag for header lines fetch */
  414. REGISTER_LONG_CONSTANT("FT_INTERNAL", FT_INTERNAL, CONST_PERSISTENT | CONST_CS);
  415. /* text can be internal strings */
  416. REGISTER_LONG_CONSTANT("FT_PREFETCHTEXT", FT_PREFETCHTEXT, CONST_PERSISTENT | CONST_CS);
  417. /* IMAP prefetch text when fetching header */
  418. /* Flagging options */
  419. REGISTER_LONG_CONSTANT("ST_UID", ST_UID, CONST_PERSISTENT | CONST_CS);
  420. /* argument is a UID sequence */
  421. REGISTER_LONG_CONSTANT("ST_SILENT", ST_SILENT, CONST_PERSISTENT | CONST_CS);
  422. /* don't return results */
  423. REGISTER_LONG_CONSTANT("ST_SET", ST_SET, CONST_PERSISTENT | CONST_CS);
  424. /* set vs. clear */
  425. /* Copy options */
  426. REGISTER_LONG_CONSTANT("CP_UID", CP_UID, CONST_PERSISTENT | CONST_CS);
  427. /* argument is a UID sequence */
  428. REGISTER_LONG_CONSTANT("CP_MOVE", CP_MOVE, CONST_PERSISTENT | CONST_CS);
  429. /* delete from source after copying */
  430. /* Search/sort options */
  431. REGISTER_LONG_CONSTANT("SE_UID", SE_UID, CONST_PERSISTENT | CONST_CS);
  432. /* return UID */
  433. REGISTER_LONG_CONSTANT("SE_FREE", SE_FREE, CONST_PERSISTENT | CONST_CS);
  434. /* free search program after finished */
  435. REGISTER_LONG_CONSTANT("SE_NOPREFETCH", SE_NOPREFETCH, CONST_PERSISTENT | CONST_CS);
  436. /* no search prefetching */
  437. REGISTER_LONG_CONSTANT("SO_FREE", SO_FREE, CONST_PERSISTENT | CONST_CS);
  438. /* free sort program after finished */
  439. REGISTER_LONG_CONSTANT("SO_NOSERVER", SO_NOSERVER, CONST_PERSISTENT | CONST_CS);
  440. /* don't do server-based sort */
  441. /* Status options */
  442. REGISTER_LONG_CONSTANT("SA_MESSAGES", SA_MESSAGES , CONST_PERSISTENT | CONST_CS);
  443. /* number of messages */
  444. REGISTER_LONG_CONSTANT("SA_RECENT", SA_RECENT, CONST_PERSISTENT | CONST_CS);
  445. /* number of recent messages */
  446. REGISTER_LONG_CONSTANT("SA_UNSEEN", SA_UNSEEN , CONST_PERSISTENT | CONST_CS);
  447. /* number of unseen messages */
  448. REGISTER_LONG_CONSTANT("SA_UIDNEXT", SA_UIDNEXT, CONST_PERSISTENT | CONST_CS);
  449. /* next UID to be assigned */
  450. REGISTER_LONG_CONSTANT("SA_UIDVALIDITY", SA_UIDVALIDITY , CONST_PERSISTENT | CONST_CS);
  451. /* UID validity value */
  452. REGISTER_LONG_CONSTANT("SA_ALL", sa_all, CONST_PERSISTENT | CONST_CS);
  453. /* get all status information */
  454. /* Bits for mm_list() and mm_lsub() */
  455. REGISTER_LONG_CONSTANT("LATT_NOINFERIORS", LATT_NOINFERIORS , CONST_PERSISTENT | CONST_CS);
  456. REGISTER_LONG_CONSTANT("LATT_NOSELECT", LATT_NOSELECT, CONST_PERSISTENT | CONST_CS);
  457. REGISTER_LONG_CONSTANT("LATT_MARKED", LATT_MARKED, CONST_PERSISTENT | CONST_CS);
  458. REGISTER_LONG_CONSTANT("LATT_UNMARKED", LATT_UNMARKED , CONST_PERSISTENT | CONST_CS);
  459. #ifdef LATT_REFERRAL
  460. REGISTER_LONG_CONSTANT("LATT_REFERRAL", LATT_REFERRAL, CONST_PERSISTENT | CONST_CS);
  461. #endif
  462. #ifdef LATT_HASCHILDREN
  463. REGISTER_LONG_CONSTANT("LATT_HASCHILDREN", LATT_HASCHILDREN, CONST_PERSISTENT | CONST_CS);
  464. #endif
  465. #ifdef LATT_HASNOCHILDREN
  466. REGISTER_LONG_CONSTANT("LATT_HASNOCHILDREN", LATT_HASNOCHILDREN, CONST_PERSISTENT | CONST_CS);
  467. #endif
  468. /* Sort functions */
  469. REGISTER_LONG_CONSTANT("SORTDATE", SORTDATE , CONST_PERSISTENT | CONST_CS);
  470. /* date */
  471. REGISTER_LONG_CONSTANT("SORTARRIVAL", SORTARRIVAL , CONST_PERSISTENT | CONST_CS);
  472. /* arrival date */
  473. REGISTER_LONG_CONSTANT("SORTFROM", SORTFROM , CONST_PERSISTENT | CONST_CS);
  474. /* from */
  475. REGISTER_LONG_CONSTANT("SORTSUBJECT", SORTSUBJECT , CONST_PERSISTENT | CONST_CS);
  476. /* subject */
  477. REGISTER_LONG_CONSTANT("SORTTO", SORTTO , CONST_PERSISTENT | CONST_CS);
  478. /* to */
  479. REGISTER_LONG_CONSTANT("SORTCC", SORTCC , CONST_PERSISTENT | CONST_CS);
  480. /* cc */
  481. REGISTER_LONG_CONSTANT("SORTSIZE", SORTSIZE , CONST_PERSISTENT | CONST_CS);
  482. /* size */
  483. REGISTER_LONG_CONSTANT("TYPETEXT", TYPETEXT , CONST_PERSISTENT | CONST_CS);
  484. REGISTER_LONG_CONSTANT("TYPEMULTIPART", TYPEMULTIPART , CONST_PERSISTENT | CONST_CS);
  485. REGISTER_LONG_CONSTANT("TYPEMESSAGE", TYPEMESSAGE , CONST_PERSISTENT | CONST_CS);
  486. REGISTER_LONG_CONSTANT("TYPEAPPLICATION", TYPEAPPLICATION , CONST_PERSISTENT | CONST_CS);
  487. REGISTER_LONG_CONSTANT("TYPEAUDIO", TYPEAUDIO , CONST_PERSISTENT | CONST_CS);
  488. REGISTER_LONG_CONSTANT("TYPEIMAGE", TYPEIMAGE , CONST_PERSISTENT | CONST_CS);
  489. REGISTER_LONG_CONSTANT("TYPEVIDEO", TYPEVIDEO , CONST_PERSISTENT | CONST_CS);
  490. REGISTER_LONG_CONSTANT("TYPEMODEL", TYPEMODEL , CONST_PERSISTENT | CONST_CS);
  491. REGISTER_LONG_CONSTANT("TYPEOTHER", TYPEOTHER , CONST_PERSISTENT | CONST_CS);
  492. /*
  493. TYPETEXT unformatted text
  494. TYPEMULTIPART multiple part
  495. TYPEMESSAGE encapsulated message
  496. TYPEAPPLICATION application data
  497. TYPEAUDIO audio
  498. TYPEIMAGE static image (GIF, JPEG, etc.)
  499. TYPEVIDEO video
  500. TYPEMODEL model
  501. TYPEOTHER unknown
  502. */
  503. REGISTER_LONG_CONSTANT("ENC7BIT", ENC7BIT , CONST_PERSISTENT | CONST_CS);
  504. REGISTER_LONG_CONSTANT("ENC8BIT", ENC8BIT , CONST_PERSISTENT | CONST_CS);
  505. REGISTER_LONG_CONSTANT("ENCBINARY", ENCBINARY , CONST_PERSISTENT | CONST_CS);
  506. REGISTER_LONG_CONSTANT("ENCBASE64", ENCBASE64, CONST_PERSISTENT | CONST_CS);
  507. REGISTER_LONG_CONSTANT("ENCQUOTEDPRINTABLE", ENCQUOTEDPRINTABLE , CONST_PERSISTENT | CONST_CS);
  508. REGISTER_LONG_CONSTANT("ENCOTHER", ENCOTHER , CONST_PERSISTENT | CONST_CS);
  509. /*
  510. ENC7BIT 7 bit SMTP semantic data
  511. ENC8BIT 8 bit SMTP semantic data
  512. ENCBINARY 8 bit binary data
  513. ENCBASE64 base-64 encoded data
  514. ENCQUOTEDPRINTABLE human-readable 8-as-7 bit data
  515. ENCOTHER unknown
  516. */
  517. REGISTER_LONG_CONSTANT("IMAP_GC_ELT", GC_ELT , CONST_PERSISTENT | CONST_CS);
  518. REGISTER_LONG_CONSTANT("IMAP_GC_ENV", GC_ENV , CONST_PERSISTENT | CONST_CS);
  519. REGISTER_LONG_CONSTANT("IMAP_GC_TEXTS", GC_TEXTS , CONST_PERSISTENT | CONST_CS);
  520. /*
  521. GC_ELT message cache elements
  522. GC_ENV ENVELOPEs and BODYs
  523. GC_TEXTS texts
  524. */
  525. if (!IMAPG(enable_rsh)) {
  526. /* disable SSH and RSH, see https://bugs.php.net/bug.php?id=77153 */
  527. mail_parameters (NIL, SET_RSHTIMEOUT, 0);
  528. mail_parameters (NIL, SET_SSHTIMEOUT, 0);
  529. }
  530. le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, "imap", module_number);
  531. return SUCCESS;
  532. }
  533. /* }}} */
  534. /* {{{ PHP_RINIT_FUNCTION
  535. */
  536. PHP_RINIT_FUNCTION(imap)
  537. {
  538. IMAPG(imap_errorstack) = NIL;
  539. IMAPG(imap_alertstack) = NIL;
  540. IMAPG(gets_stream) = NIL;
  541. return SUCCESS;
  542. }
  543. /* }}} */
  544. /* {{{ PHP_RSHUTDOWN_FUNCTION
  545. */
  546. PHP_RSHUTDOWN_FUNCTION(imap)
  547. {
  548. ERRORLIST *ecur = NIL;
  549. STRINGLIST *acur = NIL;
  550. if (IMAPG(imap_errorstack) != NIL) {
  551. /* output any remaining errors at their original error level */
  552. if (EG(error_reporting) & E_NOTICE) {
  553. ecur = IMAPG(imap_errorstack);
  554. while (ecur != NIL) {
  555. php_error_docref(NULL, E_NOTICE, "%s (errflg=%ld)", ecur->LTEXT, ecur->errflg);
  556. ecur = ecur->next;
  557. }
  558. }
  559. mail_free_errorlist(&IMAPG(imap_errorstack));
  560. IMAPG(imap_errorstack) = NIL;
  561. }
  562. if (IMAPG(imap_alertstack) != NIL) {
  563. /* output any remaining alerts at E_NOTICE level */
  564. if (EG(error_reporting) & E_NOTICE) {
  565. acur = IMAPG(imap_alertstack);
  566. while (acur != NIL) {
  567. php_error_docref(NULL, E_NOTICE, "%s", acur->LTEXT);
  568. acur = acur->next;
  569. }
  570. }
  571. mail_free_stringlist(&IMAPG(imap_alertstack));
  572. IMAPG(imap_alertstack) = NIL;
  573. }
  574. return SUCCESS;
  575. }
  576. /* }}} */
  577. #if !defined(CCLIENTVERSION)
  578. #if HAVE_IMAP2007e
  579. #define CCLIENTVERSION "2007e"
  580. #elif HAVE_IMAP2007d
  581. #define CCLIENTVERSION "2007d"
  582. #elif HAVE_IMAP2007b
  583. #define CCLIENTVERSION "2007b"
  584. #elif HAVE_IMAP2007a
  585. #define CCLIENTVERSION "2007a"
  586. #elif HAVE_IMAP2004
  587. #define CCLIENTVERSION "2004"
  588. #elif HAVE_IMAP2001
  589. #define CCLIENTVERSION "2001"
  590. #elif HAVE_IMAP2000
  591. #define CCLIENTVERSION "2000"
  592. #elif defined(IMAP41)
  593. #define CCLIENTVERSION "4.1"
  594. #else
  595. #define CCLIENTVERSION "4.0"
  596. #endif
  597. #endif
  598. /* {{{ PHP_MINFO_FUNCTION
  599. */
  600. PHP_MINFO_FUNCTION(imap)
  601. {
  602. php_info_print_table_start();
  603. php_info_print_table_row(2, "IMAP c-Client Version", CCLIENTVERSION);
  604. #if HAVE_IMAP_SSL
  605. php_info_print_table_row(2, "SSL Support", "enabled");
  606. #endif
  607. #if HAVE_IMAP_KRB && HAVE_IMAP_AUTH_GSS
  608. php_info_print_table_row(2, "Kerberos Support", "enabled");
  609. #endif
  610. php_info_print_table_end();
  611. DISPLAY_INI_ENTRIES();
  612. }
  613. /* }}} */
  614. /* {{{ imap_do_open
  615. */
  616. static void php_imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
  617. {
  618. zend_string *mailbox, *user, *passwd;
  619. zend_long retries = 0, flags = NIL, cl_flags = NIL;
  620. MAILSTREAM *imap_stream;
  621. pils *imap_le_struct;
  622. zval *params = NULL;
  623. int argc = ZEND_NUM_ARGS();
  624. if (zend_parse_parameters(argc, "PSS|lla", &mailbox, &user,
  625. &passwd, &flags, &retries, &params) == FAILURE) {
  626. RETURN_THROWS();
  627. }
  628. if (argc >= 4) {
  629. if (flags & PHP_EXPUNGE) {
  630. cl_flags = CL_EXPUNGE;
  631. flags ^= PHP_EXPUNGE;
  632. }
  633. if (flags & OP_PROTOTYPE) {
  634. cl_flags |= OP_PROTOTYPE;
  635. }
  636. }
  637. if (params) {
  638. zval *disabled_auth_method;
  639. if ((disabled_auth_method = zend_hash_str_find(Z_ARRVAL_P(params), "DISABLE_AUTHENTICATOR", sizeof("DISABLE_AUTHENTICATOR") - 1)) != NULL) {
  640. switch (Z_TYPE_P(disabled_auth_method)) {
  641. case IS_STRING:
  642. if (Z_STRLEN_P(disabled_auth_method) > 1) {
  643. mail_parameters(NIL, DISABLE_AUTHENTICATOR, (void *)Z_STRVAL_P(disabled_auth_method));
  644. }
  645. break;
  646. case IS_ARRAY:
  647. {
  648. zval *z_auth_method;
  649. int i;
  650. int nelems = zend_hash_num_elements(Z_ARRVAL_P(disabled_auth_method));
  651. if (nelems == 0 ) {
  652. break;
  653. }
  654. for (i = 0; i < nelems; i++) {
  655. if ((z_auth_method = zend_hash_index_find(Z_ARRVAL_P(disabled_auth_method), i)) != NULL) {
  656. if (Z_TYPE_P(z_auth_method) == IS_STRING) {
  657. if (Z_STRLEN_P(z_auth_method) > 1) {
  658. mail_parameters(NIL, DISABLE_AUTHENTICATOR, (void *)Z_STRVAL_P(z_auth_method));
  659. }
  660. } else {
  661. php_error_docref(NULL, E_WARNING, "Invalid argument, expect string or array of strings");
  662. }
  663. }
  664. }
  665. }
  666. break;
  667. case IS_LONG:
  668. default:
  669. php_error_docref(NULL, E_WARNING, "Invalid argument, expect string or array of strings");
  670. break;
  671. }
  672. }
  673. }
  674. if (IMAPG(imap_user)) {
  675. efree(IMAPG(imap_user));
  676. IMAPG(imap_user) = 0;
  677. }
  678. if (IMAPG(imap_password)) {
  679. efree(IMAPG(imap_password));
  680. IMAPG(imap_password) = 0;
  681. }
  682. /* local filename, need to perform open_basedir check */
  683. if (ZSTR_VAL(mailbox)[0] != '{' && php_check_open_basedir(ZSTR_VAL(mailbox))) {
  684. RETURN_FALSE;
  685. }
  686. IMAPG(imap_user) = estrndup(ZSTR_VAL(user), ZSTR_LEN(user));
  687. IMAPG(imap_password) = estrndup(ZSTR_VAL(passwd), ZSTR_LEN(passwd));
  688. #ifdef SET_MAXLOGINTRIALS
  689. if (argc >= 5) {
  690. if (retries < 0) {
  691. php_error_docref(NULL, E_WARNING ,"Retries must be greater or equal to 0");
  692. } else {
  693. mail_parameters(NIL, SET_MAXLOGINTRIALS, (void *) retries);
  694. }
  695. }
  696. #endif
  697. imap_stream = mail_open(NIL, ZSTR_VAL(mailbox), flags);
  698. if (imap_stream == NIL) {
  699. php_error_docref(NULL, E_WARNING, "Couldn't open stream %s", ZSTR_VAL(mailbox));
  700. efree(IMAPG(imap_user)); IMAPG(imap_user) = 0;
  701. efree(IMAPG(imap_password)); IMAPG(imap_password) = 0;
  702. RETURN_FALSE;
  703. }
  704. imap_le_struct = emalloc(sizeof(pils));
  705. imap_le_struct->imap_stream = imap_stream;
  706. imap_le_struct->flags = cl_flags;
  707. RETURN_RES(zend_register_resource(imap_le_struct, le_imap));
  708. }
  709. /* }}} */
  710. /* {{{ proto resource imap_open(string mailbox, string user, string password [, int options [, int n_retries]])
  711. Open an IMAP stream to a mailbox */
  712. PHP_FUNCTION(imap_open)
  713. {
  714. php_imap_do_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  715. }
  716. /* }}} */
  717. /* {{{ proto bool imap_reopen(resource stream_id, string mailbox [, int options [, int n_retries]])
  718. Reopen an IMAP stream to a new mailbox */
  719. PHP_FUNCTION(imap_reopen)
  720. {
  721. zval *streamind;
  722. zend_string *mailbox;
  723. zend_long options = 0, retries = 0;
  724. pils *imap_le_struct;
  725. long flags=NIL;
  726. long cl_flags=NIL;
  727. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS|ll", &streamind, &mailbox, &options, &retries) == FAILURE) {
  728. RETURN_THROWS();
  729. }
  730. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  731. RETURN_THROWS();
  732. }
  733. if (options) {
  734. flags = options;
  735. if (flags & PHP_EXPUNGE) {
  736. cl_flags = CL_EXPUNGE;
  737. flags ^= PHP_EXPUNGE;
  738. }
  739. imap_le_struct->flags = cl_flags;
  740. }
  741. #ifdef SET_MAXLOGINTRIALS
  742. if (retries) {
  743. mail_parameters(NIL, SET_MAXLOGINTRIALS, (void *) retries);
  744. }
  745. #endif
  746. /* local filename, need to perform open_basedir check */
  747. if (ZSTR_VAL(mailbox)[0] != '{' && php_check_open_basedir(ZSTR_VAL(mailbox))) {
  748. RETURN_FALSE;
  749. }
  750. imap_le_struct->imap_stream = mail_open(imap_le_struct->imap_stream, ZSTR_VAL(mailbox), flags);
  751. if (imap_le_struct->imap_stream == NIL) {
  752. zend_list_delete(Z_RES_P(streamind));
  753. php_error_docref(NULL, E_WARNING, "Couldn't re-open stream");
  754. RETURN_FALSE;
  755. }
  756. RETURN_TRUE;
  757. }
  758. /* }}} */
  759. /* {{{ proto bool imap_append(resource stream_id, string folder, string message [, string options [, string internal_date]])
  760. Append a new message to a specified mailbox */
  761. PHP_FUNCTION(imap_append)
  762. {
  763. zval *streamind;
  764. zend_string *folder, *message, *internal_date = NULL, *flags = NULL;
  765. pils *imap_le_struct;
  766. STRING st;
  767. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSS|SS", &streamind, &folder, &message, &flags, &internal_date) == FAILURE) {
  768. RETURN_THROWS();
  769. }
  770. if (internal_date) {
  771. zend_string *regex = zend_string_init("/[0-3][0-9]-((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec))-[0-9]{4} [0-2][0-9]:[0-5][0-9]:[0-5][0-9] [+-][0-9]{4}/", sizeof("/[0-3][0-9]-((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec))-[0-9]{4} [0-2][0-9]:[0-5][0-9]:[0-5][0-9] [+-][0-9]{4}/") - 1, 0);
  772. pcre_cache_entry *pce; /* Compiled regex */
  773. zval *subpats = NULL; /* Parts (not used) */
  774. int global = 0;
  775. /* Make sure the given internal_date string matches the RFC specifiedformat */
  776. if ((pce = pcre_get_compiled_regex_cache(regex))== NULL) {
  777. zend_string_release(regex);
  778. RETURN_FALSE;
  779. }
  780. zend_string_release(regex);
  781. php_pcre_match_impl(pce, internal_date, return_value, subpats, global,
  782. 0, Z_L(0), Z_L(0));
  783. if (!Z_LVAL_P(return_value)) {
  784. php_error_docref(NULL, E_WARNING, "Internal date not correctly formatted");
  785. internal_date = NULL;
  786. }
  787. }
  788. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  789. RETURN_THROWS();
  790. }
  791. INIT (&st, mail_string, (void *) ZSTR_VAL(message), ZSTR_LEN(message));
  792. if (mail_append_full(imap_le_struct->imap_stream, ZSTR_VAL(folder), (flags ? ZSTR_VAL(flags) : NIL), (internal_date ? ZSTR_VAL(internal_date) : NIL), &st)) {
  793. RETURN_TRUE;
  794. } else {
  795. RETURN_FALSE;
  796. }
  797. }
  798. /* }}} */
  799. /* {{{ proto int imap_num_msg(resource stream_id)
  800. Gives the number of messages in the current mailbox */
  801. PHP_FUNCTION(imap_num_msg)
  802. {
  803. zval *streamind;
  804. pils *imap_le_struct;
  805. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &streamind) == FAILURE) {
  806. RETURN_THROWS();
  807. }
  808. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  809. RETURN_THROWS();
  810. }
  811. RETURN_LONG(imap_le_struct->imap_stream->nmsgs);
  812. }
  813. /* }}} */
  814. /* {{{ proto bool imap_ping(resource stream_id)
  815. Check if the IMAP stream is still active */
  816. PHP_FUNCTION(imap_ping)
  817. {
  818. zval *streamind;
  819. pils *imap_le_struct;
  820. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &streamind) == FAILURE) {
  821. RETURN_THROWS();
  822. }
  823. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  824. RETURN_THROWS();
  825. }
  826. RETURN_BOOL(mail_ping(imap_le_struct->imap_stream));
  827. }
  828. /* }}} */
  829. /* {{{ proto int imap_num_recent(resource stream_id)
  830. Gives the number of recent messages in current mailbox */
  831. PHP_FUNCTION(imap_num_recent)
  832. {
  833. zval *streamind;
  834. pils *imap_le_struct;
  835. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &streamind) == FAILURE) {
  836. RETURN_THROWS();
  837. }
  838. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  839. RETURN_THROWS();
  840. }
  841. RETURN_LONG(imap_le_struct->imap_stream->recent);
  842. }
  843. /* }}} */
  844. #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
  845. /* {{{ proto array imap_get_quota(resource stream_id, string qroot)
  846. Returns the quota set to the mailbox account qroot */
  847. PHP_FUNCTION(imap_get_quota)
  848. {
  849. zval *streamind;
  850. zend_string *qroot;
  851. pils *imap_le_struct;
  852. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &streamind, &qroot) == FAILURE) {
  853. RETURN_THROWS();
  854. }
  855. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  856. RETURN_THROWS();
  857. }
  858. array_init(return_value);
  859. IMAPG(quota_return) = &return_value;
  860. /* set the callback for the GET_QUOTA function */
  861. mail_parameters(NIL, SET_QUOTA, (void *) mail_getquota);
  862. if (!imap_getquota(imap_le_struct->imap_stream, ZSTR_VAL(qroot))) {
  863. php_error_docref(NULL, E_WARNING, "C-client imap_getquota failed");
  864. zend_array_destroy(Z_ARR_P(return_value));
  865. RETURN_FALSE;
  866. }
  867. }
  868. /* }}} */
  869. /* {{{ proto array imap_get_quotaroot(resource stream_id, string mbox)
  870. Returns the quota set to the mailbox account mbox */
  871. PHP_FUNCTION(imap_get_quotaroot)
  872. {
  873. zval *streamind;
  874. zend_string *mbox;
  875. pils *imap_le_struct;
  876. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &streamind, &mbox) == FAILURE) {
  877. RETURN_THROWS();
  878. }
  879. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  880. RETURN_THROWS();
  881. }
  882. array_init(return_value);
  883. IMAPG(quota_return) = &return_value;
  884. /* set the callback for the GET_QUOTAROOT function */
  885. mail_parameters(NIL, SET_QUOTA, (void *) mail_getquota);
  886. if (!imap_getquotaroot(imap_le_struct->imap_stream, ZSTR_VAL(mbox))) {
  887. php_error_docref(NULL, E_WARNING, "C-client imap_getquotaroot failed");
  888. zend_array_destroy(Z_ARR_P(return_value));
  889. RETURN_FALSE;
  890. }
  891. }
  892. /* }}} */
  893. /* {{{ proto bool imap_set_quota(resource stream_id, string qroot, int mailbox_size)
  894. Will set the quota for qroot mailbox */
  895. PHP_FUNCTION(imap_set_quota)
  896. {
  897. zval *streamind;
  898. zend_string *qroot;
  899. zend_long mailbox_size;
  900. pils *imap_le_struct;
  901. STRINGLIST limits;
  902. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSl", &streamind, &qroot, &mailbox_size) == FAILURE) {
  903. RETURN_THROWS();
  904. }
  905. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  906. RETURN_THROWS();
  907. }
  908. limits.text.data = (unsigned char*)"STORAGE";
  909. limits.text.size = mailbox_size;
  910. limits.next = NIL;
  911. RETURN_BOOL(imap_setquota(imap_le_struct->imap_stream, ZSTR_VAL(qroot), &limits));
  912. }
  913. /* }}} */
  914. /* {{{ proto bool imap_setacl(resource stream_id, string mailbox, string id, string rights)
  915. Sets the ACL for a given mailbox */
  916. PHP_FUNCTION(imap_setacl)
  917. {
  918. zval *streamind;
  919. zend_string *mailbox, *id, *rights;
  920. pils *imap_le_struct;
  921. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSSS", &streamind, &mailbox, &id, &rights) == FAILURE) {
  922. RETURN_THROWS();
  923. }
  924. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  925. RETURN_THROWS();
  926. }
  927. RETURN_BOOL(imap_setacl(imap_le_struct->imap_stream, ZSTR_VAL(mailbox), ZSTR_VAL(id), ZSTR_VAL(rights)));
  928. }
  929. /* }}} */
  930. /* {{{ proto array imap_getacl(resource stream_id, string mailbox)
  931. Gets the ACL for a given mailbox */
  932. PHP_FUNCTION(imap_getacl)
  933. {
  934. zval *streamind;
  935. zend_string *mailbox;
  936. pils *imap_le_struct;
  937. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &streamind, &mailbox) == FAILURE) {
  938. RETURN_THROWS();
  939. }
  940. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  941. RETURN_THROWS();
  942. }
  943. /* initializing the special array for the return values */
  944. array_init(return_value);
  945. IMAPG(imap_acl_list) = return_value;
  946. /* set the callback for the GET_ACL function */
  947. mail_parameters(NIL, SET_ACL, (void *) mail_getacl);
  948. if (!imap_getacl(imap_le_struct->imap_stream, ZSTR_VAL(mailbox))) {
  949. php_error(E_WARNING, "c-client imap_getacl failed");
  950. zend_array_destroy(Z_ARR_P(return_value));
  951. RETURN_FALSE;
  952. }
  953. IMAPG(imap_acl_list) = NIL;
  954. }
  955. /* }}} */
  956. #endif /* HAVE_IMAP2000 || HAVE_IMAP2001 */
  957. /* {{{ proto bool imap_expunge(resource stream_id)
  958. Permanently delete all messages marked for deletion */
  959. PHP_FUNCTION(imap_expunge)
  960. {
  961. zval *streamind;
  962. pils *imap_le_struct;
  963. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &streamind) == FAILURE) {
  964. RETURN_THROWS();
  965. }
  966. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  967. RETURN_THROWS();
  968. }
  969. mail_expunge (imap_le_struct->imap_stream);
  970. RETURN_TRUE;
  971. }
  972. /* }}} */
  973. /* {{{ proto bool imap_gc(resource stream_id, int flags)
  974. This function garbage collects (purges) the cache of entries of a specific type. */
  975. PHP_FUNCTION(imap_gc)
  976. {
  977. zval *streamind;
  978. pils *imap_le_struct;
  979. zend_long flags;
  980. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &streamind, &flags) == FAILURE) {
  981. RETURN_THROWS();
  982. }
  983. if (flags && ((flags & ~(GC_TEXTS | GC_ELT | GC_ENV)) != 0)) {
  984. php_error_docref(NULL, E_WARNING, "Invalid value for the flags parameter");
  985. RETURN_FALSE;
  986. }
  987. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  988. RETURN_THROWS();
  989. }
  990. mail_gc(imap_le_struct->imap_stream, flags);
  991. RETURN_TRUE;
  992. }
  993. /* }}} */
  994. /* {{{ proto bool imap_close(resource stream_id [, int options])
  995. Close an IMAP stream */
  996. PHP_FUNCTION(imap_close)
  997. {
  998. zval *streamind;
  999. pils *imap_le_struct=NULL;
  1000. zend_long options = 0, flags = NIL;
  1001. int argc = ZEND_NUM_ARGS();
  1002. if (zend_parse_parameters(argc, "r|l", &streamind, &options) == FAILURE) {
  1003. RETURN_THROWS();
  1004. }
  1005. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1006. RETURN_THROWS();
  1007. }
  1008. if (argc == 2) {
  1009. flags = options;
  1010. /* Check that flags is exactly equal to PHP_EXPUNGE or zero */
  1011. if (flags && ((flags & ~PHP_EXPUNGE) != 0)) {
  1012. php_error_docref(NULL, E_WARNING, "Invalid value for the flags parameter");
  1013. RETURN_FALSE;
  1014. }
  1015. /* Do the translation from PHP's internal PHP_EXPUNGE define to c-client's CL_EXPUNGE */
  1016. if (flags & PHP_EXPUNGE) {
  1017. flags ^= PHP_EXPUNGE;
  1018. flags |= CL_EXPUNGE;
  1019. }
  1020. imap_le_struct->flags = flags;
  1021. }
  1022. zend_list_close(Z_RES_P(streamind));
  1023. RETURN_TRUE;
  1024. }
  1025. /* }}} */
  1026. /* {{{ proto array imap_headers(resource stream_id)
  1027. Returns headers for all messages in a mailbox */
  1028. PHP_FUNCTION(imap_headers)
  1029. {
  1030. zval *streamind;
  1031. pils *imap_le_struct;
  1032. unsigned long i;
  1033. char *t;
  1034. unsigned int msgno;
  1035. char tmp[MAILTMPLEN];
  1036. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &streamind) == FAILURE) {
  1037. RETURN_THROWS();
  1038. }
  1039. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1040. RETURN_THROWS();
  1041. }
  1042. /* Initialize return array */
  1043. array_init(return_value);
  1044. for (msgno = 1; msgno <= imap_le_struct->imap_stream->nmsgs; msgno++) {
  1045. MESSAGECACHE * cache = mail_elt (imap_le_struct->imap_stream, msgno);
  1046. mail_fetchstructure(imap_le_struct->imap_stream, msgno, NIL);
  1047. tmp[0] = cache->recent ? (cache->seen ? 'R': 'N') : ' ';
  1048. tmp[1] = (cache->recent | cache->seen) ? ' ' : 'U';
  1049. tmp[2] = cache->flagged ? 'F' : ' ';
  1050. tmp[3] = cache->answered ? 'A' : ' ';
  1051. tmp[4] = cache->deleted ? 'D' : ' ';
  1052. tmp[5] = cache->draft ? 'X' : ' ';
  1053. snprintf(tmp + 6, sizeof(tmp) - 6, "%4ld) ", cache->msgno);
  1054. mail_date(tmp+11, cache);
  1055. tmp[22] = ' ';
  1056. tmp[23] = '\0';
  1057. mail_fetchfrom(tmp+23, imap_le_struct->imap_stream, msgno, (long)20);
  1058. strcat(tmp, " ");
  1059. if ((i = cache->user_flags)) {
  1060. strcat(tmp, "{");
  1061. while (i) {
  1062. strlcat(tmp, imap_le_struct->imap_stream->user_flags[find_rightmost_bit (&i)], sizeof(tmp));
  1063. if (i) strlcat(tmp, " ", sizeof(tmp));
  1064. }
  1065. strlcat(tmp, "} ", sizeof(tmp));
  1066. }
  1067. mail_fetchsubject(t = tmp + strlen(tmp), imap_le_struct->imap_stream, msgno, (long)25);
  1068. snprintf(t += strlen(t), sizeof(tmp) - strlen(tmp), " (%ld chars)", cache->rfc822_size);
  1069. add_next_index_string(return_value, tmp);
  1070. }
  1071. }
  1072. /* }}} */
  1073. /* {{{ proto string imap_body(resource stream_id, int msg_no [, int options])
  1074. Read the message body */
  1075. PHP_FUNCTION(imap_body)
  1076. {
  1077. zval *streamind;
  1078. zend_long msgno, flags = 0;
  1079. pils *imap_le_struct;
  1080. int msgindex, argc = ZEND_NUM_ARGS();
  1081. char *body;
  1082. unsigned long body_len = 0;
  1083. if (zend_parse_parameters(argc, "rl|l", &streamind, &msgno, &flags) == FAILURE) {
  1084. RETURN_THROWS();
  1085. }
  1086. if (flags && ((flags & ~(FT_UID|FT_PEEK|FT_INTERNAL)) != 0)) {
  1087. php_error_docref(NULL, E_WARNING, "Invalid value for the options parameter");
  1088. RETURN_FALSE;
  1089. }
  1090. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1091. RETURN_THROWS();
  1092. }
  1093. if ((argc == 3) && (flags & FT_UID)) {
  1094. /* This should be cached; if it causes an extra RTT to the
  1095. IMAP server, then that's the price we pay for making
  1096. sure we don't crash. */
  1097. msgindex = mail_msgno(imap_le_struct->imap_stream, msgno);
  1098. } else {
  1099. msgindex = msgno;
  1100. }
  1101. if ((msgindex < 1) || ((unsigned) msgindex > imap_le_struct->imap_stream->nmsgs)) {
  1102. php_error_docref(NULL, E_WARNING, "Bad message number");
  1103. RETURN_FALSE;
  1104. }
  1105. body = mail_fetchtext_full (imap_le_struct->imap_stream, msgno, &body_len, (argc == 3 ? flags : NIL));
  1106. if (body_len == 0) {
  1107. RETVAL_EMPTY_STRING();
  1108. } else {
  1109. RETVAL_STRINGL(body, body_len);
  1110. }
  1111. }
  1112. /* }}} */
  1113. /* {{{ proto bool imap_mail_copy(resource stream_id, string msglist, string mailbox [, int options])
  1114. Copy specified message to a mailbox */
  1115. PHP_FUNCTION(imap_mail_copy)
  1116. {
  1117. zval *streamind;
  1118. zend_long options = 0;
  1119. zend_string *seq, *folder;
  1120. int argc = ZEND_NUM_ARGS();
  1121. pils *imap_le_struct;
  1122. if (zend_parse_parameters(argc, "rSS|l", &streamind, &seq, &folder, &options) == FAILURE) {
  1123. RETURN_THROWS();
  1124. }
  1125. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1126. RETURN_THROWS();
  1127. }
  1128. if (mail_copy_full(imap_le_struct->imap_stream, ZSTR_VAL(seq), ZSTR_VAL(folder), (argc == 4 ? options : NIL)) == T) {
  1129. RETURN_TRUE;
  1130. } else {
  1131. RETURN_FALSE;
  1132. }
  1133. }
  1134. /* }}} */
  1135. /* {{{ proto bool imap_mail_move(resource stream_id, string sequence, string mailbox [, int options])
  1136. Move specified message to a mailbox */
  1137. PHP_FUNCTION(imap_mail_move)
  1138. {
  1139. zval *streamind;
  1140. zend_string *seq, *folder;
  1141. zend_long options = 0;
  1142. pils *imap_le_struct;
  1143. int argc = ZEND_NUM_ARGS();
  1144. if (zend_parse_parameters(argc, "rSS|l", &streamind, &seq, &folder, &options) == FAILURE) {
  1145. RETURN_THROWS();
  1146. }
  1147. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1148. RETURN_THROWS();
  1149. }
  1150. if (mail_copy_full(imap_le_struct->imap_stream, ZSTR_VAL(seq), ZSTR_VAL(folder), (argc == 4 ? (options | CP_MOVE) : CP_MOVE)) == T) {
  1151. RETURN_TRUE;
  1152. } else {
  1153. RETURN_FALSE;
  1154. }
  1155. }
  1156. /* }}} */
  1157. /* {{{ proto bool imap_createmailbox(resource stream_id, string mailbox)
  1158. Create a new mailbox */
  1159. PHP_FUNCTION(imap_createmailbox)
  1160. {
  1161. zval *streamind;
  1162. zend_string *folder;
  1163. pils *imap_le_struct;
  1164. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &streamind, &folder) == FAILURE) {
  1165. RETURN_THROWS();
  1166. }
  1167. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1168. RETURN_THROWS();
  1169. }
  1170. if (mail_create(imap_le_struct->imap_stream, ZSTR_VAL(folder)) == T) {
  1171. RETURN_TRUE;
  1172. } else {
  1173. RETURN_FALSE;
  1174. }
  1175. }
  1176. /* }}} */
  1177. /* {{{ proto bool imap_renamemailbox(resource stream_id, string old_name, string new_name)
  1178. Rename a mailbox */
  1179. PHP_FUNCTION(imap_renamemailbox)
  1180. {
  1181. zval *streamind;
  1182. zend_string *old_mailbox, *new_mailbox;
  1183. pils *imap_le_struct;
  1184. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSS", &streamind, &old_mailbox, &new_mailbox) == FAILURE) {
  1185. RETURN_THROWS();
  1186. }
  1187. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1188. RETURN_THROWS();
  1189. }
  1190. if (mail_rename(imap_le_struct->imap_stream, ZSTR_VAL(old_mailbox), ZSTR_VAL(new_mailbox)) == T) {
  1191. RETURN_TRUE;
  1192. } else {
  1193. RETURN_FALSE;
  1194. }
  1195. }
  1196. /* }}} */
  1197. /* {{{ proto bool imap_deletemailbox(resource stream_id, string mailbox)
  1198. Delete a mailbox */
  1199. PHP_FUNCTION(imap_deletemailbox)
  1200. {
  1201. zval *streamind;
  1202. zend_string *folder;
  1203. pils *imap_le_struct;
  1204. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rS", &streamind, &folder) == FAILURE) {
  1205. RETURN_THROWS();
  1206. }
  1207. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1208. RETURN_THROWS();
  1209. }
  1210. if (mail_delete(imap_le_struct->imap_stream, ZSTR_VAL(folder)) == T) {
  1211. RETURN_TRUE;
  1212. } else {
  1213. RETURN_FALSE;
  1214. }
  1215. }
  1216. /* }}} */
  1217. /* {{{ proto array imap_list(resource stream_id, string ref, string pattern)
  1218. Read the list of mailboxes */
  1219. PHP_FUNCTION(imap_list)
  1220. {
  1221. zval *streamind;
  1222. zend_string *ref, *pat;
  1223. pils *imap_le_struct;
  1224. STRINGLIST *cur=NIL;
  1225. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSS", &streamind, &ref, &pat) == FAILURE) {
  1226. RETURN_THROWS();
  1227. }
  1228. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1229. RETURN_THROWS();
  1230. }
  1231. /* set flag for normal, old mailbox list */
  1232. IMAPG(folderlist_style) = FLIST_ARRAY;
  1233. IMAPG(imap_folders) = IMAPG(imap_folders_tail) = NIL;
  1234. mail_list(imap_le_struct->imap_stream, ZSTR_VAL(ref), ZSTR_VAL(pat));
  1235. if (IMAPG(imap_folders) == NIL) {
  1236. RETURN_FALSE;
  1237. }
  1238. array_init(return_value);
  1239. cur=IMAPG(imap_folders);
  1240. while (cur != NIL) {
  1241. add_next_index_string(return_value, (char*)cur->LTEXT);
  1242. cur=cur->next;
  1243. }
  1244. mail_free_stringlist (&IMAPG(imap_folders));
  1245. IMAPG(imap_folders) = IMAPG(imap_folders_tail) = NIL;
  1246. }
  1247. /* }}} */
  1248. /* {{{ proto array imap_getmailboxes(resource stream_id, string ref, string pattern)
  1249. Reads the list of mailboxes and returns a full array of objects containing name, attributes, and delimiter */
  1250. /* Author: CJH */
  1251. PHP_FUNCTION(imap_getmailboxes)
  1252. {
  1253. zval *streamind, mboxob;
  1254. zend_string *ref, *pat;
  1255. pils *imap_le_struct;
  1256. FOBJECTLIST *cur=NIL;
  1257. char *delim=NIL;
  1258. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSS", &streamind, &ref, &pat) == FAILURE) {
  1259. RETURN_THROWS();
  1260. }
  1261. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1262. RETURN_THROWS();
  1263. }
  1264. /* set flag for new, improved array of objects mailbox list */
  1265. IMAPG(folderlist_style) = FLIST_OBJECT;
  1266. IMAPG(imap_folder_objects) = IMAPG(imap_folder_objects_tail) = NIL;
  1267. mail_list(imap_le_struct->imap_stream, ZSTR_VAL(ref), ZSTR_VAL(pat));
  1268. if (IMAPG(imap_folder_objects) == NIL) {
  1269. RETURN_FALSE;
  1270. }
  1271. array_init(return_value);
  1272. delim = safe_emalloc(2, sizeof(char), 0);
  1273. cur=IMAPG(imap_folder_objects);
  1274. while (cur != NIL) {
  1275. object_init(&mboxob);
  1276. add_property_string(&mboxob, "name", (char*)cur->LTEXT);
  1277. add_property_long(&mboxob, "attributes", cur->attributes);
  1278. #ifdef IMAP41
  1279. delim[0] = (char)cur->delimiter;
  1280. delim[1] = 0;
  1281. add_property_string(&mboxob, "delimiter", delim);
  1282. #else
  1283. add_property_string(&mboxob, "delimiter", cur->delimiter);
  1284. #endif
  1285. add_next_index_object(return_value, &mboxob);
  1286. cur=cur->next;
  1287. }
  1288. mail_free_foblist(&IMAPG(imap_folder_objects), &IMAPG(imap_folder_objects_tail));
  1289. efree(delim);
  1290. IMAPG(folderlist_style) = FLIST_ARRAY; /* reset to default */
  1291. }
  1292. /* }}} */
  1293. /* {{{ proto array imap_listscan(resource stream_id, string ref, string pattern, string content)
  1294. Read list of mailboxes containing a certain string */
  1295. PHP_FUNCTION(imap_listscan)
  1296. {
  1297. zval *streamind;
  1298. zend_string *ref, *pat, *content;
  1299. pils *imap_le_struct;
  1300. STRINGLIST *cur=NIL;
  1301. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSSS", &streamind, &ref, &pat, &content) == FAILURE) {
  1302. RETURN_THROWS();
  1303. }
  1304. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1305. RETURN_THROWS();
  1306. }
  1307. IMAPG(imap_folders) = NIL;
  1308. mail_scan(imap_le_struct->imap_stream, ZSTR_VAL(ref), ZSTR_VAL(pat), ZSTR_VAL(content));
  1309. if (IMAPG(imap_folders) == NIL) {
  1310. RETURN_FALSE;
  1311. }
  1312. array_init(return_value);
  1313. cur=IMAPG(imap_folders);
  1314. while (cur != NIL) {
  1315. add_next_index_string(return_value, (char*)cur->LTEXT);
  1316. cur=cur->next;
  1317. }
  1318. mail_free_stringlist (&IMAPG(imap_folders));
  1319. IMAPG(imap_folders) = IMAPG(imap_folders_tail) = NIL;
  1320. }
  1321. /* }}} */
  1322. /* {{{ proto object imap_check(resource stream_id)
  1323. Get mailbox properties */
  1324. PHP_FUNCTION(imap_check)
  1325. {
  1326. zval *streamind;
  1327. pils *imap_le_struct;
  1328. char date[100];
  1329. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &streamind) == FAILURE) {
  1330. RETURN_THROWS();
  1331. }
  1332. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1333. RETURN_THROWS();
  1334. }
  1335. if (mail_ping (imap_le_struct->imap_stream) == NIL) {
  1336. RETURN_FALSE;
  1337. }
  1338. if (imap_le_struct->imap_stream && imap_le_struct->imap_stream->mailbox) {
  1339. rfc822_date(date);
  1340. object_init(return_value);
  1341. add_property_string(return_value, "Date", date);
  1342. add_property_string(return_value, "Driver", imap_le_struct->imap_stream->dtb->name);
  1343. add_property_string(return_value, "Mailbox", imap_le_struct->imap_stream->mailbox);
  1344. add_property_long(return_value, "Nmsgs", imap_le_struct->imap_stream->nmsgs);
  1345. add_property_long(return_value, "Recent", imap_le_struct->imap_stream->recent);
  1346. } else {
  1347. RETURN_FALSE;
  1348. }
  1349. }
  1350. /* }}} */
  1351. /* {{{ proto bool imap_delete(resource stream_id, int msg_no [, int options])
  1352. Mark a message for deletion */
  1353. PHP_FUNCTION(imap_delete)
  1354. {
  1355. zval *streamind, *sequence;
  1356. pils *imap_le_struct;
  1357. zend_long flags = 0;
  1358. int argc = ZEND_NUM_ARGS();
  1359. if (zend_parse_parameters(argc, "rz|l", &streamind, &sequence, &flags) == FAILURE) {
  1360. RETURN_THROWS();
  1361. }
  1362. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1363. RETURN_THROWS();
  1364. }
  1365. if (!try_convert_to_string(sequence)) {
  1366. RETURN_THROWS();
  1367. }
  1368. mail_setflag_full(imap_le_struct->imap_stream, Z_STRVAL_P(sequence), "\\DELETED", (argc == 3 ? flags : NIL));
  1369. RETVAL_TRUE;
  1370. }
  1371. /* }}} */
  1372. /* {{{ proto bool imap_undelete(resource stream_id, int msg_no [, int flags])
  1373. Remove the delete flag from a message */
  1374. PHP_FUNCTION(imap_undelete)
  1375. {
  1376. zval *streamind, *sequence;
  1377. zend_long flags = 0;
  1378. pils *imap_le_struct;
  1379. int argc = ZEND_NUM_ARGS();
  1380. if (zend_parse_parameters(argc, "rz|l", &streamind, &sequence, &flags) == FAILURE) {
  1381. RETURN_THROWS();
  1382. }
  1383. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1384. RETURN_THROWS();
  1385. }
  1386. if (!try_convert_to_string(sequence)) {
  1387. RETURN_THROWS();
  1388. }
  1389. mail_clearflag_full(imap_le_struct->imap_stream, Z_STRVAL_P(sequence), "\\DELETED", (argc == 3 ? flags : NIL));
  1390. RETVAL_TRUE;
  1391. }
  1392. /* }}} */
  1393. /* {{{ proto object imap_headerinfo(resource stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
  1394. Read the headers of the message */
  1395. PHP_FUNCTION(imap_headerinfo)
  1396. {
  1397. zval *streamind;
  1398. zend_string *defaulthost = NULL;
  1399. int argc = ZEND_NUM_ARGS();
  1400. zend_long msgno, fromlength, subjectlength;
  1401. pils *imap_le_struct;
  1402. MESSAGECACHE *cache;
  1403. ENVELOPE *en;
  1404. char dummy[2000], fulladdress[MAILTMPLEN + 1];
  1405. if (zend_parse_parameters(argc, "rl|llS", &streamind, &msgno, &fromlength, &subjectlength, &defaulthost) == FAILURE) {
  1406. RETURN_THROWS();
  1407. }
  1408. if ((imap_le_struct = (pils *)zend_fetch_resource(Z_RES_P(streamind), "imap", le_imap)) == NULL) {
  1409. RETURN_THROWS();
  1410. }
  1411. if (argc >= 3) {
  1412. if (fromlength < 0 || fromlength > MAILTMPLEN) {
  1413. php_error_docref(NULL, E_WARNING, "From length has to be between 0 and %d", MAILTMPLEN);
  1414. RETURN_FALSE;
  1415. }
  1416. } else {
  1417. fromlength = 0x00;
  1418. }
  1419. if (argc >= 4) {
  1420. if (subjectlength < 0 || subjectlength > MAILTMPLEN) {
  1421. php_error_docref(NULL, E_WARNING, "Subject length has to be between 0 and %d", MAILTMPLEN);
  1422. RETURN_FALSE;
  1423. }
  1424. } else {
  1425. subjectlength = 0x00;
  1426. }
  1427. PHP_IMAP_CHECK_MSGNO(msgno);
  1428. if (mail_fetchstructure(imap_le_struct->imap_stream, msgno, NIL)) {
  1429. cache = mail_elt(imap_le_struct->imap_stream, msgno);
  1430. } else {
  1431. RETURN_FALSE;
  1432. }
  1433. en = mail_fetchenvelope(imap_le_struct->imap_stream, msgno);
  1434. /* call a function to parse all the text, so that we can use the
  1435. same function to parse text from other sources */
  1436. _php_make_header_object(return_value, en);
  1437. /* now run through properties th…

Large files files are truncated, but you can click here to view the full file