Back to index

php5  5.3.10
Classes | Defines | Enumerations | Functions | Variables
session.c File Reference
#include "php.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "php_ini.h"
#include "SAPI.h"
#include "php_session.h"
#include "ext/standard/md5.h"
#include "ext/standard/sha1.h"
#include "ext/standard/php_var.h"
#include "ext/date/php_date.h"
#include "ext/standard/php_lcg.h"
#include "ext/standard/url_scanner_ex.h"
#include "ext/standard/php_rand.h"
#include "ext/standard/info.h"
#include "ext/standard/php_smart_str.h"
#include "ext/standard/url.h"
#include "mod_files.h"
#include "mod_user.h"

Go to the source code of this file.

Classes

struct  php_session_cache_limiter_t

Defines

#define IF_SESSION_VARS()   if (PS(http_session_vars) && PS(http_session_vars)->type == IS_ARRAY)
#define SESSION_CHECK_ACTIVE_STATE
#define PS_BIN_NR_OF_BITS   8
#define PS_BIN_UNDEF   (1<<(PS_BIN_NR_OF_BITS-1))
#define PS_BIN_MAX   (PS_BIN_UNDEF-1)
#define PS_DELIMITER   '|'
#define PS_UNDEF_MARKER   '!'
#define MAX_SERIALIZERS   10
#define PREDEFINED_SERIALIZERS   2
#define MAX_MODULES   10
#define PREDEFINED_MODULES   2
#define CACHE_LIMITER(name)   _php_cache_limiter_##name
#define CACHE_LIMITER_FUNC(name)   static void CACHE_LIMITER(name)(TSRMLS_D)
#define CACHE_LIMITER_ENTRY(name)   { #name, CACHE_LIMITER(name) },
#define ADD_HEADER(a)   sapi_add_header(a, strlen(a), 1);
#define MAX_STR   512
#define LAST_MODIFIED   "Last-Modified: "
#define EXPIRES   "Expires: "
#define COOKIE_SET_COOKIE   "Set-Cookie: "
#define COOKIE_EXPIRES   "; expires="
#define COOKIE_PATH   "; path="
#define COOKIE_DOMAIN   "; domain="
#define COOKIE_SECURE   "; secure"
#define COOKIE_HTTPONLY   "; HttpOnly"
#define PPID2SID

Enumerations

enum  { PS_HASH_FUNC_MD5, PS_HASH_FUNC_SHA1, PS_HASH_FUNC_OTHER }

Functions

PHPAPI ZEND_DECLARE_MODULE_GLOBALS (ps)
static void php_rinit_session_globals (TSRMLS_D)
static void php_rshutdown_session_globals (TSRMLS_D)
static int php_session_destroy (TSRMLS_D)
PHPAPI void php_add_session_var (char *name, size_t namelen TSRMLS_DC)
PHPAPI void php_set_session_var (char *name, size_t namelen, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC)
PHPAPI int php_get_session_var (char *name, size_t namelen, zval ***state_var TSRMLS_DC)
static void php_session_track_init (TSRMLS_D)
static char * php_session_encode (int *newlen TSRMLS_DC)
static void php_session_decode (const char *val, int vallen TSRMLS_DC)
static char * bin_to_readable (char *in, size_t inlen, char *out, char nbits)
PHPAPI char * php_session_create_id (PS_CREATE_SID_ARGS)
static void php_session_initialize (TSRMLS_D)
static int migrate_global (HashTable *ht, HashPosition *pos TSRMLS_DC)
static void php_session_save_current_state (TSRMLS_D)
static PHP_INI_MH (OnUpdateSaveHandler)
static PHP_INI_MH (OnUpdateSerializer)
static PHP_INI_MH (OnUpdateTransSid)
static PHP_INI_MH (OnUpdateSaveDir)
static PHP_INI_MH (OnUpdateHashFunc)
 PS_SERIALIZER_ENCODE_FUNC (php_binary)
PHPAPI int php_session_register_serializer (const char *name, int(*encode)(PS_SERIALIZER_ENCODE_ARGS), int(*decode)(PS_SERIALIZER_DECODE_ARGS))
PHPAPI int php_session_register_module (ps_module *ptr)
static void strcpy_gmt (char *ubuf, time_t *when)
static void last_modified (TSRMLS_D)
 CACHE_LIMITER_FUNC (public)
 CACHE_LIMITER_FUNC (private_no_expire)
 CACHE_LIMITER_FUNC (private)
 CACHE_LIMITER_FUNC (nocache)
static int php_session_cache_limiter (TSRMLS_D)
static void php_session_send_cookie (TSRMLS_D)
PHPAPI ps_module_php_find_ps_module (char *name TSRMLS_DC)
PHPAPI const ps_serializer_php_find_ps_serializer (char *name TSRMLS_DC)
static void php_session_reset_id (TSRMLS_D)
PHPAPI void php_session_start (TSRMLS_D)
static void php_session_flush (TSRMLS_D)
PHPAPI void session_adapt_url (const char *url, size_t urllen, char **new, size_t *newlen TSRMLS_DC)
static PHP_FUNCTION (session_set_cookie_params)
static PHP_FUNCTION (session_get_cookie_params)
static PHP_FUNCTION (session_name)
static PHP_FUNCTION (session_module_name)
static PHP_FUNCTION (session_set_save_handler)
static PHP_FUNCTION (session_save_path)
static PHP_FUNCTION (session_id)
static PHP_FUNCTION (session_regenerate_id)
static PHP_FUNCTION (session_cache_limiter)
static PHP_FUNCTION (session_cache_expire)
static void php_register_var (zval **entry TSRMLS_DC)
static PHP_FUNCTION (session_encode)
static PHP_FUNCTION (session_decode)
static PHP_FUNCTION (session_start)
static PHP_FUNCTION (session_destroy)
static PHP_FUNCTION (session_unset)
static PHP_FUNCTION (session_write_close)
static PHP_FUNCTION (session_register)
static PHP_FUNCTION (session_unregister)
static PHP_FUNCTION (session_is_registered)
static PHP_RINIT_FUNCTION (session)
static PHP_RSHUTDOWN_FUNCTION (session)
static PHP_GINIT_FUNCTION (ps)
static PHP_MINIT_FUNCTION (session)
static PHP_MSHUTDOWN_FUNCTION (session)
static PHP_MINFO_FUNCTION (session)

Variables

static char hexconvtab [] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-"
static ps_moduleps_modules [MAX_MODULES+1]
static char * month_names []
static char * week_days []
static php_session_cache_limiter_t php_session_cache_limiters []
static const zend_function_entry session_functions []
static const zend_module_dep session_deps []
zend_module_entry session_module_entry

Define Documentation

#define ADD_HEADER (   a)    sapi_add_header(a, strlen(a), 1);

Definition at line 1071 of file session.c.

#define CACHE_LIMITER (   name)    _php_cache_limiter_##name

Definition at line 1068 of file session.c.

#define CACHE_LIMITER_ENTRY (   name)    { #name, CACHE_LIMITER(name) },

Definition at line 1070 of file session.c.

#define CACHE_LIMITER_FUNC (   name)    static void CACHE_LIMITER(name)(TSRMLS_D)

Definition at line 1069 of file session.c.

#define COOKIE_DOMAIN   "; domain="

Definition at line 1220 of file session.c.

#define COOKIE_EXPIRES   "; expires="

Definition at line 1218 of file session.c.

#define COOKIE_HTTPONLY   "; HttpOnly"

Definition at line 1222 of file session.c.

#define COOKIE_PATH   "; path="

Definition at line 1219 of file session.c.

#define COOKIE_SECURE   "; secure"

Definition at line 1221 of file session.c.

