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