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