#define COOKIE_SET_COOKIE   "Set-Cookie: "

Definition at line 1217 of file session.c.

#define EXPIRES   "Expires: "

Definition at line 1126 of file session.c.

#define IF_SESSION_VARS ( )    if (PS(http_session_vars) && PS(http_session_vars)->type == IS_ARRAY)

Definition at line 65 of file session.c.

#define LAST_MODIFIED   "Last-Modified: "
#define MAX_MODULES   10

Definition at line 1035 of file session.c.

#define MAX_SERIALIZERS   10
#define MAX_STR   512

Definition at line 1072 of file session.c.

#define PPID2SID
Value:
convert_to_string((*ppid)); \
              PS(id) = estrndup(Z_STRVAL_PP(ppid), Z_STRLEN_PP(ppid))

Definition at line 1326 of file session.c.

#define PREDEFINED_MODULES   2

Definition at line 1036 of file session.c.

#define PREDEFINED_SERIALIZERS   2
#define PS_BIN_MAX   (PS_BIN_UNDEF-1)

Definition at line 826 of file session.c.

#define PS_BIN_NR_OF_BITS   8

Definition at line 824 of file session.c.

#define PS_BIN_UNDEF   (1<<(PS_BIN_NR_OF_BITS-1))

Definition at line 825 of file session.c.

#define PS_DELIMITER   '|'
#define PS_UNDEF_MARKER   '!'
Value:
if (PS(session_status) == php_session_active) {  \
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "A session is active. You cannot change the session module's ini settings at this time");       \
              return FAILURE;      \
       }

Definition at line 68 of file session.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
PS_HASH_FUNC_MD5 
PS_HASH_FUNC_SHA1 
PS_HASH_FUNC_OTHER 

Definition at line 300 of file session.c.


Function Documentation

PHPAPI ps_module* _php_find_ps_module ( char *name  TSRMLS_DC)

Definition at line 1295 of file session.c.

{
       ps_module *ret = NULL;
       ps_module **mod;
       int i;

       for (i = 0, mod = ps_modules; i < MAX_MODULES; i++, mod++) {
              if (*mod && !strcasecmp(name, (*mod)->s_name)) {
                     ret = *mod;
                     break;
              }
       }
       return ret;
}

Here is the caller graph for this function:

PHPAPI const ps_serializer* _php_find_ps_serializer ( char *name  TSRMLS_DC)

Definition at line 1311 of file session.c.

{
       const ps_serializer *ret = NULL;
       const ps_serializer *mod;

       for (mod = ps_serializers; mod->name; mod++) {
              if (!strcasecmp(name, mod->name)) {
                     ret = mod;
                     break;
              }
       }
       return ret;
}

Here is the caller graph for this function:

static char* bin_to_readable ( char *  in,
size_t  inlen,
char *  out,
char  nbits 
) [static]

Definition at line 307 of file session.c.

{
       unsigned char *p, *q;
       unsigned short w;
       int mask;
       int have;

       p = (unsigned char *) in;
       q = (unsigned char *)in + inlen;

       w = 0;
       have = 0;
       mask = (1 << nbits) - 1;

       while (1) {
              if (have < nbits) {
                     if (p < q) {
                            w |= *p++ << have;
                            have += 8;
                     } else {
                            /* consumed everything? */
                            if (have == 0) break;
                            /* No? We need a final round */
                            have = nbits;
                     }
              }

              /* consume nbits */
              *out++ = hexconvtab[w & mask];
              w >>= nbits;
              have -= nbits;
       }

       *out = '\0';
       return out;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1127 of file session.c.

{
       char buf[MAX_STR + 1];
       struct timeval tv;
       time_t now;

       gettimeofday(&tv, NULL);
       now = tv.tv_sec + PS(cache_expire) * 60;
       memcpy(buf, EXPIRES, sizeof(EXPIRES) - 1);
       strcpy_gmt(buf + sizeof(EXPIRES) - 1, &now);
       ADD_HEADER(buf);

       snprintf(buf, sizeof(buf) , "Cache-Control: public, max-age=%ld", PS(cache_expire) * 60); /* SAFE */
       ADD_HEADER(buf);

       last_modified(TSRMLS_C);
}

Here is the call graph for this function:

CACHE_LIMITER_FUNC ( private_no_expire  )

Definition at line 1146 of file session.c.

{
       char buf[MAX_STR + 1];

       snprintf(buf, sizeof(buf), "Cache-Control: private, max-age=%ld, pre-check=%ld", PS(cache_expire) * 60, PS(cache_expire) * 60); /* SAFE */
       ADD_HEADER(buf);

       last_modified(TSRMLS_C);
}

Here is the call graph for this function:

Definition at line 1157 of file session.c.

{
       ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
       CACHE_LIMITER(private_no_expire)(TSRMLS_C);
}
CACHE_LIMITER_FUNC ( nocache  )

Definition at line 1164 of file session.c.

{
       ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");

       /* For HTTP/1.1 conforming clients and the rest (MSIE 5) */
       ADD_HEADER("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");

       /* For HTTP/1.0 conforming clients */
       ADD_HEADER("Pragma: no-cache");
}
static void last_modified ( TSRMLS_D  ) [inline, static]

Definition at line 1106 of file session.c.

{
       const char *path;
       struct stat sb;
       char buf[MAX_STR + 1];

       path = SG(request_info).path_translated;
       if (path) {
              if (VCWD_STAT(path, &sb) == -1) {
                     return;
              }

#define LAST_MODIFIED "Last-Modified: "
              memcpy(buf, LAST_MODIFIED, sizeof(LAST_MODIFIED) - 1);
              strcpy_gmt(buf + sizeof(LAST_MODIFIED) - 1, &sb.st_mtime);
              ADD_HEADER(buf);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int migrate_global ( HashTable ht,
HashPosition *pos  TSRMLS_DC 
) [static]

Definition at line 544 of file session.c.

{
       char *str;
       uint str_len;
       ulong num_key;
       int n;
       zval **val;
       int ret = 0;

       n = zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key, 0, pos);

       switch (n) {
              case HASH_KEY_IS_STRING:
                     if (zend_hash_find(&EG(symbol_table), str, str_len, (void **) &val) == SUCCESS &&
                            val && Z_TYPE_PP(val) != IS_NULL
                     ) {
                            ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val, Z_REFCOUNT_PP(val) + 1, 1);
                            ret = 1;
                     }
                     break;
              case HASH_KEY_IS_LONG:
                     php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The session bug compatibility code will not "
                                   "try to locate the global variable $%lu due to its "
                                   "numeric nature", num_key);
                     break;
       }
       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void php_add_session_var ( char *  name,
size_t namelen  TSRMLS_DC 
)

Definition at line 125 of file session.c.

{
       zval **sym_track = NULL;

       IF_SESSION_VARS() {
              zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, (void *) &sym_track);
       } else {
              return;
       }

       /* Set up a proper reference between $_SESSION["x"] and $x. */

       if (PG(register_globals)) {
              zval **sym_global = NULL;

              if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void *) &sym_global) == SUCCESS) {
                     if ((Z_TYPE_PP(sym_global) == IS_ARRAY && Z_ARRVAL_PP(sym_global) == &EG(symbol_table)) || *sym_global == PS(http_session_vars)) {
                            return;
                     }
              }

              if (sym_global == NULL && sym_track == NULL) {
                     zval *empty_var;

                     ALLOC_INIT_ZVAL(empty_var); /* this sets refcount to 1 */
                     Z_SET_REFCOUNT_P(empty_var, 0); /* our module does not maintain a ref */
                     /* The next call will increase refcount by NR_OF_SYM_TABLES==2 */
                     zend_set_hash_symbol(empty_var, name, namelen, 1, 2, Z_ARRVAL_P(PS(http_session_vars)), &EG(symbol_table));
              } else if (sym_global == NULL) {
                     SEPARATE_ZVAL_IF_NOT_REF(sym_track);
                     zend_set_hash_symbol(*sym_track, name, namelen, 1, 1, &EG(symbol_table));
              } else if (sym_track == NULL) {
                     SEPARATE_ZVAL_IF_NOT_REF(sym_global);
                     zend_set_hash_symbol(*sym_global, name, namelen, 1, 1, Z_ARRVAL_P(PS(http_session_vars)));
              }
       } else {
              if (sym_track == NULL) {
                     zval *empty_var;

                     ALLOC_INIT_ZVAL(empty_var);
                     ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL_P(PS(http_session_vars)), name, namelen+1, empty_var, 1, 0);
              }
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_set_cookie_params  ) [static]

