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(&current, &q, endptr, &var_hash TSRMLS_CC)) {
+                zend_set_hash_symbol(current, name, namelen, 0, 1, Z_ARRVAL_P(session_data));
+			}
+			zval_ptr_dtor(&current);
+		}
+		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

Reply via email to