Howdy, I have created a patch against the latest CVS to add a couple new functions to the session extension. They enable some new features that would be useful for folks building Applications with PHP. I currently need the abilities that these functions enable. By default These new functions are off, since they wouldn't be wanted by most ISP's which run virtual hosted sites on 1 box.
The patch provides: configure option "--enable-app-session", which turns on the new functions. session_get_list() : function which returns an array of active session ids. session_get_data() : function which returns the session data array of a particular session id. session_destroy_id() : destroys a particular session. This is my first stab at a patch, so I'm sure there are things which I have missed. Walt
? foo.patch Index: config.m4 =================================================================== RCS file: /repository/php4/ext/session/config.m4,v retrieving revision 1.17 diff -u -r1.17 config.m4 --- config.m4 7 Mar 2002 14:19:36 -0000 1.17 +++ config.m4 19 Mar 2002 18:42:47 -0000 @@ -8,6 +8,16 @@ PHP_ARG_WITH(mm,for mm support, [ --with-mm[=DIR] Include mm support for session storage]) +AC_ARG_ENABLE(app-session, +[ --enable-app-session Enable Application Session functions. Access to all sessions.],[ + PHP_APP_SESSION=$enableval +],[ + PHP_APP_SESSION=no +]) + +AC_MSG_CHECKING(whether to enable application session access functions) +AC_MSG_RESULT($PHP_APP_SESSION) + if test "$PHP_MM" != "no"; then for i in /usr/local /usr $PHP_MM; do if test -f "$i/include/mm.h"; then @@ -23,6 +33,11 @@ PHP_ADD_INCLUDE($MM_DIR/include) AC_DEFINE(HAVE_LIBMM, 1, [Whether you have libmm]) PHP_MODULE_PTR(phpext_ps_mm_ptr) +fi + +if test "$PHP_APP_SESSION" = "yes"; then + AC_DEFINE(APP_SESSON, 1, [Activate application sessions functions]) + CFLAGS="$CFLAGS -DAPP_SESSION" fi if test "$PHP_SESSION" != "no"; then Index: mod_files.c =================================================================== RCS file: /repository/php4/ext/session/mod_files.c,v retrieving revision 1.72 diff -u -r1.72 mod_files.c --- mod_files.c 6 Mar 2002 11:49:51 -0000 1.72 +++ mod_files.c 19 Mar 2002 18:42:48 -0000 @@ -210,6 +210,49 @@ return (nrdels); } +#ifdef APP_SESSION +static int ps_files_get_session_list(const char *dirname, zval *list) { + + DIR *dir; + char dentry[sizeof(struct dirent) + MAXPATHLEN]; + struct dirent *entry = (struct dirent *) &dentry; + //struct stat sbuf; + char buf[MAXPATHLEN]; + char id[MAXPATHLEN]; + time_t now; + //int nrdels = 0; + size_t dirname_len; + TSRMLS_FETCH(); + + dir = opendir(dirname); + if (!dir) { + php_error(E_NOTICE, "ps_files_get_session_list: opendir(%s) failed: %s (%d)\n", dirname, strerror(errno), errno); + return 0; + } + time(&now); + + dirname_len = strlen(dirname); + + /* Prepare buffer (dirname never changes) */ + memcpy(buf, dirname, dirname_len); + buf[dirname_len] = PHP_DIR_SEPARATOR; + + while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) { + /* does the file start with our prefix? */ + if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) { + /* We found a session file here */ + /* lets extract the session id */ + memset(id, 0, sizeof(id) ); + strcpy(id, entry->d_name+5); + add_next_index_string( list, id, 1); + } + } + + closedir(dir); + return 1; +} +#endif + #define PS_FILES_DATA ps_files *data = PS_GET_MOD_DATA() PS_OPEN_FUNC(files) @@ -338,6 +381,22 @@ return SUCCESS; } + +#ifdef APP_SESSION +PS_GET_LIST_FUNC(files) +{ + int ret=0; + PS_FILES_DATA; + + if (ps_files_get_session_list( data->basedir, *list )) { + return SUCCESS; + } else { + return FAILURE; + } + + return SUCCESS; +} +#endif /* * Local variables: Index: mod_mm.c =================================================================== RCS file: /repository/php4/ext/session/mod_mm.c,v retrieving revision 1.38 diff -u -r1.38 mod_mm.c --- mod_mm.c 6 Mar 2002 12:25:01 -0000 1.38 +++ mod_mm.c 19 Mar 2002 18:42:48 -0000 @@ -247,6 +247,26 @@ free(data); } +#ifdef APP_SESSION +static int ps_mm_get_session_list(ps_mm *data, zval *list) { + + ps_sd **ohash, **ehash; + ps_sd *sd, *next; + + ehash = data->hash + data->hash_max + 1; + for (ohash = data->hash; ohash < ehash; ohash++) + for (sd = *ohash; sd; sd = next) { + next = sd->next; + if (sd->ctime) { + //we assume since ctime isn't + add_next_index_string( list, sd->key, 1); + } + } + + return 1; +} +#endif + PHP_MINIT_FUNCTION(ps_mm) { int save_path_len = strlen(PS(save_path)); @@ -422,6 +442,27 @@ return SUCCESS; } + +#ifdef APP_SESSION +PS_GET_LIST_FUNC(mm) +{ + PS_MM_DATA; + ps_sd *sd; + int ret=0; + + mm_lock(data->mm, MM_LOCK_RW); + + ret = ps_mm_get_session_list( data, *list ); + + mm_unlock(data->mm); + + if (ret) { + return SUCCESS; + } else { + return FAILURE; + } +} +#endif zend_module_entry php_session_mm_module = { STANDARD_MODULE_HEADER, Index: mod_user.c =================================================================== RCS file: /repository/php4/ext/session/mod_user.c,v retrieving revision 1.25 diff -u -r1.25 mod_user.c --- mod_user.c 6 Mar 2002 11:49:51 -0000 1.25 +++ mod_user.c 19 Mar 2002 18:42:48 -0000 @@ -174,6 +174,18 @@ FINISH; } +#ifdef APP_SESSION +PS_GET_LIST_FUNC(user) +{ + zval *args[1]; + STDVARS; + + retval = ps_call_handler(PSF(get_list), 1, args); + FINISH; +} +#endif + + /* * Local variables: * tab-width: 4 Index: mod_user.h =================================================================== RCS file: /repository/php4/ext/session/mod_user.h,v retrieving revision 1.9 diff -u -r1.9 mod_user.h --- mod_user.h 28 Feb 2002 08:26:40 -0000 1.9 +++ mod_user.h 19 Mar 2002 18:42:48 -0000 @@ -28,6 +28,9 @@ zval *ps_write; zval *ps_destroy; zval *ps_gc; +#ifdef APP_SESSION + zval *ps_get_list; +#endif } name; } ps_user; Index: php_session.h =================================================================== RCS file: /repository/php4/ext/session/php_session.h,v retrieving revision 1.73 diff -u -r1.73 php_session.h --- php_session.h 6 Mar 2002 11:49:51 -0000 1.73 +++ php_session.h 19 Mar 2002 18:42:48 -0000 @@ -29,6 +29,9 @@ #define PS_WRITE_ARGS void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC +#ifdef APP_SESSION +#define PS_GET_LIST_ARGS void **mod_data, zval **list TSRMLS_DC +#endif typedef struct ps_module_struct { const char *name; @@ -38,6 +41,9 @@ int (*write)(PS_WRITE_ARGS); int (*destroy)(PS_DESTROY_ARGS); int (*gc)(PS_GC_ARGS); +#ifdef APP_SESSION + int (*get_list)(PS_GET_LIST_ARGS); +#endif } ps_module; #define PS_GET_MOD_DATA() *mod_data @@ -49,6 +55,22 @@ #define PS_WRITE_FUNC(x) int ps_write_##x(PS_WRITE_ARGS) #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) +#ifdef APP_SESSION +#define PS_GET_LIST_FUNC(x) int ps_get_list_##x(PS_GET_LIST_ARGS) + +#define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ + PS_CLOSE_FUNC(x); \ + PS_READ_FUNC(x); \ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ + PS_GET_LIST_FUNC(x) + +#define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ + ps_delete_##x, ps_gc_##x, ps_get_list_##x +#else #define PS_FUNCS(x) \ PS_OPEN_FUNC(x); \ @@ -62,6 +84,7 @@ #define PS_MOD(x) \ #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ ps_delete_##x, ps_gc_##x +#endif typedef enum { php_session_disabled, @@ -121,6 +144,11 @@ PHP_FUNCTION(session_set_cookie_params); PHP_FUNCTION(session_get_cookie_params); PHP_FUNCTION(session_write_close); +#ifdef APP_SESSION +PHP_FUNCTION(session_get_list); +PHP_FUNCTION(session_get_data); +PHP_FUNCTION(session_destroy_id); +#endif #ifdef ZTS #define PS(v) TSRMG(ps_globals_id, php_ps_globals *, v) Index: session.c =================================================================== RCS file: /repository/php4/ext/session/session.c,v retrieving revision 1.294 diff -u -r1.294 session.c --- session.c 13 Mar 2002 13:08:49 -0000 1.294 +++ session.c 19 Mar 2002 18:42:48 -0000 @@ -71,6 +71,11 @@ PHP_FE(session_set_cookie_params, NULL) PHP_FE(session_get_cookie_params, NULL) PHP_FE(session_write_close, NULL) + #ifdef APP_SESSION + PHP_FE(session_get_list, NULL) + PHP_FE(session_get_data, NULL) + PHP_FE(session_destroy_id, NULL) + #endif {NULL, NULL, NULL} }; /* }}} */ @@ -1394,6 +1399,154 @@ } /* }}} */ +#ifdef APP_SESSION +/* {{{ proto string session_id([string newid]) + Destroy a specific session. */ +PHP_FUNCTION(session_destroy_id) +{ + pval **p_name; + int ac = ZEND_NUM_ARGS(); + char *key = NULL; + + if (ac != 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) + WRONG_PARAM_COUNT; + + if (ac == 1) { + convert_to_string_ex(p_name); + key = emalloc(Z_STRLEN_PP(p_name) + 1); + if (key == NULL) { + php_error(E_NOTICE, "session_get_data: Could not Allocate space for session id." ); + } + memset(key, 0, Z_STRLEN_PP(p_name) + 1); + strcpy(key, Z_STRVAL_PP(p_name) ); + } + + if (PS(mod)->destroy(&PS(mod_data), key TSRMLS_CC) == FAILURE) { + php_error(E_WARNING, "Session object destruction failed"); + efree(key); + RETURN_FALSE; + } else { + efree(key); + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ proto bool session_destroy(void) + construct an array of all active session id's */ +PHP_FUNCTION(session_get_list) +{ + zend_bool retval = SUCCESS; + + if (array_init(return_value) != SUCCESS) { + php_error(E_NOTICE, "Could not Allocate space for session list" ); + } + + if (ZEND_NUM_ARGS() != 0) { + WRONG_PARAM_COUNT; + } + + if (PS(mod)->get_list(&PS(mod_data), &return_value TSRMLS_CC) == FAILURE) { + retval = FAILURE; + php_error(E_WARNING, "Session Get list failed"); + } +} +/* }}} */ + + + +/* {{{ proto bool session_destroy(void) + build a return array with a session's data */ +PHP_FUNCTION(session_get_data) +{ + zend_bool retval = SUCCESS; + pval **p_name; + char *key = NULL; + char *val; + int vallen; + int ac = ZEND_NUM_ARGS(); + + + if (ac != 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) + WRONG_PARAM_COUNT; + + if (ac == 1) { + convert_to_string_ex(p_name); + key = emalloc(Z_STRLEN_PP(p_name) + 1); + if (key == NULL) { + php_error(E_NOTICE, "session_get_data: Could not Allocate space for session id." ); + } + memset(key, 0, Z_STRLEN_PP(p_name) + 1); + strcpy(key, Z_STRVAL_PP(p_name) ); + } + + if (array_init(return_value) != SUCCESS) { + php_error(E_NOTICE, "Could not Allocate space for session data" ); + } + + //lets get the session data + if (PS(mod)->read(&PS(mod_data), key, &val, &vallen TSRMLS_CC) == FAILURE) { + php_error(E_NOTICE, "session_get_data: Could not read Session data"); + } + efree(key); + + session_get_data_decode(return_value,val, vallen); + efree(val); +} +/* }}} */ + + +session_get_data_decode(zval *session_data, const char *val, int vallen TSRMLS_DC) +{ + 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_data_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) { + MAKE_STD_ZVAL(current); + if (php_var_unserialize(¤t, &q, endptr, &var_hash TSRMLS_CC)) { + zend_set_hash_symbol(current, name, namelen, 0, 1, Z_ARRVAL_P(session_data)); + } + zval_ptr_dtor(¤t); + } + PS_ADD_VARL(name, namelen); + efree(name); + + p = q; + } +break_outer_data_loop: + + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + + return SUCCESS; +} + +#endif + PHPAPI void session_adapt_url(const char *url, size_t urllen, char **new, size_t *newlen TSRMLS_DC) { @@ -1505,6 +1658,9 @@ { php_info_print_table_start(); php_info_print_table_row(2, "Session Support", "enabled" ); + #ifdef APP_SESSION + php_info_print_table_row(2, "Global Session functions", "Enabled"); + #endif php_info_print_table_end(); DISPLAY_INI_ENTRIES();
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php