Definition at line 1536 of file session.c.

{
       zval **lifetime = NULL;
       char *path = NULL, *domain = NULL;
       int path_len, domain_len, argc = ZEND_NUM_ARGS();
       zend_bool secure = 0, httponly = 0;

       if (!PS(use_cookies) ||
              zend_parse_parameters(argc TSRMLS_CC, "Z|ssbb", &lifetime, &path, &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
              return;
       }

       convert_to_string_ex(lifetime);

       zend_alter_ini_entry("session.cookie_lifetime", sizeof("session.cookie_lifetime"), Z_STRVAL_PP(lifetime), Z_STRLEN_PP(lifetime), PHP_INI_USER, PHP_INI_STAGE_RUNTIME);

       if (path) {
              zend_alter_ini_entry("session.cookie_path", sizeof("session.cookie_path"), path, path_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
       if (domain) {
              zend_alter_ini_entry("session.cookie_domain", sizeof("session.cookie_domain"), domain, domain_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }

       if (argc > 3) {
              zend_alter_ini_entry("session.cookie_secure", sizeof("session.cookie_secure"), secure ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
       if (argc > 4) {
              zend_alter_ini_entry("session.cookie_httponly", sizeof("session.cookie_httponly"), httponly ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_get_cookie_params  ) [static]

Definition at line 1570 of file session.c.

{
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       array_init(return_value);

       add_assoc_long(return_value, "lifetime", PS(cookie_lifetime));
       add_assoc_string(return_value, "path", PS(cookie_path), 1);
       add_assoc_string(return_value, "domain", PS(cookie_domain), 1);
       add_assoc_bool(return_value, "secure", PS(cookie_secure));
       add_assoc_bool(return_value, "httponly", PS(cookie_httponly));
}
static PHP_FUNCTION ( session_name  ) [static]

Definition at line 1588 of file session.c.

{
       char *name = NULL;
       int name_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
              return;
       }

       RETVAL_STRING(PS(session_name), 1);

       if (name) {
              zend_alter_ini_entry("session.name", sizeof("session.name"), name, name_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_module_name  ) [static]

Definition at line 1607 of file session.c.

{
       char *name = NULL;
       int name_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
              return;
       }

       /* Set return_value to current module name */
       if (PS(mod) && PS(mod)->s_name) {
              RETVAL_STRING(safe_estrdup(PS(mod)->s_name), 0);
       } else {
              RETVAL_EMPTY_STRING();
       }

       if (name) {
              if (!_php_find_ps_module(name TSRMLS_CC)) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot find named PHP session module (%s)", name);

                     zval_dtor(return_value);
                     RETURN_FALSE;
              }
              if (PS(mod_data)) {
                     PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
              }
              PS(mod_data) = NULL;

              zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), name, name_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_set_save_handler  ) [static]

Definition at line 1642 of file session.c.

{
       zval ***args = NULL;
       int i, num_args, argc = ZEND_NUM_ARGS();
       char *name;

       if (PS(session_status) != php_session_none) {
              RETURN_FALSE;
       }

       if (argc != 6) {
              WRONG_PARAM_COUNT;
       }

       if (zend_parse_parameters(argc TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
              return;
       }

       for (i = 0; i < 6; i++) {
              if (!zend_is_callable(*args[i], 0, &name TSRMLS_CC)) {
                     efree(args);
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
                     efree(name);
                     RETURN_FALSE;
              }
              efree(name);
       }

       zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);

       for (i = 0; i < 6; i++) {
              if (PS(mod_user_names).names[i] != NULL) {
                     zval_ptr_dtor(&PS(mod_user_names).names[i]);
              }
              Z_ADDREF_PP(args[i]);
              PS(mod_user_names).names[i] = *args[i];
       }

       efree(args);
       RETURN_TRUE;
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_save_path  ) [static]

Definition at line 1687 of file session.c.

{
       char *name = NULL;
       int name_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
              return;
       }

       RETVAL_STRING(PS(save_path), 1);

       if (name) {
              if (memchr(name, '\0', name_len) != NULL) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "The save_path cannot contain NULL characters");
                     zval_dtor(return_value);
                     RETURN_FALSE;
              }
              zend_alter_ini_entry("session.save_path", sizeof("session.save_path"), name, name_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_id  ) [static]

Definition at line 1711 of file session.c.

{
       char *name = NULL;
       int name_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
              return;
       }

       if (PS(id)) {
              RETVAL_STRING(PS(id), 1);
       } else {
              RETVAL_EMPTY_STRING();
       }

       if (name) {
              if (PS(id)) {
                     efree(PS(id));
              }
              PS(id) = estrndup(name, name_len);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_regenerate_id  ) [static]

Definition at line 1737 of file session.c.

{
       zend_bool del_ses = 0;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
              return;
       }

       if (SG(headers_sent) && PS(use_cookies)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent");
              RETURN_FALSE;
       }

       if (PS(session_status) == php_session_active) {
              if (PS(id)) {
                     if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
                            RETURN_FALSE;
                     }
                     efree(PS(id));
                     PS(id) = NULL;
              }

              PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);

              PS(send_cookie) = 1;
              php_session_reset_id(TSRMLS_C);

              RETURN_TRUE;
       }
       RETURN_FALSE;
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_cache_limiter  ) [static]

Definition at line 1773 of file session.c.

{
       char *limiter = NULL;
       int limiter_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &limiter, &limiter_len) == FAILURE) {
              return;
       }

       RETVAL_STRING(PS(cache_limiter), 1);

       if (limiter) {
              zend_alter_ini_entry("session.cache_limiter", sizeof("session.cache_limiter"), limiter, limiter_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_cache_expire  ) [static]

Definition at line 1792 of file session.c.

{
       zval **expires = NULL;
       int argc = ZEND_NUM_ARGS();

       if (zend_parse_parameters(argc TSRMLS_CC, "|Z", &expires) == FAILURE) {
              return;
       }

       RETVAL_LONG(PS(cache_expire));

       if (argc == 1) {
              convert_to_string_ex(expires);
              zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(expires), Z_STRLEN_PP(expires), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_encode  ) [static]

Definition at line 1843 of file session.c.

{
       int len;
       char *enc;

       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       enc = php_session_encode(&len TSRMLS_CC);
       if (enc == NULL) {
              RETURN_FALSE;
       }

       RETVAL_STRINGL(enc, len, 0);
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_decode  ) [static]

Definition at line 1863 of file session.c.

{
       char *str;
       int str_len;

       if (PS(session_status) == php_session_none) {
              RETURN_FALSE;
       }

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
              return;
       }

       php_session_decode(str, str_len TSRMLS_CC);

       RETURN_TRUE;
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_start  ) [static]

Definition at line 1884 of file session.c.

{
       /* skipping check for non-zero args for performance reasons here ?*/
       php_session_start(TSRMLS_C);

       if (PS(session_status) != php_session_active) {
              RETURN_FALSE;
       }
       RETURN_TRUE;
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_destroy  ) [static]

Definition at line 1898 of file session.c.

Here is the call graph for this function:

static PHP_FUNCTION ( session_unset  ) [static]

Definition at line 1910 of file session.c.

{
       if (PS(session_status) == php_session_none) {
              RETURN_FALSE;
       }

       IF_SESSION_VARS() {
              HashTable *ht_sess_var;

              SEPARATE_ZVAL_IF_NOT_REF(&PS(http_session_vars));
              ht_sess_var = Z_ARRVAL_P(PS(http_session_vars));

              if (PG(register_globals)) {
                     uint str_len;
                     char *str;
                     ulong num_key;
                     HashPosition pos;

                     zend_hash_internal_pointer_reset_ex(ht_sess_var, &pos);

                     while (zend_hash_get_current_key_ex(ht_sess_var, &str, &str_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING) {
                            zend_delete_global_variable(str, str_len - 1 TSRMLS_CC);
                            zend_hash_move_forward_ex(ht_sess_var, &pos);
                     }
              }

              /* Clean $_SESSION. */
              zend_hash_clean(ht_sess_var);
       }
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_write_close  ) [static]

Definition at line 1944 of file session.c.

Here is the call graph for this function:

static PHP_FUNCTION ( session_register  ) [static]

Definition at line 1952 of file session.c.

{
       zval ***args = NULL;
       int num_args, i;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
              return;
       }

       if (PS(session_status) == php_session_none || PS(session_status) == php_session_disabled) {
              php_session_start(TSRMLS_C);
       }

       if (PS(session_status) == php_session_disabled) {
              if (args) {
                     efree(args);
              }
              RETURN_FALSE;
       }

       for (i = 0; i < num_args; i++) {
              if (Z_TYPE_PP(args[i]) == IS_ARRAY) {
                     SEPARATE_ZVAL(args[i]);
              }
              php_register_var(args[i] TSRMLS_CC);
       }

       if (args) {
              efree(args);
       }

       RETURN_TRUE;
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_unregister  ) [static]

Definition at line 1989 of file session.c.

{
       char *p_name;
       int p_name_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &p_name, &p_name_len) == FAILURE) {
              return;
       }

       IF_SESSION_VARS() {
              SEPARATE_ZVAL_IF_NOT_REF(&PS(http_session_vars));
              PS_DEL_VARL(p_name, p_name_len);
       }

       RETURN_TRUE;
}

Here is the call graph for this function:

static PHP_FUNCTION ( session_is_registered  ) [static]

Definition at line 2009 of file session.c.

{
       zval *p_var;
       char *p_name;
       int p_name_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &p_name, &p_name_len) == FAILURE) {
              return;
       }

       if (PS(session_status) == php_session_none) {
              RETURN_FALSE;
       }

       IF_SESSION_VARS() {
              if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), p_name, p_name_len+1, (void **)&p_var) == SUCCESS) {
                     RETURN_TRUE;
              }
       }
       RETURN_FALSE;
}

