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