1999-12-12 22:22:55 +08:00
/*
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 16:18:22 +08:00
| PHP Version 5 |
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| Copyright ( c ) 1997 - 2006 The PHP Group |
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
1999-07-16 21:13:16 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
1999-07-16 21:13:16 +08: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-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-07-10 18:09:15 +08:00
| Authors : Sascha Schumann < sascha @ schumann . cx > |
2002-05-14 01:28:38 +08:00
| Andrei Zmievski < andrei @ php . net > |
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2001-06-06 22:32:27 +08:00
/* $Id$ */
2001-05-24 18:07:29 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2000-02-11 21:41:30 +08:00
# include "php.h"
2000-02-11 23:59:30 +08:00
# ifdef PHP_WIN32
1999-06-07 03:53:59 +08:00
# include "win32/time.h"
2000-02-11 21:41:30 +08:00
# else
# include <sys/time.h>
1999-06-07 02:22:17 +08:00
# endif
1999-06-06 03:52:58 +08:00
1999-12-12 22:16:55 +08:00
# include <sys/stat.h>
1999-09-12 01:20:31 +08:00
# include <fcntl.h>
1999-06-06 03:52:58 +08:00
# include "php_ini.h"
# include "SAPI.h"
# include "php_session.h"
1999-06-07 03:53:59 +08:00
# include "ext/standard/md5.h"
2003-01-12 21:07:14 +08:00
# include "ext/standard/sha1.h"
1999-12-05 03:19:57 +08:00
# include "ext/standard/php_var.h"
1999-06-29 23:39:59 +08:00
# include "ext/standard/datetime.h"
1999-09-01 22:20:15 +08:00
# include "ext/standard/php_lcg.h"
2000-09-20 09:22:55 +08:00
# include "ext/standard/url_scanner_ex.h"
1999-12-19 07:28:43 +08:00
# include "ext/standard/php_rand.h" /* for RAND_MAX */
2000-04-07 05:07:44 +08:00
# include "ext/standard/info.h"
2001-03-14 00:53:34 +08:00
# include "ext/standard/php_smart_str.h"
2001-05-03 23:48:49 +08:00
# include "mod_files.h"
# include "mod_user.h"
2002-06-28 10:27:02 +08:00
# ifdef HAVE_LIBMM
# include "mod_mm.h"
# endif
2001-06-06 22:32:27 +08:00
/* {{{ session_functions[]
*/
2005-12-06 10:28:41 +08:00
zend_function_entry session_functions [ ] = {
2002-07-03 10:16:46 +08:00
PHP_FE ( session_name , NULL )
PHP_FE ( session_module_name , NULL )
PHP_FE ( session_save_path , NULL )
PHP_FE ( session_id , NULL )
2003-02-19 02:50:44 +08:00
PHP_FE ( session_regenerate_id , NULL )
2002-07-03 10:16:46 +08:00
PHP_FE ( session_decode , NULL )
PHP_FE ( session_register , NULL )
PHP_FE ( session_unregister , NULL )
PHP_FE ( session_is_registered , NULL )
PHP_FE ( session_encode , NULL )
PHP_FE ( session_start , NULL )
PHP_FE ( session_destroy , NULL )
PHP_FE ( session_unset , NULL )
PHP_FE ( session_set_save_handler , NULL )
PHP_FE ( session_cache_limiter , NULL )
PHP_FE ( session_cache_expire , NULL )
2002-05-10 04:02:47 +08:00
PHP_FE ( session_set_cookie_params , NULL )
PHP_FE ( session_get_cookie_params , NULL )
2002-07-03 10:16:46 +08:00
PHP_FE ( session_write_close , NULL )
2003-09-21 19:53:12 +08:00
PHP_FALIAS ( session_commit , session_write_close , NULL )
2002-05-10 04:02:47 +08:00
{ NULL , NULL , NULL }
1999-06-06 03:52:58 +08:00
} ;
2001-06-06 22:32:27 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
2004-01-09 23:30:07 +08:00
PHPAPI ZEND_DECLARE_MODULE_GLOBALS ( ps ) ;
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( ps ) ;
2001-05-02 01:01:51 +08:00
2003-12-15 07:24:50 +08:00
# define SESSION_CHECK_ACTIVE_STATE \
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 ; \
} \
2000-05-26 21:02:11 +08:00
static PHP_INI_MH ( OnUpdateSaveHandler )
{
2006-08-30 23:43:10 +08:00
ps_module * tmp ;
2003-12-15 07:24:50 +08:00
SESSION_CHECK_ACTIVE_STATE ;
2006-08-30 23:43:10 +08:00
tmp = _php_find_ps_module ( new_value TSRMLS_CC ) ;
2002-05-12 20:51:42 +08:00
2006-08-30 23:43:10 +08:00
if ( PG ( modules_activated ) & & ! tmp ) {
2006-08-31 00:24:40 +08:00
int err_type ;
if ( stage = = ZEND_INI_STAGE_RUNTIME ) {
err_type = E_WARNING ;
} else {
err_type = E_ERROR ;
}
php_error_docref ( NULL TSRMLS_CC , err_type , " Cannot find save handler %s " , new_value ) ;
2006-08-30 23:43:10 +08:00
return FAILURE ;
2002-05-12 20:51:42 +08:00
}
2006-08-30 23:43:10 +08:00
PS ( mod ) = tmp ;
2003-08-26 10:03:41 +08:00
2002-05-10 04:02:47 +08:00
return SUCCESS ;
2000-05-26 21:02:11 +08:00
}
2003-12-15 07:24:50 +08:00
static PHP_INI_MH ( OnUpdateTransSid )
2000-05-26 21:02:11 +08:00
{
2003-12-15 07:24:50 +08:00
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 ) ;
2002-11-21 01:15:00 +08:00
}
2003-12-15 07:24:50 +08:00
return SUCCESS ;
}
static PHP_INI_MH ( OnUpdateSerializer )
{
2006-08-30 23:43:10 +08:00
const ps_serializer * tmp ;
2003-12-15 07:24:50 +08:00
SESSION_CHECK_ACTIVE_STATE ;
2006-08-30 23:43:10 +08:00
tmp = _php_find_ps_serializer ( new_value TSRMLS_CC ) ;
2002-05-12 20:51:42 +08:00
2006-08-30 23:43:10 +08:00
if ( PG ( modules_activated ) & & ! tmp ) {
2006-08-31 00:24:40 +08:00
int err_type ;
if ( stage = = ZEND_INI_STAGE_RUNTIME ) {
err_type = E_WARNING ;
} else {
err_type = E_ERROR ;
}
php_error_docref ( NULL TSRMLS_CC , err_type , " Cannot find serialization handler %s " , new_value ) ;
2006-08-30 23:43:10 +08:00
return FAILURE ;
2002-05-12 20:51:42 +08:00
}
2006-08-30 23:43:10 +08:00
PS ( serializer ) = tmp ;
2003-08-26 10:03:41 +08:00
2002-05-10 04:02:47 +08:00
return SUCCESS ;
2000-05-26 21:02:11 +08:00
}
2005-05-23 14:46:25 +08:00
static PHP_INI_MH ( OnUpdateSaveDir )
{
2005-05-22 01:37:56 +08:00
/* Only do the safemode/open_basedir check at runtime */
2005-05-23 14:46:25 +08:00
if ( stage = = PHP_INI_STAGE_RUNTIME ) {
2006-10-02 04:58:02 +08:00
char * p ;
2006-12-01 08:27:20 +08:00
if ( memchr ( new_value , ' \0 ' , new_value_length ) ! = NULL ) {
return FAILURE ;
}
2006-10-02 04:58:02 +08:00
if ( ( p = zend_memrchr ( new_value , ' ; ' , new_value_length ) ) ) {
p + + ;
} else {
p = new_value ;
}
if ( PG ( safe_mode ) & & ( ! php_checkuid ( p , NULL , CHECKUID_ALLOW_ONLY_DIR ) ) ) {
2005-05-22 01:37:56 +08:00
return FAILURE ;
}
2006-10-02 04:58:02 +08:00
if ( php_check_open_basedir ( p TSRMLS_CC ) ) {
2005-05-22 01:37:56 +08:00
return FAILURE ;
}
}
OnUpdateString ( entry , new_value , new_value_length , mh_arg1 , mh_arg2 , mh_arg3 , stage TSRMLS_CC ) ;
2005-05-22 20:57:26 +08:00
return SUCCESS ;
2005-05-22 01:37:56 +08:00
}
2000-05-26 21:02:11 +08:00
2001-06-06 22:32:27 +08:00
/* {{{ PHP_INI
*/
1999-06-06 03:52:58 +08:00
PHP_INI_BEGIN ( )
2002-10-03 11:23:02 +08:00
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 )
2005-05-22 01:37:56 +08:00
STD_PHP_INI_ENTRY ( " session.save_path " , " " , PHP_INI_ALL , OnUpdateSaveDir , save_path , php_ps_globals , ps_globals )
2002-07-03 10:16:46 +08:00
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 )
2003-03-07 13:15:28 +08:00
STD_PHP_INI_ENTRY ( " session.gc_probability " , " 1 " , PHP_INI_ALL , OnUpdateLong , gc_probability , php_ps_globals , ps_globals )
2003-04-05 19:22:15 +08:00
STD_PHP_INI_ENTRY ( " session.gc_divisor " , " 100 " , PHP_INI_ALL , OnUpdateLong , gc_divisor , php_ps_globals , ps_globals )
2003-03-07 13:15:28 +08:00
STD_PHP_INI_ENTRY ( " session.gc_maxlifetime " , " 1440 " , PHP_INI_ALL , OnUpdateLong , gc_maxlifetime , php_ps_globals , ps_globals )
2002-07-03 10:16:46 +08:00
PHP_INI_ENTRY ( " session.serialize_handler " , " php " , PHP_INI_ALL , OnUpdateSerializer )
2003-03-07 13:15:28 +08:00
STD_PHP_INI_ENTRY ( " session.cookie_lifetime " , " 0 " , PHP_INI_ALL , OnUpdateLong , cookie_lifetime , php_ps_globals , ps_globals )
2002-07-03 10:16:46 +08:00
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 )
2006-08-10 21:50:56 +08:00
STD_PHP_INI_BOOLEAN ( " session.cookie_httponly " , " " , PHP_INI_ALL , OnUpdateBool , cookie_httponly , php_ps_globals , ps_globals )
2002-07-03 10:16:46 +08:00
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 " , " 0 " , 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 )
2003-03-07 13:15:28 +08:00
STD_PHP_INI_ENTRY ( " session.entropy_length " , " 0 " , PHP_INI_ALL , OnUpdateLong , entropy_length , php_ps_globals , ps_globals )
2002-07-03 10:16:46 +08:00
STD_PHP_INI_ENTRY ( " session.cache_limiter " , " nocache " , PHP_INI_ALL , OnUpdateString , cache_limiter , php_ps_globals , ps_globals )
2003-03-07 13:15:28 +08:00
STD_PHP_INI_ENTRY ( " session.cache_expire " , " 180 " , PHP_INI_ALL , OnUpdateLong , cache_expire , php_ps_globals , ps_globals )
2003-12-15 07:24:50 +08:00
PHP_INI_ENTRY ( " session.use_trans_sid " , " 0 " , PHP_INI_ALL , OnUpdateTransSid )
2003-03-07 13:15:28 +08:00
STD_PHP_INI_ENTRY ( " session.hash_function " , " 0 " , PHP_INI_ALL , OnUpdateLong , hash_func , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.hash_bits_per_character " , " 4 " , PHP_INI_ALL , OnUpdateLong , hash_bits_per_character , php_ps_globals , ps_globals )
2003-01-16 15:21:49 +08:00
2002-05-10 04:02:47 +08:00
/* Commented out until future discussion */
/* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
1999-06-06 03:52:58 +08:00
PHP_INI_END ( )
2001-06-06 22:32:27 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-07-01 13:45:48 +08:00
PS_SERIALIZER_FUNCS ( php ) ;
2000-09-01 23:24:58 +08:00
PS_SERIALIZER_FUNCS ( php_binary ) ;
1999-07-01 13:45:48 +08:00
2001-05-02 01:01:51 +08:00
# define MAX_SERIALIZERS 10
2004-12-08 02:02:25 +08:00
# define PREDEFINED_SERIALIZERS 2
1999-09-17 13:40:59 +08:00
2001-05-02 01:01:51 +08:00
static ps_serializer ps_serializers [ MAX_SERIALIZERS + 1 ] = {
2002-05-10 04:02:47 +08:00
PS_SERIALIZER_ENTRY ( php ) ,
PS_SERIALIZER_ENTRY ( php_binary )
1999-07-01 13:45:48 +08:00
} ;
1999-06-07 03:53:59 +08:00
2001-05-03 23:48:49 +08:00
# define MAX_MODULES 10
2004-12-08 02:02:25 +08:00
# define PREDEFINED_MODULES 2
2001-05-03 23:48:49 +08:00
static ps_module * ps_modules [ MAX_MODULES + 1 ] = {
2002-05-10 04:02:47 +08:00
ps_files_ptr ,
ps_user_ptr
2001-05-03 23:48:49 +08:00
} ;
2002-10-03 11:23:02 +08:00
# define IF_SESSION_VARS() \
if ( PS ( http_session_vars ) & & PS ( http_session_vars ) - > type = = IS_ARRAY )
2002-05-10 04:02:47 +08:00
PHPAPI int php_session_register_serializer ( const char * name ,
int ( * encode ) ( PS_SERIALIZER_ENCODE_ARGS ) ,
int ( * decode ) ( PS_SERIALIZER_DECODE_ARGS ) )
2001-05-02 01:01:51 +08:00
{
2002-05-10 04:02:47 +08:00
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 ;
2001-05-02 01:01:51 +08:00
}
2002-01-17 07:24:37 +08:00
PHPAPI int php_session_register_module ( ps_module * ptr )
2001-05-03 23:48:49 +08:00
{
2002-05-10 04:02:47 +08:00
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 ;
2001-05-03 23:48:49 +08:00
}
2001-05-02 01:01:51 +08:00
1999-09-17 13:40:59 +08:00
PHP_MINIT_FUNCTION ( session ) ;
PHP_RINIT_FUNCTION ( session ) ;
PHP_MSHUTDOWN_FUNCTION ( session ) ;
2000-01-17 05:03:49 +08:00
PHP_RSHUTDOWN_FUNCTION ( session ) ;
1999-09-17 13:40:59 +08:00
PHP_MINFO_FUNCTION ( session ) ;
2001-07-28 19:36:37 +08:00
static void php_rinit_session_globals ( TSRMLS_D ) ;
static void php_rshutdown_session_globals ( TSRMLS_D ) ;
static zend_bool php_session_destroy ( TSRMLS_D ) ;
1999-06-06 03:52:58 +08:00
zend_module_entry session_module_entry = {
2002-05-10 04:02:47 +08:00
STANDARD_MODULE_HEADER ,
" session " ,
session_functions ,
PHP_MINIT ( session ) , PHP_MSHUTDOWN ( session ) ,
PHP_RINIT ( session ) , PHP_RSHUTDOWN ( session ) ,
PHP_MINFO ( session ) ,
2002-07-03 10:16:46 +08:00
NO_VERSION_YET ,
2006-06-16 02:33:09 +08:00
PHP_MODULE_GLOBALS ( ps ) ,
PHP_GINIT ( ps ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
1999-06-06 03:52:58 +08:00
} ;
2000-05-23 17:33:51 +08:00
# ifdef COMPILE_DL_SESSION
2000-05-02 08:30:36 +08:00
ZEND_GET_MODULE ( session )
2000-05-01 10:42:55 +08:00
# endif
1999-12-12 22:16:55 +08:00
typedef struct {
2002-05-10 04:02:47 +08:00
char * name ;
void ( * func ) ( TSRMLS_D ) ;
2000-09-06 22:16:12 +08:00
} php_session_cache_limiter_t ;
1999-12-12 22:16:55 +08:00
2002-05-12 20:51:42 +08:00
# 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) },
1999-12-12 22:16:55 +08:00
2003-04-28 00:04:53 +08:00
# define ADD_HEADER(a) sapi_add_header(a, strlen(a), 1);
1999-12-12 22:16:55 +08:00
1999-06-06 03:52:58 +08:00
# define MAX_STR 512
2006-01-28 14:18:01 +08:00
PHPAPI void php_add_session_var ( char * name , size_t namelen TSRMLS_DC )
2002-10-01 19:59:45 +08:00
{
zval * * sym_track = NULL ;
2006-08-02 17:16:52 +08:00
IF_SESSION_VARS ( ) {
zend_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 ,
( void * ) & sym_track ) ;
} else {
return ;
}
2002-10-01 19:59:45 +08:00
/*
* Set up a proper reference between $ _SESSION [ " x " ] and $ x .
*/
if ( PG ( register_globals ) ) {
zval * * sym_global = NULL ;
zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 ,
( void * ) & sym_global ) ;
if ( sym_global = = NULL & & sym_track = = NULL ) {
zval * empty_var ;
2002-10-03 05:51:32 +08:00
ALLOC_INIT_ZVAL ( empty_var ) ; /* this sets refcount to 1 */
2004-02-15 20:58:19 +08:00
empty_var - > refcount = 0 ; /* our module does not maintain a ref */
2002-10-03 05:51:32 +08:00
/* The next call will increase refcount by NR_OF_SYM_TABLES==2 */
2002-10-01 19:59:45 +08:00
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 ) {
2003-05-15 21:33:18 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( sym_track ) ;
2002-10-01 19:59:45 +08:00
zend_set_hash_symbol ( * sym_track , name , namelen , 1 , 1 , & EG ( symbol_table ) ) ;
} else if ( sym_track = = NULL ) {
2003-05-15 21:33:18 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( sym_global ) ;
2002-10-01 19:59:45 +08:00
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 ) ;
2002-10-03 05:51:32 +08:00
ZEND_SET_SYMBOL_WITH_LENGTH ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , empty_var , 1 , 0 ) ;
2002-10-01 19:59:45 +08:00
}
}
}
2006-01-28 14:18:01 +08: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-05 01:02:04 +08:00
{
2002-05-10 04:02:47 +08:00
if ( PG ( register_globals ) ) {
zval * * old_symbol ;
if ( zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 , ( void * ) & old_symbol ) = = SUCCESS ) {
2003-08-29 20:33:47 +08:00
2002-05-10 04:02:47 +08:00
/*
2003-08-29 20:33:47 +08: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-10 04:02:47 +08:00
*/
REPLACE_ZVAL_VALUE ( old_symbol , state_val , 1 ) ;
2003-08-29 20:33:47 +08: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-10 04:02:47 +08:00
*/
2003-08-29 20:33:47 +08:00
if ( var_hash ) {
PHP_VAR_UNSERIALIZE_ZVAL_CHANGED ( var_hash , state_val , * old_symbol ) ;
}
2002-05-10 04:02:47 +08: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 11:23:02 +08:00
} else IF_SESSION_VARS ( ) {
2003-08-12 03:20:44 +08:00
zend_set_hash_symbol ( state_val , name , namelen , PZVAL_IS_REF ( state_val ) , 1 , Z_ARRVAL_P ( PS ( http_session_vars ) ) ) ;
2002-05-10 04:02:47 +08:00
}
1999-12-05 01:02:04 +08:00
}
2006-01-28 14:18:01 +08:00
PHPAPI int php_get_session_var ( char * name , size_t namelen , zval * * * state_var TSRMLS_DC )
1999-12-05 01:02:04 +08:00
{
2002-10-03 12:53:05 +08:00
int ret = FAILURE ;
2002-10-03 11:23:02 +08:00
IF_SESSION_VARS ( ) {
2002-10-03 12:53:05 +08:00
ret = zend_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name ,
2002-10-01 19:59:45 +08:00
namelen + 1 , ( void * * ) state_var ) ;
2002-10-03 12:53:05 +08: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
*/
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 22:04:50 +08:00
}
2002-10-03 12:53:05 +08:00
return ret ;
1999-12-05 01:02:04 +08:00
}
1999-11-30 07:07:20 +08:00
2000-09-01 23:24:58 +08:00
# 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 )
{
2002-05-10 04:02:47 +08:00
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 ;
* newstr = buf . c ;
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
return SUCCESS ;
2000-09-01 23:24:58 +08:00
}
PS_SERIALIZER_DECODE_FUNC ( php_binary )
{
2002-05-10 04:02:47 +08:00
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 ; ) {
namelen = * p & ( ~ PS_BIN_UNDEF ) ;
has_value = * p & PS_BIN_UNDEF ? 0 : 1 ;
name = estrndup ( p + 1 , namelen ) ;
p + = namelen + 1 ;
if ( has_value ) {
2005-01-22 00:03:47 +08:00
ALLOC_INIT_ZVAL ( current ) ;
2006-07-13 08:13:19 +08:00
if ( php_var_unserialize ( & current , ( const unsigned char * * ) & p , ( const unsigned char * ) endptr , & var_hash TSRMLS_CC ) ) {
2002-05-10 04:02:47 +08:00
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 ;
2000-09-01 23:24:58 +08:00
}
# define PS_DELIMITER '|'
# define PS_UNDEF_MARKER '!'
1999-07-01 13:45:48 +08:00
PS_SERIALIZER_ENCODE_FUNC ( php )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
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 , ( unsigned char ) key_length ) ;
2004-09-02 10:44:04 +08:00
if ( memchr ( key , PS_DELIMITER , key_length ) ) {
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
smart_str_free ( & buf ) ;
return FAILURE ;
}
2002-05-10 04:02:47 +08:00
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 ;
* newstr = buf . c ;
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
1999-06-06 03:52:58 +08:00
}
2002-05-10 04:02:47 +08:00
PS_SERIALIZER_DECODE_FUNC ( php )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
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 ) {
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 ( has_value ) {
2004-02-29 08:26:36 +08:00
ALLOC_INIT_ZVAL ( current ) ;
2006-07-13 08:13:19 +08:00
if ( php_var_unserialize ( & current , ( const unsigned char * * ) & q , ( const unsigned char * ) endptr , & var_hash TSRMLS_CC ) ) {
2002-05-10 04:02:47 +08:00
php_set_session_var ( name , namelen , current , & var_hash TSRMLS_CC ) ;
}
zval_ptr_dtor ( & current ) ;
}
PS_ADD_VARL ( name , namelen ) ;
efree ( name ) ;
p = q ;
}
2001-07-26 03:02:13 +08:00
break_outer_loop :
2002-05-10 04:02:47 +08:00
PHP_VAR_UNSERIALIZE_DESTROY ( var_hash ) ;
2001-06-22 02:46:26 +08:00
2002-05-10 04:02:47 +08:00
return SUCCESS ;
1999-07-01 13:45:48 +08:00
}
2001-08-05 22:36:51 +08:00
static void php_session_track_init ( TSRMLS_D )
1999-12-05 01:02:04 +08:00
{
2004-07-10 15:46:17 +08:00
zval * session_vars = NULL ;
2002-10-03 05:51:32 +08:00
/* Unconditionally destroy existing arrays -- possible dirty data */
2004-10-05 04:17:06 +08:00
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-10 04:02:47 +08:00
2004-07-10 15:46:17 +08:00
MAKE_STD_ZVAL ( session_vars ) ;
array_init ( session_vars ) ;
PS ( http_session_vars ) = session_vars ;
2005-02-11 03:38:11 +08:00
if ( PG ( register_long_arrays ) ) {
ZEND_SET_GLOBAL_VAR_WITH_LENGTH ( " HTTP_SESSION_VARS " , sizeof ( " HTTP_SESSION_VARS " ) , PS ( http_session_vars ) , 2 , 1 ) ;
2005-02-11 04:22:07 +08:00
ZEND_SET_GLOBAL_VAR_WITH_LENGTH ( " _SESSION " , sizeof ( " _SESSION " ) , PS ( http_session_vars ) , 2 , 1 ) ;
}
else {
2005-03-24 08:17:16 +08:00
ZEND_SET_GLOBAL_VAR_WITH_LENGTH ( " _SESSION " , sizeof ( " _SESSION " ) , PS ( http_session_vars ) , 1 , 0 ) ;
2005-02-11 03:38:11 +08:00
}
1999-12-05 01:02:04 +08:00
}
2001-07-28 19:36:37 +08:00
static char * php_session_encode ( int * newlen TSRMLS_DC )
1999-07-01 13:45:48 +08:00
{
2002-05-10 04:02:47 +08:00
char * ret = NULL ;
1999-07-01 13:45:48 +08:00
2002-10-03 11:23:02 +08:00
IF_SESSION_VARS ( ) {
2004-09-30 20:19:59 +08:00
if ( ! PS ( serializer ) ) {
2004-09-30 22:20:02 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unknown session.serialize_handler. Failed to encode session object. " ) ;
2004-09-30 20:19:59 +08:00
ret = NULL ;
}
else if ( PS ( serializer ) - > encode ( & ret , newlen TSRMLS_CC ) = = FAILURE )
2002-10-03 11:23:02 +08:00
ret = NULL ;
} else {
2002-09-29 23:55:11 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot encode non-existent session. " ) ;
}
2002-05-10 04:02:47 +08:00
return ret ;
1999-07-01 13:45:48 +08:00
}
2002-03-06 17:02:31 +08:00
static void php_session_decode ( const char * val , int vallen TSRMLS_DC )
1999-07-01 13:45:48 +08:00
{
2004-09-30 20:19:59 +08:00
if ( ! PS ( serializer ) ) {
2004-09-30 22:20:02 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unknown session.serialize_handler. Failed to decode session object. " ) ;
2004-09-30 20:19:59 +08:00
return ;
}
2002-05-10 04:02:47 +08:00
if ( PS ( serializer ) - > decode ( val , vallen TSRMLS_CC ) = = FAILURE ) {
php_session_destroy ( TSRMLS_C ) ;
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Failed to decode session object. Session has been destroyed. " ) ;
2002-05-10 04:02:47 +08:00
}
1999-06-06 03:52:58 +08:00
}
2003-01-16 15:21:49 +08:00
/*
* Note that we cannot use the BASE64 alphabet here , because
* it contains " / " and " + " : both are unacceptable for simple inclusion
* into URLs .
*/
static char hexconvtab [ ] = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,- " ;
2003-01-12 21:07:14 +08:00
enum {
PS_HASH_FUNC_MD5 ,
PS_HASH_FUNC_SHA1
} ;
2001-05-19 17:58:31 +08:00
2003-01-16 15:21:49 +08: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 )
{
unsigned char * p , * q ;
unsigned short w ;
int mask ;
int have ;
2006-07-13 08:13:19 +08:00
p = ( unsigned char * ) in ;
q = ( unsigned char * ) in + inlen ;
2003-01-16 15:21:49 +08:00
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 ;
}
2003-12-03 07:14:31 +08:00
PHPAPI char * php_session_create_id ( PS_CREATE_SID_ARGS )
1999-06-06 03:52:58 +08:00
{
2003-01-12 21:07:14 +08:00
PHP_MD5_CTX md5_context ;
PHP_SHA1_CTX sha1_context ;
unsigned char digest [ 21 ] ;
int digest_len ;
2003-01-16 15:21:49 +08:00
int j ;
2003-01-12 21:07:14 +08:00
char * buf ;
2002-05-10 04:02:47 +08:00
struct timeval tv ;
2003-01-12 21:07:14 +08:00
zval * * array ;
zval * * token ;
char * remote_addr = NULL ;
2002-05-10 04:02:47 +08:00
gettimeofday ( & tv , NULL ) ;
2003-01-12 21:07:14 +08:00
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 ) ;
}
buf = emalloc ( 100 ) ;
/* maximum 15+19+19+10 bytes */
sprintf ( buf , " %.15s%ld%ld%0.8f " , remote_addr ? remote_addr : " " ,
2006-07-13 08:13:19 +08:00
tv . tv_sec , ( long int ) tv . tv_usec , php_combined_lcg ( TSRMLS_C ) * 10 ) ;
2003-01-12 21:07:14 +08:00
switch ( PS ( hash_func ) ) {
case PS_HASH_FUNC_MD5 :
PHP_MD5Init ( & md5_context ) ;
2006-07-13 08:13:19 +08:00
PHP_MD5Update ( & md5_context , ( unsigned char * ) buf , strlen ( buf ) ) ;
2003-01-12 21:07:14 +08:00
digest_len = 16 ;
break ;
case PS_HASH_FUNC_SHA1 :
PHP_SHA1Init ( & sha1_context ) ;
2006-07-13 08:13:19 +08:00
PHP_SHA1Update ( & sha1_context , ( unsigned char * ) buf , strlen ( buf ) ) ;
2003-01-12 21:07:14 +08:00
digest_len = 20 ;
break ;
default :
2003-01-19 08:45:53 +08:00
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Invalid session hash function " ) ;
2003-01-12 21:07:14 +08:00
efree ( buf ) ;
return NULL ;
}
2002-05-10 04:02:47 +08:00
if ( PS ( entropy_length ) > 0 ) {
int fd ;
fd = VCWD_OPEN ( PS ( entropy_file ) , O_RDONLY ) ;
if ( fd > = 0 ) {
2003-01-12 21:07:14 +08:00
unsigned char rbuf [ 2048 ] ;
2002-05-10 04:02:47 +08:00
int n ;
int to_read = PS ( entropy_length ) ;
while ( to_read > 0 ) {
2003-01-12 21:07:14 +08:00
n = read ( fd , rbuf , MIN ( to_read , sizeof ( rbuf ) ) ) ;
2002-05-10 04:02:47 +08:00
if ( n < = 0 ) break ;
2003-01-12 21:07:14 +08:00
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 ;
}
2002-05-10 04:02:47 +08:00
to_read - = n ;
}
close ( fd ) ;
}
}
1999-06-06 03:52:58 +08:00
2003-01-12 21:07:14 +08:00
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 ;
}
2003-01-16 15:21:49 +08:00
if ( PS ( hash_bits_per_character ) < 4
| | PS ( hash_bits_per_character ) > 6 ) {
PS ( hash_bits_per_character ) = 4 ;
2003-01-12 21:07:14 +08:00
2003-01-19 08:45:53 +08: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-10 04:02:47 +08:00
}
2006-07-13 08:13:19 +08:00
j = ( int ) ( bin_to_readable ( ( char * ) digest , digest_len , buf , PS ( hash_bits_per_character ) ) - buf ) ;
2002-05-10 04:02:47 +08:00
if ( newlen )
* newlen = j ;
2003-01-12 21:07:14 +08:00
return buf ;
2002-05-10 04:02:47 +08:00
}
2002-05-10 03:42:00 +08:00
2002-02-03 13:40:19 +08:00
static void php_session_initialize ( TSRMLS_D )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
char * val ;
int vallen ;
2006-01-16 00:51:18 +08:00
/* check session name for invalid characters */
if ( PS ( id ) & & strpbrk ( PS ( id ) , " \r \n \t <>' \" \\ " ) ) {
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
}
2002-09-30 02:33:14 +08:00
if ( ! PS ( mod ) ) {
2004-02-19 09:54:21 +08:00
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " No storage module chosen - failed to initialize session. " ) ;
2002-09-30 02:33:14 +08:00
return ;
}
2002-05-10 04:02:47 +08:00
/* Open session handler first */
2003-02-11 08:42:14 +08:00
if ( PS ( mod ) - > s_open ( & PS ( mod_data ) , PS ( save_path ) , PS ( session_name ) TSRMLS_CC ) = = FAILURE ) {
2004-02-19 09:54:21 +08: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-10 04:02:47 +08:00
return ;
}
/* If there is no ID, use session module to create one */
2006-07-27 22:00:13 +08:00
if ( ! PS ( id ) ) {
new_session :
2003-02-11 08:42:14 +08:00
PS ( id ) = PS ( mod ) - > s_create_sid ( & PS ( mod_data ) , NULL TSRMLS_CC ) ;
2006-07-27 22:00:13 +08:00
if ( PS ( use_cookies ) ) {
PS ( send_cookie ) = 1 ;
}
}
2002-05-10 04:02:47 +08: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 23:33:16 +08:00
PS ( invalid_session_id ) = 0 ;
2003-02-11 08:42:14 +08:00
if ( PS ( mod ) - > s_read ( & PS ( mod_data ) , PS ( id ) , & val , & vallen TSRMLS_CC ) = = SUCCESS ) {
2002-05-10 04:02:47 +08:00
php_session_decode ( val , vallen TSRMLS_CC ) ;
efree ( val ) ;
2006-07-27 23:33:16 +08: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 ) ) ;
2006-07-27 22:00:13 +08:00
goto new_session ;
2002-05-10 04:02:47 +08:00
}
1999-06-06 03:52:58 +08:00
}
2002-10-07 10:37:50 +08:00
static int migrate_global ( HashTable * ht , HashPosition * pos TSRMLS_DC )
1999-06-06 03:52:58 +08:00
{
2002-10-03 11:23:02 +08:00
char * str ;
uint str_len ;
2002-05-10 04:02:47 +08:00
ulong num_key ;
2002-10-03 11:23:02 +08:00
int n ;
2003-07-22 09:11:07 +08:00
zval * * val ;
2002-10-07 10:37:50 +08:00
int ret = 0 ;
2002-05-10 04:02:47 +08:00
2002-10-03 11:23:02 +08: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 09:11:07 +08: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 ,
( * val ) - > refcount + 1 , 1 ) ;
2002-10-07 10:37:50 +08:00
ret = 1 ;
2002-10-03 11:23:02 +08:00
}
break ;
case HASH_KEY_IS_LONG :
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " The session bug compatibility code will not "
2003-08-29 01:34:33 +08:00
" try to locate the global variable $%lu due to its "
2002-10-03 11:23:02 +08:00
" numeric nature. " , num_key ) ;
break ;
2002-09-29 23:26:50 +08:00
}
2002-10-07 10:37:50 +08:00
return ret ;
2002-10-03 11:23:02 +08:00
}
static void php_session_save_current_state ( TSRMLS_D )
{
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 ) {
2002-10-07 10:37:50 +08:00
if ( migrate_global ( ht , & pos TSRMLS_CC ) )
do_warn = 1 ;
2002-10-03 11:23:02 +08:00
}
zend_hash_move_forward_ex ( ht , & pos ) ;
}
if ( do_warn & & PS ( bug_compat_warn ) ) {
2002-12-06 04:13:35 +08: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 11:23:02 +08:00
}
2002-05-10 04:02:47 +08:00
}
2002-10-03 13:53:45 +08:00
if ( PS ( mod_data ) ) {
char * val ;
int vallen ;
2002-10-03 11:23:02 +08:00
2002-10-03 13:53:45 +08:00
val = php_session_encode ( & vallen TSRMLS_CC ) ;
if ( val ) {
2003-02-11 08:42:14 +08:00
ret = PS ( mod ) - > s_write ( & PS ( mod_data ) , PS ( id ) , val , vallen TSRMLS_CC ) ;
2002-10-03 13:53:45 +08:00
efree ( val ) ;
} else {
2003-02-11 08:42:14 +08:00
ret = PS ( mod ) - > s_write ( & PS ( mod_data ) , PS ( id ) , " " , 0 TSRMLS_CC ) ;
2002-10-03 13:53:45 +08:00
}
2002-05-10 04:02:47 +08:00
}
2002-10-03 13:53:45 +08:00
if ( ret = = FAILURE )
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Failed to write session data (%s). Please "
2002-10-03 13:53:45 +08:00
" verify that the current setting of session.save_path "
" is correct (%s) " ,
2003-02-11 08:42:14 +08:00
PS ( mod ) - > s_name ,
2002-10-03 13:53:45 +08:00
PS ( save_path ) ) ;
2002-05-10 04:02:47 +08:00
}
if ( PS ( mod_data ) )
2003-02-11 08:42:14 +08:00
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
1999-06-06 03:52:58 +08:00
}
1999-12-12 22:16:55 +08:00
static char * month_names [ ] = {
2002-05-10 04:02:47 +08:00
" Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
" Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec "
1999-12-12 22:16:55 +08:00
} ;
1999-12-12 22:22:55 +08:00
static char * week_days [ ] = {
2002-05-10 04:02:47 +08:00
" Sun " , " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat " , " Sun "
1999-12-12 22:16:55 +08:00
} ;
2001-03-14 00:53:34 +08:00
static void strcpy_gmt ( char * ubuf , time_t * when )
1999-12-12 22:16:55 +08:00
{
2002-05-10 04:02:47 +08:00
char buf [ MAX_STR ] ;
struct tm tm ;
int n ;
php_gmtime_r ( when , & tm ) ;
2003-12-07 22:29:43 +08:00
n = sprintf ( buf , " %s, %02d %s %d %02d:%02d:%02d GMT " , /* SAFE */
2002-05-10 04:02:47 +08: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 22:16:55 +08:00
}
2001-08-05 22:36:51 +08:00
static void last_modified ( TSRMLS_D )
1999-12-12 22:16:55 +08:00
{
2002-05-10 04:02:47 +08:00
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 ;
}
1999-12-12 22:16:55 +08:00
2001-03-14 00:53:34 +08:00
# define LAST_MODIFIED "Last-Modified: "
2002-05-10 04:02:47 +08:00
memcpy ( buf , LAST_MODIFIED , sizeof ( LAST_MODIFIED ) - 1 ) ;
2004-09-30 22:31:30 +08:00
# ifdef NETWARE
strcpy_gmt ( buf + sizeof ( LAST_MODIFIED ) - 1 , & ( sb . st_mtime . tv_sec ) ) ;
# else
2002-05-10 04:02:47 +08:00
strcpy_gmt ( buf + sizeof ( LAST_MODIFIED ) - 1 , & sb . st_mtime ) ;
2004-09-30 22:31:30 +08:00
# endif
2003-04-28 00:04:53 +08:00
ADD_HEADER ( buf ) ;
2002-05-10 04:02:47 +08:00
}
1999-12-12 22:16:55 +08:00
}
CACHE_LIMITER_FUNC ( public )
{
2002-05-10 04:02:47 +08:00
char buf [ MAX_STR + 1 ] ;
struct timeval tv ;
time_t now ;
gettimeofday ( & tv , NULL ) ;
now = tv . tv_sec + PS ( cache_expire ) * 60 ;
2001-03-14 00:53:34 +08:00
# define EXPIRES "Expires: "
2002-05-10 04:02:47 +08:00
memcpy ( buf , EXPIRES , sizeof ( EXPIRES ) - 1 ) ;
strcpy_gmt ( buf + sizeof ( EXPIRES ) - 1 , & now ) ;
2003-04-28 00:04:53 +08:00
ADD_HEADER ( buf ) ;
2002-05-10 04:02:47 +08:00
2002-05-12 20:51:42 +08:00
sprintf ( buf , " Cache-Control: public, max-age=%ld " , PS ( cache_expire ) * 60 ) ; /* SAFE */
2003-04-28 00:04:53 +08:00
ADD_HEADER ( buf ) ;
2002-05-10 04:02:47 +08:00
last_modified ( TSRMLS_C ) ;
1999-12-12 22:16:55 +08:00
}
2001-09-21 21:38:44 +08:00
2002-05-12 20:51:42 +08:00
CACHE_LIMITER_FUNC ( private_no_expire )
1999-12-12 22:16:55 +08:00
{
2002-05-10 04:02:47 +08:00
char buf [ MAX_STR + 1 ] ;
2002-05-12 20:51:42 +08:00
sprintf ( buf , " Cache-Control: private, max-age=%ld, pre-check=%ld " , PS ( cache_expire ) * 60 , PS ( cache_expire ) * 60 ) ; /* SAFE */
2003-04-28 00:04:53 +08:00
ADD_HEADER ( buf ) ;
1999-12-12 22:16:55 +08:00
2002-05-10 04:02:47 +08:00
last_modified ( TSRMLS_C ) ;
1999-12-12 22:16:55 +08:00
}
2002-05-12 20:51:42 +08:00
CACHE_LIMITER_FUNC ( private )
2001-11-03 06:27:07 +08:00
{
2003-04-28 00:04:53 +08:00
ADD_HEADER ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
2002-05-12 20:51:42 +08:00
CACHE_LIMITER ( private_no_expire ) ( TSRMLS_C ) ;
2001-11-03 06:27:07 +08:00
}
1999-12-12 22:16:55 +08:00
CACHE_LIMITER_FUNC ( nocache )
{
2003-04-28 00:04:53 +08:00
ADD_HEADER ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
2002-05-10 04:02:47 +08:00
/* For HTTP/1.1 conforming clients and the rest (MSIE 5) */
2003-04-28 00:04:53 +08:00
ADD_HEADER ( " Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 " ) ;
2002-05-10 04:02:47 +08:00
/* For HTTP/1.0 conforming clients */
2003-04-28 00:04:53 +08:00
ADD_HEADER ( " Pragma: no-cache " ) ;
1999-12-12 22:16:55 +08:00
}
2000-09-06 22:16:12 +08:00
static php_session_cache_limiter_t php_session_cache_limiters [ ] = {
2002-05-12 20:51:42 +08:00
CACHE_LIMITER_ENTRY ( public )
CACHE_LIMITER_ENTRY ( private )
CACHE_LIMITER_ENTRY ( private_no_expire )
CACHE_LIMITER_ENTRY ( nocache )
2002-05-10 04:02:47 +08:00
{ 0 }
1999-12-12 22:16:55 +08:00
} ;
2001-07-28 19:36:37 +08:00
static int php_session_cache_limiter ( TSRMLS_D )
1999-12-12 22:16:55 +08:00
{
2002-05-10 04:02:47 +08:00
php_session_cache_limiter_t * lim ;
2002-10-03 23:10:36 +08:00
if ( PS ( cache_limiter ) [ 0 ] = = ' \0 ' ) return 0 ;
2002-05-10 04:02:47 +08: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-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cache limiter - headers already sent (output started at %s:%d) " ,
2002-05-10 04:02:47 +08:00
output_start_filename , output_start_lineno ) ;
} else {
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cache limiter - headers already sent " ) ;
2002-05-10 04:02:47 +08:00
}
2002-10-03 23:10:36 +08:00
return - 2 ;
2002-05-10 04:02:47 +08:00
}
for ( lim = php_session_cache_limiters ; lim - > name ; lim + + ) {
if ( ! strcasecmp ( lim - > name , PS ( cache_limiter ) ) ) {
lim - > func ( TSRMLS_C ) ;
2002-10-03 23:10:36 +08:00
return 0 ;
2002-05-10 04:02:47 +08:00
}
}
2002-10-03 23:10:36 +08:00
return - 1 ;
1999-12-12 22:16:55 +08:00
}
2001-03-14 00:53:34 +08:00
# define COOKIE_SET_COOKIE "Set-Cookie: "
2002-05-10 04:02:47 +08:00
# define COOKIE_EXPIRES "; expires="
# define COOKIE_PATH "; path="
# define COOKIE_DOMAIN "; domain="
# define COOKIE_SECURE "; secure"
2006-08-10 21:50:56 +08:00
# define COOKIE_HTTPONLY "; HttpOnly"
1999-06-06 03:52:58 +08:00
2001-07-28 19:36:37 +08:00
static void php_session_send_cookie ( TSRMLS_D )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
smart_str ncookie = { 0 } ;
char * date_fmt = NULL ;
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-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cookie - headers already sent by (output started at %s:%d) " ,
2002-05-10 04:02:47 +08:00
output_start_filename , output_start_lineno ) ;
} else {
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cookie - headers already sent " ) ;
2002-05-10 04:02:47 +08:00
}
return ;
}
smart_str_appends ( & ncookie , COOKIE_SET_COOKIE ) ;
smart_str_appends ( & ncookie , PS ( session_name ) ) ;
smart_str_appendc ( & ncookie , ' = ' ) ;
smart_str_appends ( & ncookie , PS ( id ) ) ;
if ( PS ( cookie_lifetime ) > 0 ) {
struct timeval tv ;
2003-10-08 18:22:51 +08:00
time_t t ;
2002-05-10 04:02:47 +08:00
gettimeofday ( & tv , NULL ) ;
2003-10-08 18:22:51 +08:00
t = tv . tv_sec + PS ( cookie_lifetime ) ;
2002-05-10 04:02:47 +08:00
2003-10-08 18:22:51 +08:00
if ( t > 0 ) {
date_fmt = php_std_date ( t TSRMLS_CC ) ;
smart_str_appends ( & ncookie , COOKIE_EXPIRES ) ;
smart_str_appends ( & ncookie , date_fmt ) ;
efree ( date_fmt ) ;
}
2002-05-10 04:02:47 +08:00
}
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 ) ;
}
2006-08-10 21:50:56 +08:00
if ( PS ( cookie_httponly ) ) {
smart_str_appends ( & ncookie , COOKIE_HTTPONLY ) ;
}
2002-05-10 04:02:47 +08:00
smart_str_0 ( & ncookie ) ;
2006-07-12 23:28:44 +08:00
/* 'replace' must be 0 here, else a previous Set-Cookie
header , probably sent with setcookie ( ) will be replaced ! */
2003-04-28 00:18:43 +08:00
sapi_add_header_ex ( ncookie . c , ncookie . len , 0 , 0 TSRMLS_CC ) ;
1999-06-06 03:52:58 +08:00
}
2006-10-07 05:11:36 +08:00
PHPAPI ps_module * _php_find_ps_module ( char * name TSRMLS_DC )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
ps_module * ret = NULL ;
ps_module * * mod ;
int i ;
for ( i = 0 , mod = ps_modules ; i < MAX_MODULES ; i + + , mod + + )
2003-02-11 08:42:14 +08:00
if ( * mod & & ! strcasecmp ( name , ( * mod ) - > s_name ) ) {
2002-05-10 04:02:47 +08:00
ret = * mod ;
break ;
}
return ret ;
1999-06-06 03:52:58 +08:00
}
2006-10-07 05:11:36 +08:00
PHPAPI const ps_serializer * _php_find_ps_serializer ( char * name TSRMLS_DC )
1999-07-01 13:45:48 +08:00
{
2002-05-10 04:02:47 +08:00
const ps_serializer * ret = NULL ;
const ps_serializer * mod ;
1999-07-01 13:45:48 +08:00
2002-05-10 04:02:47 +08:00
for ( mod = ps_serializers ; mod - > name ; mod + + )
if ( ! strcasecmp ( name , mod - > name ) ) {
ret = mod ;
break ;
}
1999-07-01 13:45:48 +08:00
2002-05-10 04:02:47 +08:00
return ret ;
1999-07-01 13:45:48 +08:00
}
1999-12-22 08:38:04 +08:00
# define PPID2SID \
2002-05-10 04:02:47 +08:00
convert_to_string ( ( * ppid ) ) ; \
PS ( id ) = estrndup ( Z_STRVAL_PP ( ppid ) , Z_STRLEN_PP ( ppid ) )
1999-12-22 08:38:04 +08:00
2003-02-19 03:29:38 +08:00
static void php_session_reset_id ( TSRMLS_D )
{
int module_number = PS ( module_number ) ;
2006-02-10 15:39:13 +08:00
if ( PS ( use_cookies ) & & PS ( send_cookie ) ) {
2003-02-19 03:29:38 +08:00
php_session_send_cookie ( TSRMLS_C ) ;
2006-02-10 15:39:13 +08:00
PS ( send_cookie ) = 0 ;
2003-02-19 03:29:38 +08:00
}
/* 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 {
2005-06-02 02:27:50 +08:00
REGISTER_STRINGL_CONSTANT ( " SID " , STR_EMPTY_ALLOC ( ) , 0 , 0 ) ;
2003-02-19 03:29:38 +08:00
}
if ( PS ( apply_trans_sid ) ) {
php_url_scanner_reset_vars ( TSRMLS_C ) ;
2003-02-20 14:18:16 +08:00
php_url_scanner_add_var ( PS ( session_name ) , strlen ( PS ( session_name ) ) , PS ( id ) , strlen ( PS ( id ) ) , 1 TSRMLS_CC ) ;
2003-02-19 03:29:38 +08:00
}
}
2002-02-05 09:28:55 +08:00
PHPAPI void php_session_start ( TSRMLS_D )
1999-06-06 06:15:49 +08:00
{
2002-05-10 04:02:47 +08:00
zval * * ppid ;
zval * * data ;
char * p ;
int nrand ;
int lensess ;
PS ( apply_trans_sid ) = PS ( use_trans_sid ) ;
2003-02-19 03:29:38 +08:00
PS ( define_sid ) = 1 ;
2003-02-19 03:13:49 +08:00
PS ( send_cookie ) = 1 ;
2003-06-10 11:56:23 +08:00
if ( PS ( session_status ) ! = php_session_none ) {
2004-09-30 20:19:59 +08:00
if ( PS ( session_status ) = = php_session_disabled ) {
char * value ;
value = zend_ini_string ( " session.save_handler " , sizeof ( " session.save_handler " ) , 0 ) ;
if ( value ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot find save handler %s " , value ) ;
}
else {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot find unknown save handler " ) ;
}
return ;
}
2003-06-10 11:56:23 +08:00
php_error ( E_NOTICE , " A session had already been started - ignoring session_start() " ) ;
2002-05-10 04:02:47 +08:00
return ;
2003-06-10 11:56:23 +08:00
}
2002-05-10 04:02:47 +08:00
lensess = strlen ( PS ( session_name ) ) ;
/*
* Cookies are preferred , because initially
* cookie and get variables will be available .
*/
if ( ! PS ( id ) ) {
2005-05-20 18:27:49 +08:00
if ( PS ( use_cookies ) & & zend_hash_find ( & EG ( symbol_table ) , " _COOKIE " ,
2002-05-10 04:02:47 +08: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-19 03:13:49 +08:00
PS ( send_cookie ) = 0 ;
2003-02-19 03:29:38 +08:00
PS ( define_sid ) = 0 ;
2002-05-10 04:02:47 +08:00
}
2002-06-12 16:18:36 +08:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & &
2002-05-10 04:02:47 +08: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-19 03:13:49 +08:00
PS ( send_cookie ) = 0 ;
2002-05-10 04:02:47 +08:00
}
2002-06-12 16:18:36 +08:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & &
2002-05-10 04:02:47 +08: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-19 03:13:49 +08:00
PS ( send_cookie ) = 0 ;
2002-05-10 04:02:47 +08: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 10:16:46 +08:00
http : //yoursite/<session-name>=<session-id>/script.php */
1999-08-22 04:48:40 +08:00
2003-08-14 09:30:06 +08: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-23 01:55:13 +08:00
sizeof ( " REQUEST_URI " ) , ( void * * ) & data ) = = SUCCESS & &
2000-09-06 22:13:31 +08:00
Z_TYPE_PP ( data ) = = IS_STRING & &
( p = strstr ( Z_STRVAL_PP ( data ) , PS ( session_name ) ) ) & &
1999-07-23 01:55:13 +08:00
p [ lensess ] = = ' = ' ) {
char * q ;
p + = lensess + 1 ;
2000-02-11 20:59:08 +08:00
if ( ( q = strpbrk ( p , " /? \\ " ) ) )
1999-07-23 01:55:13 +08:00
PS ( id ) = estrndup ( p , q - p ) ;
}
1999-08-22 04:48:40 +08:00
/* check whether the current request was referred to by
an external site which invalidates the previously found id */
2000-02-11 20:59:08 +08:00
if ( PS ( id ) & &
1999-08-22 04:48:40 +08:00
PS ( extern_referer_chk ) [ 0 ] ! = ' \0 ' & &
2003-08-14 09:30:06 +08:00
PG ( http_globals ) [ TRACK_VARS_SERVER ] & &
zend_hash_find ( Z_ARRVAL_P ( PG ( http_globals ) [ TRACK_VARS_SERVER ] ) , " HTTP_REFERER " ,
1999-08-22 04:48:40 +08:00
sizeof ( " HTTP_REFERER " ) , ( void * * ) & data ) = = SUCCESS & &
2000-09-06 22:13:31 +08:00
Z_TYPE_PP ( data ) = = IS_STRING & &
Z_STRLEN_PP ( data ) ! = 0 & &
strstr ( Z_STRVAL_PP ( data ) , PS ( extern_referer_chk ) ) = = NULL ) {
1999-08-22 04:48:40 +08:00
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
2003-02-19 03:13:49 +08:00
PS ( send_cookie ) = 1 ;
2001-10-18 17:05:16 +08:00
if ( PS ( use_trans_sid ) )
PS ( apply_trans_sid ) = 1 ;
1999-08-22 04:48:40 +08:00
}
1999-06-06 06:15:49 +08:00
2002-03-30 00:00:27 +08:00
php_session_initialize ( TSRMLS_C ) ;
1999-10-22 16:10:08 +08:00
2003-02-19 03:13:49 +08:00
if ( ! PS ( use_cookies ) & & PS ( send_cookie ) ) {
2001-10-18 17:05:16 +08:00
if ( PS ( use_trans_sid ) )
PS ( apply_trans_sid ) = 1 ;
2003-02-19 03:13:49 +08:00
PS ( send_cookie ) = 0 ;
1999-10-22 16:10:08 +08:00
}
2001-07-11 21:46:11 +08:00
2003-02-19 03:29:38 +08:00
php_session_reset_id ( TSRMLS_C ) ;
2002-09-27 02:12:27 +08:00
2001-08-26 19:49:43 +08:00
PS ( session_status ) = php_session_active ;
1999-06-06 06:15:49 +08:00
2001-07-28 19:36:37 +08:00
php_session_cache_limiter ( TSRMLS_C ) ;
2002-02-03 13:40:19 +08:00
2002-03-06 17:02:31 +08:00
if ( PS ( mod_data ) & & PS ( gc_probability ) > 0 ) {
2000-03-30 04:37:29 +08:00
int nrdels = - 1 ;
2002-03-06 17:02:31 +08:00
2003-04-05 19:22:15 +08:00
nrand = ( int ) ( ( float ) PS ( gc_divisor ) * php_combined_lcg ( TSRMLS_C ) ) ;
2001-07-26 03:02:13 +08:00
if ( nrand < PS ( gc_probability ) ) {
2003-02-11 08:42:14 +08:00
PS ( mod ) - > s_gc ( & PS ( mod_data ) , PS ( gc_maxlifetime ) , & nrdels TSRMLS_CC ) ;
2000-09-20 09:38:39 +08:00
#if 0
2002-05-10 04:02:47 +08:00
if ( nrdels ! = - 1 )
2003-08-29 04:43:18 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " purged %d expired session objects " , nrdels ) ;
2000-09-20 09:38:39 +08:00
# endif
2002-05-10 04:02:47 +08:00
}
}
1999-06-08 00:43:24 +08:00
}
2001-07-28 19:36:37 +08:00
static zend_bool php_session_destroy ( TSRMLS_D )
1999-06-08 00:43:24 +08:00
{
2002-05-10 04:02:47 +08:00
zend_bool retval = SUCCESS ;
2000-07-05 09:26:22 +08:00
2002-05-10 04:02:47 +08:00
if ( PS ( session_status ) ! = php_session_active ) {
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Trying to destroy uninitialized session " ) ;
2002-05-10 04:02:47 +08:00
return FAILURE ;
}
2002-05-10 03:42:00 +08:00
2003-02-11 08:42:14 +08:00
if ( PS ( mod ) - > s_destroy ( & PS ( mod_data ) , PS ( id ) TSRMLS_CC ) = = FAILURE ) {
2002-05-10 04:02:47 +08:00
retval = FAILURE ;
2002-12-06 04:13:35 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Session object destruction failed " ) ;
2002-05-10 04:02:47 +08:00
}
php_rshutdown_session_globals ( TSRMLS_C ) ;
php_rinit_session_globals ( TSRMLS_C ) ;
2000-07-05 09:26:22 +08:00
2002-05-10 04:02:47 +08:00
return retval ;
1999-06-06 06:15:49 +08:00
}
2001-09-11 18:16:01 +08:00
2006-08-11 05:10:03 +08:00
/* {{{ proto void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]])
2000-02-05 07:34:24 +08:00
Set session cookie parameters */
PHP_FUNCTION ( session_set_cookie_params )
{
2006-08-10 21:50:56 +08:00
zval * * lifetime , * * path , * * domain , * * secure , * * httponly ;
2000-02-05 07:34:24 +08:00
2002-05-10 04:02:47 +08:00
if ( ! PS ( use_cookies ) )
return ;
2000-02-05 07:34:24 +08:00
2006-08-10 21:50:56 +08:00
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 5 | |
zend_get_parameters_ex ( ZEND_NUM_ARGS ( ) , & lifetime , & path , & domain , & secure , & httponly ) = = FAILURE )
2002-05-10 04:02:47 +08:00
WRONG_PARAM_COUNT ;
2004-04-13 08:39:05 +08:00
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 ) ;
2002-05-10 04:02:47 +08:00
if ( ZEND_NUM_ARGS ( ) > 1 ) {
convert_to_string_ex ( path ) ;
zend_alter_ini_entry ( " session.cookie_path " , sizeof ( " session.cookie_path " ) , Z_STRVAL_PP ( path ) , Z_STRLEN_PP ( path ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
if ( ZEND_NUM_ARGS ( ) > 2 ) {
convert_to_string_ex ( domain ) ;
zend_alter_ini_entry ( " session.cookie_domain " , sizeof ( " session.cookie_domain " ) , Z_STRVAL_PP ( domain ) , Z_STRLEN_PP ( domain ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
if ( ZEND_NUM_ARGS ( ) > 3 ) {
convert_to_long_ex ( secure ) ;
zend_alter_ini_entry ( " session.cookie_secure " , sizeof ( " session.cookie_secure " ) , Z_BVAL_PP ( secure ) ? " 1 " : " 0 " , 1 , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
2006-08-10 21:50:56 +08:00
if ( ZEND_NUM_ARGS ( ) > 4 ) {
convert_to_long_ex ( httponly ) ;
zend_alter_ini_entry ( " session.cookie_httponly " , sizeof ( " session.cookie_httponly " ) , Z_BVAL_PP ( httponly ) ? " 1 " : " 0 " , 1 , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
2002-05-10 04:02:47 +08:00
}
}
2000-02-05 07:34:24 +08:00
}
/* }}} */
2000-06-24 01:37:49 +08:00
/* {{{ proto array session_get_cookie_params(void)
2002-05-10 04:02:47 +08:00
Return the session cookie parameters */
2000-03-31 04:02:21 +08:00
PHP_FUNCTION ( session_get_cookie_params )
{
2002-05-10 04:02:47 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
2003-01-19 03:28:10 +08:00
array_init ( return_value ) ;
2002-05-10 04:02:47 +08: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 21:50:56 +08:00
add_assoc_bool ( return_value , " httponly " , PS ( cookie_httponly ) ) ;
2000-03-31 02:50:09 +08:00
}
/* }}} */
2000-02-05 07:34:24 +08:00
1999-06-06 22:19:55 +08:00
/* {{{ proto string session_name([string newname])
2000-06-24 01:37:49 +08:00
Return the current session name . If newname is given , the session name is replaced with newname */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_name )
{
2002-05-10 04:02:47 +08:00
zval * * p_name ;
int ac = ZEND_NUM_ARGS ( ) ;
char * old ;
1999-06-06 03:52:58 +08:00
2002-05-10 04:02:47 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
WRONG_PARAM_COUNT ;
old = estrdup ( PS ( session_name ) ) ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ac = = 1 ) {
convert_to_string_ex ( p_name ) ;
zend_alter_ini_entry ( " session.name " , sizeof ( " session.name " ) , Z_STRVAL_PP ( p_name ) , Z_STRLEN_PP ( p_name ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
RETVAL_STRING ( old , 0 ) ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-06-06 22:19:55 +08:00
/* {{{ proto string session_module_name([string newname])
2000-06-24 01:37:49 +08:00
Return the current module name used for accessing session data . If newname is given , the module name is replaced with newname */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_module_name )
{
2002-05-10 04:02:47 +08:00
zval * * p_name ;
int ac = ZEND_NUM_ARGS ( ) ;
2005-06-04 06:09:22 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE ) {
2002-05-10 04:02:47 +08:00
WRONG_PARAM_COUNT ;
2005-06-04 06:09:22 +08:00
}
2002-05-10 04:02:47 +08:00
2005-06-04 06:09:22 +08: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 ( ) ;
}
2002-05-10 04:02:47 +08:00
if ( ac = = 1 ) {
convert_to_string_ex ( p_name ) ;
2004-04-14 02:18:22 +08:00
if ( ! _php_find_ps_module ( Z_STRVAL_PP ( p_name ) TSRMLS_CC ) ) {
2006-08-30 23:43:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot find named PHP session module (%s) " ,
2002-05-10 04:02:47 +08:00
Z_STRVAL_PP ( p_name ) ) ;
2006-08-30 23:43:10 +08:00
zval_dtor ( return_value ) ;
2002-05-10 04:02:47 +08:00
RETURN_FALSE ;
}
2004-04-14 02:18:22 +08:00
if ( PS ( mod_data ) ) {
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
}
PS ( mod_data ) = NULL ;
2002-05-10 04:02:47 +08:00
2004-04-14 02:18:22 +08:00
zend_alter_ini_entry ( " session.save_handler " , sizeof ( " session.save_handler " ) , Z_STRVAL_PP ( p_name ) , Z_STRLEN_PP ( p_name ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
2002-03-06 17:02:31 +08:00
/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
2000-02-24 23:11:09 +08:00
Sets user - level functions */
1999-09-17 13:40:59 +08:00
PHP_FUNCTION ( session_set_save_handler )
{
2002-05-10 04:02:47 +08:00
zval * * args [ 6 ] ;
int i ;
ps_user * mdata ;
2005-01-10 01:42:02 +08:00
char * name ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 6 | | zend_get_parameters_array_ex ( 6 , args ) = = FAILURE )
WRONG_PARAM_COUNT ;
if ( PS ( session_status ) ! = php_session_none )
RETURN_FALSE ;
2005-01-10 01:42:02 +08:00
for ( i = 0 ; i < 6 ; i + + ) {
if ( ! zend_is_callable ( * args [ i ] , 0 , & name ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Argument %d is not a valid callback " , i + 1 ) ;
efree ( name ) ;
RETURN_FALSE ;
2005-01-10 01:49:51 +08:00
}
efree ( name ) ;
2005-01-10 01:42:02 +08:00
}
2002-05-10 04:02:47 +08: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-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
mdata = emalloc ( sizeof ( * mdata ) ) ;
for ( i = 0 ; i < 6 ; i + + ) {
ZVAL_ADDREF ( * args [ i ] ) ;
mdata - > names [ i ] = * args [ i ] ;
}
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
PS ( mod_data ) = ( void * ) mdata ;
RETURN_TRUE ;
1999-09-17 13:40:59 +08:00
}
/* }}} */
1999-06-06 22:19:55 +08:00
/* {{{ proto string session_save_path([string newname])
2000-06-24 01:37:49 +08:00
Return the current save path passed to module_name . If newname is given , the save path is replaced with newname */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_save_path )
{
2002-05-10 04:02:47 +08:00
zval * * p_name ;
int ac = ZEND_NUM_ARGS ( ) ;
char * old ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
WRONG_PARAM_COUNT ;
old = estrdup ( PS ( save_path ) ) ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ac = = 1 ) {
convert_to_string_ex ( p_name ) ;
zend_alter_ini_entry ( " session.save_path " , sizeof ( " session.save_path " ) , Z_STRVAL_PP ( p_name ) , Z_STRLEN_PP ( p_name ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
RETVAL_STRING ( old , 0 ) ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-06-06 22:19:55 +08:00
/* {{{ proto string session_id([string newid])
2000-06-24 01:37:49 +08:00
Return the current session id . If newid is given , the session id is replaced with newid */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_id )
{
2002-05-10 04:02:47 +08:00
zval * * p_name ;
int ac = ZEND_NUM_ARGS ( ) ;
2004-07-19 15:19:50 +08:00
char * old ;
2002-03-06 17:02:31 +08:00
2002-05-10 04:02:47 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
WRONG_PARAM_COUNT ;
2002-03-06 20:34:47 +08:00
2004-07-19 15:19:50 +08:00
if ( PS ( id ) ) {
2002-05-10 04:02:47 +08:00
old = estrdup ( PS ( id ) ) ;
2004-07-19 15:19:50 +08:00
} else {
old = STR_EMPTY_ALLOC ( ) ;
}
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ac = = 1 ) {
convert_to_string_ex ( p_name ) ;
if ( PS ( id ) ) efree ( PS ( id ) ) ;
PS ( id ) = estrndup ( Z_STRVAL_PP ( p_name ) , Z_STRLEN_PP ( p_name ) ) ;
}
RETVAL_STRING ( old , 0 ) ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
2005-05-30 00:51:25 +08: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 . */
2003-02-19 02:50:44 +08:00
PHP_FUNCTION ( session_regenerate_id )
{
2005-05-30 00:51:25 +08:00
zend_bool del_ses = 0 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |b " , & del_ses ) = = FAILURE ) {
2006-11-03 22:46:48 +08:00
return ;
2005-05-30 00:51:25 +08:00
}
2006-05-19 06:12:26 +08:00
if ( SG ( headers_sent ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot regenerate session id - headers already sent " ) ;
RETURN_FALSE ;
}
2003-02-19 03:13:49 +08:00
if ( PS ( session_status ) = = php_session_active ) {
2005-05-30 00:51:25 +08: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 ) ) ;
}
2003-02-19 02:50:44 +08:00
PS ( id ) = PS ( mod ) - > s_create_sid ( & PS ( mod_data ) , NULL TSRMLS_CC ) ;
2003-02-19 03:13:49 +08:00
2006-02-10 15:39:13 +08:00
PS ( send_cookie ) = 1 ;
2003-02-19 03:29:38 +08:00
php_session_reset_id ( TSRMLS_C ) ;
2003-02-19 02:50:44 +08:00
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
2000-09-01 23:56:26 +08: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 */
PHP_FUNCTION ( session_cache_limiter )
{
2002-05-10 04:02:47 +08:00
zval * * p_cache_limiter ;
int ac = ZEND_NUM_ARGS ( ) ;
char * old ;
2000-09-01 23:56:26 +08:00
2002-05-10 04:02:47 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_cache_limiter ) = = FAILURE )
WRONG_PARAM_COUNT ;
old = estrdup ( PS ( cache_limiter ) ) ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ac = = 1 ) {
convert_to_string_ex ( p_cache_limiter ) ;
zend_alter_ini_entry ( " session.cache_limiter " , sizeof ( " session.cache_limiter " ) , Z_STRVAL_PP ( p_cache_limiter ) , Z_STRLEN_PP ( p_cache_limiter ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
RETVAL_STRING ( old , 0 ) ;
2000-09-01 23:56:26 +08:00
}
/* }}} */
2001-10-22 23:18:06 +08: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 */
PHP_FUNCTION ( session_cache_expire )
{
2002-05-10 04:02:47 +08:00
zval * * p_cache_expire ;
int ac = ZEND_NUM_ARGS ( ) ;
long old ;
2002-03-06 17:02:31 +08:00
2002-05-10 04:02:47 +08:00
old = PS ( cache_expire ) ;
2001-10-22 23:18:06 +08:00
2002-05-10 04:02:47 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_cache_expire ) = = FAILURE )
WRONG_PARAM_COUNT ;
2001-10-22 23:18:06 +08:00
2002-05-10 04:02:47 +08:00
if ( ac = = 1 ) {
2006-08-01 16:32:07 +08:00
convert_to_string_ex ( p_cache_expire ) ;
zend_alter_ini_entry ( " session.cache_expire " , sizeof ( " session.cache_expire " ) , Z_STRVAL_PP ( p_cache_expire ) , Z_STRLEN_PP ( p_cache_expire ) , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME ) ;
2002-05-10 04:02:47 +08:00
}
2001-10-22 23:18:06 +08:00
2002-05-10 04:02:47 +08:00
RETVAL_LONG ( old ) ;
2001-10-22 23:18:06 +08:00
}
/* }}} */
2001-07-28 19:36:37 +08:00
/* {{{ static void php_register_var(zval** entry TSRMLS_DC) */
static void php_register_var ( zval * * entry TSRMLS_DC )
1999-11-28 05:18:41 +08:00
{
2002-05-10 04:02:47 +08:00
zval * * value ;
if ( Z_TYPE_PP ( entry ) = = IS_ARRAY ) {
zend_hash_internal_pointer_reset ( Z_ARRVAL_PP ( entry ) ) ;
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 ) ) ;
}
} else {
convert_to_string_ex ( entry ) ;
2004-05-08 13:58:18 +08:00
if ( ( strcmp ( Z_STRVAL_PP ( entry ) , " HTTP_SESSION_VARS " ) ! = 0 ) & &
2002-05-10 04:02:47 +08:00
( strcmp ( Z_STRVAL_PP ( entry ) , " _SESSION " ) ! = 0 ) ) {
PS_ADD_VARL ( Z_STRVAL_PP ( entry ) , Z_STRLEN_PP ( entry ) ) ;
}
}
1999-11-28 05:18:41 +08:00
}
/* }}} */
2000-06-24 01:37:49 +08:00
/* {{{ proto bool session_register(mixed var_names [, mixed ...])
2000-02-24 23:11:09 +08:00
Adds varname ( s ) to the list of variables which are freezed at the session end */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_register )
{
2002-05-10 04:02:47 +08:00
zval * * * args ;
int argc = ZEND_NUM_ARGS ( ) ;
int i ;
if ( argc < = 0 )
RETURN_FALSE
else
2003-08-12 08:58:52 +08:00
args = ( zval * * * ) safe_emalloc ( argc , sizeof ( zval * * ) , 0 ) ;
2002-05-10 04:02:47 +08:00
if ( zend_get_parameters_array_ex ( argc , args ) = = FAILURE ) {
efree ( args ) ;
WRONG_PARAM_COUNT ;
}
2002-05-10 03:42:00 +08:00
2004-09-30 20:19:59 +08:00
if ( PS ( session_status ) = = php_session_none | | PS ( session_status ) = = php_session_disabled ) {
2002-05-10 04:02:47 +08:00
php_session_start ( TSRMLS_C ) ;
2004-09-30 20:19:59 +08:00
}
if ( PS ( session_status ) = = php_session_disabled ) {
efree ( args ) ;
RETURN_FALSE ;
}
2002-05-10 04:02:47 +08:00
for ( i = 0 ; i < argc ; i + + ) {
if ( Z_TYPE_PP ( args [ i ] ) = = IS_ARRAY )
SEPARATE_ZVAL ( args [ i ] ) ;
php_register_var ( args [ i ] TSRMLS_CC ) ;
}
efree ( args ) ;
RETURN_TRUE ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-10-25 00:17:45 +08:00
/* {{{ proto bool session_unregister(string varname)
2000-02-24 23:11:09 +08:00
Removes varname from the list of variables which are freezed at the session end */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_unregister )
{
2002-05-10 04:02:47 +08:00
zval * * p_name ;
int ac = ZEND_NUM_ARGS ( ) ;
2002-05-10 03:42:00 +08:00
2002-05-10 04:02:47 +08:00
if ( ac ! = 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
WRONG_PARAM_COUNT ;
convert_to_string_ex ( p_name ) ;
PS_DEL_VARL ( Z_STRVAL_PP ( p_name ) , Z_STRLEN_PP ( p_name ) ) ;
1999-10-25 00:17:45 +08:00
2002-05-10 04:02:47 +08:00
RETURN_TRUE ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-06-28 23:46:56 +08:00
/* {{{ proto bool session_is_registered(string varname)
2000-02-24 23:11:09 +08:00
Checks if a variable is registered in session */
1999-06-28 23:46:56 +08:00
PHP_FUNCTION ( session_is_registered )
{
2002-05-10 04:02:47 +08:00
zval * * p_name ;
zval * p_var ;
int ac = ZEND_NUM_ARGS ( ) ;
1999-06-28 23:46:56 +08:00
2002-05-10 04:02:47 +08:00
if ( ac ! = 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
WRONG_PARAM_COUNT ;
convert_to_string_ex ( p_name ) ;
2002-10-03 11:23:02 +08:00
if ( PS ( session_status ) = = php_session_none )
2002-05-10 04:02:47 +08:00
RETURN_FALSE ;
2002-10-03 11:23:02 +08:00
IF_SESSION_VARS ( ) {
if ( zend_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) ,
Z_STRVAL_PP ( p_name ) , Z_STRLEN_PP ( p_name ) + 1 ,
( void * * ) & p_var ) = = SUCCESS ) {
RETURN_TRUE ;
}
}
RETURN_FALSE ;
1999-06-28 23:46:56 +08:00
}
/* }}} */
2000-02-24 23:11:09 +08:00
/* {{{ proto string session_encode(void)
Serializes the current setup and returns the serialized representation */
1999-06-06 23:18:51 +08:00
PHP_FUNCTION ( session_encode )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
int len ;
char * enc ;
1999-06-06 03:52:58 +08:00
2002-05-10 04:02:47 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
2001-08-13 14:43:47 +08:00
2002-05-10 04:02:47 +08:00
enc = php_session_encode ( & len TSRMLS_CC ) ;
2002-09-29 23:55:11 +08:00
if ( enc = = NULL ) {
RETURN_FALSE ;
}
2002-05-10 04:02:47 +08:00
RETVAL_STRINGL ( enc , len , 0 ) ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
2000-05-24 07:13:02 +08:00
/* {{{ proto bool session_decode(string data)
2000-02-24 23:11:09 +08:00
Deserializes data and reinitializes the variables */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_decode )
{
2002-05-10 04:02:47 +08:00
zval * * str ;
1999-06-06 03:52:58 +08:00
2002-12-30 02:50:55 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & str ) = = FAILURE ) {
2002-05-10 04:02:47 +08:00
WRONG_PARAM_COUNT ;
2002-12-30 02:50:55 +08:00
}
1999-06-06 03:52:58 +08:00
2002-12-30 02:50:55 +08:00
if ( PS ( session_status ) = = php_session_none ) {
2002-10-03 23:33:00 +08:00
RETURN_FALSE ;
2002-12-30 02:50:55 +08:00
}
2002-10-03 23:33:00 +08:00
2002-05-10 04:02:47 +08:00
convert_to_string_ex ( str ) ;
1999-09-17 17:26:03 +08:00
2002-05-10 04:02:47 +08:00
php_session_decode ( Z_STRVAL_PP ( str ) , Z_STRLEN_PP ( str ) TSRMLS_CC ) ;
2002-12-30 02:50:55 +08:00
RETURN_TRUE ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
2000-05-24 07:13:02 +08:00
/* {{{ proto bool session_start(void)
1999-06-06 22:19:55 +08:00
Begin session - reinitializes freezed variables , registers browsers etc */
1999-06-06 03:52:58 +08:00
PHP_FUNCTION ( session_start )
{
2002-05-10 04:02:47 +08:00
/* skipping check for non-zero args for performance reasons here ?*/
php_session_start ( TSRMLS_C ) ;
RETURN_TRUE ;
1999-06-06 03:52:58 +08:00
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
2000-07-05 09:26:22 +08:00
/* {{{ proto bool session_destroy(void)
1999-06-08 00:43:24 +08:00
Destroy the current session and all data associated with it */
PHP_FUNCTION ( session_destroy )
{
2002-05-10 04:02:47 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
if ( php_session_destroy ( TSRMLS_C ) = = SUCCESS ) {
RETURN_TRUE ;
} else {
RETURN_FALSE ;
}
1999-06-08 00:43:24 +08:00
}
/* }}} */
2001-07-04 23:30:21 +08:00
2000-05-24 07:13:02 +08:00
/* {{{ proto void session_unset(void)
1999-09-12 06:31:04 +08:00
Unset all registered variables */
PHP_FUNCTION ( session_unset )
{
2002-05-10 04:02:47 +08:00
if ( PS ( session_status ) = = php_session_none )
RETURN_FALSE ;
2002-10-03 11:23:02 +08:00
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 ) {
2004-10-05 04:17:06 +08:00
zend_delete_global_variable ( str , str_len - 1 TSRMLS_CC ) ;
2002-10-03 11:23:02 +08:00
zend_hash_move_forward_ex ( ht , & pos ) ;
}
2002-05-10 04:02:47 +08:00
}
2002-10-03 11:23:02 +08:00
/* Clean $_SESSION. */
zend_hash_clean ( ht ) ;
2002-05-10 04:02:47 +08:00
}
1999-09-12 06:31:04 +08:00
}
/* }}} */
2002-05-06 00:39:49 +08: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 ) ;
}
}
2001-09-01 04:03:09 +08:00
2001-07-28 19:36:37 +08:00
static void php_rinit_session_globals ( TSRMLS_D )
2000-05-26 21:02:11 +08:00
{
1999-06-07 02:39:48 +08:00
PS ( id ) = NULL ;
2001-07-11 21:27:27 +08:00
PS ( session_status ) = php_session_none ;
1999-06-07 02:39:48 +08:00
PS ( mod_data ) = NULL ;
2002-03-02 23:59:16 +08:00
PS ( http_session_vars ) = NULL ;
1999-06-06 03:52:58 +08:00
}
2001-07-28 19:36:37 +08:00
static void php_rshutdown_session_globals ( TSRMLS_D )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
if ( PS ( mod_data ) ) {
2005-09-23 16:14:13 +08:00
zend_try {
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
} zend_end_try ( ) ;
2002-05-10 04:02:47 +08:00
}
if ( PS ( id ) ) {
efree ( PS ( id ) ) ;
}
1999-06-06 03:52:58 +08:00
}
1999-11-18 06:59:27 +08:00
1999-09-17 13:40:59 +08:00
PHP_RINIT_FUNCTION ( session )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
php_rinit_session_globals ( TSRMLS_C ) ;
1999-06-07 02:22:17 +08:00
2002-05-10 04:02:47 +08:00
if ( PS ( mod ) = = NULL ) {
char * value ;
2001-05-24 07:18:51 +08:00
2002-05-10 04:02:47 +08:00
value = zend_ini_string ( " session.save_handler " , sizeof ( " session.save_handler " ) , 0 ) ;
if ( value ) {
PS ( mod ) = _php_find_ps_module ( value TSRMLS_CC ) ;
}
2001-05-24 07:18:51 +08:00
2002-05-10 04:02:47 +08:00
if ( ! PS ( mod ) ) {
/* current status is unusable */
PS ( session_status ) = php_session_disabled ;
return SUCCESS ;
}
}
1999-08-28 05:03:22 +08:00
2002-05-10 04:02:47 +08:00
if ( PS ( auto_start ) ) {
php_session_start ( TSRMLS_C ) ;
}
1999-06-06 03:52:58 +08:00
2002-05-10 04:02:47 +08:00
return SUCCESS ;
2000-01-17 05:03:49 +08:00
}
2000-01-15 21:09:32 +08:00
2001-07-28 19:36:37 +08:00
static void php_session_flush ( TSRMLS_D )
2000-01-17 05:03:49 +08:00
{
2005-09-23 16:14:13 +08: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-10 04:02:47 +08:00
}
2000-10-12 03:47:15 +08:00
}
2001-12-05 06:57:16 +08:00
/* {{{ proto void session_write_close(void)
Write session data and end session */
2000-10-12 03:47:15 +08:00
PHP_FUNCTION ( session_write_close )
{
2002-05-10 04:02:47 +08:00
php_session_flush ( TSRMLS_C ) ;
2000-10-12 03:47:15 +08:00
}
PHP_RSHUTDOWN_FUNCTION ( session )
{
2005-09-23 16:14:13 +08:00
php_session_flush ( TSRMLS_C ) ;
php_rshutdown_session_globals ( TSRMLS_C ) ;
2005-09-21 04:56:54 +08:00
1999-06-06 03:52:58 +08:00
return SUCCESS ;
}
2001-12-05 06:57:16 +08:00
/* }}} */
2000-01-17 05:03:49 +08:00
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( ps )
2004-02-24 16:47:35 +08:00
{
ps_globals - > save_path = NULL ;
ps_globals - > session_name = NULL ;
ps_globals - > id = NULL ;
ps_globals - > mod = NULL ;
ps_globals - > mod_data = NULL ;
ps_globals - > session_status = php_session_none ;
ps_globals - > http_session_vars = NULL ;
}
2000-01-17 05:03:49 +08:00
1999-09-17 13:40:59 +08:00
PHP_MINIT_FUNCTION ( session )
1999-06-06 03:52:58 +08:00
{
2003-03-02 18:19:15 +08:00
zend_register_auto_global ( " _SESSION " , sizeof ( " _SESSION " ) - 1 , NULL TSRMLS_CC ) ;
2001-08-11 18:49:03 +08:00
2002-05-06 00:39:49 +08: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 10:27:02 +08:00
2003-01-08 21:28:16 +08:00
PS ( session_status ) = php_session_none ;
1999-06-06 03:52:58 +08:00
REGISTER_INI_ENTRIES ( ) ;
2002-06-28 10:27:02 +08:00
# ifdef HAVE_LIBMM
PHP_MINIT ( ps_mm ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
# endif
1999-06-06 03:52:58 +08:00
return SUCCESS ;
}
1999-09-17 13:40:59 +08:00
PHP_MSHUTDOWN_FUNCTION ( session )
1999-06-06 03:52:58 +08:00
{
2002-05-10 04:02:47 +08:00
UNREGISTER_INI_ENTRIES ( ) ;
2002-06-28 10:27:02 +08:00
# ifdef HAVE_LIBMM
PHP_MSHUTDOWN ( ps_mm ) ( SHUTDOWN_FUNC_ARGS_PASSTHRU ) ;
# endif
2004-12-08 02:02:25 +08:00
ps_serializers [ PREDEFINED_SERIALIZERS ] . name = NULL ;
2005-09-20 22:03:29 +08:00
memset ( & ps_modules [ PREDEFINED_MODULES ] , 0 , ( MAX_MODULES - PREDEFINED_MODULES ) * sizeof ( ps_module * ) ) ;
2004-12-08 02:02:25 +08:00
2002-05-10 04:02:47 +08:00
return SUCCESS ;
1999-06-06 03:52:58 +08:00
}
1999-06-07 03:53:59 +08:00
1999-09-17 13:40:59 +08:00
PHP_MINFO_FUNCTION ( session )
1999-06-07 03:53:59 +08:00
{
2002-06-28 10:27:02 +08:00
ps_module * * mod ;
2003-08-26 10:03:41 +08:00
ps_serializer * ser ;
smart_str save_handlers = { 0 } ;
smart_str ser_handlers = { 0 } ;
2002-06-28 10:27:02 +08:00
int i ;
2003-08-26 10:03:41 +08:00
/* Get save handlers */
2002-06-28 10:27:02 +08:00
for ( i = 0 , mod = ps_modules ; i < MAX_MODULES ; i + + , mod + + ) {
2003-02-11 08:42:14 +08:00
if ( * mod & & ( * mod ) - > s_name ) {
2003-08-26 10:03:41 +08: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 10:27:02 +08:00
}
}
2002-05-10 04:02:47 +08:00
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " Session Support " , " enabled " ) ;
2002-06-28 10:27:02 +08:00
2003-08-26 10:03:41 +08: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 10:27:02 +08:00
} else {
php_info_print_table_row ( 2 , " Registered save handlers " , " none " ) ;
}
2003-08-26 10:03:41 +08: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-10 04:02:47 +08:00
php_info_print_table_end ( ) ;
2000-04-07 05:07:44 +08:00
2002-05-10 04:02:47 +08:00
DISPLAY_INI_ENTRIES ( ) ;
1999-06-07 03:53:59 +08:00
}
2001-06-06 22:32:27 +08:00
2001-08-25 23:57:42 +08:00
2001-06-06 22:32:27 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2006-05-19 06:12:26 +08:00
* vim600 : noet sw = 4 ts = 4 fdm = marker
2001-09-09 21:29:31 +08:00
* vim < 600 : sw = 4 ts = 4
2001-06-06 22:32:27 +08:00
*/