Here is the call graph for this function:

PHPAPI int php_get_session_var ( char *  name,
size_t  namelen,
zval ***state_var  TSRMLS_DC 
)

Definition at line 210 of file session.c.

{
       int ret = FAILURE;

       IF_SESSION_VARS() {
              ret = zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, (void **) state_var);

              /* If register_globals is enabled, and
               * if there is an entry for the slot in $_SESSION, and
               * if that entry is still set to NULL, and
               * if the global var exists, then
               * we prefer the same key in the global sym table. */

              if (PG(register_globals) && ret == SUCCESS && Z_TYPE_PP(*state_var) == IS_NULL) {
                     zval **tmp;

                     if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
                            *state_var = tmp;
                     }
              }
       }
       return ret;
}

Here is the call graph for this function:

static PHP_GINIT_FUNCTION ( ps  ) [static]

Definition at line 2185 of file session.c.

{
       int i;

       ps_globals->save_path = NULL;
       ps_globals->session_name = NULL;
       ps_globals->id = NULL;
       ps_globals->mod = NULL;
       ps_globals->serializer = NULL;
       ps_globals->mod_data = NULL;
       ps_globals->session_status = php_session_none;
       for (i = 0; i < 6; i++) {
              ps_globals->mod_user_names.names[i] = NULL;
       }
       ps_globals->http_session_vars = NULL;
}
static PHP_INI_MH ( OnUpdateSaveHandler  ) [static]

Definition at line 633 of file session.c.

{
       ps_module *tmp;
       SESSION_CHECK_ACTIVE_STATE;

       tmp = _php_find_ps_module(new_value TSRMLS_CC);

       if (PG(modules_activated) && !tmp) {
              int err_type;

              if (stage == ZEND_INI_STAGE_RUNTIME) {
                     err_type = E_WARNING;
              } else {
                     err_type = E_ERROR;
              }

              /* Do not output error when restoring ini options. */
              if (stage != ZEND_INI_STAGE_DEACTIVATE) {
                     php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find save handler '%s'", new_value);
              }
              return FAILURE;
       }
       PS(mod) = tmp;

       return SUCCESS;
}

Here is the call graph for this function:

static PHP_INI_MH ( OnUpdateSerializer  ) [static]

Definition at line 661 of file session.c.

{
       const ps_serializer *tmp;
       SESSION_CHECK_ACTIVE_STATE;

       tmp = _php_find_ps_serializer(new_value TSRMLS_CC);

       if (PG(modules_activated) && !tmp) {
              int err_type;

              if (stage == ZEND_INI_STAGE_RUNTIME) {
                     err_type = E_WARNING;
              } else {
                     err_type = E_ERROR;
              }

              /* Do not output error when restoring ini options. */
              if (stage != ZEND_INI_STAGE_DEACTIVATE) {
                     php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find serialization handler '%s'", new_value);
              }
              return FAILURE;
       }
       PS(serializer) = tmp;

       return SUCCESS;
}

Here is the call graph for this function:

static PHP_INI_MH ( OnUpdateTransSid  ) [static]

Definition at line 689 of file session.c.

{
       SESSION_CHECK_ACTIVE_STATE;

       if (!strncasecmp(new_value, "on", sizeof("on"))) {
              PS(use_trans_sid) = (zend_bool) 1;
       } else {
              PS(use_trans_sid) = (zend_bool) atoi(new_value);
       }

       return SUCCESS;
}
static PHP_INI_MH ( OnUpdateSaveDir  ) [static]

Definition at line 703 of file session.c.

