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