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

📄 dba.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	char *file_mode;	char mode[4], *pmode, *lock_file_mode = NULL;	int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0;		if(ac < 2) {		WRONG_PARAM_COUNT;	}		/* we pass additional args to the respective handler */	args = safe_emalloc(ac, sizeof(zval *), 0);	if (zend_get_parameters_array_ex(ac, args) != SUCCESS) {		FREENOW;		WRONG_PARAM_COUNT;	}			/* we only take string arguments */	for (i = 0; i < ac; i++) {		convert_to_string_ex(args[i]);		keylen += Z_STRLEN_PP(args[i]);	}	if (persistent) {		list_entry *le;				/* calculate hash */		key = safe_emalloc(keylen, 1, 1);		key[keylen] = '\0';		keylen = 0;				for(i = 0; i < ac; i++) {			memcpy(key+keylen, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i]));			keylen += Z_STRLEN_PP(args[i]);		}		/* try to find if we already have this link in our persistent list */		if (zend_hash_find(&EG(persistent_list), key, keylen+1, (void **) &le) == SUCCESS) {			FREENOW;						if (Z_TYPE_P(le) != le_pdb) {				RETURN_FALSE;			}					info = (dba_info *)le->ptr;			ZEND_REGISTER_RESOURCE(return_value, info, le_pdb);			return;		}	}		if (ac==2) {		hptr = DBA_G(default_hptr);		if (!hptr) {			php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "No default handler selected");			FREENOW;			RETURN_FALSE;		}	} else {		for (hptr = handler; hptr->name && strcasecmp(hptr->name, Z_STRVAL_PP(args[2])); hptr++);	}	if (!hptr->name) {		php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "No such handler: %s", Z_STRVAL_PP(args[2]));		FREENOW;		RETURN_FALSE;	}	/* Check mode: [rwnc][fl]?t?	 * r: Read	 * w: Write	 * n: Create/Truncate	 * c: Create	 *	 * d: force lock on database file	 * l: force lock on lck file	 * -: ignore locking	 *	 * t: test open database, warning if locked	 */	strlcpy(mode, Z_STRVAL_PP(args[1]), sizeof(mode));	pmode = &mode[0];	if (pmode[0] && (pmode[1]=='d' || pmode[1]=='l' || pmode[1]=='-')) { /* force lock on db file or lck file or disable locking */		switch (pmode[1]) {		case 'd':			lock_dbf = 1;			if ((hptr->flags & DBA_LOCK_ALL) == 0) {				lock_flag = (hptr->flags & DBA_LOCK_ALL);				break;			}			/* no break */		case 'l':			lock_flag = DBA_LOCK_ALL;			if ((hptr->flags & DBA_LOCK_ALL) == 0) {				php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_NOTICE, "Handler %s does locking internally", hptr->name);			}			break;		default:		case '-':			if ((hptr->flags & DBA_LOCK_ALL) == 0) {				php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Locking cannot be disabled for handler %s", hptr->name);				FREENOW;				RETURN_FALSE;			}			lock_flag = 0;			break;		}	} else {		lock_flag = (hptr->flags&DBA_LOCK_ALL);		lock_dbf = 1;	}	switch (*pmode++) {		case 'r': 			modenr = DBA_READER; 			lock_mode = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0;			file_mode = "r";			break;		case 'w': 			modenr = DBA_WRITER; 			lock_mode = (lock_flag & DBA_LOCK_WRITER) ? LOCK_EX : 0;			file_mode = "r+b";			break;		case 'c': 			modenr = DBA_CREAT; 			lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0;			if (lock_mode) {				if (lock_dbf) {					/* the create/append check will be done on the lock					 * when the lib opens the file it is already created					 */					file_mode = "r+b";       /* read & write, seek 0 */					lock_file_mode = "a+b";  /* append */				} else {					file_mode = "a+b";       /* append */					lock_file_mode = "w+b";  /* create/truncate */				}			} else {			file_mode = "a+b";			}			/* In case of the 'a+b' append mode, the handler is responsible 			 * to handle any rewind problems (see flatfile handler).			 */			break;		case 'n':			modenr = DBA_TRUNC;			lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0;			file_mode = "w+b";			break;		default:			php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Illegal DBA mode");			FREENOW;			RETURN_FALSE;	}	if (!lock_file_mode) {		lock_file_mode = file_mode;	}	if (*pmode=='d' || *pmode=='l' || *pmode=='-') {		pmode++; /* done already - skip here */	}	if (*pmode=='t') {		pmode++;		if (!lock_flag) {			php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "You cannot combine modifiers - (no lock) and t (test lock)");			FREENOW;			RETURN_FALSE;		}		if (!lock_mode) {			if ((hptr->flags & DBA_LOCK_ALL) == 0) {				php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Handler %s uses its own locking which doesn't support mode modifier t (test lock)", hptr->name);				FREENOW;				RETURN_FALSE;			} else {				php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Handler %s doesn't uses locking for this mode which makes modifier t (test lock) obsolete", hptr->name);				FREENOW;				RETURN_FALSE;			}		} else {			lock_mode |= LOCK_NB; /* test =: non blocking */		}	}	if (*pmode) {		php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Illegal DBA mode");		FREENOW;		RETURN_FALSE;	}				info = pemalloc(sizeof(dba_info), persistent);	memset(info, 0, sizeof(dba_info));	info->path = pestrdup(Z_STRVAL_PP(args[0]), persistent);	info->mode = modenr;	info->argc = ac - 3;	info->argv = args + 3;	info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL) | (persistent ? DBA_PERSISTENT : 0);	info->lock.mode = lock_mode;	/* if any open call is a locking call:	 * check if we already habe a locking call open that should block this call	 * the problem is some systems would allow read during write	 */	if (hptr->flags & DBA_LOCK_ALL) {		if ((other = php_dba_find(info->path TSRMLS_CC)) != NULL) {			if (   ( (lock_mode&LOCK_EX)        && (other->lock.mode&(LOCK_EX|LOCK_SH)) )			    || ( (other->lock.mode&LOCK_EX) && (lock_mode&(LOCK_EX|LOCK_SH))        )			   ) {				error = "Unable to establish lock (database file already open)"; /* force failure exit */			}		}	}	if (!error && lock_mode) {		if (lock_dbf) {			info->lock.name = pestrdup(info->path, persistent);		} else {			spprintf(&info->lock.name, 0, "%s.lck", info->path);			if (!strcmp(file_mode, "r")) {				/* when in read only mode try to use existing .lck file first */				/* do not log errors for .lck file while in read ony mode on .lck file */				lock_file_mode = "rb";				info->lock.fp = php_stream_open_wrapper(info->lock.name, lock_file_mode, STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE|persistent_flag, NULL);			}			if (!info->lock.fp) {				/* when not in read mode or failed to open .lck file read only. now try again in create(write) mode and log errors */				lock_file_mode = "a+b";			}		}		if (!info->lock.fp) {			info->lock.fp = php_stream_open_wrapper(info->lock.name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE|persistent_flag, NULL);		}		if (!info->lock.fp) {			dba_close(info TSRMLS_CC);			/* stream operation already wrote an error message */			FREENOW;			RETURN_FALSE;		}		if (php_stream_cast(info->lock.fp, PHP_STREAM_AS_FD, (void*)&info->lock.fd, 1) == FAILURE) {			dba_close(info TSRMLS_CC);			/* stream operation already wrote an error message */			FREENOW;			RETURN_FALSE;		}		if (php_flock(info->lock.fd, lock_mode)) {					error = "Unable to establish lock"; /* force failure exit */		}	}	/* centralised open stream for builtin */	if (!error && (hptr->flags&DBA_STREAM_OPEN)==DBA_STREAM_OPEN) {		if (info->lock.fp && lock_dbf) {			info->fp = info->lock.fp; /* use the same stream for locking and database access */		} else {			info->fp = php_stream_open_wrapper(info->path, file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE|persistent_flag, NULL);		}		if (!info->fp) {			dba_close(info TSRMLS_CC);			/* stream operation already wrote an error message */			FREENOW;			RETURN_FALSE;		}	}	if (error || hptr->open(info, &error TSRMLS_CC) != SUCCESS) {		dba_close(info TSRMLS_CC);		php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:"");		FREENOW;		RETURN_FALSE;	}	info->hnd = hptr;	info->argc = 0;	info->argv = NULL;	if (persistent) {		list_entry new_le;		Z_TYPE(new_le) = le_pdb;		new_le.ptr = info;		if (zend_hash_update(&EG(persistent_list), key, keylen+1, &new_le, sizeof(list_entry), NULL) == FAILURE) {			dba_close(info TSRMLS_CC);			php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Could not register persistent resource");			FREENOW;			RETURN_FALSE;		}	}	ZEND_REGISTER_RESOURCE(return_value, info, (persistent ? le_pdb : le_db));	FREENOW;}/* }}} */#undef FREENOW/* {{{ proto resource dba_popen(string path, string mode [, string handlername, string ...])   Opens path using the specified handler in mode persistently */PHP_FUNCTION(dba_popen){	php_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto resource dba_open(string path, string mode [, string handlername, string ...])   Opens path using the specified handler in mode*/PHP_FUNCTION(dba_open){	php_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto void dba_close(resource handle)   Closes database */PHP_FUNCTION(dba_close){	DBA_ID_GET1;		zend_list_delete(Z_RESVAL_PP(id));}/* }}} *//* {{{ proto bool dba_exists(string key, resource handle)   Checks, if the specified key exists */PHP_FUNCTION(dba_exists){	DBA_ID_GET2;	if(info->hnd->exists(info, key_str, key_len TSRMLS_CC) == SUCCESS) {		DBA_ID_DONE;		RETURN_TRUE;	}	DBA_ID_DONE;	RETURN_FALSE;}/* }}} *//* {{{ proto string dba_fetch(string key, [int skip ,] resource handle)   Fetches the data associated with key */PHP_FUNCTION(dba_fetch){	char *val;	int len = 0;	DBA_ID_GET2_3;	if (ac==3) {		if (!strcmp(info->hnd->name, "cdb")) {			if (skip < 0) {				php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s accepts only skip values greater than or equal to zero, using skip=0", info->hnd->name);				skip = 0;			}		} else if (!strcmp(info->hnd->name, "inifile")) {			/* "-1" is compareable to 0 but allows a non restrictive 			 * access which is fater. For example 'inifile' uses this			 * to allow faster access when the key was already found			 * using firstkey/nextkey. However explicitly setting the			 * value to 0 ensures the first value. 			 */			if (skip < -1) {				php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s accepts only skip value -1 and greater, using skip=0", info->hnd->name);				skip = 0;			}		} else {			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s does not support optional skip parameter, the value will be ignored", info->hnd->name);			skip = 0;					}	} else {		skip = 0; 	}	if((val = info->hnd->fetch(info, key_str, key_len, skip, &len TSRMLS_CC)) != NULL) {		if (val && PG(magic_quotes_runtime)) {			val = php_addslashes(val, len, &len, 1 TSRMLS_CC);		}		DBA_ID_DONE;		RETURN_STRINGL(val, len, 0);	} 	DBA_ID_DONE;	RETURN_FALSE;}/* }}} *//* {{{ proto string dba_firstkey(resource handle)   Resets the internal key pointer and returns the first key */PHP_FUNCTION(dba_firstkey){	char *fkey;	int len;	DBA_ID_GET1;	fkey = info->hnd->firstkey(info, &len TSRMLS_CC);	if(fkey)		RETURN_STRINGL(fkey, len, 0);	RETURN_FALSE;}/* }}} *//* {{{ proto string dba_nextkey(resource handle)   Returns the next key */PHP_FUNCTION(dba_nextkey){	char *nkey;	int len;	DBA_ID_GET1;	nkey = info->hnd->nextkey(info, &len TSRMLS_CC);	if(nkey)		RETURN_STRINGL(nkey, len, 0);	RETURN_FALSE;}/* }}} *//* {{{ proto bool dba_delete(string key, resource handle)   Deletes the entry associated with key   If inifile: remove all other key lines */PHP_FUNCTION(dba_delete){	DBA_ID_GET2;		DBA_WRITE_CHECK;		if(info->hnd->delete(info, key_str, key_len TSRMLS_CC) == SUCCESS)	{		DBA_ID_DONE;		RETURN_TRUE;	}	DBA_ID_DONE;	RETURN_FALSE;}/* }}} *//* {{{ proto bool dba_insert(string key, string value, resource handle)   If not inifile: Insert value as key, return false, if key exists already    If inifile: Add vakue as key (next instance of key) */PHP_FUNCTION(dba_insert){	php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto bool dba_replace(string key, string value, resource handle)   Inserts value as key, replaces key, if key exists already   If inifile: remove all other key lines */PHP_FUNCTION(dba_replace){	php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto bool dba_optimize(resource handle)   Optimizes (e.g. clean up, vacuum) database */PHP_FUNCTION(dba_optimize){	DBA_ID_GET1;		DBA_WRITE_CHECK;	if(info->hnd->optimize(info TSRMLS_CC) == SUCCESS) {		RETURN_TRUE;	}	RETURN_FALSE;}/* }}} *//* {{{ proto bool dba_sync(resource handle)   Synchronizes database */PHP_FUNCTION(dba_sync){	DBA_ID_GET1;		if(info->hnd->sync(info TSRMLS_CC) == SUCCESS) {		RETURN_TRUE;	}	RETURN_FALSE;}/* }}} *//* {{{ proto array dba_handlers([bool full_info])   List configured database handlers */PHP_FUNCTION(dba_handlers){	dba_handler *hptr;	zend_bool full_info = 0;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &full_info) == FAILURE) {		ZEND_WRONG_PARAM_COUNT();		RETURN_FALSE;	}	array_init(return_value);	for(hptr = handler; hptr->name; hptr++) {		if (full_info) {			add_assoc_string(return_value, hptr->name, hptr->info(hptr, NULL TSRMLS_CC), 0);		} else {			add_next_index_string(return_value, hptr->name, 1);		} 	}}/* }}} *//* {{{ proto array dba_list()   List opened databases */PHP_FUNCTION(dba_list){	ulong numitems, i;	zend_rsrc_list_entry *le;	dba_info *info;	if (ZEND_NUM_ARGS()!=0) {		ZEND_WRONG_PARAM_COUNT();		RETURN_FALSE;	}	array_init(return_value);	numitems = zend_hash_next_free_element(&EG(regular_list));	for (i=1; i<numitems; i++) {		if (zend_hash_index_find(&EG(regular_list), i, (void **) &le)==FAILURE) {			continue;		}		if (Z_TYPE_P(le) == le_db || Z_TYPE_P(le) == le_pdb) {			info = (dba_info *)(le->ptr);			add_index_string(return_value, i, info->path, 1);		}	}}/* }}} */#endif /* HAVE_DBA *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */

⌨️ 快捷键说明

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