{
       /* Only do the safemode/open_basedir check at runtime */
       if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) {
              char *p;

              if (memchr(new_value, '\0', new_value_length) != NULL) {
                     return FAILURE;
              }

              /* we do not use zend_memrchr() since path can contain ; itself */
              if ((p = strchr(new_value, ';'))) {
                     char *p2;
                     p++;
                     if ((p2 = strchr(p, ';'))) {
                            p = p2 + 1;
                     }
              } else {
                     p = new_value;
              }

              if (PG(safe_mode) && *p && (!php_checkuid(p, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
                     return FAILURE;
              }

              if (PG(open_basedir) && *p && php_check_open_basedir(p TSRMLS_CC)) {
                     return FAILURE;
              }
       }

       OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
       return SUCCESS;
}

Here is the call graph for this function:

static PHP_INI_MH ( OnUpdateHashFunc  ) [static]

Definition at line 738 of file session.c.

{
       long val;
       char *endptr = NULL;

#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
       PS(hash_ops) = NULL;
#endif

       val = strtol(new_value, &endptr, 10);
       if (endptr && (*endptr == '\0')) {
              /* Numeric value */
              PS(hash_func) = val ? 1 : 0;

              return SUCCESS;
       }

       if (new_value_length == (sizeof("md5") - 1) &&
              strncasecmp(new_value, "md5", sizeof("md5") - 1) == 0) {
              PS(hash_func) = PS_HASH_FUNC_MD5;

              return SUCCESS;
       }

       if (new_value_length == (sizeof("sha1") - 1) &&
              strncasecmp(new_value, "sha1", sizeof("sha1") - 1) == 0) {
              PS(hash_func) = PS_HASH_FUNC_SHA1;

              return SUCCESS;
       }

#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH) /* {{{ */
{
       php_hash_ops *ops = (php_hash_ops*)php_hash_fetch_ops(new_value, new_value_length);

       if (ops) {
              PS(hash_func) = PS_HASH_FUNC_OTHER;
              PS(hash_ops) = ops;

              return SUCCESS;
       }
}
#endif /* HAVE_HASH_EXT }}} */

       return FAILURE;
}

Here is the call graph for this function:

static PHP_MINFO_FUNCTION ( session  ) [static]

Definition at line 2234 of file session.c.

{
       ps_module **mod;
       ps_serializer *ser;
       smart_str save_handlers = {0};
       smart_str ser_handlers = {0};
       int i;

       /* Get save handlers */
       for (i = 0, mod = ps_modules; i < MAX_MODULES; i++, mod++) {
              if (*mod && (*mod)->s_name) {
                     smart_str_appends(&save_handlers, (*mod)->s_name);
                     smart_str_appendc(&save_handlers, ' ');
              }
       }

       /* Get serializer handlers */
       for (i = 0, ser = ps_serializers; i < MAX_SERIALIZERS; i++, ser++) {
              if (ser && ser->name) {
                     smart_str_appends(&ser_handlers, ser->name);
                     smart_str_appendc(&ser_handlers, ' ');
              }
       }

       php_info_print_table_start();
       php_info_print_table_row(2, "Session Support", "enabled" );

       if (save_handlers.c) {
              smart_str_0(&save_handlers);
              php_info_print_table_row(2, "Registered save handlers", save_handlers.c);
              smart_str_free(&save_handlers);
       } else {
              php_info_print_table_row(2, "Registered save handlers", "none");
       }

       if (ser_handlers.c) {
              smart_str_0(&ser_handlers);
              php_info_print_table_row(2, "Registered serializer handlers", ser_handlers.c);
              smart_str_free(&ser_handlers);
       } else {
              php_info_print_table_row(2, "Registered serializer handlers", "none");
       }

       php_info_print_table_end();

       DISPLAY_INI_ENTRIES();
}

Here is the call graph for this function:

static PHP_MINIT_FUNCTION ( session  ) [static]

Definition at line 2203 of file session.c.

{
       zend_register_auto_global("_SESSION", sizeof("_SESSION")-1, NULL TSRMLS_CC);

       PS(module_number) = module_number; /* if we really need this var we need to init it in zts mode as well! */

       PS(session_status) = php_session_none;
       REGISTER_INI_ENTRIES();

#ifdef HAVE_LIBMM
       PHP_MINIT(ps_mm) (INIT_FUNC_ARGS_PASSTHRU);
#endif
       return SUCCESS;
}

Here is the call graph for this function:

static PHP_MSHUTDOWN_FUNCTION ( session  ) [static]

Definition at line 2219 of file session.c.

{
       UNREGISTER_INI_ENTRIES();

#ifdef HAVE_LIBMM
       PHP_MSHUTDOWN(ps_mm) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
#endif

       ps_serializers[PREDEFINED_SERIALIZERS].name = NULL;
       memset(&ps_modules[PREDEFINED_MODULES], 0, (MAX_MODULES-PREDEFINED_MODULES)*sizeof(ps_module *));

       return SUCCESS;
}
static void php_register_var ( zval **entry  TSRMLS_DC) [static]

Definition at line 1811 of file session.c.

{
       zval **value;

       if (Z_TYPE_PP(entry) == IS_ARRAY) {
              if (Z_ARRVAL_PP(entry)->nApplyCount > 1) {
                     return;
              }

              zend_hash_internal_pointer_reset(Z_ARRVAL_PP(entry));
              Z_ARRVAL_PP(entry)->nApplyCount++;

              while (zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void**)&value) == SUCCESS) {
                     php_register_var(value TSRMLS_CC);
                     zend_hash_move_forward(Z_ARRVAL_PP(entry));
              }

              Z_ARRVAL_PP(entry)->nApplyCount--;
       } else {
              convert_to_string_ex(entry);

              if ((strcmp(Z_STRVAL_PP(entry), "HTTP_SESSION_VARS") != 0) &&
                     (strcmp(Z_STRVAL_PP(entry), "_SESSION") != 0)
              ) {
                     PS_ADD_VARL(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
              }
       }
}

Here is the caller graph for this function:

static PHP_RINIT_FUNCTION ( session  ) [static]

Definition at line 2130 of file session.c.

{
       php_rinit_session_globals(TSRMLS_C);

       if (PS(mod) == NULL) {
              char *value;

              value = zend_ini_string("session.save_handler", sizeof("session.save_handler"), 0);
              if (value) {
                     PS(mod) = _php_find_ps_module(value TSRMLS_CC);
              }
       }

       if (PS(serializer) == NULL) {
              char *value;

              value = zend_ini_string("session.serialize_handler", sizeof("session.serialize_handler"), 0);
              if (value) {
                     PS(serializer) = _php_find_ps_serializer(value TSRMLS_CC);
              }
       }

       if (PS(mod) == NULL || PS(serializer) == NULL) {
              /* current status is unusable */
              PS(session_status) = php_session_disabled;
              return SUCCESS;
       }

       if (PS(auto_start)) {
              php_session_start(TSRMLS_C);
       }

       return SUCCESS;
}

Here is the call graph for this function:

static void php_rinit_session_globals ( TSRMLS_D  ) [inline, static]

Definition at line 75 of file session.c.

{
       PS(id) = NULL;
       PS(session_status) = php_session_none;
       PS(mod_data) = NULL;
       /* Do NOT init PS(mod_user_names) here! */
       PS(http_session_vars) = NULL;
}

Here is the caller graph for this function:

static PHP_RSHUTDOWN_FUNCTION ( session  ) [static]

Definition at line 2166 of file session.c.

{
       int i;

       php_session_flush(TSRMLS_C);
       php_rshutdown_session_globals(TSRMLS_C);

       /* this should NOT be done in php_rshutdown_session_globals() */
       for (i = 0; i < 6; i++) {
              if (PS(mod_user_names).names[i] != NULL) {
                     zval_ptr_dtor(&PS(mod_user_names).names[i]);
                     PS(mod_user_names).names[i] = NULL;
              }
       }

       return SUCCESS;
}

Here is the call graph for this function:

static void php_rshutdown_session_globals ( TSRMLS_D  ) [inline, static]

Definition at line 86 of file session.c.

{
       if (PS(http_session_vars)) {
              zval_ptr_dtor(&PS(http_session_vars));
              PS(http_session_vars) = NULL;
       }
       /* Do NOT destroy PS(mod_user_names) here! */
       if (PS(mod_data)) {
              zend_try {
                     PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
              } zend_end_try();
       }
       if (PS(id)) {
              efree(PS(id));
       }
}

Here is the caller graph for this function:

static int php_session_cache_limiter ( TSRMLS_D  ) [static]

Definition at line 1184 of file session.c.

