1999-12-12 22:22:55 +08:00
/*
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
1999-07-16 21:13:16 +08:00
| PHP version 4.0 |
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-01-01 09:32:05 +08:00
| Copyright ( c ) 1997 , 1998 , 1999 , 2000 The PHP Group |
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-02-20 07:41:32 +08:00
| This source file is subject to version 2.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 |
| available at through the world - wide - web at |
2000-02-20 07:41:32 +08:00
| http : //www.php.net/license/2_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
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
1999-11-28 05:18:41 +08:00
| Authors : Sascha Schumann < ss @ schumann . cx > |
1999-10-01 22:54:55 +08:00
| Andrei Zmievski < andrei @ ispi . net > |
1999-06-06 03:52:58 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
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"
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"
1999-09-12 07:47:16 +08:00
# include "ext/standard/url_scanner.h"
1999-12-19 07:28:43 +08:00
# include "ext/standard/php_rand.h" /* for RAND_MAX */
1999-06-06 03:52:58 +08:00
# ifdef ZTS
int ps_globals_id ;
# else
static php_ps_globals ps_globals ;
# endif
# include "modules.c"
function_entry session_functions [ ] = {
PHP_FE ( session_name , NULL )
PHP_FE ( session_module_name , NULL )
PHP_FE ( session_save_path , NULL )
PHP_FE ( session_id , NULL )
PHP_FE ( session_decode , NULL )
PHP_FE ( session_register , NULL )
PHP_FE ( session_unregister , NULL )
1999-06-28 23:46:56 +08:00
PHP_FE ( session_is_registered , NULL )
1999-06-06 23:18:51 +08:00
PHP_FE ( session_encode , NULL )
1999-06-06 03:52:58 +08:00
PHP_FE ( session_start , NULL )
1999-06-08 00:43:24 +08:00
PHP_FE ( session_destroy , NULL )
1999-09-12 06:31:04 +08:00
PHP_FE ( session_unset , NULL )
1999-09-17 13:40:59 +08:00
PHP_FE ( session_set_save_handler , NULL )
2000-02-05 07:34:24 +08:00
PHP_FE ( session_set_cookie_params , NULL )
1999-06-06 03:52:58 +08:00
{ 0 }
} ;
PHP_INI_BEGIN ( )
1999-07-18 09:00:42 +08:00
PHP_INI_ENTRY ( " session.save_path " , " /tmp " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.name " , " PHPSESSID " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.save_handler " , " files " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.auto_start " , " 0 " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.gc_probability " , " 1 " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.gc_maxlifetime " , " 1440 " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.serialize_handler " , " php " , PHP_INI_ALL , NULL )
1999-10-31 21:26:40 +08:00
PHP_INI_ENTRY ( " session.cookie_lifetime " , " 0 " , PHP_INI_ALL , NULL )
1999-11-09 22:27:56 +08:00
PHP_INI_ENTRY ( " session.cookie_path " , " / " , PHP_INI_ALL , NULL )
1999-10-31 21:29:00 +08:00
PHP_INI_ENTRY ( " session.cookie_domain " , " " , PHP_INI_ALL , NULL )
1999-10-22 16:10:08 +08:00
PHP_INI_ENTRY ( " session.use_cookies " , " 1 " , PHP_INI_ALL , NULL )
1999-12-12 22:16:55 +08:00
PHP_INI_ENTRY ( " session.referer_check " , " " , PHP_INI_ALL , NULL )
1999-09-12 01:20:31 +08:00
PHP_INI_ENTRY ( " session.entropy_file " , " " , PHP_INI_ALL , NULL )
1999-09-12 20:27:11 +08:00
PHP_INI_ENTRY ( " session.entropy_length " , " 0 " , PHP_INI_ALL , NULL )
1999-12-12 22:16:55 +08:00
PHP_INI_ENTRY ( " session.cache_limiter " , " nocache " , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " session.cache_expire " , " 180 " , PHP_INI_ALL , NULL )
1999-12-05 01:02:04 +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 ( )
1999-07-01 13:45:48 +08:00
PS_SERIALIZER_FUNCS ( php ) ;
1999-09-16 20:00:58 +08:00
# ifdef WDDX_SERIALIZER
PS_SERIALIZER_FUNCS ( wddx ) ;
# endif
1999-07-01 13:45:48 +08:00
1999-09-17 13:40:59 +08:00
1999-07-01 13:45:48 +08:00
const static ps_serializer ps_serializers [ ] = {
1999-09-16 20:00:58 +08:00
# ifdef WDDX_SERIALIZER
PS_SERIALIZER_ENTRY ( wddx ) ,
# endif
1999-07-01 13:45:48 +08:00
PS_SERIALIZER_ENTRY ( php ) ,
{ 0 }
} ;
1999-06-07 03:53:59 +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 ) ;
1999-09-12 06:31:04 +08:00
static void php_rinit_session_globals ( PSLS_D ) ;
1999-06-11 17:23:00 +08:00
static void php_rshutdown_session_globals ( PSLS_D ) ;
1999-06-06 03:52:58 +08:00
zend_module_entry session_module_entry = {
1999-12-06 07:38:25 +08:00
" Session Management " ,
1999-06-06 03:52:58 +08:00
session_functions ,
1999-09-17 13:40:59 +08:00
PHP_MINIT ( session ) , PHP_MSHUTDOWN ( session ) ,
2000-01-17 05:03:49 +08:00
PHP_RINIT ( session ) , PHP_RSHUTDOWN ( session ) ,
1999-09-17 13:40:59 +08:00
PHP_MINFO ( session ) ,
1999-06-06 03:52:58 +08:00
STANDARD_MODULE_PROPERTIES ,
} ;
1999-12-12 22:16:55 +08:00
typedef struct {
char * name ;
void ( * func ) ( PSLS_D ) ;
} php_session_cache_limiter ;
# define CACHE_LIMITER_FUNC(name) void _php_cache_limiter_##name(PSLS_D)
# define CACHE_LIMITER(name) { #name, _php_cache_limiter_##name },
# define ADD_COOKIE(a) sapi_add_header(estrdup(a), strlen(a));
1999-06-06 03:52:58 +08:00
# define STR_CAT(P,S,I) {\
pval * __p = ( P ) ; \
ulong __i = __p - > value . str . len ; \
__p - > value . str . len + = ( I ) ; \
if ( __p - > value . str . val ) { \
__p - > value . str . val = ( char * ) erealloc ( __p - > value . str . val , __p - > value . str . len + 1 ) ; \
} else { \
__p - > value . str . val = emalloc ( __p - > value . str . len + 1 ) ; \
* __p - > value . str . val = 0 ; \
} \
strcat ( __p - > value . str . val + __i , ( S ) ) ; \
}
# define MAX_STR 512
# define STD_FMT "%s|"
# define NOTFOUND_FMT "!%s|"
1999-09-04 19:25:43 +08:00
# define PS_ADD_VARL(name,namelen) \
zend_hash_update ( & PS ( vars ) , name , namelen + 1 , 0 , 0 , NULL )
# define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name))
# define PS_DEL_VARL(name,namelen) \
zend_hash_del ( & PS ( vars ) , name , namelen + 1 ) ;
# define PS_DEL_VAR(name) PS_DEL_VARL(name, strlen(name))
1999-11-30 07:07:20 +08:00
# define ENCODE_VARS \
char * key ; \
ulong num_key ; \
1999-12-05 02:40:06 +08:00
zval * * struc ; \
2000-03-06 22:36:11 +08:00
ELS_FETCH ( ) ; \
PLS_FETCH ( )
1999-11-30 07:07:20 +08:00
# define ENCODE_LOOP(code) \
2000-02-11 20:59:08 +08:00
for ( zend_hash_internal_pointer_reset ( & PS ( vars ) ) ; \
1999-11-30 07:07:20 +08:00
zend_hash_get_current_key ( & PS ( vars ) , & key , & num_key ) = = HASH_KEY_IS_STRING ; \
zend_hash_move_forward ( & PS ( vars ) ) ) { \
2000-02-11 20:59:08 +08:00
if ( php_get_session_var ( key , strlen ( key ) , & struc PSLS_CC ELS_CC ) = = SUCCESS ) { \
1999-11-30 07:07:20 +08:00
code ; \
} \
efree ( key ) ; \
}
1999-12-05 01:02:04 +08:00
static void php_set_session_var ( char * name , size_t namelen ,
zval * state_val PSLS_DC )
{
zval * state_val_copy ;
PLS_FETCH ( ) ;
ELS_FETCH ( ) ;
1999-11-30 07:07:20 +08:00
1999-12-27 05:21:33 +08:00
ALLOC_ZVAL ( state_val_copy ) ;
1999-12-05 01:02:04 +08:00
* state_val_copy = * state_val ;
zval_copy_ctor ( state_val_copy ) ;
1999-12-05 02:56:17 +08:00
state_val_copy - > refcount = 0 ;
1999-12-05 01:02:04 +08:00
2000-01-29 02:29:37 +08:00
if ( PG ( register_globals ) & & PG ( track_vars ) ) {
2000-02-29 00:00:46 +08:00
zend_set_hash_symbol ( state_val_copy , name , namelen , 0 , 2 , PS ( http_state_vars ) - > value . ht , & EG ( symbol_table ) ) ;
1999-12-05 01:02:04 +08:00
} else {
2000-01-29 02:29:37 +08:00
if ( PG ( register_globals ) ) {
1999-12-10 02:57:57 +08:00
zend_set_hash_symbol ( state_val_copy , name , namelen , 0 , 1 , & EG ( symbol_table ) ) ;
1999-12-05 01:02:04 +08:00
}
if ( PG ( track_vars ) ) {
1999-12-10 02:57:57 +08:00
zend_set_hash_symbol ( state_val_copy , name , namelen , 0 , 1 , PS ( http_state_vars ) - > value . ht ) ;
1999-12-05 01:02:04 +08:00
}
}
}
static int php_get_session_var ( char * name , size_t namelen , zval * * * state_var PSLS_DC ELS_DC )
{
2000-03-06 22:36:11 +08:00
HashTable * ht = & EG ( symbol_table ) ;
if ( ! PG ( register_globals ) & & PG ( track_vars ) )
ht = PS ( http_state_vars ) - > value . ht ;
return zend_hash_find ( ht , name , namelen + 1 , ( void * * ) state_var ) ;
1999-12-05 01:02:04 +08:00
}
1999-11-30 07:07:20 +08:00
1999-07-01 13:45:48 +08:00
PS_SERIALIZER_ENCODE_FUNC ( php )
1999-06-06 03:52:58 +08:00
{
1999-12-05 01:02:04 +08:00
zval * buf ;
1999-06-06 03:52:58 +08:00
char strbuf [ MAX_STR + 1 ] ;
1999-12-05 02:40:06 +08:00
ENCODE_VARS ;
1999-06-06 03:52:58 +08:00
buf = ecalloc ( sizeof ( * buf ) , 1 ) ;
buf - > type = IS_STRING ;
buf - > refcount + + ;
1999-11-30 07:07:20 +08:00
ENCODE_LOOP (
1999-06-06 03:52:58 +08:00
snprintf ( strbuf , MAX_STR , STD_FMT , key ) ;
STR_CAT ( buf , strbuf , strlen ( strbuf ) ) ;
1999-09-20 22:14:26 +08:00
php_var_serialize ( buf , struc ) ;
1999-06-06 03:52:58 +08:00
} else {
snprintf ( strbuf , MAX_STR , NOTFOUND_FMT , key ) ;
STR_CAT ( buf , strbuf , strlen ( strbuf ) ) ;
1999-11-30 07:07:20 +08:00
) ;
1999-06-06 03:52:58 +08:00
2000-02-11 20:59:08 +08:00
if ( newlen ) * newlen = buf - > value . str . len ;
1999-07-01 13:45:48 +08:00
* newstr = buf - > value . str . val ;
1999-06-06 03:52:58 +08:00
efree ( buf ) ;
1999-07-01 13:45:48 +08:00
return SUCCESS ;
1999-06-06 03:52:58 +08:00
}
1999-07-01 13:45:48 +08:00
PS_SERIALIZER_DECODE_FUNC ( php )
1999-06-06 03:52:58 +08:00
{
1999-07-01 13:45:48 +08:00
const char * p , * q ;
1999-06-06 03:52:58 +08:00
char * name ;
1999-07-01 13:45:48 +08:00
const char * endptr = val + vallen ;
1999-12-05 01:02:04 +08:00
zval * current ;
1999-06-06 03:52:58 +08:00
int namelen ;
int has_value ;
1999-12-05 01:02:04 +08:00
current = ( zval * ) ecalloc ( sizeof ( zval ) , 1 ) ;
2000-02-11 20:59:08 +08:00
for ( p = q = val ; ( p < endptr ) & & ( q = strchr ( p , ' | ' ) ) ; p = q ) {
if ( p [ 0 ] = = ' ! ' ) {
1999-06-06 03:52:58 +08:00
p + + ;
has_value = 0 ;
1999-09-16 23:35:49 +08:00
} else {
1999-06-06 03:52:58 +08:00
has_value = 1 ;
1999-09-16 23:35:49 +08:00
}
1999-06-06 03:52:58 +08:00
namelen = q - p ;
1999-06-08 00:43:24 +08:00
name = estrndup ( p , namelen ) ;
1999-06-06 03:52:58 +08:00
q + + ;
2000-02-11 20:59:08 +08:00
if ( has_value ) {
if ( php_var_unserialize ( & current , & q , endptr ) ) {
1999-12-05 01:02:04 +08:00
php_set_session_var ( name , namelen , current PSLS_CC ) ;
zval_dtor ( current ) ;
1999-06-06 03:52:58 +08:00
}
}
PS_ADD_VAR ( name ) ;
efree ( name ) ;
}
1999-12-05 01:02:04 +08:00
efree ( current ) ;
1999-07-01 13:45:48 +08:00
return SUCCESS ;
}
1999-09-16 20:00:58 +08:00
# ifdef WDDX_SERIALIZER
1999-09-04 19:25:43 +08:00
PS_SERIALIZER_ENCODE_FUNC ( wddx )
{
wddx_packet * packet ;
1999-12-05 02:40:06 +08:00
ENCODE_VARS ;
1999-09-04 19:25:43 +08:00
2000-01-04 02:10:27 +08:00
packet = php_wddx_constructor ( ) ;
2000-02-11 21:41:30 +08:00
if ( ! packet )
return FAILURE ;
1999-09-04 19:25:43 +08:00
2000-01-04 02:10:27 +08:00
php_wddx_packet_start ( packet , NULL ) ;
php_wddx_add_chunk ( packet , WDDX_STRUCT_S ) ;
1999-09-04 19:25:43 +08:00
1999-11-30 07:07:20 +08:00
ENCODE_LOOP (
2000-01-04 02:10:27 +08:00
php_wddx_serialize_var ( packet , * struc , key ) ;
1999-11-30 07:07:20 +08:00
) ;
1999-09-04 19:25:43 +08:00
2000-01-04 02:10:27 +08:00
php_wddx_add_chunk ( packet , WDDX_STRUCT_E ) ;
php_wddx_packet_end ( packet ) ;
* newstr = php_wddx_gather ( packet ) ;
php_wddx_destructor ( packet ) ;
1999-09-04 19:25:43 +08:00
2000-02-11 21:41:30 +08:00
if ( newlen )
* newlen = strlen ( * newstr ) ;
1999-09-04 19:25:43 +08:00
return SUCCESS ;
}
1999-12-12 22:22:55 +08:00
PS_SERIALIZER_DECODE_FUNC ( wddx )
1999-09-04 19:25:43 +08:00
{
zval * retval ;
zval * * ent ;
char * key ;
char tmp [ 128 ] ;
ulong idx ;
int hash_type ;
1999-09-16 20:55:31 +08:00
int dofree = 1 ;
1999-09-04 19:25:43 +08:00
2000-02-11 21:41:30 +08:00
if ( vallen = = 0 )
return FAILURE ;
1999-09-16 20:00:58 +08:00
MAKE_STD_ZVAL ( retval ) ;
1999-09-04 19:25:43 +08:00
2000-01-04 02:10:27 +08:00
php_wddx_deserialize_ex ( ( char * ) val , vallen , retval ) ;
1999-09-04 19:25:43 +08:00
2000-02-11 20:59:08 +08:00
for ( zend_hash_internal_pointer_reset ( retval - > value . ht ) ;
1999-09-04 19:25:43 +08:00
zend_hash_get_current_data ( retval - > value . ht , ( void * * ) & ent ) = = SUCCESS ;
zend_hash_move_forward ( retval - > value . ht ) ) {
hash_type = zend_hash_get_current_key ( retval - > value . ht , & key , & idx ) ;
2000-02-11 20:59:08 +08:00
switch ( hash_type ) {
1999-09-04 19:25:43 +08:00
case HASH_KEY_IS_LONG :
sprintf ( tmp , " %ld " , idx ) ;
key = tmp ;
1999-09-16 20:55:31 +08:00
dofree = 0 ;
2000-02-11 20:59:08 +08:00
/* fallthru */
1999-09-04 19:25:43 +08:00
case HASH_KEY_IS_STRING :
1999-12-05 03:46:12 +08:00
php_set_session_var ( key , strlen ( key ) , * ent PSLS_CC ) ;
1999-09-16 20:55:31 +08:00
PS_ADD_VAR ( key ) ;
2000-02-11 20:59:08 +08:00
if ( dofree ) efree ( key ) ;
1999-09-16 20:55:31 +08:00
dofree = 1 ;
1999-09-04 19:25:43 +08:00
}
}
zval_dtor ( retval ) ;
efree ( retval ) ;
return SUCCESS ;
}
1999-09-16 20:00:58 +08:00
1999-09-04 19:25:43 +08:00
# endif
1999-12-05 18:29:06 +08:00
static void php_session_track_init ( void )
1999-12-05 01:02:04 +08:00
{
PSLS_FETCH ( ) ;
ELS_FETCH ( ) ;
if ( zend_hash_find ( & EG ( symbol_table ) , " HTTP_STATE_VARS " , sizeof ( " HTTP_STATE_VARS " ) ,
( void * * ) & PS ( http_state_vars ) ) = = FAILURE | | PS ( http_state_vars ) - > type ! = IS_ARRAY ) {
MAKE_STD_ZVAL ( PS ( http_state_vars ) ) ;
array_init ( PS ( http_state_vars ) ) ;
ZEND_SET_GLOBAL_VAR_WITH_LENGTH ( " HTTP_STATE_VARS " , sizeof ( " HTTP_STATE_VARS " ) , PS ( http_state_vars ) , 1 , 0 ) ;
} else
zend_hash_clean ( PS ( http_state_vars ) - > value . ht ) ;
}
1999-07-01 13:45:48 +08:00
static char * _php_session_encode ( int * newlen PSLS_DC )
{
char * ret = NULL ;
2000-02-11 21:41:30 +08:00
if ( PS ( serializer ) - > encode ( & ret , newlen PSLS_CC ) = = FAILURE )
1999-09-16 20:00:58 +08:00
ret = NULL ;
1999-07-01 13:45:48 +08:00
return ret ;
}
static void _php_session_decode ( const char * val , int vallen PSLS_DC )
{
1999-12-05 02:40:06 +08:00
PLS_FETCH ( ) ;
1999-12-05 01:02:04 +08:00
if ( PG ( track_vars ) )
php_session_track_init ( ) ;
1999-07-01 13:45:48 +08:00
PS ( serializer ) - > decode ( val , vallen PSLS_CC ) ;
1999-06-06 03:52:58 +08:00
}
1999-09-12 01:20:31 +08:00
static char * _php_create_id ( int * newlen PSLS_DC )
1999-06-06 03:52:58 +08:00
{
2000-02-26 11:20:55 +08:00
PHP_MD5_CTX context ;
1999-06-06 03:52:58 +08:00
unsigned char digest [ 16 ] ;
char buf [ 256 ] ;
struct timeval tv ;
int i ;
gettimeofday ( & tv , NULL ) ;
2000-02-26 11:20:55 +08:00
PHP_MD5Init ( & context ) ;
1999-06-06 03:52:58 +08:00
1999-08-22 04:48:40 +08:00
sprintf ( buf , " %ld%ld%0.8f " , tv . tv_sec , tv . tv_usec , php_combined_lcg ( ) * 10 ) ;
2000-02-26 11:20:55 +08:00
PHP_MD5Update ( & context , buf , strlen ( buf ) ) ;
1999-06-06 03:52:58 +08:00
2000-02-11 20:59:08 +08:00
if ( PS ( entropy_length ) > 0 ) {
1999-09-12 01:20:31 +08:00
int fd ;
fd = open ( PS ( entropy_file ) , O_RDONLY ) ;
2000-02-11 20:59:08 +08:00
if ( fd > = 0 ) {
1999-09-12 01:20:31 +08:00
char * p ;
int n ;
p = emalloc ( PS ( entropy_length ) ) ;
n = read ( fd , p , PS ( entropy_length ) ) ;
2000-02-11 20:59:08 +08:00
if ( n > 0 ) {
2000-02-26 11:20:55 +08:00
PHP_MD5Update ( & context , p , n ) ;
1999-09-12 01:20:31 +08:00
}
efree ( p ) ;
close ( fd ) ;
}
}
2000-02-26 11:20:55 +08:00
PHP_MD5Final ( digest , & context ) ;
1999-06-06 03:52:58 +08:00
2000-02-11 20:59:08 +08:00
for ( i = 0 ; i < 16 ; i + + )
1999-06-06 03:52:58 +08:00
sprintf ( buf + ( i < < 1 ) , " %02x " , digest [ i ] ) ;
buf [ i < < 1 ] = ' \0 ' ;
2000-02-11 21:41:30 +08:00
if ( newlen )
* newlen = i < < 1 ;
1999-06-06 03:52:58 +08:00
return estrdup ( buf ) ;
}
1999-06-07 03:26:31 +08:00
static void _php_session_initialize ( PSLS_D )
1999-06-06 03:52:58 +08:00
{
char * val ;
int vallen ;
2000-02-11 20:59:08 +08:00
if ( PS ( mod ) - > open ( & PS ( mod_data ) , PS ( save_path ) , PS ( session_name ) ) = = FAILURE ) {
2000-02-22 22:44:29 +08:00
php_error ( E_ERROR , " Failed to initialize session module " ) ;
1999-06-06 03:52:58 +08:00
return ;
}
2000-02-11 20:59:08 +08:00
if ( PS ( mod ) - > read ( & PS ( mod_data ) , PS ( id ) , & val , & vallen ) = = SUCCESS ) {
1999-06-07 03:25:39 +08:00
_php_session_decode ( val , vallen PSLS_CC ) ;
1999-06-06 03:52:58 +08:00
efree ( val ) ;
}
}
1999-06-07 03:25:39 +08:00
static void _php_session_save_current_state ( PSLS_D )
1999-06-06 03:52:58 +08:00
{
char * val ;
int vallen ;
2000-02-22 22:44:29 +08:00
int ret ;
1999-06-06 03:52:58 +08:00
1999-06-07 03:25:39 +08:00
val = _php_session_encode ( & vallen PSLS_CC ) ;
2000-02-11 20:59:08 +08:00
if ( val ) {
2000-02-22 22:44:29 +08:00
ret = PS ( mod ) - > write ( & PS ( mod_data ) , PS ( id ) , val , vallen ) ;
1999-06-06 03:52:58 +08:00
efree ( val ) ;
2000-02-22 22:44:29 +08:00
} else
ret = PS ( mod ) - > write ( & PS ( mod_data ) , PS ( id ) , " " , 0 ) ;
if ( ret = = FAILURE )
php_error ( E_WARNING , " Failed to write session data. Please check that "
" the current setting of session.save_path is correct (%s) " ,
PS ( save_path ) ) ;
1999-06-06 03:52:58 +08:00
PS ( mod ) - > close ( & PS ( mod_data ) ) ;
}
1999-12-12 22:16:55 +08:00
static char * month_names [ ] = {
1999-12-12 22:22:55 +08:00
" Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
1999-12-12 22:16:55 +08:00
" Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec "
} ;
1999-12-12 22:22:55 +08:00
static char * week_days [ ] = {
1999-12-12 22:16:55 +08:00
" Sun " , " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat " , " Sun "
} ;
static void strcat_gmt ( char * ubuf , time_t * when )
{
char buf [ MAX_STR ] ;
struct tm tm ;
gmtime_r ( when , & tm ) ;
/* we know all components, thus it is safe to use sprintf */
sprintf ( buf , " %s, %d %s %d %02d:%02d:%02d GMT " , 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 ) ;
strcat ( ubuf , buf ) ;
}
static void last_modified ( void )
{
char * path ;
struct stat sb ;
char buf [ MAX_STR + 1 ] ;
SLS_FETCH ( ) ;
path = SG ( request_info ) . path_translated ;
if ( path ) {
if ( stat ( path , & sb ) = = - 1 ) {
return ;
}
strcpy ( buf , " Last-Modified: " ) ;
strcat_gmt ( buf , & sb . st_mtime ) ;
ADD_COOKIE ( buf ) ;
}
}
CACHE_LIMITER_FUNC ( public )
{
char buf [ MAX_STR + 1 ] ;
time_t now ;
time ( & now ) ;
now + = PS ( cache_expire ) * 60 ;
strcpy ( buf , " Expires: " ) ;
strcat_gmt ( buf , & now ) ;
ADD_COOKIE ( buf ) ;
sprintf ( buf , " Cache-Control: public, max-age=%d " , PS ( cache_expire ) * 60 ) ;
ADD_COOKIE ( buf ) ;
last_modified ( ) ;
}
CACHE_LIMITER_FUNC ( private )
{
char buf [ MAX_STR + 1 ] ;
ADD_COOKIE ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
sprintf ( buf , " Cache-Control: private, max-age=%d " , PS ( cache_expire ) * 60 ) ;
ADD_COOKIE ( buf ) ;
last_modified ( ) ;
}
CACHE_LIMITER_FUNC ( nocache )
{
ADD_COOKIE ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
/* For HTTP/1.1 conforming clients */
ADD_COOKIE ( " Cache-Control: no-cache " ) ;
/* For HTTP/1.0 conforming clients */
ADD_COOKIE ( " Pragma: no-cache " ) ;
}
static php_session_cache_limiter php_session_cache_limiters [ ] = {
CACHE_LIMITER ( public )
CACHE_LIMITER ( private )
CACHE_LIMITER ( nocache )
{ 0 }
} ;
static void _php_session_cache_limiter ( PSLS_D )
{
php_session_cache_limiter * lim ;
2000-01-16 00:56:30 +08:00
SLS_FETCH ( ) ;
1999-12-12 22:16:55 +08:00
2000-01-15 21:20:39 +08:00
if ( SG ( headers_sent ) ) {
php_error ( E_WARNING , " Cannot send session cache limiter - headers already sent " ) ;
return ;
}
1999-12-12 22:16:55 +08:00
for ( lim = php_session_cache_limiters ; lim - > name ; lim + + ) {
if ( ! strcasecmp ( lim - > name , PS ( cache_limiter ) ) ) {
lim - > func ( PSLS_C ) ;
break ;
}
}
}
1999-12-09 06:22:20 +08:00
# define COOKIE_FMT "Set-Cookie: %s=%s"
1999-06-29 23:39:59 +08:00
# define COOKIE_EXPIRES "; expires="
1999-10-31 21:26:40 +08:00
# define COOKIE_PATH "; path="
# define COOKIE_DOMAIN "; domain="
1999-06-06 03:52:58 +08:00
1999-06-07 03:25:39 +08:00
static void _php_session_send_cookie ( PSLS_D )
1999-06-06 03:52:58 +08:00
{
1999-10-31 21:26:40 +08:00
int len ;
int pathlen ;
int domainlen ;
1999-06-06 03:52:58 +08:00
char * cookie ;
1999-06-29 23:39:59 +08:00
char * date_fmt = NULL ;
2000-01-16 00:56:30 +08:00
SLS_FETCH ( ) ;
1999-06-06 03:52:58 +08:00
2000-01-15 21:20:39 +08:00
if ( SG ( headers_sent ) ) {
php_error ( E_WARNING , " Cannot send session cookie - headers already sent " ) ;
return ;
}
1999-06-06 03:52:58 +08:00
len = strlen ( PS ( session_name ) ) + strlen ( PS ( id ) ) + sizeof ( COOKIE_FMT ) ;
1999-10-31 21:26:40 +08:00
if ( PS ( cookie_lifetime ) > 0 ) {
1999-12-18 12:01:20 +08:00
date_fmt = php_std_date ( time ( NULL ) + PS ( cookie_lifetime ) ) ;
1999-06-29 23:39:59 +08:00
len + = sizeof ( COOKIE_EXPIRES ) + strlen ( date_fmt ) ;
}
1999-10-31 21:26:40 +08:00
pathlen = strlen ( PS ( cookie_path ) ) ;
2000-02-11 20:59:08 +08:00
if ( pathlen > 0 )
1999-10-31 21:26:40 +08:00
len + = pathlen + sizeof ( COOKIE_PATH ) ;
domainlen = strlen ( PS ( cookie_domain ) ) ;
2000-02-11 20:59:08 +08:00
if ( domainlen > 0 )
1999-10-31 21:26:40 +08:00
len + = domainlen + sizeof ( COOKIE_DOMAIN ) ;
1999-08-28 05:03:22 +08:00
cookie = ecalloc ( len + 1 , 1 ) ;
1999-06-29 23:39:59 +08:00
1999-09-12 20:27:11 +08:00
len = snprintf ( cookie , len , COOKIE_FMT , PS ( session_name ) , PS ( id ) ) ;
1999-10-31 21:26:40 +08:00
if ( PS ( cookie_lifetime ) > 0 ) {
1999-06-29 23:39:59 +08:00
strcat ( cookie , COOKIE_EXPIRES ) ;
strcat ( cookie , date_fmt ) ;
1999-09-12 20:27:11 +08:00
len + = strlen ( COOKIE_EXPIRES ) + strlen ( date_fmt ) ;
1999-06-29 23:39:59 +08:00
efree ( date_fmt ) ;
}
1999-10-31 21:26:40 +08:00
if ( pathlen > 0 ) {
strcat ( cookie , COOKIE_PATH ) ;
strcat ( cookie , PS ( cookie_path ) ) ;
}
if ( domainlen > 0 ) {
strcat ( cookie , COOKIE_DOMAIN ) ;
strcat ( cookie , PS ( cookie_domain ) ) ;
}
1999-06-06 03:52:58 +08:00
sapi_add_header ( cookie , len ) ;
}
1999-06-07 03:25:39 +08:00
static ps_module * _php_find_ps_module ( char * name PSLS_DC )
1999-06-06 03:52:58 +08:00
{
ps_module * ret = NULL ;
ps_module * * mod ;
1999-08-28 05:03:22 +08:00
ps_module * * end = ps_modules + ( sizeof ( ps_modules ) / sizeof ( ps_module * ) ) ;
1999-06-06 03:52:58 +08:00
2000-02-11 21:41:30 +08:00
for ( mod = ps_modules ; mod < end ; mod + + )
2000-02-11 20:59:08 +08:00
if ( * mod & & ! strcasecmp ( name , ( * mod ) - > name ) ) {
1999-06-06 03:52:58 +08:00
ret = * mod ;
break ;
}
return ret ;
}
1999-07-01 13:45:48 +08:00
static const ps_serializer * _php_find_ps_serializer ( char * name PSLS_DC )
{
const ps_serializer * ret = NULL ;
const ps_serializer * mod ;
2000-02-11 21:41:30 +08:00
for ( mod = ps_serializers ; mod - > name ; mod + + )
2000-02-11 20:59:08 +08:00
if ( ! strcasecmp ( name , mod - > name ) ) {
1999-07-01 13:45:48 +08:00
ret = mod ;
break ;
}
return ret ;
}
1999-12-22 08:38:04 +08:00
# define PPID2SID \
convert_to_string ( ( * ppid ) ) ; \
PS ( id ) = estrndup ( ( * ppid ) - > value . str . val , ( * ppid ) - > value . str . len )
1999-06-07 03:25:39 +08:00
static void _php_session_start ( PSLS_D )
1999-06-06 06:15:49 +08:00
{
pval * * ppid ;
1999-07-16 03:37:35 +08:00
pval * * data ;
1999-07-23 01:55:13 +08:00
char * p ;
1999-06-06 06:15:49 +08:00
int send_cookie = 1 ;
1999-07-16 03:37:35 +08:00
int define_sid = 1 ;
2000-01-29 02:29:37 +08:00
zend_bool register_globals ;
1999-12-22 08:11:04 +08:00
zend_bool track_vars ;
1999-07-16 03:37:35 +08:00
int module_number = PS ( module_number ) ;
1999-06-08 00:43:24 +08:00
int nrand ;
1999-07-23 01:55:13 +08:00
int lensess ;
1999-06-07 02:22:17 +08:00
ELS_FETCH ( ) ;
2000-02-11 21:41:30 +08:00
if ( PS ( nr_open_sessions ) ! = 0 )
return ;
1999-07-08 05:50:33 +08:00
1999-07-23 01:55:13 +08:00
lensess = strlen ( PS ( session_name ) ) ;
2000-01-29 02:29:37 +08:00
register_globals = INI_BOOL ( " register_globals " ) ;
1999-12-22 08:11:04 +08:00
track_vars = INI_BOOL ( " track_vars " ) ;
2000-01-29 02:29:37 +08:00
if ( ! register_globals & & ! track_vars ) {
2000-02-22 22:23:09 +08:00
php_error ( E_ERROR , " The session module will not work, if you have disabled track_vars and register_globals. Enable at least one of them. " ) ;
1999-12-22 08:11:04 +08:00
return ;
}
1999-12-22 08:38:04 +08:00
2000-02-11 21:41:30 +08:00
if ( ! track_vars & & PS ( use_cookies ) )
1999-12-22 08:38:04 +08:00
php_error ( E_NOTICE , " Because track_vars are disabled, the session module will not be able to determine whether the user has sent a cookie. SID will always be defined. " ) ;
1999-12-22 08:11:04 +08:00
1999-12-22 08:38:04 +08:00
/*
* If our only resource is the global symbol_table , then check it .
* If track_vars are enabled , we prefer these , because they are more
* reliable , and we always know whether the user has accepted the
* cookie .
*/
1999-08-22 04:48:40 +08:00
2000-01-29 02:29:37 +08:00
if ( register_globals & &
1999-12-22 08:38:04 +08:00
! track_vars & &
1999-12-22 08:11:04 +08:00
! PS ( id ) & &
1999-07-16 03:37:35 +08:00
zend_hash_find ( & EG ( symbol_table ) , PS ( session_name ) ,
1999-07-23 01:55:13 +08:00
lensess + 1 , ( void * * ) & ppid ) = = SUCCESS ) {
1999-12-22 08:38:04 +08:00
PPID2SID ;
1999-06-06 06:15:49 +08:00
send_cookie = 0 ;
}
1999-12-22 08:38:04 +08:00
/*
* Now check the track_vars . Cookies are preferred , because initially
* cookie and get variables will be available .
*/
1999-07-16 03:37:35 +08:00
1999-12-22 08:38:04 +08:00
if ( ! PS ( id ) & & track_vars ) {
1999-12-22 08:11:04 +08:00
if ( zend_hash_find ( & EG ( symbol_table ) , " HTTP_COOKIE_VARS " ,
sizeof ( " HTTP_COOKIE_VARS " ) , ( void * * ) & data ) = = SUCCESS & &
( * data ) - > type = = IS_ARRAY & &
zend_hash_find ( ( * data ) - > value . ht , PS ( session_name ) ,
lensess + 1 , ( void * * ) & ppid ) = = SUCCESS ) {
1999-12-22 08:38:04 +08:00
PPID2SID ;
1999-12-22 08:11:04 +08:00
define_sid = 0 ;
1999-12-22 08:38:04 +08:00
send_cookie = 0 ;
1999-12-22 08:11:04 +08:00
}
1999-12-22 08:38:04 +08:00
if ( ! PS ( id ) & &
1999-12-22 08:11:04 +08:00
zend_hash_find ( & EG ( symbol_table ) , " HTTP_GET_VARS " ,
sizeof ( " HTTP_GET_VARS " ) , ( void * * ) & data ) = = SUCCESS & &
( * data ) - > type = = IS_ARRAY & &
zend_hash_find ( ( * data ) - > value . ht , PS ( session_name ) ,
lensess + 1 , ( void * * ) & ppid ) = = SUCCESS ) {
1999-12-22 08:38:04 +08:00
PPID2SID ;
1999-12-22 08:11:04 +08:00
}
1999-12-22 08:38:04 +08:00
if ( ! PS ( id ) & &
1999-12-22 08:11:04 +08:00
zend_hash_find ( & EG ( symbol_table ) , " HTTP_POST_VARS " ,
sizeof ( " HTTP_POST_VARS " ) , ( void * * ) & data ) = = SUCCESS & &
( * data ) - > type = = IS_ARRAY & &
zend_hash_find ( ( * data ) - > value . ht , PS ( session_name ) ,
lensess + 1 , ( void * * ) & ppid ) = = SUCCESS ) {
1999-12-22 08:38:04 +08:00
PPID2SID ;
1999-12-22 08:11:04 +08:00
}
1999-07-16 03:37:35 +08:00
}
1999-07-23 01:55:13 +08:00
1999-08-22 04:48:40 +08:00
/* check the REQUEST_URI symbol for a string of the form
' < session - name > = < session - id > ' to allow URLs of the form
http : //yoursite/<session-name>=<session-id>/script.php */
2000-02-11 20:59:08 +08:00
if ( ! PS ( id ) & &
1999-12-12 22:22:55 +08:00
zend_hash_find ( & EG ( symbol_table ) , " REQUEST_URI " ,
1999-07-23 01:55:13 +08:00
sizeof ( " REQUEST_URI " ) , ( void * * ) & data ) = = SUCCESS & &
( * data ) - > type = = IS_STRING & &
( p = strstr ( ( * data ) - > value . str . val , PS ( session_name ) ) ) & &
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 ' & &
zend_hash_find ( & EG ( symbol_table ) , " HTTP_REFERER " ,
sizeof ( " HTTP_REFERER " ) , ( void * * ) & data ) = = SUCCESS & &
( * data ) - > type = = IS_STRING & &
( * data ) - > value . str . len ! = 0 & &
strstr ( ( * data ) - > value . str . val , PS ( extern_referer_chk ) ) = = NULL ) {
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
send_cookie = 1 ;
define_sid = 1 ;
}
1999-06-06 06:15:49 +08:00
2000-02-11 21:41:30 +08:00
if ( ! PS ( id ) )
1999-09-12 17:57:51 +08:00
PS ( id ) = _php_create_id ( NULL PSLS_CC ) ;
1999-10-22 16:10:08 +08:00
2000-02-11 20:59:08 +08:00
if ( ! PS ( use_cookies ) & & send_cookie ) {
1999-10-22 16:10:08 +08:00
define_sid = 1 ;
send_cookie = 0 ;
}
2000-02-11 21:41:30 +08:00
if ( send_cookie )
1999-06-07 03:25:39 +08:00
_php_session_send_cookie ( PSLS_C ) ;
1999-07-16 03:37:35 +08:00
2000-02-11 20:59:08 +08:00
if ( define_sid ) {
1999-07-16 03:37:35 +08:00
char * buf ;
buf = emalloc ( strlen ( PS ( session_name ) ) + strlen ( PS ( id ) ) + 5 ) ;
sprintf ( buf , " %s=%s " , PS ( session_name ) , PS ( id ) ) ;
REGISTER_STRING_CONSTANT ( " SID " , buf , 0 ) ;
2000-02-11 21:41:30 +08:00
} else
1999-07-16 05:14:46 +08:00
REGISTER_STRING_CONSTANT ( " SID " , empty_string , 0 ) ;
1999-09-12 07:47:16 +08:00
PS ( define_sid ) = define_sid ;
1999-07-16 03:37:35 +08:00
1999-06-06 06:15:49 +08:00
PS ( nr_open_sessions ) + + ;
1999-12-12 22:16:55 +08:00
_php_session_cache_limiter ( PSLS_C ) ;
1999-06-07 03:25:39 +08:00
_php_session_initialize ( PSLS_C ) ;
1999-06-08 00:43:24 +08:00
2000-02-11 20:59:08 +08:00
if ( PS ( mod_data ) & & PS ( gc_probability ) > 0 ) {
1999-06-08 00:43:24 +08:00
srand ( time ( NULL ) ) ;
1999-06-11 17:23:00 +08:00
nrand = ( int ) ( 100.0 * rand ( ) / RAND_MAX ) ;
2000-02-11 20:59:08 +08:00
if ( nrand < PS ( gc_probability ) )
1999-06-08 00:43:24 +08:00
PS ( mod ) - > gc ( & PS ( mod_data ) , PS ( gc_maxlifetime ) ) ;
}
}
static void _php_session_destroy ( PSLS_D )
{
2000-02-11 21:41:30 +08:00
if ( PS ( nr_open_sessions ) = = 0 ) {
1999-09-12 06:31:04 +08:00
php_error ( E_WARNING , " Trying to destroy uninitialized session " ) ;
1999-06-08 00:43:24 +08:00
return ;
1999-09-12 06:31:04 +08:00
}
1999-06-08 00:43:24 +08:00
2000-01-15 20:17:18 +08:00
if ( PS ( mod ) - > destroy ( & PS ( mod_data ) , PS ( id ) ) = = FAILURE ) {
php_error ( E_WARNING , " Destroying the session object failed " ) ;
}
1999-06-11 17:23:00 +08:00
php_rshutdown_session_globals ( PSLS_C ) ;
1999-09-12 06:31:04 +08:00
php_rinit_session_globals ( PSLS_C ) ;
1999-06-06 06:15:49 +08:00
}
2000-02-05 07:34:24 +08:00
2000-02-24 23:11:09 +08:00
/* {{{ proto void session_set_cookie_params(int lifetime [, string path [, string domain]])
2000-02-05 07:34:24 +08:00
Set session cookie parameters */
PHP_FUNCTION ( session_set_cookie_params )
{
zval * * lifetime , * * path , * * domain ;
PSLS_FETCH ( ) ;
if ( ! PS ( use_cookies ) )
return ;
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 3 | |
2000-02-11 21:41:30 +08:00
zend_get_parameters_ex ( ZEND_NUM_ARGS ( ) , & lifetime , & path , & domain ) = = FAILURE )
2000-02-05 07:34:24 +08:00
WRONG_PARAM_COUNT ;
convert_to_long_ex ( lifetime ) ;
PS ( cookie_lifetime ) = ( * lifetime ) - > value . lval ;
if ( ZEND_NUM_ARGS ( ) > 1 ) {
convert_to_string_ex ( path ) ;
efree ( PS ( cookie_path ) ) ;
PS ( cookie_path ) = estrndup ( ( * path ) - > value . str . val ,
( * path ) - > value . str . len ) ;
if ( ZEND_NUM_ARGS ( ) > 2 ) {
convert_to_string_ex ( domain ) ;
efree ( PS ( cookie_domain ) ) ;
PS ( cookie_domain ) = estrndup ( ( * domain ) - > value . str . val ,
( * domain ) - > value . str . len ) ;
}
}
}
/* }}} */
1999-06-06 22:19:55 +08:00
/* {{{ proto string session_name([string newname])
2000-02-24 23:11:09 +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 )
{
1999-09-17 17:26:03 +08:00
pval * * p_name ;
1999-06-06 03:52:58 +08:00
int ac = ARG_COUNT ( ht ) ;
char * old ;
PSLS_FETCH ( ) ;
old = estrdup ( PS ( session_name ) ) ;
2000-02-23 06:52:14 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
2000-02-11 20:59:08 +08:00
if ( ac = = 1 ) {
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( p_name ) ;
1999-06-06 03:52:58 +08:00
efree ( PS ( session_name ) ) ;
1999-09-17 17:26:03 +08:00
PS ( session_name ) = estrndup ( ( * p_name ) - > value . str . val , ( * p_name ) - > value . str . len ) ;
1999-06-06 03:52:58 +08:00
}
RETVAL_STRING ( old , 0 ) ;
}
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-02-24 23:11:09 +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 )
{
1999-09-17 17:26:03 +08:00
pval * * p_name ;
1999-06-06 03:52:58 +08:00
int ac = ARG_COUNT ( ht ) ;
char * old ;
PSLS_FETCH ( ) ;
old = estrdup ( PS ( mod ) - > name ) ;
2000-02-23 06:52:14 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
2000-02-11 20:59:08 +08:00
if ( ac = = 1 ) {
1999-06-06 03:52:58 +08:00
ps_module * tempmod ;
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( p_name ) ;
tempmod = _php_find_ps_module ( ( * p_name ) - > value . str . val PSLS_CC ) ;
2000-02-11 20:59:08 +08:00
if ( tempmod ) {
if ( PS ( mod_data ) )
1999-06-06 03:52:58 +08:00
PS ( mod ) - > close ( & PS ( mod_data ) ) ;
PS ( mod_data ) = tempmod ;
} else {
efree ( old ) ;
1999-08-03 03:17:14 +08:00
php_error ( E_ERROR , " Cannot find named PHP session module (%s) " ,
1999-09-17 17:26:03 +08:00
( * p_name ) - > value . str . val ) ;
1999-06-06 03:52:58 +08:00
RETURN_FALSE ;
}
}
RETVAL_STRING ( old , 0 ) ;
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-09-17 13:40:59 +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 )
{
zval * * args [ 6 ] ;
int i ;
ps_user * mdata ;
PSLS_FETCH ( ) ;
2000-02-11 21:41:30 +08:00
if ( ARG_COUNT ( ht ) ! = 6 | | zend_get_parameters_array_ex ( 6 , args ) = = FAILURE )
1999-09-17 13:40:59 +08:00
WRONG_PARAM_COUNT ;
2000-02-11 21:41:30 +08:00
if ( PS ( nr_open_sessions ) > 0 )
1999-09-17 13:40:59 +08:00
RETURN_FALSE ;
PS ( mod ) = _php_find_ps_module ( " user " PSLS_CC ) ;
mdata = emalloc ( sizeof * mdata ) ;
2000-02-11 20:59:08 +08:00
for ( i = 0 ; i < 6 ; i + + ) {
1999-09-17 13:40:59 +08:00
convert_to_string_ex ( args [ i ] ) ;
mdata - > names [ i ] = estrdup ( ( * args [ i ] ) - > value . str . val ) ;
}
PS ( mod_data ) = ( void * ) mdata ;
RETURN_TRUE ;
}
/* }}} */
1999-06-06 22:19:55 +08:00
/* {{{ proto string session_save_path([string newname])
2000-02-24 23:11:09 +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 )
{
1999-09-17 17:26:03 +08:00
pval * * p_name ;
1999-06-06 03:52:58 +08:00
int ac = ARG_COUNT ( ht ) ;
char * old ;
PSLS_FETCH ( ) ;
old = estrdup ( PS ( save_path ) ) ;
2000-02-23 06:52:14 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
2000-02-11 20:59:08 +08:00
if ( ac = = 1 ) {
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( p_name ) ;
1999-06-06 03:52:58 +08:00
efree ( PS ( save_path ) ) ;
1999-09-17 17:26:03 +08:00
PS ( save_path ) = estrndup ( ( * p_name ) - > value . str . val , ( * p_name ) - > value . str . len ) ;
1999-06-06 03:52:58 +08:00
}
RETVAL_STRING ( old , 0 ) ;
}
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-02-24 23:11:09 +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 )
{
1999-09-17 17:26:03 +08:00
pval * * p_name ;
1999-06-06 03:52:58 +08:00
int ac = ARG_COUNT ( ht ) ;
char * old = empty_string ;
PSLS_FETCH ( ) ;
2000-02-11 20:59:08 +08:00
if ( PS ( id ) )
1999-06-06 03:52:58 +08:00
old = estrdup ( PS ( id ) ) ;
2000-02-23 06:52:14 +08:00
if ( ac < 0 | | ac > 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
2000-02-11 20:59:08 +08:00
if ( ac = = 1 ) {
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( p_name ) ;
2000-02-11 20:59:08 +08:00
if ( PS ( id ) ) efree ( PS ( id ) ) ;
1999-09-17 17:26:03 +08:00
PS ( id ) = estrndup ( ( * p_name ) - > value . str . val , ( * p_name ) - > value . str . len ) ;
1999-06-06 03:52:58 +08:00
}
RETVAL_STRING ( old , 0 ) ;
}
1999-06-06 22:19:55 +08:00
/* }}} */
1999-06-06 03:52:58 +08:00
1999-11-28 05:18:41 +08:00
1999-12-05 01:02:04 +08:00
/* {{{ static void php_register_var(zval** entry PSLS_DC PLS_DC) */
static void php_register_var ( zval * * entry PSLS_DC PLS_DC )
1999-11-28 05:18:41 +08:00
{
2000-02-11 21:41:30 +08:00
zval * * value ;
1999-11-28 05:18:41 +08:00
if ( ( * entry ) - > type = = IS_ARRAY ) {
zend_hash_internal_pointer_reset ( ( * entry ) - > value . ht ) ;
2000-02-11 21:41:30 +08:00
while ( zend_hash_get_current_data ( ( * entry ) - > value . ht , ( void * * ) & value ) = = SUCCESS ) {
1999-12-05 01:05:45 +08:00
php_register_var ( value PSLS_CC PLS_CC ) ;
1999-11-28 05:18:41 +08:00
zend_hash_move_forward ( ( * entry ) - > value . ht ) ;
}
2000-01-18 06:41:59 +08:00
} else {
1999-11-28 05:18:41 +08:00
convert_to_string_ex ( entry ) ;
2000-01-18 06:41:59 +08:00
2000-02-11 21:41:30 +08:00
if ( ! PG ( track_vars ) | | strcmp ( ( * entry ) - > value . str . val , " HTTP_STATE_VARS " ) ! = 0 )
2000-01-18 06:41:59 +08:00
PS_ADD_VARL ( ( * entry ) - > value . str . val , ( * entry ) - > value . str . len ) ;
1999-11-28 05:18:41 +08:00
}
}
/* }}} */
2000-02-24 23:11:09 +08:00
/* {{{ proto bool session_register(mixed var_names [, ...])
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 )
{
2000-02-11 21:41:30 +08:00
zval * * * args ;
1999-11-28 05:18:41 +08:00
int argc = ARG_COUNT ( ht ) ;
int i ;
1999-06-06 03:52:58 +08:00
PSLS_FETCH ( ) ;
1999-12-05 01:02:04 +08:00
PLS_FETCH ( ) ;
1999-06-06 03:52:58 +08:00
2000-02-11 21:41:30 +08:00
if ( argc < = 0 )
RETURN_FALSE
else
1999-11-28 05:18:41 +08:00
args = ( zval * * * ) emalloc ( argc * sizeof ( zval * * ) ) ;
1999-12-19 06:40:35 +08:00
if ( zend_get_parameters_array_ex ( argc , args ) = = FAILURE ) {
1999-11-28 05:18:41 +08:00
efree ( args ) ;
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-11 21:41:30 +08:00
if ( PS ( nr_open_sessions ) = = 0 )
_php_session_start ( PSLS_C ) ;
1999-11-28 05:18:41 +08:00
2000-02-11 21:41:30 +08:00
for ( i = 0 ; i < argc ; i + + ) {
if ( ( * args [ i ] ) - > type = = IS_ARRAY )
1999-11-28 05:18:41 +08:00
SEPARATE_ZVAL ( args [ i ] ) ;
1999-12-05 01:05:45 +08:00
php_register_var ( args [ i ] PSLS_CC PLS_CC ) ;
1999-11-28 05:18:41 +08:00
}
efree ( args ) ;
1999-10-25 00:17:45 +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-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 )
{
1999-09-17 17:26:03 +08:00
pval * * p_name ;
1999-06-06 03:52:58 +08:00
int ac = ARG_COUNT ( ht ) ;
PSLS_FETCH ( ) ;
2000-02-11 21:41:30 +08:00
if ( ac ! = 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( p_name ) ;
1999-06-06 03:52:58 +08:00
1999-09-17 17:26:03 +08:00
PS_DEL_VAR ( ( * p_name ) - > value . str . val ) ;
1999-10-25 00:17:45 +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 )
{
1999-09-17 17:26:03 +08:00
pval * * p_name ;
1999-06-28 23:46:56 +08:00
pval * p_var ;
int ac = ARG_COUNT ( ht ) ;
PSLS_FETCH ( ) ;
2000-02-11 21:41:30 +08:00
if ( ac ! = 1 | | zend_get_parameters_ex ( ac , & p_name ) = = FAILURE )
1999-06-28 23:46:56 +08:00
WRONG_PARAM_COUNT ;
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( p_name ) ;
1999-06-28 23:46:56 +08:00
2000-02-11 21:41:30 +08:00
if ( zend_hash_find ( & PS ( vars ) , ( * p_name ) - > value . str . val ,
( * p_name ) - > value . str . len + 1 , ( void * * ) & p_var ) = = SUCCESS )
RETURN_TRUE
else
1999-06-28 23:46:56 +08:00
RETURN_FALSE ;
}
/* }}} */
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
{
int len ;
char * enc ;
1999-06-07 03:53:59 +08:00
PSLS_FETCH ( ) ;
1999-06-06 03:52:58 +08:00
1999-06-07 03:25:39 +08:00
enc = _php_session_encode ( & len PSLS_CC ) ;
1999-06-06 03:52:58 +08:00
RETVAL_STRINGL ( enc , len , 0 ) ;
}
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 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 )
{
1999-09-17 17:26:03 +08:00
pval * * str ;
1999-06-07 03:53:59 +08:00
PSLS_FETCH ( ) ;
1999-06-06 03:52:58 +08:00
2000-02-11 21:41:30 +08:00
if ( ARG_COUNT ( ht ) ! = 1 | | zend_get_parameters_ex ( 1 , & str ) = = FAILURE )
1999-06-06 03:52:58 +08:00
WRONG_PARAM_COUNT ;
1999-09-17 17:26:03 +08:00
convert_to_string_ex ( str ) ;
_php_session_decode ( ( * str ) - > value . str . val , ( * str ) - > value . str . len PSLS_CC ) ;
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-02-24 23:11:09 +08:00
/* {{{ proto 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 )
{
1999-06-07 03:25:39 +08:00
PSLS_FETCH ( ) ;
_php_session_start ( PSLS_C ) ;
1999-08-23 23:37:11 +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-02-24 23:11:09 +08:00
/* {{{ proto 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 )
{
PSLS_FETCH ( ) ;
1999-09-12 06:31:04 +08:00
1999-06-08 00:43:24 +08:00
_php_session_destroy ( PSLS_C ) ;
}
/* }}} */
1999-09-12 07:47:16 +08:00
# ifdef TRANS_SID
void session_adapt_uris ( const char * src , uint srclen , char * * new , uint * newlen )
{
char * data ;
size_t len ;
char buf [ 512 ] ;
PSLS_FETCH ( ) ;
2000-02-11 20:59:08 +08:00
if ( PS ( define_sid ) & & PS ( nr_open_sessions ) > 0 ) {
1999-09-12 07:47:16 +08:00
snprintf ( buf , sizeof ( buf ) , " %s=%s " , PS ( session_name ) , PS ( id ) ) ;
data = url_adapt ( src , srclen , buf , & len ) ;
* new = data ;
* newlen = len ;
}
}
# endif
1999-09-12 06:31:04 +08:00
2000-02-24 23:11:09 +08:00
/* {{{ proto session_unset(void)
1999-09-12 06:31:04 +08:00
Unset all registered variables */
PHP_FUNCTION ( session_unset )
{
zval * * tmp ;
char * variable ;
1999-11-28 05:18:41 +08:00
ulong num_key ;
1999-09-12 06:31:04 +08:00
PSLS_FETCH ( ) ;
2000-02-11 20:59:08 +08:00
for ( zend_hash_internal_pointer_reset ( & PS ( vars ) ) ;
1999-11-28 05:18:41 +08:00
zend_hash_get_current_key ( & PS ( vars ) , & variable , & num_key ) = = HASH_KEY_IS_STRING ;
1999-09-12 06:31:04 +08:00
zend_hash_move_forward ( & PS ( vars ) ) ) {
2000-02-11 20:59:08 +08:00
if ( zend_hash_find ( & EG ( symbol_table ) , variable , strlen ( variable ) + 1 , ( void * * ) & tmp )
2000-02-11 21:41:30 +08:00
= = SUCCESS )
1999-09-12 08:07:10 +08:00
zend_hash_del ( & EG ( symbol_table ) , variable , strlen ( variable ) + 1 ) ;
1999-09-17 04:59:44 +08:00
efree ( variable ) ;
1999-09-12 06:31:04 +08:00
}
}
/* }}} */
1999-06-11 17:23:00 +08:00
static void php_rinit_session_globals ( PSLS_D )
1999-06-06 03:52:58 +08:00
{
1999-07-18 09:00:42 +08:00
PS ( mod ) = _php_find_ps_module ( INI_STR ( " session.save_handler " ) PSLS_CC ) ;
1999-07-01 13:45:48 +08:00
PS ( serializer ) = \
1999-07-18 09:00:42 +08:00
_php_find_ps_serializer ( INI_STR ( " session.serialize_handler " ) PSLS_CC ) ;
1999-06-06 03:52:58 +08:00
1999-06-07 02:36:42 +08:00
zend_hash_init ( & PS ( vars ) , 0 , NULL , NULL , 0 ) ;
1999-09-12 07:47:16 +08:00
PS ( define_sid ) = 0 ;
1999-11-06 18:01:55 +08:00
PS ( use_cookies ) = INI_BOOL ( " session.use_cookies " ) ;
1999-07-18 09:00:42 +08:00
PS ( save_path ) = estrdup ( INI_STR ( " session.save_path " ) ) ;
PS ( session_name ) = estrdup ( INI_STR ( " session.name " ) ) ;
1999-09-12 01:20:31 +08:00
PS ( entropy_file ) = estrdup ( INI_STR ( " session.entropy_file " ) ) ;
PS ( entropy_length ) = INI_INT ( " session.entropy_length " ) ;
1999-07-18 09:00:42 +08:00
PS ( gc_probability ) = INI_INT ( " session.gc_probability " ) ;
PS ( gc_maxlifetime ) = INI_INT ( " session.gc_maxlifetime " ) ;
1999-12-12 22:16:55 +08:00
PS ( extern_referer_chk ) = estrdup ( INI_STR ( " session.referer_check " ) ) ;
1999-06-07 02:39:48 +08:00
PS ( id ) = NULL ;
1999-10-31 21:26:40 +08:00
PS ( cookie_lifetime ) = INI_INT ( " session.cookie_lifetime " ) ;
PS ( cookie_path ) = estrdup ( INI_STR ( " session.cookie_path " ) ) ;
PS ( cookie_domain ) = estrdup ( INI_STR ( " session.cookie_domain " ) ) ;
1999-12-12 22:16:55 +08:00
PS ( cache_limiter ) = estrdup ( INI_STR ( " session.cache_limiter " ) ) ;
PS ( cache_expire ) = INI_INT ( " session.cache_expire " ) ;
1999-06-07 02:39:48 +08:00
PS ( nr_open_sessions ) = 0 ;
PS ( mod_data ) = NULL ;
1999-06-06 03:52:58 +08:00
}
1999-06-11 17:23:00 +08:00
static void php_rshutdown_session_globals ( PSLS_D )
1999-06-06 03:52:58 +08:00
{
2000-02-11 20:59:08 +08:00
if ( PS ( mod_data ) )
1999-06-07 02:39:48 +08:00
PS ( mod ) - > close ( & PS ( mod_data ) ) ;
2000-02-11 21:41:30 +08:00
if ( PS ( id ) )
efree ( PS ( id ) ) ;
efree ( PS ( entropy_file ) ) ;
efree ( PS ( extern_referer_chk ) ) ;
efree ( PS ( save_path ) ) ;
efree ( PS ( session_name ) ) ;
1999-12-12 22:16:55 +08:00
efree ( PS ( cache_limiter ) ) ;
1999-10-31 21:26:40 +08:00
efree ( PS ( cookie_path ) ) ;
efree ( PS ( cookie_domain ) ) ;
1999-06-07 02:39:48 +08:00
zend_hash_destroy ( & PS ( vars ) ) ;
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
{
1999-06-07 02:36:42 +08:00
PSLS_FETCH ( ) ;
1999-06-11 17:23:00 +08:00
php_rinit_session_globals ( PSLS_C ) ;
1999-06-07 02:22:17 +08:00
2000-02-11 20:59:08 +08:00
if ( PS ( mod ) = = NULL ) {
1999-08-28 05:03:22 +08:00
/* current status is unusable */
PS ( nr_open_sessions ) = - 1 ;
1999-11-26 21:43:55 +08:00
return SUCCESS ;
1999-08-28 05:03:22 +08:00
}
2000-02-11 21:41:30 +08:00
if ( INI_INT ( " session.auto_start " ) )
2000-01-17 04:37:09 +08:00
_php_session_start ( PSLS_C ) ;
1999-06-06 03:52:58 +08:00
2000-01-17 05:03:49 +08:00
return SUCCESS ;
}
2000-01-15 21:09:32 +08:00
2000-01-17 05:03:49 +08:00
PHP_RSHUTDOWN_FUNCTION ( session )
{
PSLS_FETCH ( ) ;
2000-02-11 20:59:08 +08:00
if ( PS ( nr_open_sessions ) > 0 ) {
2000-01-17 05:03:49 +08:00
_php_session_save_current_state ( PSLS_C ) ;
PS ( nr_open_sessions ) - - ;
}
php_rshutdown_session_globals ( PSLS_C ) ;
1999-06-06 03:52:58 +08:00
return SUCCESS ;
}
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
{
1999-06-07 02:56:11 +08:00
# ifdef ZTS
1999-07-17 00:09:01 +08:00
php_ps_globals * ps_globals ;
1999-06-07 02:56:11 +08:00
ps_globals_id = ts_allocate_id ( sizeof ( php_ps_globals ) , NULL , NULL ) ;
1999-07-17 00:09:01 +08:00
ps_globals = ts_resource ( ps_globals_id ) ;
1999-06-07 02:56:11 +08:00
# endif
1999-07-17 00:09:01 +08:00
1999-07-16 03:37:35 +08:00
PS ( module_number ) = module_number ;
1999-06-06 03:52:58 +08:00
REGISTER_INI_ENTRIES ( ) ;
return SUCCESS ;
}
1999-09-17 13:40:59 +08:00
PHP_MSHUTDOWN_FUNCTION ( session )
1999-06-06 03:52:58 +08:00
{
UNREGISTER_INI_ENTRIES ( ) ;
return SUCCESS ;
}
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
{
DISPLAY_INI_ENTRIES ( ) ;
}