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, §ion, §ion_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, §ion) == 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 : {
|