{
       php_session_cache_limiter_t *lim;

       if (PS(cache_limiter)[0] == '\0') return 0;

       if (SG(headers_sent)) {
              char *output_start_filename = php_get_output_start_filename(TSRMLS_C);
              int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);

              if (output_start_filename) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno);
              } else {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");
              }
              return -2;
       }

       for (lim = php_session_cache_limiters; lim->name; lim++) {
              if (!strcasecmp(lim->name, PS(cache_limiter))) {
                     lim->func(TSRMLS_C);
                     return 0;
              }
       }

       return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 345 of file session.c.

{
       PHP_MD5_CTX md5_context;
       PHP_SHA1_CTX sha1_context;
#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
       void *hash_context;
#endif
       unsigned char *digest;
       int digest_len;
       int j;
       char *buf, *outid;
       struct timeval tv;
       zval **array;
       zval **token;
       char *remote_addr = NULL;

       gettimeofday(&tv, NULL);

       if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
              Z_TYPE_PP(array) == IS_ARRAY &&
              zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS
       ) {
              remote_addr = Z_STRVAL_PP(token);
       }

       /* maximum 15+19+19+10 bytes */
       spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);

       switch (PS(hash_func)) {
              case PS_HASH_FUNC_MD5:
                     PHP_MD5Init(&md5_context);
                     PHP_MD5Update(&md5_context, (unsigned char *) buf, strlen(buf));
                     digest_len = 16;
                     break;
              case PS_HASH_FUNC_SHA1:
                     PHP_SHA1Init(&sha1_context);
                     PHP_SHA1Update(&sha1_context, (unsigned char *) buf, strlen(buf));
                     digest_len = 20;
                     break;
#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
              case PS_HASH_FUNC_OTHER:
                     if (!PS(hash_ops)) {
                            php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid session hash function");
                            efree(buf);
                            return NULL;
                     }

                     hash_context = emalloc(PS(hash_ops)->context_size);
                     PS(hash_ops)->hash_init(hash_context);
                     PS(hash_ops)->hash_update(hash_context, (unsigned char *) buf, strlen(buf));
                     digest_len = PS(hash_ops)->digest_size;
                     break;
#endif /* HAVE_HASH_EXT */
              default:
                     php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid session hash function");
                     efree(buf);
                     return NULL;
       }
       efree(buf);

       if (PS(entropy_length) > 0) {
#ifdef PHP_WIN32
              unsigned char rbuf[2048];
              size_t toread = PS(entropy_length);

              if (php_win32_get_random_bytes(rbuf, (size_t) toread) == SUCCESS){

                     switch (PS(hash_func)) {
                            case PS_HASH_FUNC_MD5:
                                   PHP_MD5Update(&md5_context, rbuf, toread);
                                   break;
                            case PS_HASH_FUNC_SHA1:
                                   PHP_SHA1Update(&sha1_context, rbuf, toread);
                                   break;
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
                            case PS_HASH_FUNC_OTHER:
                                   PS(hash_ops)->hash_update(hash_context, rbuf, toread);
                                   break;
# endif /* HAVE_HASH_EXT */
                     }
              }
#else
              int fd;

              fd = VCWD_OPEN(PS(entropy_file), O_RDONLY);
              if (fd >= 0) {
                     unsigned char rbuf[2048];
                     int n;
                     int to_read = PS(entropy_length);

                     while (to_read > 0) {
                            n = read(fd, rbuf, MIN(to_read, sizeof(rbuf)));
                            if (n <= 0) break;

                            switch (PS(hash_func)) {
                                   case PS_HASH_FUNC_MD5:
                                          PHP_MD5Update(&md5_context, rbuf, n);
                                          break;
                                   case PS_HASH_FUNC_SHA1:
                                          PHP_SHA1Update(&sha1_context, rbuf, n);
                                          break;
#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
                                   case PS_HASH_FUNC_OTHER:
                                          PS(hash_ops)->hash_update(hash_context, rbuf, n);
                                          break;
#endif /* HAVE_HASH_EXT */
                            }
                            to_read -= n;
                     }
                     close(fd);
              }
#endif
       }

       digest = emalloc(digest_len + 1);
       switch (PS(hash_func)) {
              case PS_HASH_FUNC_MD5:
                     PHP_MD5Final(digest, &md5_context);
                     break;
              case PS_HASH_FUNC_SHA1:
                     PHP_SHA1Final(digest, &sha1_context);
                     break;
#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
              case PS_HASH_FUNC_OTHER:
                     PS(hash_ops)->hash_final(digest, hash_context);
                     efree(hash_context);
                     break;
#endif /* HAVE_HASH_EXT */
       }

       if (PS(hash_bits_per_character) < 4
                     || PS(hash_bits_per_character) > 6) {
              PS(hash_bits_per_character) = 4;

              php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ini setting hash_bits_per_character is out of range (should be 4, 5, or 6) - using 4 for now");
       }
       
       outid = emalloc((size_t)((digest_len + 2) * ((8.0f / PS(hash_bits_per_character)) + 0.5)));
       j = (int) (bin_to_readable((char *)digest, digest_len, outid, (char)PS(hash_bits_per_character)) - outid);
       efree(digest);

       if (newlen) {
              *newlen = j;
       }

       return outid;
}

Here is the call graph for this function:

static void php_session_decode ( const char *  val,
int vallen  TSRMLS_DC 
) [static]

Definition at line 279 of file session.c.

{
       if (!PS(serializer)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object");
              return;
       }
       if (PS(serializer)->decode(val, vallen TSRMLS_CC) == FAILURE) {
              php_session_destroy(TSRMLS_C);
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to decode session object. Session has been destroyed");
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int php_session_destroy ( TSRMLS_D  ) [static]

Definition at line 104 of file session.c.

{
       int retval = SUCCESS;

       if (PS(session_status) != php_session_active) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to destroy uninitialized session");
              return FAILURE;
       }

       if (PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
              retval = FAILURE;
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
       }

       php_rshutdown_session_globals(TSRMLS_C);
       php_rinit_session_globals(TSRMLS_C);

       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* php_session_encode ( int *newlen  TSRMLS_DC) [static]

Definition at line 261 of file session.c.

{
       char *ret = NULL;

       IF_SESSION_VARS() {
              if (!PS(serializer)) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown session.serialize_handler. Failed to encode session object");
                     ret = NULL;
              } else if (PS(serializer)->encode(&ret, newlen TSRMLS_CC) == FAILURE) {
                     ret = NULL;
              }
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode non-existent session");
       }
       return ret;
}

Here is the caller graph for this function:

static void php_session_flush ( TSRMLS_D  ) [static]

Definition at line 1511 of file session.c.

{
       if (PS(session_status) == php_session_active) {
              PS(session_status) = php_session_none;
              zend_try {
                     php_session_save_current_state(TSRMLS_C);
              } zend_end_try();
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void php_session_initialize ( TSRMLS_D  ) [static]

Definition at line 494 of file session.c.

{
       char *val;
       int vallen;

       /* check session name for invalid characters */
       if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {
              efree(PS(id));
              PS(id) = NULL;
       }

       if (!PS(mod)) {
              php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session");
              return;
       }

       /* Open session handler first */
       if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name) TSRMLS_CC) == FAILURE) {
              php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to initialize storage module: %s (path: %s)", PS(mod)->s_name, PS(save_path));
              return;
       }

       /* If there is no ID, use session module to create one */
       if (!PS(id)) {
new_session:
              PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
              if (PS(use_cookies)) {
                     PS(send_cookie) = 1;
              }
       }

       /* Read data */
       /* Question: if you create a SID here, should you also try to read data?
        * I'm not sure, but while not doing so will remove one session operation
        * it could prove usefull for those sites which wish to have "default"
        * session information. */
       php_session_track_init(TSRMLS_C);
       PS(invalid_session_id) = 0;
       if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {
              php_session_decode(val, vallen TSRMLS_CC);
              efree(val);
       } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */
              PS(invalid_session_id) = 0;
              efree(PS(id));
              PS(id) = NULL;
              goto new_session;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1043 of file session.c.

{
       int ret = -1;
       int i;

       for (i = 0; i < MAX_MODULES; i++) {
              if (!ps_modules[i]) {
                     ps_modules[i] = ptr;
                     ret = 0;
                     break;
              }
       }
       return ret;
}

Here is the caller graph for this function:

Definition at line 1012 of file session.c.

{
       int ret = -1;
       int i;

       for (i = 0; i < MAX_SERIALIZERS; i++) {
              if (ps_serializers[i].name == NULL) {
                     ps_serializers[i].name = name;
                     ps_serializers[i].encode = encode;
                     ps_serializers[i].decode = decode;
                     ps_serializers[i + 1].name = NULL;
                     ret = 0;
                     break;
              }
       }
       return ret;
}
static void php_session_reset_id ( TSRMLS_D  ) [static]

Definition at line 1330 of file session.c.

{
       int module_number = PS(module_number);

       if (PS(use_cookies) && PS(send_cookie)) {
              php_session_send_cookie(TSRMLS_C);
              PS(send_cookie) = 0;
       }

       /* if the SID constant exists, destroy it. */
       zend_hash_del(EG(zend_constants), "sid", sizeof("sid"));

       if (PS(define_sid)) {
              smart_str var = {0};

              smart_str_appends(&var, PS(session_name));
              smart_str_appendc(&var, '=');
              smart_str_appends(&var, PS(id));
              smart_str_0(&var);
              REGISTER_STRINGL_CONSTANT("SID", var.c, var.len, 0);
       } else {
              REGISTER_STRINGL_CONSTANT("SID", STR_EMPTY_ALLOC(), 0, 0);
       }

       if (PS(apply_trans_sid)) {
              php_url_scanner_reset_vars(TSRMLS_C);
              php_url_scanner_add_var(PS(session_name), strlen(PS(session_name)), PS(id), strlen(PS(id)), 1 TSRMLS_CC);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void php_session_save_current_state ( TSRMLS_D  ) [static]

Definition at line 574 of file session.c.

{
       int ret = FAILURE;

       IF_SESSION_VARS() {
              if (PS(bug_compat) && !PG(register_globals)) {
                     HashTable *ht = Z_ARRVAL_P(PS(http_session_vars));
                     HashPosition pos;
                     zval **val;
                     int do_warn = 0;

                     zend_hash_internal_pointer_reset_ex(ht, &pos);

                     while (zend_hash_get_current_data_ex(ht, (void **) &val, &pos) != FAILURE) {
                            if (Z_TYPE_PP(val) == IS_NULL) {
                                   if (migrate_global(ht, &pos TSRMLS_CC)) {
                                          do_warn = 1;
                                   }
                            }
                            zend_hash_move_forward_ex(ht, &pos);
                     }

                     if (do_warn && PS(bug_compat_warn)) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Your script possibly relies on a session side-effect which existed until PHP 4.2.3. Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled. You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively");
                     }
              }

              if (PS(mod_data)) {
                     char *val;
                     int vallen;

                     val = php_session_encode(&vallen TSRMLS_CC);
                     if (val) {
                            ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC);
                            efree(val);
                     } else {
                            ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC);
                     }
              }

              if (ret == FAILURE) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write session data (%s). Please "
                                   "verify that the current setting of session.save_path "
                                   "is correct (%s)",
                                   PS(mod)->s_name,
                                   PS(save_path));
              }
       }

       if (PS(mod_data)) {
              PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void php_session_send_cookie ( TSRMLS_D  ) [static]

Definition at line 1224 of file session.c.

{
       smart_str ncookie = {0};
       char *date_fmt = NULL;
       char *e_session_name, *e_id;

       if (SG(headers_sent)) {
              char *output_start_filename = php_get_output_start_filename(TSRMLS_C);
              int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);

              if (output_start_filename) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)", output_start_filename, output_start_lineno);
              } else {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent");
              }
              return;
       }

       /* URL encode session_name and id because they might be user supplied */
       e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL);
       e_id = php_url_encode(PS(id), strlen(PS(id)), NULL);

       smart_str_appends(&ncookie, COOKIE_SET_COOKIE);
       smart_str_appends(&ncookie, e_session_name);
       smart_str_appendc(&ncookie, '=');
       smart_str_appends(&ncookie, e_id);

       efree(e_session_name);
       efree(e_id);

       if (PS(cookie_lifetime) > 0) {
              struct timeval tv;
              time_t t;

              gettimeofday(&tv, NULL);
              t = tv.tv_sec + PS(cookie_lifetime);

              if (t > 0) {
                     date_fmt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
                     smart_str_appends(&ncookie, COOKIE_EXPIRES);
                     smart_str_appends(&ncookie, date_fmt);
                     efree(date_fmt);
              }
       }

       if (PS(cookie_path)[0]) {
              smart_str_appends(&ncookie, COOKIE_PATH);
              smart_str_appends(&ncookie, PS(cookie_path));
       }

       if (PS(cookie_domain)[0]) {
              smart_str_appends(&ncookie, COOKIE_DOMAIN);
              smart_str_appends(&ncookie, PS(cookie_domain));
       }

       if (PS(cookie_secure)) {
              smart_str_appends(&ncookie, COOKIE_SECURE);
       }

       if (PS(cookie_httponly)) {
              smart_str_appends(&ncookie, COOKIE_HTTPONLY);
       }

       smart_str_0(&ncookie);

       /*     'replace' must be 0 here, else a previous Set-Cookie
              header, probably sent with setcookie() will be replaced! */
       sapi_add_header_ex(ncookie.c, ncookie.len, 0, 0 TSRMLS_CC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1361 of file session.c.

{
       zval **ppid;
       zval **data;
       char *p, *value;
       int nrand;
       int lensess;

       if (PS(use_only_cookies)) {
              PS(apply_trans_sid) = 0;
       } else {
              PS(apply_trans_sid) = PS(use_trans_sid);
       }

       switch (PS(session_status)) {
              case php_session_active:
                     php_error(E_NOTICE, "A session had already been started - ignoring session_start()");
                     return;
                     break;

              case php_session_disabled:
                     value = zend_ini_string("session.save_handler", sizeof("session.save_handler"), 0);
                     if (!PS(mod) && value) {
                            PS(mod) = _php_find_ps_module(value TSRMLS_CC);
                            if (!PS(mod)) {
                                   php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot find save handler '%s' - session startup failed", value);
                                   return;
                            }
                     }
                     value = zend_ini_string("session.serialize_handler", sizeof("session.serialize_handler"), 0);
                     if (!PS(serializer) && value) {
                            PS(serializer) = _php_find_ps_serializer(value TSRMLS_CC);
                            if (!PS(serializer)) {
                                   php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot find serialization handler '%s' - session startup failed", value);
                                   return;
                            }
                     }
                     PS(session_status) = php_session_none;
                     /* fallthrough */

              default:
              case php_session_none:
                     PS(define_sid) = 1;
                     PS(send_cookie) = 1;
       }

       lensess = strlen(PS(session_name));

       /* Cookies are preferred, because initially
        * cookie and get variables will be available. */

       if (!PS(id)) {
              if (PS(use_cookies) && zend_hash_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE"), (void **) &data) == SUCCESS &&
                            Z_TYPE_PP(data) == IS_ARRAY &&
                            zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
              ) {
                     PPID2SID;
                     PS(apply_trans_sid) = 0;
                     PS(send_cookie) = 0;
                     PS(define_sid) = 0;
              }

              if (!PS(use_only_cookies) && !PS(id) &&
                            zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &data) == SUCCESS &&
                            Z_TYPE_PP(data) == IS_ARRAY &&
                            zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
              ) {
                     PPID2SID;
                     PS(send_cookie) = 0;
              }

              if (!PS(use_only_cookies) && !PS(id) &&
                            zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &data) == SUCCESS &&
                            Z_TYPE_PP(data) == IS_ARRAY &&
                            zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
              ) {
                     PPID2SID;
                     PS(send_cookie) = 0;
              }
       }

       /* Check the REQUEST_URI symbol for a string of the form
        * '<session-name>=<session-id>' to allow URLs of the form
        * http://yoursite/<session-name>=<session-id>/script.php */

       if (!PS(use_only_cookies) && !PS(id) && PG(http_globals)[TRACK_VARS_SERVER] &&
                     zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &data) == SUCCESS &&
                     Z_TYPE_PP(data) == IS_STRING &&
                     (p = strstr(Z_STRVAL_PP(data), PS(session_name))) &&
                     p[lensess] == '='
       ) {
              char *q;

              p += lensess + 1;
              if ((q = strpbrk(p, "/?\\"))) {
                     PS(id) = estrndup(p, q - p);
                     PS(send_cookie) = 0;
              }
       }

       /* Check whether the current request was referred to by
        * an external site which invalidates the previously found id. */

       if (PS(id) &&
                     PS(extern_referer_chk)[0] != '\0' &&
                     PG(http_globals)[TRACK_VARS_SERVER] &&
                     zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER"), (void **) &data) == SUCCESS &&
                     Z_TYPE_PP(data) == IS_STRING &&
                     Z_STRLEN_PP(data) != 0 &&
                     strstr(Z_STRVAL_PP(data), PS(extern_referer_chk)) == NULL
       ) {
              efree(PS(id));
              PS(id) = NULL;
              PS(send_cookie) = 1;
              if (PS(use_trans_sid) && !PS(use_only_cookies)) {
                     PS(apply_trans_sid) = 1;
              }
       }

       php_session_initialize(TSRMLS_C);

       if (!PS(use_cookies) && PS(send_cookie)) {
              if (PS(use_trans_sid) && !PS(use_only_cookies)) {
                     PS(apply_trans_sid) = 1;
              }
              PS(send_cookie) = 0;
       }

       php_session_reset_id(TSRMLS_C);

       PS(session_status) = php_session_active;

       php_session_cache_limiter(TSRMLS_C);

       if (PS(mod_data) && PS(gc_probability) > 0) {
              int nrdels = -1;

              nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg(TSRMLS_C));
              if (nrand < PS(gc_probability)) {
                     PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels TSRMLS_CC);
