⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		}		PS_ADD_VARL(name, namelen);		efree(name);	}	PHP_VAR_UNSERIALIZE_DESTROY(var_hash);	return SUCCESS;}#define PS_DELIMITER '|'#define PS_UNDEF_MARKER '!'PS_SERIALIZER_ENCODE_FUNC(php){	smart_str buf = {0};	php_serialize_data_t var_hash;	PS_ENCODE_VARS;	PHP_VAR_SERIALIZE_INIT(var_hash);	PS_ENCODE_LOOP(			smart_str_appendl(&buf, key, key_length);			if (memchr(key, PS_DELIMITER, key_length)) {				PHP_VAR_SERIALIZE_DESTROY(var_hash);				smart_str_free(&buf);								return FAILURE;			}			smart_str_appendc(&buf, PS_DELIMITER);						php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);		} else {			smart_str_appendc(&buf, PS_UNDEF_MARKER);			smart_str_appendl(&buf, key, key_length);			smart_str_appendc(&buf, PS_DELIMITER);	);		if (newlen) *newlen = buf.len;	*newstr = buf.c;	PHP_VAR_SERIALIZE_DESTROY(var_hash);	return SUCCESS;}PS_SERIALIZER_DECODE_FUNC(php)	{	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) {		zval **tmp;		q = p;		while (*q != PS_DELIMITER)			if (++q >= endptr) goto break_outer_loop;				if (p[0] == PS_UNDEF_MARKER) {			p++;			has_value = 0;		} else {			has_value = 1;		}				namelen = q - p;		name = estrndup(p, namelen);		q++;		if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {			if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) {				goto skip;			}		}		if (has_value) {			ALLOC_INIT_ZVAL(current);			if (php_var_unserialize(&current, (const unsigned char **)&q, endptr, &var_hash TSRMLS_CC)) {				php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);			}			zval_ptr_dtor(&current);		}		PS_ADD_VARL(name, namelen);skip:		efree(name);				p = q;	}break_outer_loop:		PHP_VAR_UNSERIALIZE_DESTROY(var_hash);	return SUCCESS;}static void php_session_track_init(TSRMLS_D){	zval *session_vars = NULL;		/* Unconditionally destroy existing arrays -- possible dirty data */	zend_hash_del(&EG(symbol_table), "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"));	zend_hash_del(&EG(symbol_table), "_SESSION", sizeof("_SESSION"));	if (PS(http_session_vars)) {		zval_ptr_dtor(&PS(http_session_vars));	}	MAKE_STD_ZVAL(session_vars);	array_init(session_vars);	PS(http_session_vars) = session_vars;	ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), PS(http_session_vars), 3, 1);	ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 3, 1);}static char *php_session_encode(int *newlen TSRMLS_DC){	char *ret = NULL;	IF_SESSION_VARS() {		if (!PS(serializer)) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown session.serialize_handler. Failed to encode session object.");			ret = NULL;		}		else if (PS(serializer)->encode(&ret, newlen TSRMLS_CC) == FAILURE)			ret = NULL;	} else {		 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode non-existent session.");	}	return ret;}static void php_session_decode(const char *val, int vallen TSRMLS_DC){	if (!PS(serializer)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object.");		return;	}	if (PS(serializer)->decode(val, vallen TSRMLS_CC) == FAILURE) {		php_session_destroy(TSRMLS_C);		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to decode session object. Session has been destroyed.");	}}static char hexconvtab[] = "0123456789abcdef";char *php_session_create_id(PS_CREATE_SID_ARGS){	PHP_MD5_CTX context;	unsigned char digest[16];	char buf[256];	struct timeval tv;	int i;	int j = 0;	unsigned char c;	gettimeofday(&tv, NULL);	PHP_MD5Init(&context);		sprintf(buf, "%ld%ld%0.8f", tv.tv_sec, tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);	PHP_MD5Update(&context, buf, strlen(buf));	if (PS(entropy_length) > 0) {		int fd;		fd = VCWD_OPEN(PS(entropy_file), O_RDONLY);		if (fd >= 0) {			unsigned char buf[2048];			int n;			int to_read = PS(entropy_length);						while (to_read > 0) {				n = read(fd, buf, MIN(to_read, sizeof(buf)));				if (n <= 0) break;				PHP_MD5Update(&context, buf, n);				to_read -= n;			}			close(fd);		}	}	PHP_MD5Final(digest, &context);		for (i = 0; i < 16; i++) {		c = digest[i];		buf[j++] = hexconvtab[c >> 4];		buf[j++] = hexconvtab[c & 15];	}	buf[j] = '\0';		if (newlen) 		*newlen = j;	return estrdup(buf);}static void php_session_initialize(TSRMLS_D){	char *val;	int vallen;	/* check session name for invalid characters */	if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {		efree(PS(id));		PS(id) = NULL;	}	if (!PS(mod)) {		php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session.");		return;	}	/* Open session handler first */	if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name) TSRMLS_CC) == FAILURE) {		php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to initialize storage module: %s (path: %s)", PS(mod)->s_name, PS(save_path));		return;	}		/* If there is no ID, use session module to create one */	if (!PS(id))		PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);		/* Read data */	/* Question: if you create a SID here, should you also try to read data?	 * I'm not sure, but while not doing so will remove one session operation	 * it could prove usefull for those sites which wish to have "default"	 * session information	 */	php_session_track_init(TSRMLS_C);	if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {		php_session_decode(val, vallen TSRMLS_CC);		efree(val);	}}static int migrate_global(HashTable *ht, HashPosition *pos TSRMLS_DC){	char *str;	uint str_len;	ulong num_key;	int n;	zval **val;	int ret = 0;		n = zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key, 0, pos);	switch (n) {		case HASH_KEY_IS_STRING:			if (zend_hash_find(&EG(symbol_table), str, str_len, 						(void **) &val) == SUCCESS 					&& val && Z_TYPE_PP(val) != IS_NULL) {				ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val, 						(*val)->refcount + 1 , 1);				ret = 1;			}			break;		case HASH_KEY_IS_LONG:			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The session bug compatibility code will not "					"try to locate the global variable $%lu due to its "					"numeric nature.", num_key);			break;	}		return ret;}static void php_session_save_current_state(TSRMLS_D){	int ret = FAILURE;		IF_SESSION_VARS() {		if (PS(bug_compat) && !PG(register_globals)) {			HashTable *ht = Z_ARRVAL_P(PS(http_session_vars));			HashPosition pos;			zval **val;			int do_warn = 0;			zend_hash_internal_pointer_reset_ex(ht, &pos);			while (zend_hash_get_current_data_ex(ht, 						(void **) &val, &pos) != FAILURE) {				if (Z_TYPE_PP(val) == IS_NULL) {					if (migrate_global(ht, &pos TSRMLS_CC))						do_warn = 1;				}				zend_hash_move_forward_ex(ht, &pos);			}			if (do_warn && PS(bug_compat_warn)) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Your script possibly relies on a session side-effect which existed until PHP 4.2.3. Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled. You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively.");			}		}		if (PS(mod_data)) {			char *val;			int vallen;			val = php_session_encode(&vallen TSRMLS_CC);			if (val) {				ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC);				efree(val);			} else {				ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC);			}		}		if (ret == FAILURE)			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write session data (%s). Please "					"verify that the current setting of session.save_path "					"is correct (%s)",					PS(mod)->s_name,					PS(save_path));	}		if (PS(mod_data))		PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);}static char *month_names[] = {	"Jan", "Feb", "Mar", "Apr", "May", "Jun",	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};static char *week_days[] = {	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};static void strcpy_gmt(char *ubuf, time_t *when){	char buf[MAX_STR];	struct tm tm;	int n;		php_gmtime_r(when, &tm);		n = sprintf(buf, "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */				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);	memcpy(ubuf, buf, n);	ubuf[n] = '\0';}static void last_modified(TSRMLS_D){	const char *path;	struct stat sb;	char buf[MAX_STR + 1];		path = SG(request_info).path_translated;	if (path) {		if (VCWD_STAT(path, &sb) == -1) {			return;		}#define LAST_MODIFIED "Last-Modified: "		memcpy(buf, LAST_MODIFIED, sizeof(LAST_MODIFIED) - 1);		strcpy_gmt(buf + sizeof(LAST_MODIFIED) - 1, &sb.st_mtime);		ADD_HEADER(buf);	}}CACHE_LIMITER_FUNC(public){	char buf[MAX_STR + 1];	struct timeval tv;	time_t now;		gettimeofday(&tv, NULL);	now = tv.tv_sec + PS(cache_expire) * 60;#define EXPIRES "Expires: "	memcpy(buf, EXPIRES, sizeof(EXPIRES) - 1);	strcpy_gmt(buf + sizeof(EXPIRES) - 1, &now);	ADD_HEADER(buf);		sprintf(buf, "Cache-Control: public, max-age=%ld", PS(cache_expire) * 60); /* SAFE */	ADD_HEADER(buf);		last_modified(TSRMLS_C);}CACHE_LIMITER_FUNC(private_no_expire){	char buf[MAX_STR + 1];		sprintf(buf, "Cache-Control: private, max-age=%ld, pre-check=%ld", PS(cache_expire) * 60, PS(cache_expire) * 60); /* SAFE */	ADD_HEADER(buf);	last_modified(TSRMLS_C);}CACHE_LIMITER_FUNC(private){	ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");	CACHE_LIMITER(private_no_expire)(TSRMLS_C);}CACHE_LIMITER_FUNC(nocache){	ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");	/* For HTTP/1.1 conforming clients and the rest (MSIE 5) */	ADD_HEADER("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");	/* For HTTP/1.0 conforming clients */	ADD_HEADER("Pragma: no-cache");}static php_session_cache_limiter_t php_session_cache_limiters[] = {	CACHE_LIMITER_ENTRY(public)	CACHE_LIMITER_ENTRY(private)	CACHE_LIMITER_ENTRY(private_no_expire)	CACHE_LIMITER_ENTRY(nocache)	{0}};static int php_session_cache_limiter(TSRMLS_D){	php_session_cache_limiter_t *lim;	if (PS(cache_limiter)[0] == '\0') return 0;		if (SG(headers_sent)) {		char *output_start_filename = php_get_output_start_filename(TSRMLS_C);		int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);		if (output_start_filename) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)",				output_start_filename, output_start_lineno);		} else {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");		}			return -2;	}		for (lim = php_session_cache_limiters; lim->name; lim++) {		if (!strcasecmp(lim->name, PS(cache_limiter))) {			lim->func(TSRMLS_C);			return 0;		}	}	return -1;}#define COOKIE_SET_COOKIE "Set-Cookie: "#define COOKIE_EXPIRES	"; expires="#define COOKIE_PATH		"; path="#define COOKIE_DOMAIN	"; domain="#define COOKIE_SECURE	"; secure"static void php_session_send_cookie(TSRMLS_D){	smart_str ncookie = {0};	char *date_fmt = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -