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