#ifdef SESSION_DEBUG
                     if (nrdels != -1) {
                            php_error_docref(NULL TSRMLS_CC, E_NOTICE, "purged %d expired session objects", nrdels);
                     }
#endif
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void php_session_track_init ( TSRMLS_D  ) [static]

Definition at line 235 of file session.c.

{
       zval *session_vars = NULL;

       /* Unconditionally destroy existing arrays -- possible dirty data */
       zend_delete_global_variable("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS")-1 TSRMLS_CC);
       zend_delete_global_variable("_SESSION", sizeof("_SESSION")-1 TSRMLS_CC);

       if (PS(http_session_vars)) {
              zval_ptr_dtor(&PS(http_session_vars));
       }

       MAKE_STD_ZVAL(session_vars);
       array_init(session_vars);
       PS(http_session_vars) = session_vars;

       if (PG(register_long_arrays)) {
              ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), PS(http_session_vars), 3, 1);
              ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 3, 1);
       }
       else {
              ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void php_set_session_var ( char *  name,
size_t  namelen,
zval *  state_val,
php_unserialize_data_t *var_hash  TSRMLS_DC 
)

Definition at line 171 of file session.c.

{
       if (PG(register_globals)) {
              zval **old_symbol;
              if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) {
                     if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) {
                            return;
                     }

                     /* A global symbol with the same name exists already. That
                      * symbol might have been created by other means (e.g. $_GET).
                      *
                      * hash_update in zend_set_hash_symbol is not good, because
                      * it will leave referenced variables (such as local instances
                      * of a global variable) dangling.
                      *
                      * BTW: if you use register_globals references between
                      * session-vars won't work because of this very reason! */

                     REPLACE_ZVAL_VALUE(old_symbol,state_val,1);

                     /* The following line will update the reference table used for
                      * unserialization.  It is optional, because some storage
                      * formats may not be able to represent references. */

                     if (var_hash) {
                            PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash,state_val,*old_symbol);
                     }

                     zend_set_hash_symbol(*old_symbol, name, namelen, 1, 1, Z_ARRVAL_P(PS(http_session_vars)));
              } else {
                     zend_set_hash_symbol(state_val, name, namelen, 1, 2, Z_ARRVAL_P(PS(http_session_vars)), &EG(symbol_table));
              }
       } else IF_SESSION_VARS() {
              zend_set_hash_symbol(state_val, name, namelen, PZVAL_IS_REF(state_val), 1, Z_ARRVAL_P(PS(http_session_vars)));
       }
}

Here is the call graph for this function:

PS_SERIALIZER_ENCODE_FUNC ( php_binary  )

Definition at line 828 of file session.c.

{
       smart_str buf = {0};
       php_serialize_data_t var_hash;
       PS_ENCODE_VARS;

       PHP_VAR_SERIALIZE_INIT(var_hash);

       PS_ENCODE_LOOP(
                     if (key_length > PS_BIN_MAX) continue;
                     smart_str_appendc(&buf, (unsigned char) key_length);
                     smart_str_appendl(&buf, key, key_length);
                     php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
              } else {

Here is the call graph for this function:

PHPAPI void session_adapt_url ( const char *  url,
size_t  urllen,
char **  new,
size_t *newlen  TSRMLS_DC 
)

Definition at line 1522 of file session.c.

{
       if (PS(apply_trans_sid) && (PS(session_status) == php_session_active)) {
              *new = php_url_scanner_adapt_single_url(url, urllen, PS(session_name), PS(id), newlen TSRMLS_CC);
       }
}

Here is the call graph for this function:

static void strcpy_gmt ( char *  ubuf,
time_t *  when 
) [inline, static]

Definition at line 1083 of file session.c.

{
       char buf[MAX_STR];
       struct tm tm, *res;
       int n;

       res = php_gmtime_r(when, &tm);

       if (!res) {
              buf[0] = '\0';
              return;
       }

       n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */
                            week_days[tm.tm_wday], tm.tm_mday,
                            month_names[tm.tm_mon], tm.tm_year + 1900,
                            tm.tm_hour, tm.tm_min,
                            tm.tm_sec);
       memcpy(ubuf, buf, n);
       ubuf[n] = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-" [static]

Definition at line 298 of file session.c.

char* month_names[] [static]
Initial value:
 {
       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}

Definition at line 1074 of file session.c.

Initial value:
 {



       CACHE_LIMITER_ENTRY(nocache)
       {0}
}

Definition at line 1176 of file session.c.

Initial value:

Definition at line 1038 of file session.c.

const zend_module_dep session_deps[] [static]
Initial value:

Definition at line 2283 of file session.c.

Initial value:

Definition at line 2101 of file session.c.

zend_module_entry session_module_entry
Initial value:

Definition at line 2290 of file session.c.

char* week_days[] [static]
Initial value:
 {
       "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
}

Definition at line 1079 of file session.c.