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