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