1999-12-12 14:22:55 +00:00
/*
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 08:18:22 +00:00
| PHP Version 5 |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-12-31 07:17:19 +00:00
| Copyright ( c ) 1997 - 2008 The PHP Group |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 of the PHP license , |
1999-07-16 13:13:16 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2006-01-01 12:51:34 +00:00
| http : //www.php.net/license/3_01.txt |
1999-07-16 13:13:16 +00:00
| 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 . |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-07-10 10:09:15 +00:00
| Authors : Sascha Schumann < sascha @ schumann . cx > |
2002-05-13 17:28:38 +00:00
| Andrei Zmievski < andrei @ php . net > |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2001-06-06 14:32:27 +00:00
/* $Id$ */
2001-05-24 10:07:29 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2000-02-11 13:41:30 +00:00
# include "php.h"
2000-02-11 15:59:30 +00:00
# ifdef PHP_WIN32
1999-06-06 19:53:59 +00:00
# include "win32/time.h"
2000-02-11 13:41:30 +00:00
# else
# include <sys/time.h>
1999-06-06 18:22:17 +00:00
# endif
1999-06-05 19:52:58 +00:00
1999-12-12 14:16:55 +00:00
# include <sys/stat.h>
1999-09-11 17:20:31 +00:00
# include <fcntl.h>
1999-06-05 19:52:58 +00:00
# include "php_ini.h"
# include "SAPI.h"
# include "php_session.h"
1999-06-06 19:53:59 +00:00
# include "ext/standard/md5.h"
2003-01-12 13:07:14 +00:00
# include "ext/standard/sha1.h"
1999-12-04 19:19:57 +00:00
# include "ext/standard/php_var.h"
2008-12-11 01:21:35 +00:00
# include "ext/date/php_date.h"
1999-09-01 14:20:15 +00:00
# include "ext/standard/php_lcg.h"
2000-09-20 01:22:55 +00:00
# include "ext/standard/url_scanner_ex.h"
2008-08-06 05:53:31 +00:00
# include "ext/standard/php_rand.h" /* for RAND_MAX */
2000-04-06 21:07:44 +00:00
# include "ext/standard/info.h"
2001-03-13 16:53:34 +00:00
# include "ext/standard/php_smart_str.h"
2007-06-17 14:25:46 +00:00
# include "ext/standard/url.h"
2001-03-13 16:53:34 +00:00
2001-05-03 15:48:49 +00:00
# include "mod_files.h"
# include "mod_user.h"
2002-06-28 02:27:02 +00:00
# ifdef HAVE_LIBMM
# include "mod_mm.h"
# endif
2008-08-06 05:53:31 +00:00
PHPAPI ZEND_DECLARE_MODULE_GLOBALS ( ps ) ;
2008-06-27 16:16:23 +00:00
2008-08-06 05:53:31 +00:00
/* ***********
* Helpers *
* * * * * * * * * * * */
2008-06-27 16:16:23 +00:00
2008-08-06 05:53:31 +00:00
# ifdef NETWARE
# define SESS_SB_MTIME(sb) ((sb).st_mtime.tv_sec)
# else
# define SESS_SB_MTIME(sb) ((sb).st_mtime)
# endif
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
# define IF_SESSION_VARS() \
if ( PS ( http_session_vars ) & & PS ( http_session_vars ) - > type = = IS_ARRAY )
2001-05-01 17:01:51 +00:00
2003-12-14 23:24:50 +00:00
# define SESSION_CHECK_ACTIVE_STATE \
if ( PS ( session_status ) = = php_session_active ) { \
2008-08-05 22:52:05 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " A session is active. You cannot change the session module's ini settings at this time " ) ; \
2003-12-14 23:24:50 +00:00
return FAILURE ; \
2008-08-06 05:53:31 +00:00
}
2003-12-14 23:24:50 +00:00
2008-08-06 05:53:31 +00:00
/* Dispatched by RINIT and by php_session_destroy */
static inline void php_rinit_session_globals ( TSRMLS_D ) /* { { { */
2000-05-26 13:02:11 +00:00
{
2008-08-06 05:53:31 +00:00
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 ;
}
/* }}} */
2002-05-12 12:51:42 +00:00
2008-08-06 05:53:31 +00:00
/* Dispatched by RSHUTDOWN and by php_session_destroy */
static inline void php_rshutdown_session_globals ( TSRMLS_D ) /* { { { */
{
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 ) ) ;
2002-05-12 12:51:42 +00:00
}
2000-05-26 13:02:11 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2000-05-26 13:02:11 +00:00
2008-08-06 05:53:31 +00:00
static int php_session_destroy ( TSRMLS_D ) /* { { { */
2000-05-26 13:02:11 +00:00
{
2008-08-06 05:53:31 +00:00
int retval = SUCCESS ;
2003-12-14 23:24:50 +00:00
2008-08-06 05:53:31 +00:00
if ( PS ( session_status ) ! = php_session_active ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Trying to destroy uninitialized session " ) ;
return FAILURE ;
2002-11-20 17:15:00 +00:00
}
2003-12-14 23:24:50 +00:00
2008-08-06 05:53:31 +00:00
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 ;
2003-12-14 23:24:50 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2003-12-14 23:24:50 +00:00
2008-08-06 05:53:31 +00:00
PHPAPI void php_add_session_var ( char * name , size_t namelen TSRMLS_DC ) /* { { { */
2003-12-14 23:24:50 +00:00
{
2008-08-06 05:53:31 +00:00
zval * * sym_track = NULL ;
2002-05-12 12:51:42 +00:00
2008-08-06 05:53:31 +00:00
IF_SESSION_VARS ( ) {
zend_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 ,
( void * ) & sym_track ) ;
} else {
return ;
2002-05-12 12:51:42 +00:00
}
2003-08-26 02:03:41 +00:00
2008-08-06 05:53:31 +00:00
/*
* Set up a proper reference between $ _SESSION [ " x " ] and $ x .
*/
2000-05-26 13:02:11 +00:00
2008-08-06 05:53:31 +00:00
if ( PG ( register_globals ) ) {
zval * * sym_global = NULL ;
2006-10-01 20:58:02 +00:00
2008-08-06 05:53:31 +00:00
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 ;
}
2006-12-01 00:27:20 +00:00
}
2008-08-06 05:53:31 +00:00
if ( sym_global = = NULL & & sym_track = = NULL ) {
zval * empty_var ;
2006-10-01 20:58:02 +00:00
2008-08-06 05:53:31 +00:00
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 ) ) ) ;
2005-05-21 17:37:56 +00:00
}
2008-08-06 05:53:31 +00:00
} else {
if ( sym_track = = NULL ) {
zval * empty_var ;
2005-05-21 17:37:56 +00:00
2008-08-06 05:53:31 +00:00
ALLOC_INIT_ZVAL ( empty_var ) ;
ZEND_SET_SYMBOL_WITH_LENGTH ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , empty_var , 1 , 0 ) ;
2005-05-21 17:37:56 +00:00
}
}
}
2001-06-06 14:32:27 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
PHPAPI void php_set_session_var ( char * name , size_t namelen , zval * state_val , php_unserialize_data_t * var_hash TSRMLS_DC ) /* { { { */
1999-12-04 17:02:04 +00:00
{
2002-05-09 20:02:47 +00:00
if ( PG ( register_globals ) ) {
zval * * old_symbol ;
if ( zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 , ( void * ) & old_symbol ) = = SUCCESS ) {
2007-01-09 15:31:12 +00:00
if ( ( Z_TYPE_PP ( old_symbol ) = = IS_ARRAY & & Z_ARRVAL_PP ( old_symbol ) = = & EG ( symbol_table ) ) | | * old_symbol = = PS ( http_session_vars ) ) {
return ;
}
2002-05-09 20:02:47 +00:00
/*
2003-08-29 12:33:47 +00:00
* 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 !
2002-05-09 20:02:47 +00:00
*/
REPLACE_ZVAL_VALUE ( old_symbol , state_val , 1 ) ;
2003-08-29 12:33:47 +00:00
/*
* 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 .
2002-05-09 20:02:47 +00:00
*/
2003-08-29 12:33:47 +00:00
if ( var_hash ) {
PHP_VAR_UNSERIALIZE_ZVAL_CHANGED ( var_hash , state_val , * old_symbol ) ;
}
2002-05-09 20:02:47 +00:00
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 ) ) ;
}
2002-10-03 03:23:02 +00:00
} else IF_SESSION_VARS ( ) {
2003-08-11 19:20:44 +00:00
zend_set_hash_symbol ( state_val , name , namelen , PZVAL_IS_REF ( state_val ) , 1 , Z_ARRVAL_P ( PS ( http_session_vars ) ) ) ;
2002-05-09 20:02:47 +00:00
}
1999-12-04 17:02:04 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-12-04 17:02:04 +00:00
2008-08-06 05:53:31 +00:00
PHPAPI int php_get_session_var ( char * name , size_t namelen , zval * * * state_var TSRMLS_DC ) /* { { { */
1999-12-04 17:02:04 +00:00
{
2002-10-03 04:53:05 +00:00
int ret = FAILURE ;
2002-10-03 03:23:02 +00:00
IF_SESSION_VARS ( ) {
2002-10-03 04:53:05 +00:00
ret = zend_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name ,
2002-10-01 11:59:45 +00:00
namelen + 1 , ( void * * ) state_var ) ;
2002-10-03 04:53:05 +00:00
/*
* 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
*/
2008-08-06 05:53:31 +00:00
2002-10-03 04:53:05 +00:00
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 ;
}
}
2002-09-23 14:04:50 +00:00
}
2002-10-03 04:53:05 +00:00
return ret ;
1999-12-04 17:02:04 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-11-29 23:07:20 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_track_init ( TSRMLS_D ) /* { { { */
2000-09-01 15:24:58 +00:00
{
2008-08-06 05:53:31 +00:00
zval * session_vars = NULL ;
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
/* 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 ) ;
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
if ( PS ( http_session_vars ) ) {
zval_ptr_dtor ( & PS ( http_session_vars ) ) ;
}
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
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 ) ;
}
2000-09-01 15:24:58 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2000-09-01 15:24:58 +00:00
2008-08-06 05:53:31 +00:00
static char * php_session_encode ( int * newlen TSRMLS_DC ) /* { { { */
2000-09-01 15:24:58 +00:00
{
2008-08-06 05:53:31 +00:00
char * ret = NULL ;
2006-12-26 16:53:47 +00:00
2008-08-06 05:53:31 +00:00
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 ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
} else {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot encode non-existent session " ) ;
}
return ret ;
}
/* }}} */
2006-12-26 16:53:47 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_decode ( const char * val , int vallen TSRMLS_DC ) /* { { { */
{
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 " ) ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
}
/* }}} */
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
/*
* Note that we cannot use the BASE64 alphabet here , because
* it contains " / " and " + " : both are unacceptable for simple inclusion
* into URLs .
*/
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
static char hexconvtab [ ] = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,- " ;
2000-09-01 15:24:58 +00:00
2008-08-06 05:53:31 +00:00
enum {
PS_HASH_FUNC_MD5 ,
PS_HASH_FUNC_SHA1 ,
PS_HASH_FUNC_OTHER
} ;
2000-09-01 15:24:58 +00:00
2008-08-06 05:53:31 +00:00
/* returns a pointer to the byte after the last valid character in out */
static char * bin_to_readable ( char * in , size_t inlen , char * out , char nbits ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2008-08-06 05:53:31 +00:00
unsigned char * p , * q ;
unsigned short w ;
int mask ;
int have ;
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
p = ( unsigned char * ) in ;
q = ( unsigned char * ) in + inlen ;
2003-01-16 07:21:49 +00:00
w = 0 ;
have = 0 ;
mask = ( 1 < < nbits ) - 1 ;
2008-08-06 05:53:31 +00:00
2003-01-16 07:21:49 +00:00
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 ;
}
2008-08-06 05:53:31 +00:00
2003-01-16 07:21:49 +00:00
* out = ' \0 ' ;
return out ;
}
2008-08-06 05:53:31 +00:00
/* }}} */
2003-01-16 07:21:49 +00:00
2008-08-06 05:53:31 +00:00
# define PS_ID_INITIAL_SIZE 100
PHPAPI char * php_session_create_id ( PS_CREATE_SID_ARGS ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2003-01-12 13:07:14 +00:00
PHP_MD5_CTX md5_context ;
PHP_SHA1_CTX sha1_context ;
2008-08-06 05:53:31 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
void * hash_context ;
# endif
unsigned char * digest ;
2003-01-12 13:07:14 +00:00
int digest_len ;
2003-01-16 07:21:49 +00:00
int j ;
2003-01-12 13:07:14 +00:00
char * buf ;
2002-05-09 20:02:47 +00:00
struct timeval tv ;
2003-01-12 13:07:14 +00:00
zval * * array ;
zval * * token ;
char * remote_addr = NULL ;
2002-05-09 20:02:47 +00:00
gettimeofday ( & tv , NULL ) ;
2008-08-06 05:53:31 +00:00
2003-01-12 13:07:14 +00:00
if ( zend_hash_find ( & EG ( symbol_table ) , " _SERVER " ,
sizeof ( " _SERVER " ) , ( void * * ) & array ) = = SUCCESS & &
2008-08-06 05:53:31 +00:00
Z_TYPE_PP ( array ) = = IS_ARRAY & &
zend_hash_find ( Z_ARRVAL_PP ( array ) , " REMOTE_ADDR " ,
2003-01-12 13:07:14 +00:00
sizeof ( " REMOTE_ADDR " ) , ( void * * ) & token ) = = SUCCESS ) {
remote_addr = Z_STRVAL_PP ( token ) ;
}
2008-08-06 05:53:31 +00:00
/* maximum 15+19+19+10 bytes */
2007-02-24 02:17:47 +00:00
spprintf ( & buf , 0 , " %.15s%ld%ld%0.8F " , remote_addr ? remote_addr : " " ,
2006-07-13 00:13:19 +00:00
tv . tv_sec , ( long int ) tv . tv_usec , php_combined_lcg ( TSRMLS_C ) * 10 ) ;
2003-01-12 13:07:14 +00:00
switch ( PS ( hash_func ) ) {
2008-08-06 05:53:31 +00:00
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 ;
2003-01-12 13:07:14 +00:00
}
2002-05-09 20:02:47 +00:00
if ( PS ( entropy_length ) > 0 ) {
int fd ;
fd = VCWD_OPEN ( PS ( entropy_file ) , O_RDONLY ) ;
if ( fd > = 0 ) {
2003-01-12 13:07:14 +00:00
unsigned char rbuf [ 2048 ] ;
2002-05-09 20:02:47 +00:00
int n ;
int to_read = PS ( entropy_length ) ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
while ( to_read > 0 ) {
2003-01-12 13:07:14 +00:00
n = read ( fd , rbuf , MIN ( to_read , sizeof ( rbuf ) ) ) ;
2002-05-09 20:02:47 +00:00
if ( n < = 0 ) break ;
2008-08-06 05:53:31 +00:00
2003-01-12 13:07:14 +00:00
switch ( PS ( hash_func ) ) {
2008-08-06 05:53:31 +00:00
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 */
2003-01-12 13:07:14 +00:00
}
2002-05-09 20:02:47 +00:00
to_read - = n ;
}
close ( fd ) ;
}
}
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
digest = emalloc ( digest_len + 1 ) ;
2003-01-12 13:07:14 +00:00
switch ( PS ( hash_func ) ) {
2008-08-06 05:53:31 +00:00
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 */
2003-01-12 13:07:14 +00:00
}
2003-01-16 07:21:49 +00:00
if ( PS ( hash_bits_per_character ) < 4
| | PS ( hash_bits_per_character ) > 6 ) {
PS ( hash_bits_per_character ) = 4 ;
2003-01-12 13:07:14 +00:00
2003-01-19 00:45:53 +00:00
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 " ) ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
if ( PS_ID_INITIAL_SIZE < ( ( digest_len + 2 ) * ( 8 / PS ( hash_bits_per_character ) ) ) ) {
/* 100 bytes is enough for most, but not all hash algos */
buf = erealloc ( buf , ( digest_len + 2 ) * ( 8 / PS ( hash_bits_per_character ) ) ) ;
}
2006-07-13 00:13:19 +00:00
j = ( int ) ( bin_to_readable ( ( char * ) digest , digest_len , buf , PS ( hash_bits_per_character ) ) - buf ) ;
2008-08-06 05:53:31 +00:00
efree ( digest ) ;
if ( newlen ) {
2002-05-09 20:02:47 +00:00
* newlen = j ;
2008-08-06 05:53:31 +00:00
}
2003-01-12 13:07:14 +00:00
return buf ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_initialize ( TSRMLS_D ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
char * val ;
int vallen ;
2006-01-15 16:51:18 +00:00
/* check session name for invalid characters */
2007-06-16 07:48:07 +00:00
if ( PS ( id ) & & strpbrk ( PS ( id ) , " \r \n \t <>' \" \\ " ) ) {
2006-01-15 16:51:18 +00:00
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
}
2002-09-29 18:33:14 +00:00
if ( ! PS ( mod ) ) {
2008-08-05 22:52:05 +00:00
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " No storage module chosen - failed to initialize session " ) ;
2002-09-29 18:33:14 +00:00
return ;
}
2002-05-09 20:02:47 +00:00
/* Open session handler first */
2003-02-11 00:42:14 +00:00
if ( PS ( mod ) - > s_open ( & PS ( mod_data ) , PS ( save_path ) , PS ( session_name ) TSRMLS_CC ) = = FAILURE ) {
2004-02-19 01:54:21 +00:00
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Failed to initialize storage module: %s (path: %s) " , PS ( mod ) - > s_name , PS ( save_path ) ) ;
2002-05-09 20:02:47 +00:00
return ;
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
/* If there is no ID, use session module to create one */
2006-07-27 14:00:13 +00:00
if ( ! PS ( id ) ) {
new_session :
2003-02-11 00:42:14 +00:00
PS ( id ) = PS ( mod ) - > s_create_sid ( & PS ( mod_data ) , NULL TSRMLS_CC ) ;
2006-07-27 14:00:13 +00:00
if ( PS ( use_cookies ) ) {
PS ( send_cookie ) = 1 ;
}
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
/* 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 ) ;
2006-07-27 15:33:16 +00:00
PS ( invalid_session_id ) = 0 ;
2003-02-11 00:42:14 +00:00
if ( PS ( mod ) - > s_read ( & PS ( mod_data ) , PS ( id ) , & val , & vallen TSRMLS_CC ) = = SUCCESS ) {
2002-05-09 20:02:47 +00:00
php_session_decode ( val , vallen TSRMLS_CC ) ;
efree ( val ) ;
2006-07-27 15:33:16 +00:00
} 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 ) ) ;
2007-03-14 19:37:07 +00:00
PS ( id ) = NULL ;
2006-07-27 14:00:13 +00:00
goto new_session ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
static int migrate_global ( HashTable * ht , HashPosition * pos TSRMLS_DC ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-10-03 03:23:02 +00:00
char * str ;
uint str_len ;
2002-05-09 20:02:47 +00:00
ulong num_key ;
2002-10-03 03:23:02 +00:00
int n ;
2003-07-22 01:11:07 +00:00
zval * * val ;
2002-10-07 02:37:50 +00:00
int ret = 0 ;
2008-08-06 05:53:31 +00:00
2002-10-03 03:23:02 +00:00
n = zend_hash_get_current_key_ex ( ht , & str , & str_len , & num_key , 0 , pos ) ;
switch ( n ) {
case HASH_KEY_IS_STRING :
2003-07-22 01:11:07 +00:00
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 ,
2007-10-07 05:22:07 +00:00
Z_REFCOUNT_PP ( val ) + 1 , 1 ) ;
2002-10-07 02:37:50 +00:00
ret = 1 ;
2002-10-03 03:23:02 +00:00
}
break ;
case HASH_KEY_IS_LONG :
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " The session bug compatibility code will not "
2003-08-28 17:34:33 +00:00
" try to locate the global variable $%lu due to its "
2008-08-05 22:52:05 +00:00
" numeric nature " , num_key ) ;
2002-10-03 03:23:02 +00:00
break ;
2002-09-29 15:26:50 +00:00
}
2002-10-07 02:37:50 +00:00
return ret ;
2002-10-03 03:23:02 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2002-10-03 03:23:02 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_save_current_state ( TSRMLS_D ) /* { { { */
2002-10-03 03:23:02 +00:00
{
int ret = FAILURE ;
2008-08-06 05:53:31 +00:00
2002-10-03 03:23:02 +00:00
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 ) {
2002-10-07 02:37:50 +00:00
if ( migrate_global ( ht , & pos TSRMLS_CC ) )
do_warn = 1 ;
2002-10-03 03:23:02 +00:00
}
zend_hash_move_forward_ex ( ht , & pos ) ;
}
if ( do_warn & & PS ( bug_compat_warn ) ) {
2008-08-05 22:52:05 +00:00
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 " ) ;
2002-10-03 03:23:02 +00:00
}
2002-05-09 20:02:47 +00:00
}
2002-10-03 05:53:45 +00:00
if ( PS ( mod_data ) ) {
char * val ;
int vallen ;
2002-10-03 03:23:02 +00:00
2008-08-06 05:53:31 +00:00
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 ) ;
}
}
/* }}} */
/* *************************
* INI Settings / Handlers *
* * * * * * * * * * * * * * * * * * * * * * * * * */
static PHP_INI_MH ( OnUpdateSaveHandler ) /* { { { */
{
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 ;
}
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 ;
}
/* }}} */
static PHP_INI_MH ( OnUpdateSerializer ) /* { { { */
{
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 ;
}
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 ;
}
/* }}} */
static PHP_INI_MH ( OnUpdateTransSid ) /* { { { */
{
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 ) /* { { { */
{
/* 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 ;
}
if ( ( p = zend_memrchr ( new_value , ' ; ' , new_value_length ) ) ) {
p + + ;
} else {
p = new_value ;
}
if ( PG ( safe_mode ) & & ( ! php_checkuid ( p , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
return FAILURE ;
}
if ( PG ( open_basedir ) & & 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 ;
}
/* }}} */
static PHP_INI_MH ( OnUpdateHashFunc ) /* { { { */
{
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 ;
}
/* }}} */
/* {{{ PHP_INI
*/
PHP_INI_BEGIN ( )
STD_PHP_INI_BOOLEAN ( " session.bug_compat_42 " , " 1 " , PHP_INI_ALL , OnUpdateBool , bug_compat , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.bug_compat_warn " , " 1 " , PHP_INI_ALL , OnUpdateBool , bug_compat_warn , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.save_path " , " " , PHP_INI_ALL , OnUpdateSaveDir , save_path , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.name " , " PHPSESSID " , PHP_INI_ALL , OnUpdateString , session_name , php_ps_globals , ps_globals )
PHP_INI_ENTRY ( " session.save_handler " , " files " , PHP_INI_ALL , OnUpdateSaveHandler )
STD_PHP_INI_BOOLEAN ( " session.auto_start " , " 0 " , PHP_INI_ALL , OnUpdateBool , auto_start , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.gc_probability " , " 1 " , PHP_INI_ALL , OnUpdateLong , gc_probability , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.gc_divisor " , " 100 " , PHP_INI_ALL , OnUpdateLong , gc_divisor , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.gc_maxlifetime " , " 1440 " , PHP_INI_ALL , OnUpdateLong , gc_maxlifetime , php_ps_globals , ps_globals )
PHP_INI_ENTRY ( " session.serialize_handler " , " php " , PHP_INI_ALL , OnUpdateSerializer )
STD_PHP_INI_ENTRY ( " session.cookie_lifetime " , " 0 " , PHP_INI_ALL , OnUpdateLong , cookie_lifetime , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.cookie_path " , " / " , PHP_INI_ALL , OnUpdateString , cookie_path , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.cookie_domain " , " " , PHP_INI_ALL , OnUpdateString , cookie_domain , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.cookie_secure " , " " , PHP_INI_ALL , OnUpdateBool , cookie_secure , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.cookie_httponly " , " " , PHP_INI_ALL , OnUpdateBool , cookie_httponly , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.use_cookies " , " 1 " , PHP_INI_ALL , OnUpdateBool , use_cookies , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.use_only_cookies " , " 1 " , PHP_INI_ALL , OnUpdateBool , use_only_cookies , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.referer_check " , " " , PHP_INI_ALL , OnUpdateString , extern_referer_chk , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.entropy_file " , " " , PHP_INI_ALL , OnUpdateString , entropy_file , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.entropy_length " , " 0 " , PHP_INI_ALL , OnUpdateLong , entropy_length , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.cache_limiter " , " nocache " , PHP_INI_ALL , OnUpdateString , cache_limiter , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.cache_expire " , " 180 " , PHP_INI_ALL , OnUpdateLong , cache_expire , php_ps_globals , ps_globals )
PHP_INI_ENTRY ( " session.use_trans_sid " , " 0 " , PHP_INI_ALL , OnUpdateTransSid )
PHP_INI_ENTRY ( " session.hash_function " , " 0 " , PHP_INI_ALL , OnUpdateHashFunc )
STD_PHP_INI_ENTRY ( " session.hash_bits_per_character " , " 4 " , PHP_INI_ALL , OnUpdateLong , hash_bits_per_character , php_ps_globals , ps_globals )
/* Commented out until future discussion */
/* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
PHP_INI_END ( )
/* }}} */
/* ***************
* Serializers *
* * * * * * * * * * * * * * * */
# 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)
PS_SERIALIZER_ENCODE_FUNC ( php_binary ) /* {{{ */
{
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 {
if ( key_length > PS_BIN_MAX ) continue ;
smart_str_appendc ( & buf , ( unsigned char ) ( key_length & PS_BIN_UNDEF ) ) ;
smart_str_appendl ( & buf , key , key_length ) ;
) ;
if ( newlen ) {
* newlen = buf . len ;
}
smart_str_0 ( & buf ) ;
* newstr = buf . c ;
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
}
/* }}} */
PS_SERIALIZER_DECODE_FUNC ( php_binary ) /* {{{ */
{
const char * p ;
char * name ;
const char * endptr = val + vallen ;
zval * current ;
int namelen ;
int has_value ;
php_unserialize_data_t var_hash ;
PHP_VAR_UNSERIALIZE_INIT ( var_hash ) ;
for ( p = val ; p < endptr ; ) {
zval * * tmp ;
namelen = ( ( unsigned char ) ( * p ) ) & ( ~ PS_BIN_UNDEF ) ;
if ( namelen < 0 | | namelen > PS_BIN_MAX | | ( p + namelen ) > = endptr ) {
return FAILURE ;
}
has_value = * p & PS_BIN_UNDEF ? 0 : 1 ;
name = estrndup ( p + 1 , namelen ) ;
p + = namelen + 1 ;
if ( zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 , ( void * * ) & tmp ) = = SUCCESS ) {
if ( ( Z_TYPE_PP ( tmp ) = = IS_ARRAY & & Z_ARRVAL_PP ( tmp ) = = & EG ( symbol_table ) ) | | * tmp = = PS ( http_session_vars ) ) {
efree ( name ) ;
continue ;
}
}
if ( has_value ) {
ALLOC_INIT_ZVAL ( current ) ;
if ( php_var_unserialize ( & current , ( const unsigned char * * ) & p , ( const unsigned char * ) endptr , & var_hash TSRMLS_CC ) ) {
php_set_session_var ( name , namelen , current , & var_hash TSRMLS_CC ) ;
}
zval_ptr_dtor ( & current ) ;
}
PS_ADD_VARL ( name , namelen ) ;
efree ( name ) ;
}
PHP_VAR_UNSERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
}
/* }}} */
# define PS_DELIMITER '|'
# define PS_UNDEF_MARKER '!'
PS_SERIALIZER_ENCODE_FUNC ( php ) /* {{{ */
{
smart_str buf = { 0 } ;
php_serialize_data_t var_hash ;
PS_ENCODE_VARS ;
PHP_VAR_SERIALIZE_INIT ( var_hash ) ;
PS_ENCODE_LOOP (
smart_str_appendl ( & buf , key , key_length ) ;
if ( memchr ( key , PS_DELIMITER , key_length ) ) {
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
smart_str_free ( & buf ) ;
return FAILURE ;
}
smart_str_appendc ( & buf , PS_DELIMITER ) ;
php_var_serialize ( & buf , struc , & var_hash TSRMLS_CC ) ;
} else {
smart_str_appendc ( & buf , PS_UNDEF_MARKER ) ;
smart_str_appendl ( & buf , key , key_length ) ;
smart_str_appendc ( & buf , PS_DELIMITER ) ;
) ;
if ( newlen ) {
* newlen = buf . len ;
}
smart_str_0 ( & buf ) ;
* newstr = buf . c ;
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
}
/* }}} */
PS_SERIALIZER_DECODE_FUNC ( php ) /* {{{ */
{
const char * p , * q ;
char * name ;
const char * endptr = val + vallen ;
zval * current ;
int namelen ;
int has_value ;
php_unserialize_data_t var_hash ;
PHP_VAR_UNSERIALIZE_INIT ( var_hash ) ;
p = val ;
while ( p < endptr ) {
zval * * tmp ;
q = p ;
while ( * q ! = PS_DELIMITER ) {
if ( + + q > = endptr ) goto break_outer_loop ;
}
if ( p [ 0 ] = = PS_UNDEF_MARKER ) {
p + + ;
has_value = 0 ;
} else {
has_value = 1 ;
}
namelen = q - p ;
name = estrndup ( p , namelen ) ;
q + + ;
if ( zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 , ( void * * ) & tmp ) = = SUCCESS ) {
if ( ( Z_TYPE_PP ( tmp ) = = IS_ARRAY & & Z_ARRVAL_PP ( tmp ) = = & EG ( symbol_table ) ) | | * tmp = = PS ( http_session_vars ) ) {
goto skip ;
}
}
if ( has_value ) {
ALLOC_INIT_ZVAL ( current ) ;
if ( php_var_unserialize ( & current , ( const unsigned char * * ) & q , ( const unsigned char * ) endptr , & var_hash TSRMLS_CC ) ) {
php_set_session_var ( name , namelen , current , & var_hash TSRMLS_CC ) ;
}
zval_ptr_dtor ( & current ) ;
}
PS_ADD_VARL ( name , namelen ) ;
skip :
efree ( name ) ;
p = q ;
}
break_outer_loop :
PHP_VAR_UNSERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
}
/* }}} */
# define MAX_SERIALIZERS 10
# define PREDEFINED_SERIALIZERS 2
static ps_serializer ps_serializers [ MAX_SERIALIZERS + 1 ] = {
PS_SERIALIZER_ENTRY ( php ) ,
PS_SERIALIZER_ENTRY ( php_binary )
} ;
PHPAPI int php_session_register_serializer (
const char * name ,
int ( * encode ) ( PS_SERIALIZER_ENCODE_ARGS ) ,
int ( * decode ) ( PS_SERIALIZER_DECODE_ARGS ) ) /* {{{ */
{
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 ;
}
/* }}} */
/* *******************
* Storage Modules *
* * * * * * * * * * * * * * * * * * * */
# define MAX_MODULES 10
# define PREDEFINED_MODULES 2
static ps_module * ps_modules [ MAX_MODULES + 1 ] = {
ps_files_ptr ,
ps_user_ptr
} ;
PHPAPI int php_session_register_module ( ps_module * ptr ) /* { { { */
{
int ret = - 1 ;
int i ;
2002-10-03 05:53:45 +00:00
2008-08-06 05:53:31 +00:00
for ( i = 0 ; i < MAX_MODULES ; i + + ) {
if ( ! ps_modules [ i ] ) {
ps_modules [ i ] = ptr ;
ret = 0 ;
break ;
}
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
return ret ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
/* ******************
* Cache Limiters *
* * * * * * * * * * * * * * * * * * */
typedef struct {
char * name ;
void ( * func ) ( TSRMLS_D ) ;
} php_session_cache_limiter_t ;
# 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
1999-06-05 19:52:58 +00:00
1999-12-12 14:16:55 +00:00
static char * month_names [ ] = {
2002-05-09 20:02:47 +00:00
" Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
" Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec "
1999-12-12 14:16:55 +00:00
} ;
1999-12-12 14:22:55 +00:00
static char * week_days [ ] = {
2002-05-09 20:02:47 +00:00
" Sun " , " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat " , " Sun "
1999-12-12 14:16:55 +00:00
} ;
2008-08-06 05:53:31 +00:00
static inline void strcpy_gmt ( char * ubuf , time_t * when ) /* { { { */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
char buf [ MAX_STR ] ;
2007-06-07 08:59:00 +00:00
struct tm tm , * res ;
2002-05-09 20:02:47 +00:00
int n ;
2008-08-06 05:53:31 +00:00
2007-06-07 08:59:00 +00:00
res = php_gmtime_r ( when , & tm ) ;
if ( ! res ) {
buf [ 0 ] = ' \0 ' ;
return ;
}
2008-08-06 05:53:31 +00:00
2007-02-27 03:28:17 +00:00
n = slprintf ( buf , sizeof ( buf ) , " %s, %02d %s %d %02d:%02d:%02d GMT " , /* SAFE */
2002-05-09 20:02:47 +00:00
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 ' ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2008-08-06 05:53:31 +00:00
static inline void last_modified ( TSRMLS_D ) /* { { { */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
const char * path ;
struct stat sb ;
char buf [ MAX_STR + 1 ] ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
path = SG ( request_info ) . path_translated ;
if ( path ) {
if ( VCWD_STAT ( path , & sb ) = = - 1 ) {
return ;
}
1999-12-12 14:16:55 +00:00
2001-03-13 16:53:34 +00:00
# define LAST_MODIFIED "Last-Modified: "
2002-05-09 20:02:47 +00:00
memcpy ( buf , LAST_MODIFIED , sizeof ( LAST_MODIFIED ) - 1 ) ;
2008-08-06 05:53:31 +00:00
strcpy_gmt ( buf + sizeof ( LAST_MODIFIED ) - 1 , & SESS_SB_MTIME ( sb ) ) ;
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
2002-05-09 20:02:47 +00:00
}
1999-12-12 14:16:55 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2008-08-06 05:53:31 +00:00
# define EXPIRES "Expires: "
CACHE_LIMITER_FUNC ( public ) /* {{{ */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
char buf [ MAX_STR + 1 ] ;
struct timeval tv ;
time_t now ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
gettimeofday ( & tv , NULL ) ;
now = tv . tv_sec + PS ( cache_expire ) * 60 ;
memcpy ( buf , EXPIRES , sizeof ( EXPIRES ) - 1 ) ;
strcpy_gmt ( buf + sizeof ( EXPIRES ) - 1 , & now ) ;
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
2008-08-06 05:53:31 +00:00
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " Cache-Control: public, max-age=%ld " , PS ( cache_expire ) * 60 ) ; /* SAFE */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
last_modified ( TSRMLS_C ) ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2001-09-21 13:38:44 +00:00
2008-08-06 05:53:31 +00:00
CACHE_LIMITER_FUNC ( private_no_expire ) /* {{{ */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
char buf [ MAX_STR + 1 ] ;
2008-08-06 05:53:31 +00:00
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " Cache-Control: private, max-age=%ld, pre-check=%ld " , PS ( cache_expire ) * 60 , PS ( cache_expire ) * 60 ) ; /* SAFE */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
1999-12-12 14:16:55 +00:00
2002-05-09 20:02:47 +00:00
last_modified ( TSRMLS_C ) ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2008-08-06 05:53:31 +00:00
CACHE_LIMITER_FUNC ( private ) /* {{{ */
2001-11-02 22:27:07 +00:00
{
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
2002-05-12 12:51:42 +00:00
CACHE_LIMITER ( private_no_expire ) ( TSRMLS_C ) ;
2001-11-02 22:27:07 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2001-11-02 22:27:07 +00:00
2008-08-06 05:53:31 +00:00
CACHE_LIMITER_FUNC ( nocache ) /* {{{ */
1999-12-12 14:16:55 +00:00
{
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
/* For HTTP/1.1 conforming clients and the rest (MSIE 5) */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 " ) ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
/* For HTTP/1.0 conforming clients */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Pragma: no-cache " ) ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2000-09-06 14:16:12 +00:00
static php_session_cache_limiter_t php_session_cache_limiters [ ] = {
2002-05-12 12:51:42 +00:00
CACHE_LIMITER_ENTRY ( public )
CACHE_LIMITER_ENTRY ( private )
CACHE_LIMITER_ENTRY ( private_no_expire )
CACHE_LIMITER_ENTRY ( nocache )
2002-05-09 20:02:47 +00:00
{ 0 }
1999-12-12 14:16:55 +00:00
} ;
2008-08-06 05:53:31 +00:00
static int php_session_cache_limiter ( TSRMLS_D ) /* { { { */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
php_session_cache_limiter_t * lim ;
2002-10-03 15:10:36 +00:00
if ( PS ( cache_limiter ) [ 0 ] = = ' \0 ' ) return 0 ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
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 ) {
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cache limiter - headers already sent (output started at %s:%d) " ,
2002-05-09 20:02:47 +00:00
output_start_filename , output_start_lineno ) ;
} else {
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cache limiter - headers already sent " ) ;
2008-08-06 05:53:31 +00:00
}
2002-10-03 15:10:36 +00:00
return - 2 ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
for ( lim = php_session_cache_limiters ; lim - > name ; lim + + ) {
if ( ! strcasecmp ( lim - > name , PS ( cache_limiter ) ) ) {
lim - > func ( TSRMLS_C ) ;
2002-10-03 15:10:36 +00:00
return 0 ;
2002-05-09 20:02:47 +00:00
}
}
2002-10-03 15:10:36 +00:00
return - 1 ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
/* *********************
* Cookie Management *
* * * * * * * * * * * * * * * * * * * * * */
1999-12-12 14:16:55 +00:00
2001-03-13 16:53:34 +00:00
# define COOKIE_SET_COOKIE "Set-Cookie: "
2002-05-09 20:02:47 +00:00
# define COOKIE_EXPIRES "; expires="
# define COOKIE_PATH "; path="
# define COOKIE_DOMAIN "; domain="
# define COOKIE_SECURE "; secure"
2006-08-10 13:50:56 +00:00
# define COOKIE_HTTPONLY "; HttpOnly"
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_send_cookie ( TSRMLS_D ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
smart_str ncookie = { 0 } ;
char * date_fmt = NULL ;
2007-06-16 07:48:07 +00:00
char * e_session_name , * e_id ;
2002-05-09 20:02:47 +00:00
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 ) {
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cookie - headers already sent by (output started at %s:%d) " ,
2002-05-09 20:02:47 +00:00
output_start_filename , output_start_lineno ) ;
} else {
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cookie - headers already sent " ) ;
2008-08-06 05:53:31 +00:00
}
2002-05-09 20:02:47 +00:00
return ;
}
2008-08-06 05:53:31 +00:00
2007-06-16 07:48:07 +00:00
/* 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 ) ;
2002-05-09 20:02:47 +00:00
smart_str_appends ( & ncookie , COOKIE_SET_COOKIE ) ;
2007-06-16 07:48:07 +00:00
smart_str_appends ( & ncookie , e_session_name ) ;
2002-05-09 20:02:47 +00:00
smart_str_appendc ( & ncookie , ' = ' ) ;
2007-06-16 07:48:07 +00:00
smart_str_appends ( & ncookie , e_id ) ;
2008-08-06 05:53:31 +00:00
2007-06-16 07:48:07 +00:00
efree ( e_session_name ) ;
efree ( e_id ) ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
if ( PS ( cookie_lifetime ) > 0 ) {
struct timeval tv ;
2003-10-08 10:22:51 +00:00
time_t t ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
gettimeofday ( & tv , NULL ) ;
2003-10-08 10:22:51 +00:00
t = tv . tv_sec + PS ( cookie_lifetime ) ;
2008-08-06 05:53:31 +00:00
2003-10-08 10:22:51 +00:00
if ( t > 0 ) {
2008-12-11 01:21:35 +00:00
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 ) ;
2003-10-08 10:22:51 +00:00
smart_str_appends ( & ncookie , COOKIE_EXPIRES ) ;
smart_str_appends ( & ncookie , date_fmt ) ;
efree ( date_fmt ) ;
}
2002-05-09 20:02:47 +00:00
}
if ( PS ( cookie_path ) [ 0 ] ) {
smart_str_appends ( & ncookie , COOKIE_PATH ) ;
smart_str_appends ( & ncookie , PS ( cookie_path ) ) ;
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
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 ) ;
}
2006-08-10 13:50:56 +00:00
if ( PS ( cookie_httponly ) ) {
smart_str_appends ( & ncookie , COOKIE_HTTPONLY ) ;
}
2002-05-09 20:02:47 +00:00
smart_str_0 ( & ncookie ) ;
2008-08-06 05:53:31 +00:00
2006-07-12 15:28:44 +00:00
/* 'replace' must be 0 here, else a previous Set-Cookie
header , probably sent with setcookie ( ) will be replaced ! */
2003-04-27 16:18:43 +00:00
sapi_add_header_ex ( ncookie . c , ncookie . len , 0 , 0 TSRMLS_CC ) ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
PHPAPI ps_module * _php_find_ps_module ( char * name TSRMLS_DC ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
ps_module * ret = NULL ;
ps_module * * mod ;
int i ;
2008-08-06 05:53:31 +00:00
for ( i = 0 , mod = ps_modules ; i < MAX_MODULES ; i + + , mod + + ) {
2003-02-11 00:42:14 +00:00
if ( * mod & & ! strcasecmp ( name , ( * mod ) - > s_name ) ) {
2002-05-09 20:02:47 +00:00
ret = * mod ;
break ;
}
2008-08-06 05:53:31 +00:00
}
2002-05-09 20:02:47 +00:00
return ret ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
PHPAPI const ps_serializer * _php_find_ps_serializer ( char * name TSRMLS_DC ) /* { { { */
1999-07-01 05:45:48 +00:00
{
2002-05-09 20:02:47 +00:00
const ps_serializer * ret = NULL ;
const ps_serializer * mod ;
1999-07-01 05:45:48 +00:00
2008-08-06 05:53:31 +00:00
for ( mod = ps_serializers ; mod - > name ; mod + + ) {
2002-05-09 20:02:47 +00:00
if ( ! strcasecmp ( name , mod - > name ) ) {
ret = mod ;
break ;
}
2008-08-06 05:53:31 +00:00
}
2002-05-09 20:02:47 +00:00
return ret ;
1999-07-01 05:45:48 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-07-01 05:45:48 +00:00
1999-12-22 00:38:04 +00:00
# define PPID2SID \
2002-05-09 20:02:47 +00:00
convert_to_string ( ( * ppid ) ) ; \
PS ( id ) = estrndup ( Z_STRVAL_PP ( ppid ) , Z_STRLEN_PP ( ppid ) )
1999-12-22 00:38:04 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_reset_id ( TSRMLS_D ) /* { { { */
2003-02-18 19:29:38 +00:00
{
int module_number = PS ( module_number ) ;
2008-08-06 05:53:31 +00:00
2006-02-10 07:39:13 +00:00
if ( PS ( use_cookies ) & & PS ( send_cookie ) ) {
2003-02-18 19:29:38 +00:00
php_session_send_cookie ( TSRMLS_C ) ;
2006-02-10 07:39:13 +00:00
PS ( send_cookie ) = 0 ;
2003-02-18 19:29:38 +00:00
}
/* if the SID constant exists, destroy it. */
zend_hash_del ( EG ( zend_constants ) , " sid " , sizeof ( " sid " ) ) ;
2008-08-06 05:53:31 +00:00
2003-02-18 19:29:38 +00:00
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 {
2005-06-01 18:27:50 +00:00
REGISTER_STRINGL_CONSTANT ( " SID " , STR_EMPTY_ALLOC ( ) , 0 , 0 ) ;
2003-02-18 19:29:38 +00:00
}
if ( PS ( apply_trans_sid ) ) {
php_url_scanner_reset_vars ( TSRMLS_C ) ;
2003-02-20 06:18:16 +00:00
php_url_scanner_add_var ( PS ( session_name ) , strlen ( PS ( session_name ) ) , PS ( id ) , strlen ( PS ( id ) ) , 1 TSRMLS_CC ) ;
2003-02-18 19:29:38 +00:00
}
}
2008-08-06 05:53:31 +00:00
/* }}} */
PHPAPI void php_session_start ( TSRMLS_D ) /* { { { */
1999-06-05 22:15:49 +00:00
{
2002-05-09 20:02:47 +00:00
zval * * ppid ;
zval * * data ;
2008-08-06 05:53:31 +00:00
char * p , * value ;
2002-05-09 20:02:47 +00:00
int nrand ;
int lensess ;
PS ( apply_trans_sid ) = PS ( use_trans_sid ) ;
2008-08-06 05:53:31 +00:00
switch ( PS ( session_status ) ) {
case php_session_active :
php_error ( E_NOTICE , " A session had already been started - ignoring session_start() " ) ;
return ;
break ;
2004-09-30 12:19:59 +00:00
2008-08-06 05:53:31 +00:00
case php_session_disabled :
2004-09-30 12:19:59 +00:00
value = zend_ini_string ( " session.save_handler " , sizeof ( " session.save_handler " ) , 0 ) ;
2008-08-06 05:53:31 +00:00
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 ;
}
2004-09-30 12:19:59 +00:00
}
2008-08-06 05:53:31 +00:00
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 ;
}
2004-09-30 12:19:59 +00:00
}
2008-08-06 05:53:31 +00:00
PS ( session_status ) = php_session_none ;
/* fallthrough */
default :
case php_session_none :
PS ( define_sid ) = 1 ;
PS ( send_cookie ) = 1 ;
2003-06-10 03:56:23 +00:00
}
2002-05-09 20:02:47 +00:00
lensess = strlen ( PS ( session_name ) ) ;
/*
* Cookies are preferred , because initially
* cookie and get variables will be available .
*/
if ( ! PS ( id ) ) {
2005-05-20 10:27:49 +00:00
if ( PS ( use_cookies ) & & zend_hash_find ( & EG ( symbol_table ) , " _COOKIE " ,
2002-05-09 20:02:47 +00:00
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 ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
2003-02-18 19:29:38 +00:00
PS ( define_sid ) = 0 ;
2002-05-09 20:02:47 +00:00
}
2002-06-12 08:18:36 +00:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & &
2002-05-09 20:02:47 +00:00
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 ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
2002-05-09 20:02:47 +00:00
}
2002-06-12 08:18:36 +00:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & &
2002-05-09 20:02:47 +00:00
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 ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
2002-05-09 20:02:47 +00:00
}
}
/* check the REQUEST_URI symbol for a string of the form
' < session - name > = < session - id > ' to allow URLs of the form
2002-07-03 02:16:46 +00:00
http : //yoursite/<session-name>=<session-id>/script.php */
1999-08-21 20:48:40 +00:00
2003-08-14 01:30:06 +00:00
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 " ,
1999-07-22 17:55:13 +00:00
sizeof ( " REQUEST_URI " ) , ( void * * ) & data ) = = SUCCESS & &
2000-09-06 14:13:31 +00:00
Z_TYPE_PP ( data ) = = IS_STRING & &
( p = strstr ( Z_STRVAL_PP ( data ) , PS ( session_name ) ) ) & &
1999-07-22 17:55:13 +00:00
p [ lensess ] = = ' = ' ) {
char * q ;
p + = lensess + 1 ;
2007-05-16 01:18:14 +00:00
if ( ( q = strpbrk ( p , " /? \\ " ) ) ) {
1999-07-22 17:55:13 +00:00
PS ( id ) = estrndup ( p , q - p ) ;
2007-05-16 01:18:14 +00:00
PS ( send_cookie ) = 0 ;
}
1999-07-22 17:55:13 +00:00
}
1999-08-21 20:48:40 +00:00
/* check whether the current request was referred to by
an external site which invalidates the previously found id */
2008-08-06 05:53:31 +00:00
2000-02-11 12:59:08 +00:00
if ( PS ( id ) & &
1999-08-21 20:48:40 +00:00
PS ( extern_referer_chk ) [ 0 ] ! = ' \0 ' & &
2003-08-14 01:30:06 +00:00
PG ( http_globals ) [ TRACK_VARS_SERVER ] & &
zend_hash_find ( Z_ARRVAL_P ( PG ( http_globals ) [ TRACK_VARS_SERVER ] ) , " HTTP_REFERER " ,
1999-08-21 20:48:40 +00:00
sizeof ( " HTTP_REFERER " ) , ( void * * ) & data ) = = SUCCESS & &
2000-09-06 14:13:31 +00:00
Z_TYPE_PP ( data ) = = IS_STRING & &
Z_STRLEN_PP ( data ) ! = 0 & &
strstr ( Z_STRVAL_PP ( data ) , PS ( extern_referer_chk ) ) = = NULL ) {
1999-08-21 20:48:40 +00:00
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 1 ;
2008-08-06 05:53:31 +00:00
if ( PS ( use_trans_sid ) ) {
2001-10-18 09:05:16 +00:00
PS ( apply_trans_sid ) = 1 ;
2008-08-06 05:53:31 +00:00
}
1999-08-21 20:48:40 +00:00
}
2008-08-06 05:53:31 +00:00
2002-03-29 16:00:27 +00:00
php_session_initialize ( TSRMLS_C ) ;
2008-08-06 05:53:31 +00:00
2003-02-18 19:13:49 +00:00
if ( ! PS ( use_cookies ) & & PS ( send_cookie ) ) {
2008-08-06 05:53:31 +00:00
if ( PS ( use_trans_sid ) ) {
2001-10-18 09:05:16 +00:00
PS ( apply_trans_sid ) = 1 ;
2008-08-06 05:53:31 +00:00
}
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
1999-10-22 08:10:08 +00:00
}
2001-07-11 13:46:11 +00:00
2003-02-18 19:29:38 +00:00
php_session_reset_id ( TSRMLS_C ) ;
2008-08-06 05:53:31 +00:00
2001-08-26 11:49:43 +00:00
PS ( session_status ) = php_session_active ;
1999-06-05 22:15:49 +00:00
2001-07-28 11:36:37 +00:00
php_session_cache_limiter ( TSRMLS_C ) ;
2002-02-03 05:40:19 +00:00
2002-03-06 09:02:31 +00:00
if ( PS ( mod_data ) & & PS ( gc_probability ) > 0 ) {
2000-03-29 20:37:29 +00:00
int nrdels = - 1 ;
2002-03-06 09:02:31 +00:00
2003-04-05 11:22:15 +00:00
nrand = ( int ) ( ( float ) PS ( gc_divisor ) * php_combined_lcg ( TSRMLS_C ) ) ;
2001-07-25 19:02:13 +00:00
if ( nrand < PS ( gc_probability ) ) {
2003-02-11 00:42:14 +00:00
PS ( mod ) - > s_gc ( & PS ( mod_data ) , PS ( gc_maxlifetime ) , & nrdels TSRMLS_CC ) ;
2008-08-06 05:53:31 +00:00
# ifdef SESSION_DEBUG
if ( nrdels ! = - 1 ) {
2003-08-28 20:43:18 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " purged %d expired session objects " , nrdels ) ;
2008-08-06 05:53:31 +00:00
}
2000-09-20 01:38:39 +00:00
# endif
2002-05-09 20:02:47 +00:00
}
}
1999-06-07 16:43:24 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-07 16:43:24 +00:00
2008-08-06 05:53:31 +00:00
static void php_session_flush ( TSRMLS_D ) /* { { { */
1999-06-07 16:43:24 +00:00
{
2008-08-06 05:53:31 +00:00
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 ( ) ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
}
/* }}} */
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
PHPAPI void session_adapt_url ( const char * url , size_t urllen , char * * new , size_t * newlen TSRMLS_DC ) /* { { { */
{
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 ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 22:15:49 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-05 22:15:49 +00:00
2008-08-06 05:53:31 +00:00
/* ********************************
* Userspace exported functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-11 10:16:01 +00:00
2006-08-10 21:10:03 +00:00
/* {{{ proto void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]])
2000-02-04 23:34:24 +00:00
Set session cookie parameters */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_set_cookie_params )
2000-02-04 23:34:24 +00:00
{
2008-08-06 05:53:31 +00:00
zval * * lifetime = NULL ;
2008-06-21 15:27:34 +00:00
char * path = NULL , * domain = NULL ;
int path_len , domain_len , argc = ZEND_NUM_ARGS ( ) ;
2008-08-06 05:53:31 +00:00
zend_bool secure = 0 , httponly = 0 ;
2000-02-04 23:34:24 +00:00
2008-08-06 05:53:31 +00:00
if ( ! PS ( use_cookies ) | |
zend_parse_parameters ( argc TSRMLS_CC , " Z|ssbb " , & lifetime , & path , & path_len ,
& domain , & domain_len , & secure , & httponly ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
}
2002-05-09 20:02:47 +00:00
2004-04-13 00:39:05 +00:00
convert_to_string_ex ( lifetime ) ;
2008-08-06 05:53:31 +00:00
2004-04-13 00:39:05 +00:00
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 ) ;
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
if ( path ) {
2008-06-21 15:27:34 +00:00
zend_alter_ini_entry ( " session.cookie_path " , sizeof ( " session.cookie_path " ) , path , path_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2008-08-06 05:53:31 +00:00
}
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 ) ;
2002-05-09 20:02:47 +00:00
}
2000-02-04 23:34:24 +00:00
}
/* }}} */
2000-06-23 17:37:49 +00:00
/* {{{ proto array session_get_cookie_params(void)
2002-05-09 20:02:47 +00:00
Return the session cookie parameters */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_get_cookie_params )
2000-03-30 20:02:21 +00:00
{
2008-03-10 22:15:36 +00:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-05-09 20:02:47 +00:00
}
2003-01-18 19:28:10 +00:00
array_init ( return_value ) ;
2002-05-09 20:02:47 +00:00
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 ) ) ;
2006-08-10 13:50:56 +00:00
add_assoc_bool ( return_value , " httponly " , PS ( cookie_httponly ) ) ;
2000-03-30 18:50:09 +00:00
}
/* }}} */
2000-02-04 23:34:24 +00:00
1999-06-06 14:19:55 +00:00
/* {{{ proto string session_name([string newname])
2000-06-23 17:37:49 +00:00
Return the current session name . If newname is given , the session name is replaced with newname */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_name )
1999-06-05 19:52:58 +00:00
{
2008-08-06 05:53:31 +00:00
char * name = NULL ;
int name_len ;
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s " , & name , & name_len ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
}
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
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 ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
1999-06-06 14:19:55 +00:00
/* {{{ proto string session_module_name([string newname])
2000-06-23 17:37:49 +00:00
Return the current module name used for accessing session data . If newname is given , the module name is replaced with newname */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_module_name )
1999-06-05 19:52:58 +00:00
{
2008-08-06 05:53:31 +00:00
char * name = NULL ;
int name_len ;
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s " , & name , & name_len ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
2005-06-03 22:09:22 +00:00
}
2002-05-09 20:02:47 +00:00
2005-06-03 22:09:22 +00:00
/* 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 ( ) ;
}
2008-08-06 05:53:31 +00:00
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 ) ;
2006-08-30 15:43:10 +00:00
zval_dtor ( return_value ) ;
2002-05-09 20:02:47 +00:00
RETURN_FALSE ;
}
2004-04-13 18:18:22 +00:00
if ( PS ( mod_data ) ) {
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
}
PS ( mod_data ) = NULL ;
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
zend_alter_ini_entry ( " session.save_handler " , sizeof ( " session.save_handler " ) , name , name_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2004-04-13 18:18:22 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2002-03-06 09:02:31 +00:00
/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
2000-02-24 15:11:09 +00:00
Sets user - level functions */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_set_save_handler )
1999-09-17 05:40:59 +00:00
{
2008-06-21 15:27:34 +00:00
zval * * * args = NULL ;
int i , num_args , argc = ZEND_NUM_ARGS ( ) ;
2005-01-09 17:42:02 +00:00
char * name ;
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
if ( PS ( session_status ) ! = php_session_none ) {
RETURN_FALSE ;
}
2008-06-21 15:27:34 +00:00
if ( argc ! = 6 ) {
2002-05-09 20:02:47 +00:00
WRONG_PARAM_COUNT ;
2008-06-21 15:27:34 +00:00
}
if ( zend_parse_parameters ( argc TSRMLS_CC , " + " , & args , & num_args ) = = FAILURE ) {
return ;
}
2008-08-06 05:53:31 +00:00
2005-01-09 17:42:02 +00:00
for ( i = 0 ; i < 6 ; i + + ) {
2008-08-02 04:46:07 +00:00
if ( ! zend_is_callable ( * args [ i ] , 0 , & name TSRMLS_CC ) ) {
2008-06-24 06:47:45 +00:00
efree ( args ) ;
2005-01-09 17:42:02 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Argument %d is not a valid callback " , i + 1 ) ;
efree ( name ) ;
RETURN_FALSE ;
2005-01-09 17:49:51 +00:00
}
efree ( name ) ;
2005-01-09 17:42:02 +00:00
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
zend_alter_ini_entry ( " session.save_handler " , sizeof ( " session.save_handler " ) , " user " , sizeof ( " user " ) - 1 , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 19:42:00 +00:00
2002-05-09 20:02:47 +00:00
for ( i = 0 ; i < 6 ; i + + ) {
2008-03-07 23:20:32 +00:00
if ( PS ( mod_user_names ) . names [ i ] ! = NULL ) {
zval_ptr_dtor ( & PS ( mod_user_names ) . names [ i ] ) ;
}
2007-10-07 05:22:07 +00:00
Z_ADDREF_PP ( args [ i ] ) ;
2008-03-07 23:20:32 +00:00
PS ( mod_user_names ) . names [ i ] = * args [ i ] ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 05:53:31 +00:00
2008-06-24 06:47:45 +00:00
efree ( args ) ;
2002-05-09 20:02:47 +00:00
RETURN_TRUE ;
1999-09-17 05:40:59 +00:00
}
/* }}} */
1999-06-06 14:19:55 +00:00
/* {{{ proto string session_save_path([string newname])
2000-06-23 17:37:49 +00:00
Return the current save path passed to module_name . If newname is given , the save path is replaced with newname */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_save_path )
1999-06-05 19:52:58 +00:00
{
2008-08-06 05:53:31 +00:00
char * name = NULL ;
int name_len ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s " , & name , & name_len ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
}
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
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 ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
1999-06-06 14:19:55 +00:00
/* {{{ proto string session_id([string newid])
2000-06-23 17:37:49 +00:00
Return the current session id . If newid is given , the session id is replaced with newid */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_id )
1999-06-05 19:52:58 +00:00
{
2008-08-06 05:53:31 +00:00
char * name = NULL ;
int name_len ;
2002-03-06 09:02:31 +00:00
2008-08-06 05:53:31 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s " , & name , & name_len ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
}
2002-03-06 12:34:47 +00:00
2004-07-19 07:19:50 +00:00
if ( PS ( id ) ) {
2008-08-06 05:53:31 +00:00
RETVAL_STRING ( PS ( id ) , 1 ) ;
2004-07-19 07:19:50 +00:00
} else {
2008-08-06 05:53:31 +00:00
RETVAL_EMPTY_STRING ( ) ;
2004-07-19 07:19:50 +00:00
}
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
if ( name ) {
2008-06-21 15:27:34 +00:00
if ( PS ( id ) ) {
efree ( PS ( id ) ) ;
}
2008-08-06 05:53:31 +00:00
PS ( id ) = estrndup ( name , name_len ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2005-05-29 16:51:25 +00:00
/* {{{ proto bool session_regenerate_id([bool delete_old_session])
Update the current session id with a newly generated one . If delete_old_session is set to true , remove the old session . */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_regenerate_id )
2003-02-18 18:50:44 +00:00
{
2005-05-29 16:51:25 +00:00
zend_bool del_ses = 0 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |b " , & del_ses ) = = FAILURE ) {
2006-11-03 14:46:48 +00:00
return ;
2005-05-29 16:51:25 +00:00
}
2006-05-18 22:12:26 +00:00
if ( SG ( headers_sent ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot regenerate session id - headers already sent " ) ;
RETURN_FALSE ;
}
2003-02-18 19:13:49 +00:00
if ( PS ( session_status ) = = php_session_active ) {
2005-05-29 16:51:25 +00:00
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 ) ) ;
2007-03-14 19:37:07 +00:00
PS ( id ) = NULL ;
2005-05-29 16:51:25 +00:00
}
2008-08-06 05:53:31 +00:00
2003-02-18 18:50:44 +00:00
PS ( id ) = PS ( mod ) - > s_create_sid ( & PS ( mod_data ) , NULL TSRMLS_CC ) ;
2003-02-18 19:13:49 +00:00
2006-02-10 07:39:13 +00:00
PS ( send_cookie ) = 1 ;
2003-02-18 19:29:38 +00:00
php_session_reset_id ( TSRMLS_C ) ;
2008-08-06 05:53:31 +00:00
2003-02-18 18:50:44 +00:00
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
2000-09-01 15:56:26 +00:00
/* {{{ proto string session_cache_limiter([string new_cache_limiter])
Return the current cache limiter . If new_cache_limited is given , the current cache_limiter is replaced with new_cache_limiter */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_cache_limiter )
2000-09-01 15:56:26 +00:00
{
2008-08-06 05:53:31 +00:00
char * limiter = NULL ;
int limiter_len ;
2000-09-01 15:56:26 +00:00
2008-08-06 05:53:31 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s " , & limiter , & limiter_len ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
}
2002-05-09 19:42:00 +00:00
2008-08-06 05:53:31 +00:00
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 ) ;
2002-05-09 20:02:47 +00:00
}
2000-09-01 15:56:26 +00:00
}
/* }}} */
2001-10-22 15:18:06 +00:00
/* {{{ proto int session_cache_expire([int new_cache_expire])
Return the current cache expire . If new_cache_expire is given , the current cache_expire is replaced with new_cache_expire */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_cache_expire )
2001-10-22 15:18:06 +00:00
{
2008-08-06 05:53:31 +00:00
zval * * expires = NULL ;
2008-06-21 15:27:34 +00:00
int argc = ZEND_NUM_ARGS ( ) ;
2001-10-22 15:18:06 +00:00
2008-08-06 05:53:31 +00:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |Z " , & expires ) = = FAILURE ) {
2008-06-21 15:27:34 +00:00
return ;
}
2001-10-22 15:18:06 +00:00
2008-08-06 05:53:31 +00:00
RETVAL_LONG ( PS ( cache_expire ) ) ;
2008-06-21 15:27:34 +00:00
if ( argc = = 1 ) {
2008-08-06 05:53:31 +00:00
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 ) ;
2002-05-09 20:02:47 +00:00
}
2001-10-22 15:18:06 +00:00
}
/* }}} */
2001-07-28 11:36:37 +00:00
/* {{{ static void php_register_var(zval** entry TSRMLS_DC) */
static void php_register_var ( zval * * entry TSRMLS_DC )
1999-11-27 21:18:41 +00:00
{
2002-05-09 20:02:47 +00:00
zval * * value ;
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
if ( Z_TYPE_PP ( entry ) = = IS_ARRAY ) {
2008-04-15 00:59:04 +00:00
if ( Z_ARRVAL_PP ( entry ) - > nApplyCount > 1 ) {
return ;
}
2002-05-09 20:02:47 +00:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_PP ( entry ) ) ;
2008-04-15 00:59:04 +00:00
Z_ARRVAL_PP ( entry ) - > nApplyCount + + ;
2002-05-09 20:02:47 +00:00
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 ) ) ;
}
2008-04-15 00:59:04 +00:00
Z_ARRVAL_PP ( entry ) - > nApplyCount - - ;
2002-05-09 20:02:47 +00:00
} else {
convert_to_string_ex ( entry ) ;
2004-05-08 05:58:18 +00:00
if ( ( strcmp ( Z_STRVAL_PP ( entry ) , " HTTP_SESSION_VARS " ) ! = 0 ) & &
2002-05-09 20:02:47 +00:00
( strcmp ( Z_STRVAL_PP ( entry ) , " _SESSION " ) ! = 0 ) ) {
PS_ADD_VARL ( Z_STRVAL_PP ( entry ) , Z_STRLEN_PP ( entry ) ) ;
}
}
1999-11-27 21:18:41 +00:00
}
/* }}} */
2008-08-06 05:53:31 +00:00
/* {{{ proto string session_encode(void)
Serializes the current setup and returns the serialized representation */
static PHP_FUNCTION ( session_encode )
{
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 ) ;
}
/* }}} */
/* {{{ proto bool session_decode(string data)
Deserializes data and reinitializes the variables */
static PHP_FUNCTION ( session_decode )
{
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 ;
}
/* }}} */
/* {{{ proto bool session_start(void)
Begin session - reinitializes freezed variables , registers browsers etc */
static PHP_FUNCTION ( session_start )
{
/* 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 ;
}
/* }}} */
/* {{{ proto bool session_destroy(void)
Destroy the current session and all data associated with it */
static PHP_FUNCTION ( session_destroy )
{
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETURN_BOOL ( php_session_destroy ( TSRMLS_C ) = = SUCCESS ) ;
}
/* }}} */
/* {{{ proto void session_unset(void)
Unset all registered variables */
static PHP_FUNCTION ( session_unset )
{
if ( PS ( session_status ) = = php_session_none ) {
RETURN_FALSE ;
}
IF_SESSION_VARS ( ) {
HashTable * ht = 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 , & pos ) ;
while ( zend_hash_get_current_key_ex ( ht , & 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 , & pos ) ;
}
}
/* Clean $_SESSION. */
zend_hash_clean ( ht ) ;
}
}
/* }}} */
/* {{{ proto void session_write_close(void)
Write session data and end session */
static PHP_FUNCTION ( session_write_close )
{
php_session_flush ( TSRMLS_C ) ;
}
/* }}} */
2000-06-23 17:37:49 +00:00
/* {{{ proto bool session_register(mixed var_names [, mixed ...])
2000-02-24 15:11:09 +00:00
Adds varname ( s ) to the list of variables which are freezed at the session end */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_register )
1999-06-05 19:52:58 +00:00
{
2008-06-21 15:27:34 +00:00
zval * * * args = NULL ;
int num_args , i ;
2008-08-06 05:53:31 +00:00
2008-06-21 15:27:34 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " + " , & args , & num_args ) = = FAILURE ) {
return ;
2002-05-09 20:02:47 +00:00
}
2002-05-09 19:42:00 +00:00
2004-09-30 12:19:59 +00:00
if ( PS ( session_status ) = = php_session_none | | PS ( session_status ) = = php_session_disabled ) {
2002-05-09 20:02:47 +00:00
php_session_start ( TSRMLS_C ) ;
2004-09-30 12:19:59 +00:00
}
2008-08-06 05:53:31 +00:00
2004-09-30 12:19:59 +00:00
if ( PS ( session_status ) = = php_session_disabled ) {
2008-06-21 15:27:34 +00:00
if ( args ) {
efree ( args ) ;
}
2004-09-30 12:19:59 +00:00
RETURN_FALSE ;
}
2008-08-06 05:53:31 +00:00
2008-06-21 15:27:34 +00:00
for ( i = 0 ; i < num_args ; i + + ) {
if ( Z_TYPE_PP ( args [ i ] ) = = IS_ARRAY ) {
2002-05-09 20:02:47 +00:00
SEPARATE_ZVAL ( args [ i ] ) ;
2008-06-21 15:27:34 +00:00
}
2002-05-09 20:02:47 +00:00
php_register_var ( args [ i ] TSRMLS_CC ) ;
2008-08-06 05:53:31 +00:00
}
2008-06-21 15:27:34 +00:00
if ( args ) {
efree ( args ) ;
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
RETURN_TRUE ;
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
1999-10-24 16:17:45 +00:00
/* {{{ proto bool session_unregister(string varname)
2000-02-24 15:11:09 +00:00
Removes varname from the list of variables which are freezed at the session end */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_unregister )
1999-06-05 19:52:58 +00:00
{
2008-06-21 15:27:34 +00:00
char * p_name ;
int p_name_len ;
2008-08-06 05:53:31 +00:00
2008-06-21 15:27:34 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & p_name , & p_name_len ) = = FAILURE ) {
return ;
}
2008-08-06 05:53:31 +00:00
2008-06-21 15:27:34 +00:00
PS_DEL_VARL ( p_name , p_name_len ) ;
1999-10-24 16:17:45 +00:00
2002-05-09 20:02:47 +00:00
RETURN_TRUE ;
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
1999-06-28 15:46:56 +00:00
/* {{{ proto bool session_is_registered(string varname)
2000-02-24 15:11:09 +00:00
Checks if a variable is registered in session */
2008-08-06 05:53:31 +00:00
static PHP_FUNCTION ( session_is_registered )
1999-06-28 15:46:56 +00:00
{
2002-05-09 20:02:47 +00:00
zval * p_var ;
2008-06-21 15:27:34 +00:00
char * p_name ;
int p_name_len ;
1999-06-28 15:46:56 +00:00
2008-06-21 15:27:34 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & p_name , & p_name_len ) = = FAILURE ) {
return ;
}
2008-08-06 05:53:31 +00:00
2008-06-21 15:27:34 +00:00
if ( PS ( session_status ) = = php_session_none ) {
2002-05-09 20:02:47 +00:00
RETURN_FALSE ;
2008-06-21 15:27:34 +00:00
}
2002-10-03 03:23:02 +00:00
IF_SESSION_VARS ( ) {
2008-06-21 15:27:34 +00:00
if ( zend_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , p_name , p_name_len + 1 , ( void * * ) & p_var ) = = SUCCESS ) {
2002-10-03 03:23:02 +00:00
RETURN_TRUE ;
}
}
RETURN_FALSE ;
1999-06-28 15:46:56 +00:00
}
/* }}} */
2008-08-06 05:53:31 +00:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_name , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , name )
ZEND_END_ARG_INFO ( )
2001-08-13 06:43:47 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_module_name , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , module )
ZEND_END_ARG_INFO ( )
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_save_path , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , path )
ZEND_END_ARG_INFO ( )
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_id , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , id )
ZEND_END_ARG_INFO ( )
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_regenerate_id , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , delete_old_session )
ZEND_END_ARG_INFO ( )
2002-10-03 15:33:00 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_decode , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , data )
ZEND_END_ARG_INFO ( )
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_register , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , name )
ZEND_ARG_INFO ( 0 , . . . )
ZEND_END_ARG_INFO ( )
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_unregister , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , name )
ZEND_END_ARG_INFO ( )
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_is_registered , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , name )
ZEND_END_ARG_INFO ( )
1999-06-07 16:43:24 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO ( arginfo_session_void , 0 )
ZEND_END_ARG_INFO ( )
2001-07-04 15:30:21 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_set_save_handler , 0 , 0 , 6 )
ZEND_ARG_INFO ( 0 , open )
ZEND_ARG_INFO ( 0 , close )
ZEND_ARG_INFO ( 0 , read )
ZEND_ARG_INFO ( 0 , write )
ZEND_ARG_INFO ( 0 , destroy )
ZEND_ARG_INFO ( 0 , gc )
ZEND_END_ARG_INFO ( )
2002-05-09 20:02:47 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_cache_limiter , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , cache_limiter )
ZEND_END_ARG_INFO ( )
2002-10-03 03:23:02 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_cache_expire , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , new_cache_expire )
ZEND_END_ARG_INFO ( )
2002-10-03 03:23:02 +00:00
2008-08-06 05:53:31 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_set_cookie_params , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , lifetime )
ZEND_ARG_INFO ( 0 , path )
ZEND_ARG_INFO ( 0 , domain )
ZEND_ARG_INFO ( 0 , secure )
ZEND_ARG_INFO ( 0 , httponly )
ZEND_END_ARG_INFO ( )
1999-09-11 22:31:04 +00:00
/* }}} */
2008-08-06 05:53:31 +00:00
/* {{{ session_functions[]
*/
static const zend_function_entry session_functions [ ] = {
PHP_FE ( session_name , arginfo_session_name )
PHP_FE ( session_module_name , arginfo_session_module_name )
PHP_FE ( session_save_path , arginfo_session_save_path )
PHP_FE ( session_id , arginfo_session_id )
PHP_FE ( session_regenerate_id , arginfo_session_regenerate_id )
PHP_FE ( session_decode , arginfo_session_decode )
2008-12-09 14:03:58 +00:00
PHP_DEP_FE ( session_register , arginfo_session_register )
PHP_DEP_FE ( session_unregister , arginfo_session_unregister )
PHP_DEP_FE ( session_is_registered , arginfo_session_is_registered )
2008-08-06 05:53:31 +00:00
PHP_FE ( session_encode , arginfo_session_void )
PHP_FE ( session_start , arginfo_session_void )
PHP_FE ( session_destroy , arginfo_session_void )
PHP_FE ( session_unset , arginfo_session_void )
PHP_FE ( session_set_save_handler , arginfo_session_set_save_handler )
PHP_FE ( session_cache_limiter , arginfo_session_cache_limiter )
PHP_FE ( session_cache_expire , arginfo_session_cache_expire )
PHP_FE ( session_set_cookie_params , arginfo_session_set_cookie_params )
PHP_FE ( session_get_cookie_params , arginfo_session_void )
PHP_FE ( session_write_close , arginfo_session_void )
PHP_FALIAS ( session_commit , session_write_close , arginfo_session_void )
{ NULL , NULL , NULL }
} ;
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
/* ********************************
* Module Setup and Destruction *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-11-17 22:59:27 +00:00
2008-08-06 05:53:31 +00:00
static PHP_RINIT_FUNCTION ( session ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
php_rinit_session_globals ( TSRMLS_C ) ;
1999-06-06 18:22:17 +00:00
2002-05-09 20:02:47 +00:00
if ( PS ( mod ) = = NULL ) {
char * value ;
2001-05-23 23:18:51 +00:00
2002-05-09 20:02:47 +00:00
value = zend_ini_string ( " session.save_handler " , sizeof ( " session.save_handler " ) , 0 ) ;
if ( value ) {
PS ( mod ) = _php_find_ps_module ( value TSRMLS_CC ) ;
}
2008-08-04 06:21:55 +00:00
}
if ( PS ( serializer ) = = NULL ) {
char * value ;
2001-05-23 23:18:51 +00:00
2008-08-04 06:21:55 +00:00
value = zend_ini_string ( " session.serialize_handler " , sizeof ( " session.serialize_handler " ) , 0 ) ;
2008-08-06 05:53:31 +00:00
if ( value ) {
2008-08-04 06:21:55 +00:00
PS ( serializer ) = _php_find_ps_serializer ( value TSRMLS_CC ) ;
2002-05-09 20:02:47 +00:00
}
}
1999-08-27 21:03:22 +00:00
2008-08-04 06:21:55 +00:00
if ( PS ( mod ) = = NULL | | PS ( serializer ) = = NULL ) {
/* current status is unusable */
PS ( session_status ) = php_session_disabled ;
return SUCCESS ;
}
2002-05-09 20:02:47 +00:00
if ( PS ( auto_start ) ) {
php_session_start ( TSRMLS_C ) ;
}
1999-06-05 19:52:58 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
2000-01-16 21:03:49 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
2000-01-15 13:09:32 +00:00
2008-08-06 05:53:31 +00:00
static PHP_RSHUTDOWN_FUNCTION ( session ) /* { { { */
2000-10-11 19:47:15 +00:00
{
2008-03-07 23:20:32 +00:00
int i ;
2005-09-23 08:14:13 +00:00
php_session_flush ( TSRMLS_C ) ;
php_rshutdown_session_globals ( TSRMLS_C ) ;
2008-08-06 05:53:31 +00:00
2008-03-07 23:20:32 +00:00
/* 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 ] ) ;
2008-03-11 09:36:41 +00:00
PS ( mod_user_names ) . names [ i ] = NULL ;
2008-03-07 23:20:32 +00:00
}
}
2005-09-20 20:56:54 +00:00
1999-06-05 19:52:58 +00:00
return SUCCESS ;
}
2001-12-04 22:57:16 +00:00
/* }}} */
2000-01-16 21:03:49 +00:00
2008-08-06 05:53:31 +00:00
static PHP_GINIT_FUNCTION ( ps ) /* { { { */
2004-02-24 08:47:35 +00:00
{
2008-03-07 23:20:32 +00:00
int i ;
2004-02-24 08:47:35 +00:00
ps_globals - > save_path = NULL ;
ps_globals - > session_name = NULL ;
ps_globals - > id = NULL ;
ps_globals - > mod = NULL ;
2008-08-06 05:53:31 +00:00
ps_globals - > serializer = NULL ;
2004-02-24 08:47:35 +00:00
ps_globals - > mod_data = NULL ;
ps_globals - > session_status = php_session_none ;
2008-03-07 23:20:32 +00:00
for ( i = 0 ; i < 6 ; i + + ) {
ps_globals - > mod_user_names . names [ i ] = NULL ;
}
2004-02-24 08:47:35 +00:00
ps_globals - > http_session_vars = NULL ;
}
2008-08-06 05:53:31 +00:00
/* }}} */
2000-01-16 21:03:49 +00:00
2008-08-06 05:53:31 +00:00
static PHP_MINIT_FUNCTION ( session ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2003-03-02 10:19:15 +00:00
zend_register_auto_global ( " _SESSION " , sizeof ( " _SESSION " ) - 1 , NULL TSRMLS_CC ) ;
2001-08-11 10:49:03 +00:00
2002-05-05 16:39:49 +00:00
PS ( module_number ) = module_number ; /* if we really need this var we need to init it in zts mode as well! */
2002-06-28 02:27:02 +00:00
2003-01-08 13:28:16 +00:00
PS ( session_status ) = php_session_none ;
1999-06-05 19:52:58 +00:00
REGISTER_INI_ENTRIES ( ) ;
2002-06-28 02:27:02 +00:00
# ifdef HAVE_LIBMM
PHP_MINIT ( ps_mm ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
# endif
1999-06-05 19:52:58 +00:00
return SUCCESS ;
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 05:53:31 +00:00
static PHP_MSHUTDOWN_FUNCTION ( session ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
UNREGISTER_INI_ENTRIES ( ) ;
2002-06-28 02:27:02 +00:00
# ifdef HAVE_LIBMM
PHP_MSHUTDOWN ( ps_mm ) ( SHUTDOWN_FUNC_ARGS_PASSTHRU ) ;
# endif
2004-12-07 18:02:25 +00:00
ps_serializers [ PREDEFINED_SERIALIZERS ] . name = NULL ;
2005-09-20 14:03:29 +00:00
memset ( & ps_modules [ PREDEFINED_MODULES ] , 0 , ( MAX_MODULES - PREDEFINED_MODULES ) * sizeof ( ps_module * ) ) ;
2004-12-07 18:02:25 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
1999-06-06 19:53:59 +00:00
2008-08-06 05:53:31 +00:00
static PHP_MINFO_FUNCTION ( session ) /* { { { */
1999-06-06 19:53:59 +00:00
{
2002-06-28 02:27:02 +00:00
ps_module * * mod ;
2003-08-26 02:03:41 +00:00
ps_serializer * ser ;
smart_str save_handlers = { 0 } ;
smart_str ser_handlers = { 0 } ;
2002-06-28 02:27:02 +00:00
int i ;
2008-08-06 05:53:31 +00:00
2003-08-26 02:03:41 +00:00
/* Get save handlers */
2002-06-28 02:27:02 +00:00
for ( i = 0 , mod = ps_modules ; i < MAX_MODULES ; i + + , mod + + ) {
2003-02-11 00:42:14 +00:00
if ( * mod & & ( * mod ) - > s_name ) {
2003-08-26 02:03:41 +00:00
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 , ' ' ) ;
2002-06-28 02:27:02 +00:00
}
}
2008-08-06 05:53:31 +00:00
2002-05-09 20:02:47 +00:00
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " Session Support " , " enabled " ) ;
2002-06-28 02:27:02 +00:00
2003-08-26 02:03:41 +00:00
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 ) ;
2002-06-28 02:27:02 +00:00
} else {
php_info_print_table_row ( 2 , " Registered save handlers " , " none " ) ;
}
2003-08-26 02:03:41 +00:00
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 " ) ;
}
2002-05-09 20:02:47 +00:00
php_info_print_table_end ( ) ;
2000-04-06 21:07:44 +00:00
2002-05-09 20:02:47 +00:00
DISPLAY_INI_ENTRIES ( ) ;
1999-06-06 19:53:59 +00:00
}
2008-08-06 05:53:31 +00:00
/* }}} */
zend_module_entry session_module_entry = {
STANDARD_MODULE_HEADER ,
" session " ,
session_functions ,
PHP_MINIT ( session ) , PHP_MSHUTDOWN ( session ) ,
PHP_RINIT ( session ) , PHP_RSHUTDOWN ( session ) ,
PHP_MINFO ( session ) ,
NO_VERSION_YET ,
PHP_MODULE_GLOBALS ( ps ) ,
PHP_GINIT ( ps ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
} ;
2001-06-06 14:32:27 +00:00
2008-08-06 05:53:31 +00:00
# ifdef COMPILE_DL_SESSION
ZEND_GET_MODULE ( session )
# endif
2001-08-25 15:57:42 +00:00
2001-06-06 14:32:27 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2006-05-18 22:12:26 +00:00
* vim600 : noet sw = 4 ts = 4 fdm = marker
2001-09-09 13:29:31 +00:00
* vim < 600 : sw = 4 ts = 4
2001-06-06 14:32:27 +00:00
*/