helly Mon Dec 9 13:03:01 2002 EDT Modified files: /php4/ext/dba dba.c Log: Recheckin as unix # *** sorry ** a new diff tool converted it to dos before last comit *** sorry ***
Index: php4/ext/dba/dba.c diff -u php4/ext/dba/dba.c:1.66 php4/ext/dba/dba.c:1.67 --- php4/ext/dba/dba.c:1.66 Mon Dec 9 12:54:13 2002 +++ php4/ext/dba/dba.c Mon Dec 9 13:03:00 2002 @@ -1,804 +1,804 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 4 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2002 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.02 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_02.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | [EMAIL PROTECTED] so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Sascha Schumann <[EMAIL PROTECTED]> | - | Marcus Boerger <[EMAIL PROTECTED]> | - +----------------------------------------------------------------------+ - */ - -/* $Id: dba.c,v 1.66 2002/12/09 17:54:13 helly Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" - -#if HAVE_DBA - -#include "ext/standard/flock_compat.h" -#include <stdio.h> -#include <fcntl.h> -#ifdef HAVE_SYS_FILE_H -#include <sys/file.h> -#endif - -#include "php_dba.h" -#include "ext/standard/info.h" -#include "ext/standard/php_string.h" - -#include "php_gdbm.h" -#include "php_ndbm.h" -#include "php_dbm.h" -#include "php_cdb.h" -#include "php_db2.h" -#include "php_db3.h" -#include "php_db4.h" -#include "php_flatfile.h" - -/* {{{ dba_functions[] - */ -function_entry dba_functions[] = { - PHP_FE(dba_open, NULL) - PHP_FE(dba_popen, NULL) - PHP_FE(dba_close, NULL) - PHP_FE(dba_delete, NULL) - PHP_FE(dba_exists, NULL) - PHP_FE(dba_fetch, NULL) - PHP_FE(dba_insert, NULL) - PHP_FE(dba_replace, NULL) - PHP_FE(dba_firstkey, NULL) - PHP_FE(dba_nextkey, NULL) - PHP_FE(dba_optimize, NULL) - PHP_FE(dba_sync, NULL) - PHP_FE(dba_handlers, NULL) - PHP_FE(dba_list, NULL) - {NULL, NULL, NULL} -}; -/* }}} */ - -PHP_MINIT_FUNCTION(dba); -PHP_MINFO_FUNCTION(dba); - -zend_module_entry dba_module_entry = { - STANDARD_MODULE_HEADER, - "dba", - dba_functions, - PHP_MINIT(dba), - NULL, - NULL, - NULL, - PHP_MINFO(dba), - NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES -}; - -#ifdef COMPILE_DL_DBA -ZEND_GET_MODULE(dba) -#endif - -typedef struct dba_handler { - char *name; /* handler name */ - int flags; /* whether and how dba does locking and other flags*/ - int (*open)(dba_info *, char **error TSRMLS_DC); - void (*close)(dba_info * TSRMLS_DC); - char* (*fetch)(dba_info *, char *, int, int, int * TSRMLS_DC); - int (*update)(dba_info *, char *, int, char *, int, int TSRMLS_DC); - int (*exists)(dba_info *, char *, int TSRMLS_DC); - int (*delete)(dba_info *, char *, int TSRMLS_DC); - char* (*firstkey)(dba_info *, int * TSRMLS_DC); - char* (*nextkey)(dba_info *, int * TSRMLS_DC); - int (*optimize)(dba_info * TSRMLS_DC); - int (*sync)(dba_info * TSRMLS_DC); -} dba_handler; - -/* {{{ macromania */ - -#define DBA_ID_PARS \ - zval **id; \ - dba_info *info = NULL; \ - int ac = ZEND_NUM_ARGS() - -/* these are used to get the standard arguments */ - -#define DBA_GET1 \ - if(ac != 1 || zend_get_parameters_ex(ac, &id) != SUCCESS) { \ - WRONG_PARAM_COUNT; \ - } - -#define DBA_GET2 \ - zval **key; \ - if(ac != 2 || zend_get_parameters_ex(ac, &key, &id) != SUCCESS) { \ - WRONG_PARAM_COUNT; \ - } \ - convert_to_string_ex(key) - -#define DBA_GET2_3 \ - zval **key; \ - zval **tmp; \ - int skip = 0; \ - switch(ac) { \ - case 2: \ - if (zend_get_parameters_ex(ac, &key, &id) != SUCCESS) { \ - WRONG_PARAM_COUNT; \ - } \ - break; \ - case 3: \ - if (zend_get_parameters_ex(ac, &key, &tmp, &id) != SUCCESS) { \ - WRONG_PARAM_COUNT; \ - } \ - convert_to_long_ex(tmp); \ - skip = Z_LVAL_PP(tmp); \ - break; \ - default: \ - WRONG_PARAM_COUNT; \ - } \ - convert_to_string_ex(key) - -#define DBA_ID_GET \ - ZEND_FETCH_RESOURCE2(info, dba_info *, id, -1, "DBA identifier", le_db, le_pdb); - -#define DBA_ID_GET1 DBA_ID_PARS; DBA_GET1; DBA_ID_GET -#define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_ID_GET -#define DBA_ID_GET2_3 DBA_ID_PARS; DBA_GET2_3; DBA_ID_GET - -/* a DBA handler must have specific routines */ - -#define DBA_NAMED_HND(name, x, flags) \ -{\ - #name, flags, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ - dba_exists_##x, dba_delete_##x, dba_firstkey_##x, dba_nextkey_##x, \ - dba_optimize_##x, dba_sync_##x \ -}, - -#define DBA_HND(x, flags) DBA_NAMED_HND(x, x, flags) - -/* check whether the user has write access */ -#define DBA_WRITE_CHECK \ - if(info->mode != DBA_WRITER && info->mode != DBA_TRUNC && info->mode != DBA_CREAT) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "You cannot perform a modification to a database without proper access"); \ - RETURN_FALSE; \ - } - -/* }}} */ - -/* {{{ globals */ - -static dba_handler handler[] = { -#if DBA_GDBM - DBA_HND(gdbm, DBA_LOCK_EXT) /* Locking done in library if set */ -#endif -#if DBA_DBM - DBA_HND(dbm, DBA_LOCK_ALL) /* No lock in lib */ -#endif -#if DBA_NDBM - DBA_HND(ndbm, DBA_LOCK_ALL) /* Could be done in library: filemode = 0644 + S_ENFMT */ -#endif -#if DBA_CDB - DBA_HND(cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ -#endif -#if DBA_CDB_BUILTIN - DBA_NAMED_HND(cdb_make, cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ -#endif -#if DBA_DB2 - DBA_HND(db2, DBA_LOCK_ALL) /* No lock in lib */ -#endif -#if DBA_DB3 - DBA_HND(db3, DBA_LOCK_ALL) /* No lock in lib */ -#endif -#if DBA_DB4 - DBA_HND(db4, DBA_LOCK_ALL) /* No lock in lib */ -#endif -#if DBA_FLATFILE - DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ -#endif - { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } -}; - -static int le_db; -static int le_pdb; -/* }}} */ - -/* {{{ dba_close - */ -static void dba_close(dba_info *info TSRMLS_DC) -{ - if (info->hnd) info->hnd->close(info TSRMLS_CC); - if (info->path) efree(info->path); - if (info->fp && info->fp!=info->lock.fp) php_stream_close(info->fp); - if (info->lock.fd) { - php_flock(info->lock.fd, LOCK_UN); - close(info->lock.fd); - info->lock.fd = 0; - } - if (info->lock.fp) php_stream_close(info->lock.fp); - if (info->lock.name) efree(info->lock.name); - efree(info); -} -/* }}} */ - -/* {{{ dba_close_rsrc - */ -static void dba_close_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - dba_info *info = (dba_info *)rsrc->ptr; - - dba_close(info TSRMLS_CC); -} -/* }}} */ - -/* {{{ PHP_MINIT_FUNCTION - */ -PHP_MINIT_FUNCTION(dba) -{ - le_db = zend_register_list_destructors_ex(dba_close_rsrc, NULL, "dba", module_number); - le_pdb = zend_register_list_destructors_ex(NULL, dba_close_rsrc, "dba persistent", module_number); - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MSHUTDOWN_FUNCTION - */ -PHP_MSHUTDOWN_FUNCTION(dba) -{ - return SUCCESS; -} -/* }}} */ - -#include "ext/standard/php_smart_str.h" - -/* {{{ PHP_MINFO_FUNCTION - */ -PHP_MINFO_FUNCTION(dba) -{ - dba_handler *hptr; - smart_str handlers = {0}; - - for(hptr = handler; hptr->name; hptr++) { - smart_str_appends(&handlers, hptr->name); - smart_str_appendc(&handlers, ' '); - } - - php_info_print_table_start(); - php_info_print_table_row(2, "DBA support", "enabled"); - if (handlers.c) { - smart_str_0(&handlers); - php_info_print_table_row(2, "Supported handlers", handlers.c); - smart_str_free(&handlers); - } else { - php_info_print_table_row(2, "Supported handlers", "none"); - } - php_info_print_table_end(); -} -/* }}} */ - -/* {{{ php_dba_update - */ -static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode) -{ - DBA_ID_PARS; - zval **val, **key; - char *v; - int len; - - if(ac != 3 || zend_get_parameters_ex(ac, &key, &val, &id) != SUCCESS) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(key); - convert_to_string_ex(val); - DBA_ID_GET; - - DBA_WRITE_CHECK; - - if (PG(magic_quotes_runtime)) { - len = Z_STRLEN_PP(val); - v = estrndup(Z_STRVAL_PP(val), len); - php_stripslashes(v, &len TSRMLS_CC); - if(info->hnd->update(info, VALLEN(key), v, len, mode TSRMLS_CC) == SUCCESS) { - efree(v); - RETURN_TRUE; - } - efree(v); - } else { - if(info->hnd->update(info, VALLEN(key), VALLEN(val), mode TSRMLS_CC) == SUCCESS) - RETURN_TRUE; - } - RETURN_FALSE; -} -/* }}} */ - -#define FREENOW if(args) efree(args); if(key) efree(key) - -/* {{{ php_find_dbm - */ -dba_info *php_dba_find(const char* path TSRMLS_DC) -{ - list_entry *le; - dba_info *info; - int numitems, i; - - 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); - if (!strcmp(info->path, path)) { - return (dba_info *)(le->ptr); - } - } - } - - return NULL; -} -/* }}} */ - -/* {{{ php_dba_open - */ -static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) -{ - zval ***args = (zval ***) NULL; - int ac = ZEND_NUM_ARGS(); - dba_mode_t modenr; - dba_info *info, *other; - dba_handler *hptr; - char *key = NULL, *error = NULL; - int keylen = 0; - int i; - int lock_mode, lock_flag, lock_dbf = 0; - char *file_mode; - char mode[4], *pmode, *lock_file_mode; - - if(ac < 3) { - WRONG_PARAM_COUNT; - } - - /* we pass additional args to the respective handler */ - args = emalloc(ac * sizeof(zval *)); - 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 = emalloc(keylen); - 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; - } - } - - 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 - * - * 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': - 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); - } - lock_dbf = 1; - /* no break */ - case 'l': - lock_flag = DBA_LOCK_ALL; - break; - default: - case '-': - lock_flag = 0; - break; - } - } else { - lock_flag = (hptr->flags&DBA_LOCK_ALL); - } - 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 'n': - modenr = DBA_TRUNC; - lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0; - file_mode = "w+b"; - break; - case 'c': - modenr = DBA_CREAT; - lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0; - file_mode = "a+b"; - break; - default: - modenr = 0; - lock_mode = 0; - 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)", hptr->name); - 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 || !modenr) { - 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 = emalloc(sizeof(dba_info)); - memset(info, 0, sizeof(dba_info)); - info->path = estrdup(Z_STRVAL_PP(args[0])); - info->mode = modenr; - info->argc = ac - 3; - info->argv = args + 3; - info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL); - 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 = estrdup(info->path); - lock_file_mode = file_mode; - } else { - spprintf(&info->lock.name, 0, "%s.lck", info->path); - lock_file_mode = "a+b"; - } - info->lock.fp = php_stream_open_wrapper(info->lock.name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE, 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, 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", Z_STRVAL_PP(args[2]), 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) { - FREENOW; - RETURN_FALSE; - } - } - - ZEND_REGISTER_RESOURCE(return_value, info, (persistent ? le_pdb : le_db)); - FREENOW; -} -/* }}} */ -#undef FREENOW - -/* {{{ proto int 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 int 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, int handle) - Checks, if the specified key exists */ -PHP_FUNCTION(dba_exists) -{ - DBA_ID_GET2; - - if(info->hnd->exists(info, VALLEN(key) TSRMLS_CC) == SUCCESS) { - RETURN_TRUE; - } - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto string dba_fetch(string key, [int skip ,] int handle) - Fetches the data associated with key */ -PHP_FUNCTION(dba_fetch) -{ - char *val; - int len = 0; - DBA_ID_GET2_3; - - if (ac==3 && strcmp(info->hnd->name, "cdb")) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s does not support optional skip parameter", info->hnd->name); - } - if((val = info->hnd->fetch(info, VALLEN(key), skip, &len TSRMLS_CC)) != NULL) { - if (val && PG(magic_quotes_runtime)) { - val = php_addslashes(val, len, &len, 1 TSRMLS_CC); - } - RETURN_STRINGL(val, len, 0); - } - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto string dba_firstkey(int 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(int 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, int handle) - Deletes the entry associated with key */ -PHP_FUNCTION(dba_delete) -{ - DBA_ID_GET2; - - DBA_WRITE_CHECK; - - if(info->hnd->delete(info, VALLEN(key) TSRMLS_CC) == SUCCESS) - RETURN_TRUE; - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto bool dba_insert(string key, string value, int handle) - Inserts value as key, returns false, if key exists already */ -PHP_FUNCTION(dba_insert) -{ - php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ proto bool dba_replace(string key, string value, int handle) - Inserts value as key, replaces key, if key exists already */ -PHP_FUNCTION(dba_replace) -{ - php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ proto bool dba_optimize(int 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(int 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() - List configured databases */ -PHP_FUNCTION(dba_handlers) -{ - dba_handler *hptr; - - if (ZEND_NUM_ARGS()!=0) { - ZEND_WRONG_PARAM_COUNT(); - RETURN_FALSE; - } - - if (array_init(return_value) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); - RETURN_FALSE; - } - for(hptr = handler; hptr->name; hptr++) { - add_next_index_string(return_value, hptr->name, 1); - } -} -/* }}} */ - -/* {{{ proto array dba_list() - List configured 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; - } - - if (array_init(return_value) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); - RETURN_FALSE; - } - 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 - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ - +/* + +----------------------------------------------------------------------+ + | PHP Version 4 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2002 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.02 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_02.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | [EMAIL PROTECTED] so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Sascha Schumann <[EMAIL PROTECTED]> | + | Marcus Boerger <[EMAIL PROTECTED]> | + +----------------------------------------------------------------------+ + */ + +/* $Id: dba.c,v 1.67 2002/12/09 18:03:00 helly Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_DBA + +#include "ext/standard/flock_compat.h" +#include <stdio.h> +#include <fcntl.h> +#ifdef HAVE_SYS_FILE_H +#include <sys/file.h> +#endif + +#include "php_dba.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" + +#include "php_gdbm.h" +#include "php_ndbm.h" +#include "php_dbm.h" +#include "php_cdb.h" +#include "php_db2.h" +#include "php_db3.h" +#include "php_db4.h" +#include "php_flatfile.h" + +/* {{{ dba_functions[] + */ +function_entry dba_functions[] = { + PHP_FE(dba_open, NULL) + PHP_FE(dba_popen, NULL) + PHP_FE(dba_close, NULL) + PHP_FE(dba_delete, NULL) + PHP_FE(dba_exists, NULL) + PHP_FE(dba_fetch, NULL) + PHP_FE(dba_insert, NULL) + PHP_FE(dba_replace, NULL) + PHP_FE(dba_firstkey, NULL) + PHP_FE(dba_nextkey, NULL) + PHP_FE(dba_optimize, NULL) + PHP_FE(dba_sync, NULL) + PHP_FE(dba_handlers, NULL) + PHP_FE(dba_list, NULL) + {NULL, NULL, NULL} +}; +/* }}} */ + +PHP_MINIT_FUNCTION(dba); +PHP_MINFO_FUNCTION(dba); + +zend_module_entry dba_module_entry = { + STANDARD_MODULE_HEADER, + "dba", + dba_functions, + PHP_MINIT(dba), + NULL, + NULL, + NULL, + PHP_MINFO(dba), + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES +}; + +#ifdef COMPILE_DL_DBA +ZEND_GET_MODULE(dba) +#endif + +typedef struct dba_handler { + char *name; /* handler name */ + int flags; /* whether and how dba does locking and other flags*/ + int (*open)(dba_info *, char **error TSRMLS_DC); + void (*close)(dba_info * TSRMLS_DC); + char* (*fetch)(dba_info *, char *, int, int, int * TSRMLS_DC); + int (*update)(dba_info *, char *, int, char *, int, int TSRMLS_DC); + int (*exists)(dba_info *, char *, int TSRMLS_DC); + int (*delete)(dba_info *, char *, int TSRMLS_DC); + char* (*firstkey)(dba_info *, int * TSRMLS_DC); + char* (*nextkey)(dba_info *, int * TSRMLS_DC); + int (*optimize)(dba_info * TSRMLS_DC); + int (*sync)(dba_info * TSRMLS_DC); +} dba_handler; + +/* {{{ macromania */ + +#define DBA_ID_PARS + \ + zval **id; + \ + dba_info *info = NULL; + \ + int ac = ZEND_NUM_ARGS() + +/* these are used to get the standard arguments */ + +#define DBA_GET1 + \ + if(ac != 1 || zend_get_parameters_ex(ac, &id) != SUCCESS) { \ + WRONG_PARAM_COUNT; + \ + } + +#define DBA_GET2 + \ + zval **key; + \ + if(ac != 2 || zend_get_parameters_ex(ac, &key, &id) != SUCCESS) { \ + WRONG_PARAM_COUNT; + \ + } + \ + convert_to_string_ex(key) + +#define DBA_GET2_3 + \ + zval **key; + \ + zval **tmp; + \ + int skip = 0; + \ + switch(ac) { + \ + case 2: + \ + if (zend_get_parameters_ex(ac, &key, &id) != SUCCESS) { \ + WRONG_PARAM_COUNT; + \ + } + \ + break; + \ + case 3: + \ + if (zend_get_parameters_ex(ac, &key, &tmp, &id) != SUCCESS) { \ + WRONG_PARAM_COUNT; + \ + } + \ + convert_to_long_ex(tmp); + \ + skip = Z_LVAL_PP(tmp); + \ + break; + \ + default: + \ + WRONG_PARAM_COUNT; + \ + } + \ + convert_to_string_ex(key) + +#define DBA_ID_GET + \ + ZEND_FETCH_RESOURCE2(info, dba_info *, id, -1, "DBA identifier", le_db, +le_pdb); + +#define DBA_ID_GET1 DBA_ID_PARS; DBA_GET1; DBA_ID_GET +#define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_ID_GET +#define DBA_ID_GET2_3 DBA_ID_PARS; DBA_GET2_3; DBA_ID_GET + +/* a DBA handler must have specific routines */ + +#define DBA_NAMED_HND(name, x, flags) \ +{\ + #name, flags, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ + dba_exists_##x, dba_delete_##x, dba_firstkey_##x, dba_nextkey_##x, \ + dba_optimize_##x, dba_sync_##x \ +}, + +#define DBA_HND(x, flags) DBA_NAMED_HND(x, x, flags) + +/* check whether the user has write access */ +#define DBA_WRITE_CHECK \ + if(info->mode != DBA_WRITER && info->mode != DBA_TRUNC && info->mode != +DBA_CREAT) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You cannot perform a +modification to a database without proper access"); \ + RETURN_FALSE; \ + } + +/* }}} */ + +/* {{{ globals */ + +static dba_handler handler[] = { +#if DBA_GDBM + DBA_HND(gdbm, DBA_LOCK_EXT) /* Locking done in library if set */ +#endif +#if DBA_DBM + DBA_HND(dbm, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_NDBM + DBA_HND(ndbm, DBA_LOCK_ALL) /* Could be done in library: filemode = 0644 + +S_ENFMT */ +#endif +#if DBA_CDB + DBA_HND(cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_CDB_BUILTIN + DBA_NAMED_HND(cdb_make, cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB2 + DBA_HND(db2, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB3 + DBA_HND(db3, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB4 + DBA_HND(db4, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_FLATFILE + DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ +#endif + { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + +static int le_db; +static int le_pdb; +/* }}} */ + +/* {{{ dba_close + */ +static void dba_close(dba_info *info TSRMLS_DC) +{ + if (info->hnd) info->hnd->close(info TSRMLS_CC); + if (info->path) efree(info->path); + if (info->fp && info->fp!=info->lock.fp) php_stream_close(info->fp); + if (info->lock.fd) { + php_flock(info->lock.fd, LOCK_UN); + close(info->lock.fd); + info->lock.fd = 0; + } + if (info->lock.fp) php_stream_close(info->lock.fp); + if (info->lock.name) efree(info->lock.name); + efree(info); +} +/* }}} */ + +/* {{{ dba_close_rsrc + */ +static void dba_close_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + dba_info *info = (dba_info *)rsrc->ptr; + + dba_close(info TSRMLS_CC); +} +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(dba) +{ + le_db = zend_register_list_destructors_ex(dba_close_rsrc, NULL, "dba", +module_number); + le_pdb = zend_register_list_destructors_ex(NULL, dba_close_rsrc, "dba +persistent", module_number); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(dba) +{ + return SUCCESS; +} +/* }}} */ + +#include "ext/standard/php_smart_str.h" + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(dba) +{ + dba_handler *hptr; + smart_str handlers = {0}; + + for(hptr = handler; hptr->name; hptr++) { + smart_str_appends(&handlers, hptr->name); + smart_str_appendc(&handlers, ' '); + } + + php_info_print_table_start(); + php_info_print_table_row(2, "DBA support", "enabled"); + if (handlers.c) { + smart_str_0(&handlers); + php_info_print_table_row(2, "Supported handlers", handlers.c); + smart_str_free(&handlers); + } else { + php_info_print_table_row(2, "Supported handlers", "none"); + } + php_info_print_table_end(); +} +/* }}} */ + +/* {{{ php_dba_update + */ +static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode) +{ + DBA_ID_PARS; + zval **val, **key; + char *v; + int len; + + if(ac != 3 || zend_get_parameters_ex(ac, &key, &val, &id) != SUCCESS) { + WRONG_PARAM_COUNT; + } + convert_to_string_ex(key); + convert_to_string_ex(val); + DBA_ID_GET; + + DBA_WRITE_CHECK; + + if (PG(magic_quotes_runtime)) { + len = Z_STRLEN_PP(val); + v = estrndup(Z_STRVAL_PP(val), len); + php_stripslashes(v, &len TSRMLS_CC); + if(info->hnd->update(info, VALLEN(key), v, len, mode TSRMLS_CC) == +SUCCESS) { + efree(v); + RETURN_TRUE; + } + efree(v); + } else { + if(info->hnd->update(info, VALLEN(key), VALLEN(val), mode TSRMLS_CC) +== SUCCESS) + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ + +#define FREENOW if(args) efree(args); if(key) efree(key) + +/* {{{ php_find_dbm + */ +dba_info *php_dba_find(const char* path TSRMLS_DC) +{ + list_entry *le; + dba_info *info; + int numitems, i; + + 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); + if (!strcmp(info->path, path)) { + return (dba_info *)(le->ptr); + } + } + } + + return NULL; +} +/* }}} */ + +/* {{{ php_dba_open + */ +static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) +{ + zval ***args = (zval ***) NULL; + int ac = ZEND_NUM_ARGS(); + dba_mode_t modenr; + dba_info *info, *other; + dba_handler *hptr; + char *key = NULL, *error = NULL; + int keylen = 0; + int i; + int lock_mode, lock_flag, lock_dbf = 0; + char *file_mode; + char mode[4], *pmode, *lock_file_mode; + + if(ac < 3) { + WRONG_PARAM_COUNT; + } + + /* we pass additional args to the respective handler */ + args = emalloc(ac * sizeof(zval *)); + 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 = emalloc(keylen); + 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; + } + } + + 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 + * + * 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': + 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); + } + lock_dbf = 1; + /* no break */ + case 'l': + lock_flag = DBA_LOCK_ALL; + break; + default: + case '-': + lock_flag = 0; + break; + } + } else { + lock_flag = (hptr->flags&DBA_LOCK_ALL); + } + 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 'n': + modenr = DBA_TRUNC; + lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0; + file_mode = "w+b"; + break; + case 'c': + modenr = DBA_CREAT; + lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0; + file_mode = "a+b"; + break; + default: + modenr = 0; + lock_mode = 0; + 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)", hptr->name); + 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 || !modenr) { + 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 = emalloc(sizeof(dba_info)); + memset(info, 0, sizeof(dba_info)); + info->path = estrdup(Z_STRVAL_PP(args[0])); + info->mode = modenr; + info->argc = ac - 3; + info->argv = args + 3; + info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL); + 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 = estrdup(info->path); + lock_file_mode = file_mode; + } else { + spprintf(&info->lock.name, 0, "%s.lck", info->path); + lock_file_mode = "a+b"; + } + info->lock.fp = php_stream_open_wrapper(info->lock.name, +lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE, 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, 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", +Z_STRVAL_PP(args[2]), 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) { + FREENOW; + RETURN_FALSE; + } + } + + ZEND_REGISTER_RESOURCE(return_value, info, (persistent ? le_pdb : le_db)); + FREENOW; +} +/* }}} */ +#undef FREENOW + +/* {{{ proto int 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 int 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, int handle) + Checks, if the specified key exists */ +PHP_FUNCTION(dba_exists) +{ + DBA_ID_GET2; + + if(info->hnd->exists(info, VALLEN(key) TSRMLS_CC) == SUCCESS) { + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto string dba_fetch(string key, [int skip ,] int handle) + Fetches the data associated with key */ +PHP_FUNCTION(dba_fetch) +{ + char *val; + int len = 0; + DBA_ID_GET2_3; + + if (ac==3 && strcmp(info->hnd->name, "cdb")) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s does not +support optional skip parameter", info->hnd->name); + } + if((val = info->hnd->fetch(info, VALLEN(key), skip, &len TSRMLS_CC)) != NULL) { + if (val && PG(magic_quotes_runtime)) { + val = php_addslashes(val, len, &len, 1 TSRMLS_CC); + } + RETURN_STRINGL(val, len, 0); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto string dba_firstkey(int 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(int 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, int handle) + Deletes the entry associated with key */ +PHP_FUNCTION(dba_delete) +{ + DBA_ID_GET2; + + DBA_WRITE_CHECK; + + if(info->hnd->delete(info, VALLEN(key) TSRMLS_CC) == SUCCESS) + RETURN_TRUE; + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto bool dba_insert(string key, string value, int handle) + Inserts value as key, returns false, if key exists already */ +PHP_FUNCTION(dba_insert) +{ + php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto bool dba_replace(string key, string value, int handle) + Inserts value as key, replaces key, if key exists already */ +PHP_FUNCTION(dba_replace) +{ + php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto bool dba_optimize(int 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(int 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() + List configured databases */ +PHP_FUNCTION(dba_handlers) +{ + dba_handler *hptr; + + if (ZEND_NUM_ARGS()!=0) { + ZEND_WRONG_PARAM_COUNT(); + RETURN_FALSE; + } + + if (array_init(return_value) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize +array"); + RETURN_FALSE; + } + for(hptr = handler; hptr->name; hptr++) { + add_next_index_string(return_value, hptr->name, 1); + } +} +/* }}} */ + +/* {{{ proto array dba_list() + List configured 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; + } + + if (array_init(return_value) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize +array"); + RETURN_FALSE; + } + 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 + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ +
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php