/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2004 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/3.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Marco Tabini | | Ilia Alshanetsky | +----------------------------------------------------------------------+ $Id: pop3.c,v 1.19 2005/07/25 21:47:03 iliaa Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "ext/standard/md5.h" /* needed for APOP auth */ #ifndef ZEND_ENGINE_2 #include "ext/standard/url.h" #include "main/php_network.h" #endif #include "php_pop3.h" #include #ifndef PHP_WIN32 #include #include #include #endif /* {{{ Internal macros */ #define POP3_VERSION "1.0.2" #define POP3_RESOURCE_NAME "POP3 Library Session" #define POP3_FETCH_SESSION(session, session_container) \ ZEND_FETCH_RESOURCE ( session, php_stream *, &session_container, -1, POP3_RESOURCE_NAME, le_pop3_resource); #ifdef ZEND_ENGINE_2 #define POP3_REGISTER_OBJECT(_object, _ptr) \ { \ pop3_object *obj; \ obj = (pop3_object*)zend_object_store_get_object(_object TSRMLS_CC); \ obj->ptr = (void *) _ptr; \ } #define POP3_FROM_OBJECT(socket_id, object) \ { \ pop3_object *obj = zend_object_store_get_object(object TSRMLS_CC); \ socket_id = (php_stream *) obj->ptr; \ if (!socket_id) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The pop3 connection was not established."); \ RETURN_FALSE; \ } \ } #define POP3_DECLARE_INIT_OBJECT(object) \ zval *object = getThis(); #else /* ZEND_ENGINE_2 */ #define POP3_REGISTER_OBJECT(_object, _ptr) {} #define POP3_FROM_OBJECT(socket_id, object) {} #define POP3_DECLARE_INIT_OBJECT(object) #define object 0 #endif /* ZEND_ENGINE_2 */ /* }}} */ #define PHP_POP3_HEADER 1 #define PHP_POP3_MESSAGE 2 #define PHP_POP3_DELETE 3 #define PHP_POP3_SIZE 4 /* True global resources - no need for thread safety here */ static int le_pop3_resource; /* {{{ _pop3_receive_response */ static int _pop3_receive_response (php_stream *stream, char *response TSRMLS_DC) /* Returns SUCCESS or FAIL */ { char buffer[2048]; size_t fetch_len; if (!php_stream_get_line(stream, buffer, sizeof(buffer) - 1, &fetch_len)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "I/O Error when receiving data from the server"); } /* Check for error */ if (buffer[0] == '-') { char *output = memchr(buffer, ' ', fetch_len); /* Find the first space */ if (!output) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3 Error: Unknown POP3 error"); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3 Error: %s", output + 1); } return FAILURE; } else { if (response) { memcpy(response, buffer, fetch_len); buffer[fetch_len] = '\0'; } return SUCCESS; } } /* }}} */ /* _pop3_send_command {{{ */ static int _pop3_send_command (php_stream *stream, char *command, char *response TSRMLS_DC) { if ((!php_stream_write_string(stream, command)) || (!php_stream_write_string(stream, "\r\n"))) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "I/O Error when sending data to server"); } return _pop3_receive_response(stream, response TSRMLS_CC); } /* }}} */ #ifdef ZEND_ENGINE_2 static zend_object_handlers pop3_object_handlers; /* {{{ pop3_objects_dtor */ static void pop3_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC) { pop3_object *intern = (pop3_object *) object; if (intern->zo.properties) { zend_hash_destroy(intern->zo.properties); FREE_HASHTABLE(intern->zo.properties); } if (intern->ptr) { _pop3_send_command((php_stream *) intern->ptr, "QUIT", NULL TSRMLS_CC); php_stream_close((php_stream *) intern->ptr); } efree(intern); } /* }}} */ /* {{{ pop3_objects_new */ PHP_POP3_API zend_object_value pop3_objects_new(zend_class_entry *class_type TSRMLS_DC) { zend_object_value retval; pop3_object *intern; intern = emalloc(sizeof(pop3_object)); intern->zo.ce = class_type; #if ZEND_MODULE_API_NO >= 20050922 intern->zo.guards = NULL; #else intern->zo.in_get = 0; intern->zo.in_set = 0; #endif intern->zo.properties = NULL; intern->ptr = NULL; retval.handle = zend_objects_store_put(intern, pop3_objects_dtor, NULL, NULL TSRMLS_CC); retval.handlers = (zend_object_handlers *) &pop3_object_handlers; return retval; } /* }}} */ #endif /* ZEND_ENGINE_2 */ /* {{{ Forward declarations */ /* * Forward declarations */ void pop3_resource_destructor (zend_rsrc_list_entry *rsrc TSRMLS_DC); /* }}} */ /* {{{ pop3_functions[] * * Every user visible function must have an entry in pop3_functions[]. */ function_entry pop3_functions[] = { PHP_FE(pop3_open, NULL) PHP_FE(pop3_close, NULL) PHP_FE(pop3_get_message_count, NULL) PHP_FE(pop3_get_account_size, NULL) PHP_FE(pop3_get_message_ids, NULL) PHP_FE(pop3_get_message_sizes, NULL) PHP_FE(pop3_get_message_header, NULL) PHP_FE(pop3_get_message_size, NULL) PHP_FE(pop3_get_message, NULL) PHP_FE(pop3_delete_message, NULL) PHP_FE(pop3_undelete, NULL) {NULL, NULL, NULL} }; /* }}} */ #define POP3_ME_MAPPING(name, func_name, arg_types) \ ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types) /* {{{ pop3_class_functions */ function_entry pop3_class_functions[] = { POP3_ME_MAPPING(pop3, pop3_open, NULL) POP3_ME_MAPPING(get_message_count, pop3_get_message_count, NULL) POP3_ME_MAPPING(get_account_size, pop3_get_account_size, NULL) POP3_ME_MAPPING(get_message_ids, pop3_get_message_ids, NULL) POP3_ME_MAPPING(get_message_sizes, pop3_get_message_sizes, NULL) POP3_ME_MAPPING(get_message_header, pop3_get_message_header, NULL) POP3_ME_MAPPING(get_message_size, pop3_get_message_size, NULL) POP3_ME_MAPPING(get_message, pop3_get_message, NULL) POP3_ME_MAPPING(delete, pop3_delete_message, NULL) POP3_ME_MAPPING(undelete, pop3_undelete, NULL) {NULL, NULL, NULL} }; /* }}} */ /* {{{ pop3_module_entry */ zend_module_entry pop3_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "pop3", pop3_functions, PHP_MINIT(pop3), PHP_MSHUTDOWN(pop3), PHP_RINIT(pop3), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(pop3), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(pop3), #if ZEND_MODULE_API_NO >= 20010901 POP3_VERSION, #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_POP3 ZEND_GET_MODULE(pop3) #endif /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini PHP_INI_BEGIN() STD_PHP_INI_ENTRY("pop3.global_value", "42", PHP_INI_ALL, OnUpdateInt, global_value, zend_pop3_globals, pop3_globals) STD_PHP_INI_ENTRY("pop3.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pop3_globals, pop3_globals) PHP_INI_END() */ /* }}} */ /* {{{ php_pop3_init_globals */ /* Uncomment this function if you have INI entries static void php_pop3_init_globals(zend_pop3_globals *pop3_globals) { pop3_globals->global_value = 0; pop3_globals->global_string = NULL; } */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(pop3) { #ifdef ZEND_ENGINE_2 zend_class_entry _pop3_class_entry; INIT_CLASS_ENTRY(_pop3_class_entry, "pop3", pop3_class_functions); _pop3_class_entry.create_object = pop3_objects_new; pop3_class_entry = zend_register_internal_class(&_pop3_class_entry TSRMLS_CC); /* copy the standard object handlers to you handler table */ memcpy(&pop3_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); #endif /* ZEND_ENGINE_2 */ /* If you have INI entries, uncomment these lines ZEND_INIT_MODULE_GLOBALS(pop3, php_pop3_init_globals, NULL); REGISTER_INI_ENTRIES(); */ le_pop3_resource = zend_register_list_destructors_ex(pop3_resource_destructor, NULL, POP3_RESOURCE_NAME, module_number); return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(pop3) { /* uncomment this line if you have INI entries UNREGISTER_INI_ENTRIES(); */ return SUCCESS; } /* }}} */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(pop3) { return SUCCESS; } /* }}} */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(pop3) { return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(pop3) { php_info_print_table_start(); php_info_print_table_header(2, "pop3 support", "enabled"); php_info_print_table_header(2, "Extension version", POP3_VERSION " - $id$"); php_info_print_table_end(); /* Remove comments if you have entries in php.ini DISPLAY_INI_ENTRIES(); */ } /* }}} */ /* {{{ pop3_resource_destructor */ void pop3_resource_destructor (zend_rsrc_list_entry *rsrc TSRMLS_DC) { if (rsrc->ptr) { _pop3_send_command(rsrc->ptr, "QUIT", NULL TSRMLS_CC); php_stream_close(rsrc->ptr); rsrc->ptr = NULL; } } /* }}} */ /* {{{ proto resource pop3_open(string server_name, string user_name, string password) */ PHP_FUNCTION(pop3_open) { char *server_name, *user_name, *password, message[513]; int server_name_length, user_name_length, password_length; zend_bool auth_mode = 0; POP3_DECLARE_INIT_OBJECT(object) php_stream *stream; #ifndef ZEND_ENGINE_2 php_url *resource = NULL; #else char *errstr = NULL; #endif /* Parse parameters */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|b", &server_name, &server_name_length, &user_name, &user_name_length, &password, &password_length, &auth_mode) == FAILURE) { RETURN_FALSE; } #ifdef ZEND_ENGINE_2 stream = php_stream_xport_create (server_name, server_name_length, 0, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, NULL, &errstr, NULL); if (errstr) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errstr); efree(errstr); RETURN_FALSE; } #else resource = php_url_parse(server_name); if (resource == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid server name identifier %s.", server_name); RETURN_FALSE; } stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, NULL, 0); php_url_free(resource); #endif if (!stream) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to connect to server"); RETURN_FALSE; } if (!auth_mode) { /* Standard Auth */ if (_pop3_receive_response (stream, NULL TSRMLS_CC) == FAILURE) { php_stream_close(stream); RETURN_FALSE; } snprintf(message, sizeof(message) - 1, "USER %s", user_name); if (_pop3_send_command (stream, message, NULL TSRMLS_CC) == FAILURE) { php_stream_close(stream); RETURN_FALSE; } snprintf(message, sizeof(message) - 1, "PASS %s", password); if (_pop3_send_command(stream, message, NULL TSRMLS_CC) == FAILURE) { php_stream_close(stream); RETURN_FALSE; } } else { /* APOP */ char *s, *e, pop3_return_val[2048] = {0}; char md5str[33]; PHP_MD5_CTX context; unsigned char digest[16]; if (_pop3_receive_response(stream, pop3_return_val TSRMLS_CC) == FAILURE) { php_stream_close(stream); RETURN_FALSE; } if (!(s = strchr(pop3_return_val, '<'))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server does not support APOP authentication."); php_stream_close(stream); RETURN_FALSE; } memmove(pop3_return_val, s, strlen(s)); if (!(e = strchr(pop3_return_val, '>'))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server does not support APOP authentication."); php_stream_close(stream); RETURN_FALSE; } e++; memcpy(e, password, password_length); md5str[0] = '\0'; PHP_MD5Init(&context); PHP_MD5Update(&context, pop3_return_val, (e - pop3_return_val) + password_length); PHP_MD5Final(digest, &context); make_digest(md5str, digest); snprintf(message, sizeof(message) - 1, "APOP %s %s", user_name, md5str); if (_pop3_send_command(stream, message, NULL TSRMLS_CC) == FAILURE) { php_stream_close(stream); RETURN_FALSE; } } /* Create and return resource or object */ if (object) { POP3_REGISTER_OBJECT(object, stream); } else { ZEND_REGISTER_RESOURCE(return_value, stream, le_pop3_resource); } } /* }}} */ /* {{{ _pop3_get_stats() */ static void _pop3_get_stats(INTERNAL_FUNCTION_PARAMETERS, int mode) { POP3_DECLARE_INIT_OBJECT(object) zval *session_container; char pop3_return_val[2048] = {0}; php_stream *stream; int messages, size; /* Retrieve session data */ if (object) { POP3_FROM_OBJECT(stream, object); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &session_container) == FAILURE) { RETURN_FALSE; } POP3_FETCH_SESSION(stream, session_container); } if (_pop3_send_command(stream, "STAT", pop3_return_val TSRMLS_CC) == FAILURE) { RETURN_FALSE; } if (sscanf(pop3_return_val, "+OK %d %d", &messages, &size) < 2) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: Unable to perform STAT command"); RETURN_FALSE; } if (!mode) { /* Stat number of messages */ RETURN_LONG(messages); } else { /* return pop3 box size */ RETURN_LONG(size); } } /* }}} */ /* {{{ proto long pop3_get_message_count (resource session) */ PHP_FUNCTION(pop3_get_message_count) { _pop3_get_stats(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ /* {{{ proto long pop3_get_account_size (resource session) */ PHP_FUNCTION(pop3_get_account_size) { _pop3_get_stats(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ /* {{{ proto array pop3_get_message_sizes (resource session) */ PHP_FUNCTION(pop3_get_message_sizes) { POP3_DECLARE_INIT_OBJECT(object) zval *session_container; char pop3_return_val[2048]; php_stream *stream; int message, size; /* Retrieve session data */ if (object) { POP3_FROM_OBJECT(stream, object); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &session_container) == FAILURE) { RETURN_FALSE; } POP3_FETCH_SESSION(stream, session_container); } if (_pop3_send_command(stream, "LIST", NULL TSRMLS_CC) == FAILURE) { RETURN_FALSE; } /* Create return array */ array_init(return_value); do { zval *row; if (!php_stream_gets(stream, pop3_return_val, sizeof(pop3_return_val) - 1)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: Unable to retrieve message list"); zval_dtor(return_value); RETURN_FALSE; } if (pop3_return_val[0] == '.') { return; } if (sscanf (pop3_return_val, "%d %d", &message, &size) < 2) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: Unable to retrieve message list"); zval_dtor(return_value); RETURN_FALSE; } /* Create row array */ MAKE_STD_ZVAL(row); array_init(row); add_assoc_long(row, "message_id", message); add_assoc_long(row, "size", size); /* Insert row in return value */ add_index_zval(return_value, message, row); } while(1); } /* }}} */ /* {{{ proto array pop3_get_message_ids (resource session) */ PHP_FUNCTION(pop3_get_message_ids) { POP3_DECLARE_INIT_OBJECT(object) zval *session_container, *row; char pop3_return_val[2048], id[513]; php_stream *stream; int message; /* Retrieve session data */ if (object) { POP3_FROM_OBJECT(stream, object); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &session_container) == FAILURE) { RETURN_FALSE; } POP3_FETCH_SESSION(stream, session_container); } if (_pop3_send_command(stream, "UIDL", NULL TSRMLS_CC) == FAILURE) { RETURN_FALSE; } /* Create return array */ array_init(return_value); do { if (!php_stream_gets(stream, pop3_return_val, sizeof(pop3_return_val) - 1)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: Unable to retrieve message list"); zval_dtor(return_value); RETURN_FALSE; } if (pop3_return_val[0] == '.') { return; } if (sscanf(pop3_return_val, "%d %512s", &message, id) < 2) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: Unable to retrieve message list"); zval_dtor(return_value); RETURN_FALSE; } /* Create row array */ MAKE_STD_ZVAL(row); array_init(row); add_assoc_long(row, "message_id", message); add_assoc_string(row, "id", id, 1); /* Insert row in return value */ add_index_zval(return_value, message, row); } while(1); } /* }}} */ /* {{{ _pop3_fetch_message_part() */ static void _pop3_fetch_message_part(INTERNAL_FUNCTION_PARAMETERS, int mode) { POP3_DECLARE_INIT_OBJECT (object) zval *session_container; char pop3_return_val[2048] = {0}, *result, message[513]; php_stream *stream; int message_id, n_lines = 0, length, size; size_t fetch_len; /* Retrieve session data and other parameters */ if (object) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &message_id, &n_lines) == FAILURE) { RETURN_FALSE; } POP3_FROM_OBJECT(stream, object); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &session_container, &message_id, &n_lines) == FAILURE) { RETURN_FALSE; } POP3_FETCH_SESSION(stream, session_container); } switch (mode) { case PHP_POP3_HEADER: /* Retrieve message headers */ snprintf(message, sizeof(message) - 1, "TOP %d %d", message_id, 0); if (_pop3_send_command(stream, message, pop3_return_val TSRMLS_CC) == FAILURE) { RETURN_FALSE; } break; case PHP_POP3_MESSAGE: if (!n_lines) { /* Retrieve message */ snprintf(message, sizeof(message) - 1, "RETR %d", message_id); if (_pop3_send_command(stream, message, pop3_return_val TSRMLS_CC) == FAILURE) { RETURN_FALSE; } } else { /* Retrieve n_lines from the message */ snprintf(message, sizeof(message) - 1, "RETR %d %d", message_id, n_lines); if (_pop3_send_command(stream, message, pop3_return_val TSRMLS_CC) == FAILURE) { RETURN_FALSE; } } break; case PHP_POP3_DELETE: /* Delete message */ snprintf(message, sizeof(message) - 1, "DELE %d", message_id); if (_pop3_send_command(stream, message, pop3_return_val TSRMLS_CC) == FAILURE) { RETURN_FALSE; } RETURN_TRUE; case PHP_POP3_SIZE: /* get message size */ snprintf(message, sizeof(message) - 1, "LIST %d", message_id); if (_pop3_send_command(stream, message, pop3_return_val TSRMLS_CC) == FAILURE) { RETURN_FALSE; } { int tmp, len = 0; if (sscanf(pop3_return_val, "+OK %d %d", &tmp, &len) < 2) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: Unable to fetch message size."); RETURN_FALSE; } RETURN_LONG(len); } default: /* can't happen */ RETURN_FALSE; } size = 2048; result = emalloc(size); length = 0; do { if (!php_stream_get_line(stream, pop3_return_val, sizeof(pop3_return_val) - 1, &fetch_len)) { efree(result); php_error_docref(NULL TSRMLS_CC, E_WARNING, "POP3: I/O failure reading from server"); RETURN_FALSE; } if (fetch_len == 3 && !strcmp(pop3_return_val, ".\r\n")) { result[length] = '\0'; RETURN_STRINGL(result, length, 0); } if (length + fetch_len > size) { size += 2048; result = erealloc(result, size); } memcpy(result + length, pop3_return_val, fetch_len); length += fetch_len; } while (1); } /* }}} */ /* {{{ proto string pop3_get_message_header (resource session, int message_id) */ PHP_FUNCTION (pop3_get_message_header) { _pop3_fetch_message_part(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_POP3_HEADER); } /* }}} */ /* {{{ proto int pop3_get_message_size (resource session, int message_id) */ PHP_FUNCTION (pop3_get_message_size) { _pop3_fetch_message_part(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_POP3_SIZE); } /* }}} */ /* {{{ proto string pop3_get_message (resource session, int message_id, [int n_lines]) */ PHP_FUNCTION (pop3_get_message) { _pop3_fetch_message_part(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_POP3_MESSAGE); } /* }}} */ /* {{{ proto bool pop3_delete_message (resource session, int message_id) */ PHP_FUNCTION (pop3_delete_message) { _pop3_fetch_message_part(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_POP3_DELETE); } /* }}} */ /* {{{ proto bool pop3_undelete (resource session) */ PHP_FUNCTION (pop3_undelete) { POP3_DECLARE_INIT_OBJECT (object) zval *session_container; php_stream *stream; if (object) { if (ZEND_NUM_ARGS()) { WRONG_PARAM_COUNT; } POP3_FROM_OBJECT(stream, object); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &session_container) == FAILURE) { RETURN_FALSE; } POP3_FETCH_SESSION(stream, session_container); } if (_pop3_send_command(stream, "RSET", NULL TSRMLS_CC) == FAILURE) { RETURN_FALSE; } else { RETURN_TRUE; } } /* }}} */ /* {{{ proto bool pop3_close (resource session) */ PHP_FUNCTION (pop3_close) { zval *session_container; php_stream *stream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &session_container) == FAILURE) { RETURN_FALSE; } POP3_FETCH_SESSION(stream, session_container); zend_list_delete(Z_RESVAL_P(session_container)); RETURN_TRUE; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */