Index: mod_cacher/xc_cacher.c
===================================================================
--- mod_cacher/xc_cacher.c	(révision 1141)
+++ mod_cacher/xc_cacher.c	(copie de travail)
@@ -28,6 +28,7 @@
 #endif
 #include "ext/standard/php_math.h"
 #include "SAPI.h"
+#include <pwd.h>
 
 #define ECALLOC_N(x, n) ((x) = ecalloc(n, sizeof((x)[0])))
 #define ECALLOC_ONE(x) ECALLOC_N(x, 1)
@@ -144,6 +145,11 @@
 
 static zend_bool xc_readonly_protection = 0;
 
+static zend_ulong xc_var_prefix_mode = 0;
+static char *xc_var_prefix_value = NULL;
+static zval *xc_var_prefix_computed = NULL;
+
+
 zend_bool xc_have_op_array_ctor = 0;
 /* }}} */
 
@@ -151,6 +157,169 @@
 
 /* any function in *_unlocked is only safe be called within locked (single thread access) area */
 
+
+static int hg_internal_var_prefix_startwith(zval** name)
+{
+	char* from = NULL;
+	char* prefix = NULL;
+
+#ifdef IS_UNICODE
+	switch (xc_var_prefix_computed->type) {
+                case IS_UNICODE:
+                        prefix = Z_UNIVAL_P(xc_var_prefix_computed);
+                        break;
+                case IS_STRING:
+                        prefix = Z_STRVAL_P(xc_var_prefix_computed);
+                        break;
+                default:
+                        assert(0);
+        }
+	switch (name->type) {
+		case IS_UNICODE:
+			from = Z_UNIVAL_PP(name);
+			break;
+		case IS_STRING:
+			from = Z_STRVAL_PP(name);
+			break;
+		default:
+			assert(0);
+	}
+#else
+	prefix = Z_STRVAL_P(xc_var_prefix_computed);
+	from = Z_STRVAL_PP(name);
+#endif
+	if (strncmp(from, prefix, strlen(prefix)) == 0)
+	{
+		return 1;
+	} else {
+		return 0;
+	}	
+}
+
+static void hg_internal_var_prefix_remove(zval** name)
+{
+	char* from = NULL;
+	char* prefix = NULL;
+	int index = 0;
+
+#ifdef IS_UNICODE
+        switch (xc_var_prefix_computed->type) {
+                case IS_UNICODE:
+                        prefix = Z_UNIVAL_P(xc_var_prefix_computed);
+                        break;
+                case IS_STRING:
+                        prefix = Z_STRVAL_P(xc_var_prefix_computed);
+                        break;
+                default:
+                        assert(0);
+        }
+        switch (name->type) {
+                case IS_UNICODE:
+                        from = Z_UNIVAL_PP(name);
+                        break;
+                case IS_STRING:
+                        from = Z_STRVAL_PP(name);
+                        break;
+                default:
+                        assert(0);
+        }
+#else
+        prefix = Z_STRVAL_P(xc_var_prefix_computed);
+        from = Z_STRVAL_PP(name);
+#endif
+	index = strlen(prefix);
+
+#ifdef IS_UNICODE
+        switch (name->type) {
+                case IS_UNICODE:
+			ZVAL_UNICODEL(*name, from + index, strlen(from) - index, 1);
+                        break;
+                case IS_STRING:
+			ZVAL_STRINGL(*name, from + index, strlen(from) - index, 1);
+                        break;
+                default:
+                        assert(0);
+        }
+#else
+	ZVAL_STRINGL(*name, from + index, strlen(from) - index, 1);
+#endif
+/* *
+#ifdef IS_UNICODE
+	php_printf("unicode prefix remove, name=%s<br>", Z_UNIVAL_PP(name));
+#else
+	php_printf("string prefix remove, name=%s<br>", Z_STRVAL_PP(name));	
+#endif
+// */
+}
+
+static char* hg_internal_var_prefix_global_server_array(char* key)
+{
+	// This code makes sure $_SERVER has been initialized
+	if (!zend_hash_exists(&EG(symbol_table), "_SERVER", 8)) {
+		zend_auto_global* auto_global;
+		if (zend_hash_find(CG(auto_globals), "_SERVER", 8, (void **)&auto_global) != FAILURE) {
+			auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
+		}
+	}
+	// This fetches $_SERVER['key']
+	zval** arr;
+	if (zend_hash_find(&EG(symbol_table), "_SERVER", 8, (void**)&arr) != FAILURE) {
+		HashTable* ht = Z_ARRVAL_P(*arr);
+		zval** val;
+		if (zend_hash_find(ht, key, strlen(key)+1, (void**)&val) != FAILURE) {
+			return Z_STRVAL_PP(val);
+		}
+	}
+	return "";
+}
+
+static void hg_internal_var_prefix_compute()
+{
+	xc_var_prefix_computed = NULL;
+	int id = -1;
+
+	MAKE_STD_ZVAL(xc_var_prefix_computed);
+
+	switch(xc_var_prefix_mode) {
+		case 1:
+			if (strncmp(xc_var_prefix_value, "uid", 3) == 0) {
+				id = getuid();
+			} else if (strncmp(xc_var_prefix_value, "gid", 3) == 0) {
+                                id = getgid();
+                        }
+			if (id == -1){
+				ZVAL_EMPTY_STRING(xc_var_prefix_computed);
+				// assert bad configuration ?
+			} else {
+				Z_TYPE_P(xc_var_prefix_computed) = IS_LONG;
+				Z_LVAL_P(xc_var_prefix_computed) = id;
+#ifdef IS_UNICODE
+        	               convert_to_unicode(xc_var_prefix_computed);
+#else
+	                       convert_to_string(xc_var_prefix_computed);
+#endif
+			}
+			break;
+		case 2:
+#ifdef IS_UNICODE
+			ZVAL_UNICODE(xc_var_prefix_computed, hg_internal_var_prefix_global_server_array(xc_var_prefix_value), 1);
+#else
+			ZVAL_STRING(xc_var_prefix_computed, hg_internal_var_prefix_global_server_array(xc_var_prefix_value), 1);
+#endif
+			break;
+		case 3:
+#ifdef IS_UNICODE
+                        ZVAL_UNICODE(xc_var_prefix_computed, xc_var_prefix_value, 1);
+#else
+                        ZVAL_STRING(xc_var_prefix_computed, xc_var_prefix_value, 1);
+#endif			
+                        break;
+		case 0:
+		default:
+			ZVAL_EMPTY_STRING(xc_var_prefix_computed);
+	}
+}
+
 static void xc_php_add_unlocked(xc_cached_t *cached, xc_entry_data_php_t *php) /* {{{ */
 {
 	xc_entry_data_php_t **head = &(cached->phps[php->hvalue]);
@@ -272,28 +441,35 @@
 static inline int xc_entry_has_prefix_unlocked(xc_entry_type_t type, xc_entry_t *entry, zval *prefix) /* {{{ */
 {
 	/* this function isn't required but can be in unlocked */
+	zval* prefixprefix = NULL;
+	MAKE_STD_VAL(prefixprefix);
 
 #ifdef IS_UNICODE
 	if (entry->name_type != prefix->type) {
 		return 0;
 	}
 
+	concat_function(prefixprefix, xc_var_prefix_computed, prefix);
+
 	if (entry->name_type == IS_UNICODE) {
-		if (entry->name.ustr.len < Z_USTRLEN_P(prefix)) {
+		if (entry->name.ustr.len < Z_USTRLEN_P(prefixprefix)) {
 			return 0;
 		}
-		return memcmp(entry->name.ustr.val, Z_USTRVAL_P(prefix), Z_USTRLEN_P(prefix) * sizeof(UChar)) == 0;
+		return memcmp(entry->name.ustr.val, Z_USTRVAL_P(prefixprefix), Z_USTRLEN_P(prefixprefix) * sizeof(UChar)) == 0;
 	}
-#endif
+#else
 	if (prefix->type != IS_STRING) {
 		return 0;
 	}
 
-	if (entry->name.str.len < Z_STRLEN_P(prefix)) {
+	concat_function(prefixprefix, xc_var_prefix_computed, prefix);
+
+	if (entry->name.str.len < Z_STRLEN_P(prefixprefix)) {
 		return 0;
 	}
 
-	return memcmp(entry->name.str.val, Z_STRVAL_P(prefix), Z_STRLEN_P(prefix)) == 0;
+	return memcmp(entry->name.str.val, Z_STRVAL_P(prefixprefix), Z_STRLEN_P(prefixprefix)) == 0;
+#endif
 }
 /* }}} */
 static void xc_entry_add_unlocked(xc_cached_t *cached, xc_hash_value_t entryslotid, xc_entry_t *entry) /* {{{ */
@@ -697,10 +873,11 @@
 	if (del) {
 		add_assoc_long_ex(ei, ZEND_STRS("dtime"), entry->dtime);
 	}
+
+	zval *zv;
+	ALLOC_INIT_ZVAL(zv);
 #ifdef IS_UNICODE
 	do {
-		zval *zv;
-		ALLOC_INIT_ZVAL(zv);
 		switch (entry->name_type) {
 			case IS_UNICODE:
 				ZVAL_UNICODEL(zv, entry->name.ustr.val, entry->name.ustr.len, 1);
@@ -715,8 +892,15 @@
 		add_assoc_zval_ex(ei, ZEND_STRS("name"), zv);
 	} while (0);
 #else
-	add_assoc_stringl_ex(ei, ZEND_STRS("name"), entry->name.str.val, entry->name.str.len, 1);
+	ZVAL_STRINGL(zv, entry->name.str.val, entry->name.str.len, 1);
+//	add_assoc_stringl_ex(ei, ZEND_STRS("name"), entry->name.str.val, entry->name.str.len, 1);
 #endif
+	if (xc_var_prefix_mode > 0) {
+		if (hg_internal_var_prefix_startwith(&zv) == 0) return;
+		hg_internal_var_prefix_remove(&zv);
+	}
+	add_assoc_zval_ex(ei, ZEND_STRS("name"), zv);
+
 	switch (type) {
 		case XC_TYPE_PHP: {
 			xc_entry_php_t *entry_php = (xc_entry_php_t *) entry;
@@ -2501,7 +2685,7 @@
 			xc_stack_init(&XG(var_holds[i]));
 		}
 	}
-
+	hg_internal_var_prefix_compute();
 #ifdef ZEND_ENGINE_2
 	zend_llist_init(&XG(gc_op_arrays), sizeof(xc_gc_op_array_t), xc_gc_op_array, 0);
 #endif
@@ -2519,6 +2703,7 @@
 	xc_gc_expires_php(TSRMLS_C);
 	xc_gc_expires_var(TSRMLS_C);
 	xc_gc_deletes(TSRMLS_C);
+	ZVAL_EMPTY_STRING(xc_var_prefix_computed);
 #ifdef ZEND_ENGINE_2
 	zend_llist_destroy(&XG(gc_op_arrays));
 #endif
@@ -2806,6 +2991,7 @@
 static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *entry_hash, zval *name TSRMLS_DC) /* {{{ */
 {
 	xc_hash_value_t hv;
+	zval *new_name = NULL;
 
 	switch (name->type) {
 #ifdef IS_UNICODE
@@ -2823,7 +3009,23 @@
 #ifdef IS_UNICODE
 	entry_var->name_type = name->type;
 #endif
-	entry_var->entry.name = name->value;
+	if (xc_var_prefix_mode>0) {
+		MAKE_STD_ZVAL(new_name);
+#ifdef IS_UNICODE
+                switch (name->type) {
+                        case IS_UNICODE:
+                                if (name->type != xc_var_prefix_computed->type) convert_to_unicode(xc_var_prefix_computed);
+                        case IS_STRING:
+                                if (name->type != xc_var_prefix_computed->type) convert_to_string(xc_var_prefix_computed);
+                }
+#endif
+		// do not concat into name directly, it update the variable php side too, the prefix goes back up to the client
+		concat_function(new_name, xc_var_prefix_computed, name);
+		// we change the entry name with the prefix, but let the real name zval untouch
+		entry_var->entry.name = new_name->value;
+	} else {
+		entry_var->entry.name = name->value;
+	}
 
 	hv = xc_entry_hash_var((xc_entry_t *) entry_var TSRMLS_CC);
 
@@ -3220,6 +3422,8 @@
 	PHP_INI_ENTRY1     ("xcache.var_gc_interval",      "120", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_var_gc_interval)
 	PHP_INI_ENTRY1     ("xcache.var_allocator",    "bestfit", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_var_allocator)
 	STD_PHP_INI_ENTRY  ("xcache.var_ttl",                "0", PHP_INI_ALL,    OnUpdateLong, var_ttl,   zend_xcache_globals, xcache_globals)
+	PHP_INI_ENTRY1     ("xcache.var_prefix_mode",        "0", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_var_prefix_mode)
+	PHP_INI_ENTRY1     ("xcache.var_prefix_value",        "", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_var_prefix_value)
 PHP_INI_END()
 /* }}} */
 static PHP_MINFO_FUNCTION(xcache_cacher) /* {{{ */
@@ -3394,6 +3598,10 @@
 		pefree(xc_var_allocator, 1);
 		xc_var_allocator = NULL;
 	}
+	if (xc_var_prefix_value) {
+                pefree(xc_var_prefix_value, 1);
+                xc_var_prefix_value = NULL;
+        }
 
 	return SUCCESS;
 }
Index: htdocs/cacher/sub/entrylist.tpl.php
===================================================================
--- htdocs/cacher/sub/entrylist.tpl.php	(révision 1141)
+++ htdocs/cacher/sub/entrylist.tpl.php	(copie de travail)
@@ -140,7 +140,7 @@
 }
 ?>
 	</table>
-<?php if (!$isphp && $listName == 'Deleted') { ?>
+<?php if (!$isphp) { ?>
 	<input type="submit" value="<?php echo _T("Remove Selected"); ?>">
 <?php } ?>
 </form>
Index: htdocs/cacher/edit.php
===================================================================
--- htdocs/cacher/edit.php	(révision 1141)
+++ htdocs/cacher/edit.php	(copie de travail)
@@ -22,7 +22,7 @@
 	exit;
 }
 $value = xcache_get($name);
-if (!empty($enable['enable_eval'])) {
+if (!empty($config['enable_eval'])) {
 	$value = var_export($value, true);
 	$editable = true;
 }
