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