summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>1999-07-21 15:12:32 +0000
committerSascha Schumann <sas@php.net>1999-07-21 15:12:32 +0000
commitb33d0fd7e7365d3247a769a1f046593fd94673ea (patch)
treecf872545df28aa0bca3719438136360928fab15f
parent3843821d114fc770b1ac36d90bbf049bcc9a28ce (diff)
downloadphp-git-b33d0fd7e7365d3247a769a1f046593fd94673ea.tar.gz
initial import of DBA
-rw-r--r--MODULES_STATUS2
-rw-r--r--ext/dba/Makefile.am7
-rw-r--r--ext/dba/config.h.stub17
-rw-r--r--ext/dba/config.m4210
-rw-r--r--ext/dba/dba.c475
-rw-r--r--ext/dba/dba_cdb.c220
-rw-r--r--ext/dba/dba_db2.c207
-rw-r--r--ext/dba/dba_dbm.c190
-rw-r--r--ext/dba/dba_gdbm.c189
-rw-r--r--ext/dba/dba_ndbm.c169
-rw-r--r--ext/dba/php3_cdb.h12
-rw-r--r--ext/dba/php3_db2.h12
-rw-r--r--ext/dba/php3_dba.h115
-rw-r--r--ext/dba/php3_dbm.h12
-rw-r--r--ext/dba/php3_gdbm.h12
-rw-r--r--ext/dba/php3_ndbm.h12
-rw-r--r--ext/dba/setup.stub6
17 files changed, 1866 insertions, 1 deletions
diff --git a/MODULES_STATUS b/MODULES_STATUS
index 4c4ed405e5..f80ef2ad41 100644
--- a/MODULES_STATUS
+++ b/MODULES_STATUS
@@ -4,7 +4,7 @@ MySQL Working
COM Working
WDDX Working
PCRE Working
-DBA Not yet ported
+DBA Not yet tested
mcrypt Working
mhash Working
dbase Working
diff --git a/ext/dba/Makefile.am b/ext/dba/Makefile.am
new file mode 100644
index 0000000000..b609be3bf3
--- /dev/null
+++ b/ext/dba/Makefile.am
@@ -0,0 +1,7 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_dba.a
+libphpext_dba_a_SOURCES=dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c \
+ dba_ndbm.c
+
diff --git a/ext/dba/config.h.stub b/ext/dba/config.h.stub
new file mode 100644
index 0000000000..f65ae9b7fa
--- /dev/null
+++ b/ext/dba/config.h.stub
@@ -0,0 +1,17 @@
+/* define if you want to use the dba extension */
+
+#define NDBM_DB1_NDBM_H 0
+#define NDBM_NDBM_H 0
+#define DB2_DB2_DB_H 0
+#define DB2_DB_DB2_H 0
+#define DB2_DB_H 0
+#define DB2_DB2_H 0
+#define HAVE_DBA 0
+#define DBA_GDBM 0
+#define DBA_NDBM 0
+#define DBA_DBOPEN 0
+#define DBA_DB2 0
+#define DBA_DBM 0
+#define DBA_CDB 0
+
+
diff --git a/ext/dba/config.m4 b/ext/dba/config.m4
new file mode 100644
index 0000000000..c3e9b60aa0
--- /dev/null
+++ b/ext/dba/config.m4
@@ -0,0 +1,210 @@
+dnl $Id$
+dnl config.m4 for extension dba
+dnl don't forget to call PHP_EXTENSION(dba)
+
+AC_DEFUN(AC_TEMP_LDFLAGS,[
+ old_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$1 $LDFLAGS"
+ $2
+ LDFLAGS="$old_LDFLAGS"
+])
+
+
+dnl Assign INCLUDE/LFLAGS from PREFIX
+AC_DEFUN(AC_DBA_STD_ASSIGN,[
+ if test "$THIS_PREFIX" != "" -a "$THIS_PREFIX" != "/usr"; then
+ THIS_INCLUDE="$THIS_PREFIX/include"
+ THIS_LFLAGS="$THIS_PREFIX/lib"
+ fi
+])
+
+dnl Standard check
+AC_DEFUN(AC_DBA_STD_CHECK,[
+ THIS_RESULT="yes"
+ if test "$THIS_PREFIX" != "/usr"; then
+ if test "$THIS_INCLUDE" = "" ; then
+ AC_MSG_ERROR(cannot find necessary header file(s))
+ elif test "$THIS_LIBS" = "" ; then
+ AC_MSG_ERROR(cannot find necessary library)
+ fi
+ fi
+])
+
+dnl Attach THIS_x to DBA_x
+AC_DEFUN(AC_DBA_STD_ATTACH,[
+ AC_ADD_INCLUDE($THIS_INCLUDE)
+ AC_ADD_LIBRARY_WITH_PATH($THIS_LIBS, $THIS_LFLAGS)
+
+ THIS_INCLUDE=""
+ THIS_LIBS=""
+ THIS_LFLAGS=""
+ THIS_PREFIX=""
+])
+
+dnl Print the result message
+AC_DEFUN(AC_DBA_STD_RESULT,[
+ if test "$THIS_RESULT" = "yes"; then
+ HAVE_DBA=1
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ THIS_RESULT=""
+])
+
+
+
+AC_ARG_WITH(gdbm,
+[ --with-gdbm[=DIR] Include GDBM support],[
+ if test "$withval" != "no"; then
+ for i in /usr/local /usr $withval; do
+ if test -f "$i/include/gdbm.h"; then
+ THIS_PREFIX="$i"
+ fi
+ done
+
+ unset ac_cv_lib_gdbm_gdbm_open
+ AC_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+ AC_CHECK_LIB(gdbm, gdbm_open, [AC_DEFINE(DBA_GDBM, 1) THIS_LIBS="gdbm"])
+ ])
+
+ AC_DBA_STD_ASSIGN
+ AC_DBA_STD_CHECK
+ AC_DBA_STD_ATTACH
+ fi
+])
+AC_MSG_CHECKING(for GDBM support)
+AC_DBA_STD_RESULT
+
+AC_ARG_WITH(ndbm,
+[ --with-ndbm[=DIR] Include NDBM support],[
+ if test "$withval" != "no"; then
+ for i in /usr/local /usr $withval; do
+ if test -f "$i/include/db1/ndbm.h" ; then
+ THIS_PREFIX="$i"
+ NDBM_EXTRA="NDBM_DB1_NDBM_H"
+ elif test -f "$i/include/ndbm.h" ; then
+ THIS_PREFIX="$i"
+ NDBM_EXTRA="NDBM_NDBM_H"
+ fi
+ done
+
+ if test "$NDBM_EXTRA" != ""; then
+ eval "AC_DEFINE($NDBM_EXTRA, 1)"
+ fi
+
+ for LIB in db1 ndbm c; do
+ AC_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+ AC_CHECK_LIB($LIB, dbm_open, [AC_DEFINE(DBA_NDBM,1) THIS_LIBS="$LIB"])
+ ])
+ done
+
+ AC_DBA_STD_ASSIGN
+ AC_DBA_STD_CHECK
+ AC_DBA_STD_ATTACH
+ fi
+])
+AC_MSG_CHECKING(for NDBM support)
+AC_DBA_STD_RESULT
+
+AC_ARG_WITH(db2,
+[ --with-db2[=DIR] Include DB2 support],[
+ if test "$withval" != "no"; then
+ for i in /usr/local /usr /usr/BerkeleyDB $withval; do
+ if test -f "$i/db2/db.h"; then
+ THIS_PREFIX="$i"
+ DB2_EXTRA="db2"
+ elif test -f "$i/include/db2/db.h"; then
+ THIS_PREFIX="$i"
+ DB2_EXTRA="DB2_DB2_DB_H"
+ elif test -f "$i/include/db/db2.h"; then
+ THIS_PREFIX="$i"
+ DB2_EXTRA="DB2_DB_DB2_H"
+ elif test -f "$i/include/db2.h"; then
+ THIS_PREFIX="$i"
+ DB2_EXTRA="DB2_DB2_H"
+ elif test -f "$i/include/db.h" ; then
+ THIS_PREFIX="$i"
+ DB2_EXTRA="DB2_DB_H"
+ fi
+ done
+
+ if test "$DB2_EXTRA" = "db2" ; then
+ DBA_INCLUDE="$DBA_INCLUDE -I$THIS_PREFIX/db2"
+ DB2_EXTRA="DB2_DB_H"
+ fi
+
+ if test "$DB2_EXTRA" != ""; then
+ eval "AC_DEFINE($DB2_EXTRA, 1)"
+ fi
+
+ for LIB in db db2 c; do
+ AC_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+ AC_CHECK_LIB($LIB, db_appinit, [AC_DEFINE(DBA_DB2,1) THIS_LIBS="$LIB"])
+ ])
+ done
+
+ AC_DBA_STD_ASSIGN
+ AC_DBA_STD_CHECK
+ AC_DBA_STD_ATTACH
+ fi
+])
+AC_MSG_CHECKING(for DB2 support)
+AC_DBA_STD_RESULT
+
+AC_ARG_WITH(dbm,
+[ --with-dbm[=DIR] Include DBM support],[
+ if test "$withval" != "no"; then
+ for i in /usr/local /usr $withval; do
+ if test -f "$i/include/dbm.h" ; then
+ THIS_PREFIX="$i"
+ fi
+ done
+
+ for LIB in db1 dbm c; do
+ AC_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+ AC_CHECK_LIB($LIB, dbminit, [AC_DEFINE(DBA_DBM,1) THIS_LIBS="$LIB"])
+ ])
+ done
+
+ AC_DBA_STD_ASSIGN
+ AC_DBA_STD_CHECK
+ AC_DBA_STD_ATTACH
+ fi
+])
+AC_MSG_CHECKING(for DBM support)
+AC_DBA_STD_RESULT
+
+AC_ARG_WITH(cdb,
+[ --with-cdb[=DIR] Include CDB support],[
+ if test "$withval" != "no"; then
+ for i in /usr/local /usr $withval; do
+ if test -f "$i/include/cdb.h" ; then
+ THIS_PREFIX="$i"
+ fi
+ done
+
+ for LIB in cdb c; do
+ AC_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+ AC_CHECK_LIB($LIB, cdb_bread, [AC_DEFINE(DBA_CDB,1) THIS_LIBS="$LIB"])
+ ])
+ done
+
+ AC_DBA_STD_ASSIGN
+ AC_DBA_STD_CHECK
+ AC_DBA_STD_ATTACH
+ fi
+])
+AC_MSG_CHECKING(for CDB support)
+AC_DBA_STD_RESULT
+
+AC_MSG_CHECKING(whether to enable DBA interface)
+if test "$HAVE_DBA" = "1"; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_DBA, 1)
+ PHP_EXTENSION(dba)
+else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(HAVE_DBA, 0)
+fi
+
diff --git a/ext/dba/dba.c b/ext/dba/dba.c
new file mode 100644
index 0000000000..25dc7a56b6
--- /dev/null
+++ b/ext/dba/dba.c
@@ -0,0 +1,475 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if HAVE_DBA
+
+#include "php3_dba.h"
+
+#include "php3_gdbm.h"
+#include "php3_ndbm.h"
+#include "php3_dbm.h"
+#include "php3_cdb.h"
+#include "php3_db2.h"
+
+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)
+ {NULL,NULL,NULL}
+};
+
+static int php3_minit_dba(INIT_FUNC_ARGS);
+static int php3_mshutdown_dba(SHUTDOWN_FUNC_ARGS);
+static void php3_info_dba(ZEND_MODULES_INFO_FUNC_ARGS);
+
+php3_module_entry dba_module_entry = {
+ "DataBase API", dba_functions,
+ php3_minit_dba,
+ php3_mshutdown_dba,
+ NULL, NULL,
+ php3_info_dba,
+ STANDARD_MODULE_PROPERTIES
+};
+
+typedef struct dba_handler {
+ char *name;
+ int (*open)(dba_info *);
+ void (*close)(dba_info *);
+ char* (*fetch)(dba_info *, char *, int, int *);
+ int (*update)(dba_info *, char *, int, char *, int, int);
+ int (*exists)(dba_info *, char *, int);
+ int (*delete)(dba_info *, char *, int);
+ char* (*firstkey)(dba_info *, int *);
+ char* (*nextkey)(dba_info *, int *);
+ int (*optimize)(dba_info *);
+ int (*sync)(dba_info *);
+} dba_handler;
+
+/* {{{ macromania */
+
+#define DBA_ID_PARS pval *id; dba_info *info = NULL; int type, ac = ARG_COUNT(ht)
+
+/* these are used to get the standard arguments */
+
+#define DBA_GET1 \
+ if(ac != 1 || getParameters(ht, ac, &id) != SUCCESS) { \
+ WRONG_PARAM_COUNT; \
+ }
+
+#define DBA_GET2 \
+ pval *key; \
+ if(ac != 2 || getParameters(ht, ac, &key, &id) != SUCCESS) { \
+ WRONG_PARAM_COUNT; \
+ } \
+ convert_to_string(key)
+
+#define DBA_IF_NOT_CORRECT_TYPE(link_id) \
+ info = php3_list_find(link_id, &type); \
+ if(!info || (type != GLOBAL(le_db) && type != GLOBAL(le_pdb)))
+
+#define DBA_ID_GET \
+ convert_to_long(id); \
+ DBA_IF_NOT_CORRECT_TYPE(id->value.lval) { \
+ php3_error(E_WARNING, "Unable to find DBA identifier %d", id->value.lval); \
+ RETURN_FALSE; \
+ }
+
+#define DBA_ID_GET1 DBA_ID_PARS; DBA_GET1; DBA_ID_GET
+#define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_ID_GET
+
+/* a DBA handler must have specific routines */
+
+#define DBA_HND(x) \
+{\
+ #x, 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 \
+},
+
+/* check whether the user has write access */
+#define DBA_WRITE_CHECK \
+ if(info->mode != DBA_WRITER && info->mode != DBA_TRUNC && info->mode != DBA_CREAT) { \
+ php3_error(E_WARNING, "you cannot perform a modification to a database without proper access"); \
+ RETURN_FALSE; \
+ }
+
+#define GLOBAL(a) a
+
+/* }}} */
+
+/* {{{ globals */
+
+static dba_handler handler[] = {
+#if DBA_GDBM
+ DBA_HND(gdbm)
+#endif
+#if DBA_DBM
+ DBA_HND(dbm)
+#endif
+#if DBA_NDBM
+ DBA_HND(ndbm)
+#endif
+#if DBA_CDB
+ DBA_HND(cdb)
+#endif
+#if DBA_DB2
+ DBA_HND(db2)
+#endif
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
+
+static int le_db;
+static int le_pdb;
+static HashTable ht_keys;
+/* }}} */
+
+/* {{{ helper routines */
+ /* {{{ dba_close */
+
+static void dba_close(dba_info *info)
+{
+ if(info->hnd) info->hnd->close(info);
+ if(info->path) free(info->path);
+ free(info);
+}
+/* }}} */
+ /* {{{ php3_minit_dba */
+
+static int php3_minit_dba(INIT_FUNC_ARGS)
+{
+ _php3_hash_init(&ht_keys, 0, NULL, NULL, 1);
+ GLOBAL(le_db) = register_list_destructors(dba_close, NULL);
+ GLOBAL(le_pdb) = register_list_destructors(NULL, dba_close);
+ return SUCCESS;
+}
+/* }}} */
+ /* {{{ php3_mshutdown_dba */
+
+static int php3_mshutdown_dba(SHUTDOWN_FUNC_ARGS)
+{
+ _php3_hash_destroy(&ht_keys);
+ return SUCCESS;
+}
+/* }}} */
+ /* {{{ php3_info_dba */
+
+static void php3_info_dba(ZEND_MODULE_INFO_FUNC_ARGS)
+{
+ dba_handler *hptr;
+
+ PUTS("V1 ($Id$)");
+ for(hptr = handler; hptr->name; hptr++) {
+ PUTS(" ");
+ PUTS(hptr->name);
+ }
+}
+/* }}} */
+ /* {{{ _php3_dba_update */
+
+static void _php3_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
+{
+ DBA_ID_PARS;
+ pval *val, *key;
+
+ if(ac != 3 || getParameters(ht, ac, &key, &val, &id) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(key);
+ convert_to_string(val);
+ DBA_ID_GET;
+
+ DBA_WRITE_CHECK;
+
+ if(info->hnd->update(info, VALLEN(key), VALLEN(val), mode) == SUCCESS)
+ RETURN_TRUE;
+ RETURN_FALSE;
+}
+/* }}} */
+ /* {{{ _php3_dba_open */
+
+#define FREENOW if(args) efree(args); if(key) efree(key)
+
+static void _php3_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+{
+ pval **args = (pval **) NULL;
+ int ac = ARG_COUNT(ht);
+ dba_mode_t modenr;
+ dba_info *info;
+ dba_handler *hptr;
+ char *key = NULL;
+ int keylen = 0;
+ int listid;
+ int i;
+
+ if(ac < 3) {
+ WRONG_PARAM_COUNT;
+ }
+
+ /* we pass additional args to the respective handler */
+ args = emalloc(ac * sizeof(pval *));
+ if(getParametersArray(ht, ac, args) != SUCCESS) {
+ FREENOW;
+ WRONG_PARAM_COUNT;
+ }
+
+ /* we only take string arguments */
+ for(i = 0; i < ac; i++) {
+ convert_to_string(args[i]);
+ keylen += args[i]->value.str.len;
+ }
+
+ if(persistent) {
+ /* calculate hash */
+ key = emalloc(keylen);
+ keylen = 0;
+
+ for(i = 0; i < ac; i++) {
+ memcpy(key+keylen,args[i]->value.str.val,args[i]->value.str.len);
+ keylen += args[i]->value.str.len;
+ }
+
+ if(_php3_hash_find(&ht_keys, key, keylen, (void **) &info) == SUCCESS) {
+ FREENOW;
+ RETURN_LONG(php3_list_insert(info, GLOBAL(le_pdb)));
+ }
+ }
+
+ /* this is O(n) and could be improved */
+ for(hptr = handler; hptr->name &&
+ strcasecmp(hptr->name, args[2]->value.str.val); hptr++);
+
+ if(!hptr->name) {
+ php3_error(E_WARNING, "no such handler: %s", args[2]->value.str.val);
+ FREENOW;
+ RETURN_FALSE;
+ }
+
+ switch(args[1]->value.str.val[0]) {
+ case 'c':
+ modenr = DBA_CREAT;
+ break;
+ case 'w':
+ modenr = DBA_WRITER;
+ break;
+ case 'r':
+ modenr = DBA_READER;
+ break;
+ case 'n':
+ modenr = DBA_TRUNC;
+ break;
+ default:
+ php3_error(E_WARNING,"illegal DBA mode: %s",args[1]->value.str.val);
+ FREENOW;
+ RETURN_FALSE;
+ }
+
+ info = malloc(sizeof(*info));
+ memset(info, 0, sizeof(info));
+ info->path = strdup(args[0]->value.str.val);
+ info->mode = modenr;
+ info->argc = ac - 3;
+ info->argv = args + 3;
+
+ if(hptr->open(info) != SUCCESS) {
+ dba_close(info);
+ php3_error(E_WARNING, "driver initialization failed");
+ FREENOW;
+ RETURN_FALSE;
+ }
+ info->hnd = hptr;
+ info->argc = 0;
+ info->argv = NULL;
+
+ listid = php3_list_insert(info, persistent?GLOBAL(le_pdb):GLOBAL(le_db));
+ if(persistent) {
+ _php3_hash_update(&ht_keys, key, keylen, info, sizeof(*info), NULL);
+ }
+
+ FREENOW;
+ RETURN_LONG(listid);
+}
+#undef FREENOW
+/* }}} */
+/* }}} */
+
+/* {{{ proto int dba_popen(string path, string mode, string handlername[, ...])
+ opens path using the specified handler in mode persistently */
+PHP_FUNCTION(dba_popen)
+{
+ _php3_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto int dba_open(string path, string mode, string handlername[, ...])
+ opens path using the specified handler in mode*/
+PHP_FUNCTION(dba_open)
+{
+ _php3_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto void dba_close(int handle)
+ closes database */
+PHP_FUNCTION(dba_close)
+{
+ DBA_ID_GET1;
+
+ php3_list_delete(id->value.lval);
+}
+/* }}} */
+
+/* {{{ 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)) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string dba_fetch(string key, int handle)
+ fetches the data associated with key */
+PHP_FUNCTION(dba_fetch)
+{
+ char *val;
+ int len = 0;
+ DBA_ID_GET2;
+
+ if((val = info->hnd->fetch(info, VALLEN(key), &len)) != NULL) {
+ 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);
+ 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);
+ 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)) == 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)
+{
+ _php3_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)
+{
+ _php3_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) == 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) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+#endif
diff --git a/ext/dba/dba_cdb.c b/ext/dba/dba_cdb.c
new file mode 100644
index 0000000000..55683590c5
--- /dev/null
+++ b/ext/dba/dba_cdb.c
@@ -0,0 +1,220 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if DBA_CDB
+#include "php3_cdb.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <cdb.h>
+#include <cdbmake.h>
+
+#define CDB_INFO \
+ dba_cdb *cdb = (dba_cdb *) info->dbf
+
+typedef struct {
+ int fd;
+ uint32 eod; /* size of constant database */
+ uint32 pos; /* current position for traversing */
+} dba_cdb;
+
+DBA_OPEN_FUNC(cdb)
+{
+ int gmode = 0;
+ dba_cdb *cdb;
+ dba_info *pinfo = (dba_info *) info;
+
+ switch(info->mode) {
+ case DBA_READER:
+ gmode = O_RDONLY; break;
+ /* currently not supported: */
+#if 0
+ case DBA_WRITER:
+ gmode = O_RDWR; break;
+#endif
+ default:
+ return FAILURE;
+ }
+
+ cdb = malloc(sizeof *cdb);
+ memset(cdb, 0, sizeof *cdb);
+
+ cdb->fd = open(info->path, gmode);
+ if(cdb->fd < 0) {
+ free(cdb);
+ return FAILURE;
+ }
+
+ pinfo->dbf = cdb;
+ return SUCCESS;
+}
+
+DBA_CLOSE_FUNC(cdb)
+{
+ CDB_INFO;
+
+ close(cdb->fd);
+ free(cdb);
+}
+
+DBA_FETCH_FUNC(cdb)
+{
+ CDB_INFO;
+ int len;
+ char *new = NULL;
+
+ if(cdb_seek(cdb->fd, key, keylen, &len) == 1) {
+ new = emalloc(len);
+ read(cdb->fd, new, len);
+ if(newlen) *newlen = len;
+ }
+
+ return new;
+}
+
+DBA_UPDATE_FUNC(cdb)
+{
+ /* if anyone figures out cdbmake.c, let me know */
+ return FAILURE;
+}
+
+DBA_EXISTS_FUNC(cdb)
+{
+ CDB_INFO;
+ int len;
+
+ if(cdb_seek(cdb->fd, key, keylen, &len) == 1)
+ return SUCCESS;
+ return FAILURE;
+}
+
+DBA_DELETE_FUNC(cdb)
+{
+ return FAILURE;
+}
+
+
+#define CREAD(n) if(read(cdb->fd, buf, n) < n) return NULL
+#define CSEEK(n) \
+ if(n >= cdb->eod) return NULL; \
+ if(lseek(cdb->fd, (off_t)n, SEEK_SET) != (off_t) n) return NULL
+
+DBA_FIRSTKEY_FUNC(cdb)
+{
+ CDB_INFO;
+ uint32 len;
+ char buf[8];
+ char *key;
+
+ cdb->eod = -1;
+ CSEEK(0);
+ CREAD(4);
+ cdb->eod = cdb_unpack(buf);
+
+ CSEEK(2048);
+ CREAD(8);
+ len = cdb_unpack(buf);
+
+ key = emalloc(len + 1);
+ if(read(cdb->fd, key, len) < len) {
+ efree(key);
+ key = NULL;
+ } else
+ key[len] = '\0';
+ /* header + klenlen + dlenlen + klen + dlen */
+ cdb->pos = 2048 + 4 + 4 + len + cdb_unpack(buf + 4);
+
+ return key;
+}
+
+DBA_NEXTKEY_FUNC(cdb)
+{
+ CDB_INFO;
+ uint32 len;
+ char buf[8];
+ char *nkey;
+
+ CSEEK(cdb->pos);
+ CREAD(8);
+ len = cdb_unpack(buf);
+
+ nkey = emalloc(len + 1);
+ if(read(cdb->fd, nkey, len) < len) {
+ efree(nkey);
+ return NULL;
+ }
+ nkey[len] = '\0';
+ if(newlen) *newlen = len;
+
+ cdb->pos += 8 + len + cdb_unpack(buf + 4);
+
+ return nkey;
+#if 0
+ /* this code cdb_seeks and is thus slower than directly seeking
+ in the file */
+ CDB_INFO;
+ char *nkey = NULL;
+ uint32 len;
+ char buf[8];
+
+ if(cdb_seek(cdb->fd, key, keylen, &len) == 1) {
+ if(lseek(cdb->fd, (off_t) len, SEEK_CUR) >= (off_t) cdb->eod)
+ return NULL;
+ CREAD(8);
+ len = cdb_unpack(buf);
+
+ nkey = emalloc(len + 1);
+ if(read(cdb->fd, nkey, len) < len) {
+ efree(nkey);
+ nkey = NULL;
+ } else
+ nkey[len] = '\0';
+ }
+ return nkey;
+#endif
+}
+
+DBA_OPTIMIZE_FUNC(cdb)
+{
+ return SUCCESS;
+}
+
+DBA_SYNC_FUNC(cdb)
+{
+ /* this is read-only */
+ return SUCCESS;
+}
+
+#endif
diff --git a/ext/dba/dba_db2.c b/ext/dba/dba_db2.c
new file mode 100644
index 0000000000..c522ef7c2d
--- /dev/null
+++ b/ext/dba/dba_db2.c
@@ -0,0 +1,207 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if DBA_DB2
+#include "php3_db2.h"
+#include <sys/stat.h>
+
+#include <string.h>
+#if DB2_DB2_DB_H
+#include <db2/db.h>
+#elif DB2_DB_DB2_H
+#include <db/db2.h>
+#elif DB2_DB2_H
+#include <db2.h>
+#elif DB2_DB_H
+#include <db.h>
+#endif
+
+#define DB2_DATA dba_db2_data *dba = info->dbf
+#define DB2_GKEY \
+ DBT gkey; \
+ memset(&gkey, 0, sizeof(gkey)); \
+ gkey.data = (char *) key; gkey.size = keylen
+
+typedef struct {
+ DB *dbp;
+ DBC *cursor;
+} dba_db2_data;
+
+DBA_OPEN_FUNC(db2)
+{
+ DB *dbp;
+ DBTYPE type;
+ int gmode = 0;
+ int filemode = 0644;
+ struct stat check_stat;
+
+ type = info->mode == DBA_READER ? DB_UNKNOWN :
+ info->mode == DBA_TRUNC ? DB_BTREE :
+ stat(info->path, &check_stat) ? DB_BTREE : DB_UNKNOWN;
+
+ gmode = info->mode == DBA_READER ? DB_RDONLY :
+ info->mode == DBA_CREAT ? DB_CREATE :
+ info->mode == DBA_WRITER ? 0 :
+ info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
+
+ if(gmode == -1)
+ return FAILURE;
+
+ if(info->argc > 0) {
+ convert_to_long(info->argv[0]);
+ filemode = info->argv[0]->value.lval;
+ }
+
+ if(!db_open(info->path, type, gmode, filemode, NULL, NULL, &dbp)) {
+ info->dbf = malloc(sizeof(dba_db2_data));
+ memset(info->dbf, 0, sizeof(dba_db2_data));
+ ((dba_db2_data *) info->dbf)->dbp = dbp;
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_CLOSE_FUNC(db2)
+{
+ DB2_DATA;
+
+ if(dba->cursor) dba->cursor->c_close(dba->cursor);
+ dba->dbp->close(dba->dbp, DB_NOSYNC);
+ free(dba);
+}
+
+DBA_FETCH_FUNC(db2)
+{
+ DBT gval;
+ char *new = NULL;
+ DB2_DATA;
+ DB2_GKEY;
+
+ memset(&gval, 0, sizeof(gval));
+ if(!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
+ if(newlen) *newlen = gval.size;
+ new = estrndup(gval.data, gval.size);
+ }
+ return new;
+}
+
+DBA_UPDATE_FUNC(db2)
+{
+ DBT gval;
+ DB2_DATA;
+ DB2_GKEY;
+
+ memset(&gval, 0, sizeof(gval));
+ gval.data = (char *) val;
+ gval.size = vallen;
+
+ if(!dba->dbp->put(dba->dbp, NULL, &gkey, &gval,
+ mode == 1 ? DB_NOOVERWRITE : 0)) {
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_EXISTS_FUNC(db2)
+{
+ DBT gval;
+ DB2_DATA;
+ DB2_GKEY;
+
+ memset(&gval, 0, sizeof(gval));
+ if(!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_DELETE_FUNC(db2)
+{
+ DB2_DATA;
+ DB2_GKEY;
+
+ return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
+}
+
+DBA_FIRSTKEY_FUNC(db2)
+{
+ DB2_DATA;
+
+ if(dba->cursor) {
+ dba->cursor->c_close(dba->cursor);
+ }
+
+ dba->cursor = NULL;
+#if (DB_VERSION_MAJOR > 2) || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR > 6) || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 6 && DB_VERSION_PATCH >= 4)
+ if(dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0)) {
+#else
+ if(dba->dbp->cursor(dba->dbp, NULL, &dba->cursor)) {
+#endif
+ return NULL;
+ }
+
+ /* we should introduce something like PARAM_PASSTHRU... */
+ return dba_nextkey_db2(info, newlen);
+}
+
+DBA_NEXTKEY_FUNC(db2)
+{
+ DB2_DATA;
+ DBT gkey, gval;
+ char *nkey = NULL;
+
+ memset(&gkey, 0, sizeof(gkey));
+ memset(&gval, 0, sizeof(gval));
+
+ if(!dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT)) {
+ if(gkey.data) {
+ nkey = estrndup(gkey.data, gkey.size);
+ if(newlen) *newlen = gkey.size;
+ }
+ }
+ return nkey;
+}
+
+DBA_OPTIMIZE_FUNC(db2)
+{
+ return SUCCESS;
+}
+
+DBA_SYNC_FUNC(db2)
+{
+ DB2_DATA;
+
+ return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
+}
+
+#endif
diff --git a/ext/dba/dba_dbm.c b/ext/dba/dba_dbm.c
new file mode 100644
index 0000000000..5858e8e610
--- /dev/null
+++ b/ext/dba/dba_dbm.c
@@ -0,0 +1,190 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if DBA_DBM
+#include "php3_dbm.h"
+
+#include <dbm.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define DBM_DATA dba_dbm_data *dba = info->dbf
+#define DBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
+
+#ifndef PATH_MAX
+#define PATH_MAX 255
+#endif
+
+#define TRUNC_IT(extension, mode) \
+ snprintf(buf, PATH_MAX, "%s" extension, info->path); \
+ buf[PATH_MAX] = '\0'; \
+ if((fd = open(buf, O_CREAT | mode | O_WRONLY, filemode)) == -1) \
+ return FAILURE; \
+ close(fd);
+
+
+typedef struct {
+ datum nextkey;
+} dba_dbm_data;
+
+DBA_OPEN_FUNC(dbm)
+{
+ int fd;
+ int filemode = 0644;
+
+ if(info->argc > 0) {
+ convert_to_long(info->argv[0]);
+ filemode = info->argv[0]->value.lval;
+ }
+
+ if(info->mode == DBA_TRUNC) {
+ char buf[PATH_MAX + 1];
+
+ /* dbm/ndbm original */
+ TRUNC_IT(".pag", O_TRUNC);
+ TRUNC_IT(".dir", O_TRUNC);
+ }
+
+ if(info->mode == DBA_CREAT) {
+ char buf[PATH_MAX + 1];
+
+ TRUNC_IT(".pag", 0);
+ TRUNC_IT(".dir", 0);
+ }
+
+ if(dbminit((char *) info->path) == -1) {
+ return FAILURE;
+ }
+
+ info->dbf = calloc(sizeof(dba_dbm_data), 1);
+ return SUCCESS;
+}
+
+DBA_CLOSE_FUNC(dbm)
+{
+ free(info->dbf);
+ dbmclose();
+}
+
+DBA_FETCH_FUNC(dbm)
+{
+ datum gval;
+ char *new = NULL;
+
+ DBM_GKEY;
+ gval = fetch(gkey);
+ if(gval.dptr) {
+ if(newlen) *newlen = gval.dsize;
+ new = estrndup(gval.dptr, gval.dsize);
+ }
+ return new;
+}
+
+DBA_UPDATE_FUNC(dbm)
+{
+ datum gval;
+
+ DBM_GKEY;
+ gval.dptr = (char *) val;
+ gval.dsize = vallen;
+
+ return (store(gkey, gval) == -1 ? FAILURE : SUCCESS);
+}
+
+DBA_EXISTS_FUNC(dbm)
+{
+ datum gval;
+ DBM_GKEY;
+
+ gval = fetch(gkey);
+ if(gval.dptr) {
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_DELETE_FUNC(dbm)
+{
+ DBM_GKEY;
+ return(delete(gkey) == -1 ? FAILURE : SUCCESS);
+}
+
+DBA_FIRSTKEY_FUNC(dbm)
+{
+ DBM_DATA;
+ datum gkey;
+ char *key = NULL;
+
+ gkey = firstkey();
+ if(gkey.dptr) {
+ if(newlen) *newlen = gkey.dsize;
+ key = estrndup(gkey.dptr, gkey.dsize);
+ dba->nextkey = gkey;
+ } else
+ dba->nextkey.dptr = NULL;
+ return key;
+}
+
+DBA_NEXTKEY_FUNC(dbm)
+{
+ DBM_DATA;
+ datum gkey;
+ char *nkey = NULL;
+
+ if(!dba->nextkey.dptr) return NULL;
+
+ gkey = nextkey(dba->nextkey);
+ if(gkey.dptr) {
+ if(newlen) *newlen = gkey.dsize;
+ nkey = estrndup(gkey.dptr, gkey.dsize);
+ dba->nextkey = gkey;
+ } else
+ dba->nextkey.dptr = NULL;
+ return nkey;
+}
+
+DBA_OPTIMIZE_FUNC(dbm)
+{
+ /* dummy */
+ return SUCCESS;
+}
+
+DBA_SYNC_FUNC(dbm)
+{
+ return SUCCESS;
+}
+
+#endif
diff --git a/ext/dba/dba_gdbm.c b/ext/dba/dba_gdbm.c
new file mode 100644
index 0000000000..0e5f1450f2
--- /dev/null
+++ b/ext/dba/dba_gdbm.c
@@ -0,0 +1,189 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if DBA_GDBM
+#include "php3_gdbm.h"
+
+#include <gdbm.h>
+
+#define GDBM_DATA dba_gdbm_data *dba = info->dbf
+#define GDBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
+
+typedef struct {
+ GDBM_FILE dbf;
+ datum nextkey;
+} dba_gdbm_data;
+
+DBA_OPEN_FUNC(gdbm)
+{
+ GDBM_FILE dbf;
+ int gmode = 0;
+ int filemode = 0644;
+
+ gmode = info->mode == DBA_READER ? GDBM_READER :
+ info->mode == DBA_WRITER ? GDBM_WRITER :
+ info->mode == DBA_CREAT ? GDBM_WRCREAT :
+ info->mode == DBA_TRUNC ? GDBM_NEWDB : -1;
+
+ if(gmode == -1)
+ return FAILURE;
+
+ if(info->argc > 0) {
+ convert_to_long(info->argv[0]);
+ filemode = info->argv[0]->value.lval;
+ }
+
+ dbf = gdbm_open(info->path, 0, gmode, filemode, NULL);
+
+ if(dbf) {
+ info->dbf = malloc(sizeof(dba_gdbm_data));
+ memset(info->dbf, 0, sizeof(dba_gdbm_data));
+ ((dba_gdbm_data *) info->dbf)->dbf = dbf;
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_CLOSE_FUNC(gdbm)
+{
+ GDBM_DATA;
+
+ if(dba->nextkey.dptr) free(dba->nextkey.dptr);
+ gdbm_close(dba->dbf);
+ free(dba);
+}
+
+DBA_FETCH_FUNC(gdbm)
+{
+ GDBM_DATA;
+ datum gval;
+ char *new = NULL;
+
+ GDBM_GKEY;
+ gval = gdbm_fetch(dba->dbf, gkey);
+ if(gval.dptr) {
+ if(newlen) *newlen = gval.dsize;
+ new = estrndup(gval.dptr, gval.dsize);
+ free(gval.dptr);
+ }
+ return new;
+}
+
+DBA_UPDATE_FUNC(gdbm)
+{
+ datum gval;
+ GDBM_DATA;
+
+ GDBM_GKEY;
+ gval.dptr = (char *) val;
+ gval.dsize = vallen;
+
+ if(gdbm_store(dba->dbf, gkey, gval,
+ mode == 1 ? GDBM_INSERT : GDBM_REPLACE) == 0)
+ return SUCCESS;
+ printf("XXX %s\n", gdbm_strerror(gdbm_errno));
+ return FAILURE;
+}
+
+DBA_EXISTS_FUNC(gdbm)
+{
+ GDBM_DATA;
+ GDBM_GKEY;
+
+ return gdbm_exists(dba->dbf, gkey) ? SUCCESS : FAILURE;
+}
+
+DBA_DELETE_FUNC(gdbm)
+{
+ GDBM_DATA;
+ GDBM_GKEY;
+
+ return gdbm_delete(dba->dbf, gkey) == -1 ? FAILURE : SUCCESS;
+}
+
+DBA_FIRSTKEY_FUNC(gdbm)
+{
+ GDBM_DATA;
+ datum gkey;
+ char *key = NULL;
+
+ if(dba->nextkey.dptr) {
+ free(dba->nextkey.dptr);
+ }
+
+ gkey = gdbm_firstkey(dba->dbf);
+ if(gkey.dptr) {
+ key = estrndup(gkey.dptr, gkey.dsize);
+ if(newlen) *newlen = gkey.dsize;
+ dba->nextkey = gkey;
+ } else {
+ dba->nextkey.dptr = NULL;
+ }
+ return key;
+}
+
+DBA_NEXTKEY_FUNC(gdbm)
+{
+ GDBM_DATA;
+ char *nkey = NULL;
+ datum gkey;
+
+ if(!dba->nextkey.dptr) return NULL;
+
+ gkey = gdbm_nextkey(dba->dbf, dba->nextkey);
+ free(dba->nextkey.dptr);
+ if(gkey.dptr) {
+ nkey = estrndup(gkey.dptr, gkey.dsize);
+ if(newlen) *newlen = gkey.dsize;
+ dba->nextkey = gkey;
+ } else {
+ dba->nextkey.dptr = NULL;
+ }
+ return nkey;
+}
+
+DBA_OPTIMIZE_FUNC(gdbm)
+{
+ GDBM_DATA;
+ gdbm_reorganize(dba->dbf);
+ return SUCCESS;
+}
+
+DBA_SYNC_FUNC(gdbm)
+{
+ GDBM_DATA;
+
+ gdbm_sync(dba->dbf);
+ return SUCCESS;
+}
+#endif
diff --git a/ext/dba/dba_ndbm.c b/ext/dba/dba_ndbm.c
new file mode 100644
index 0000000000..0c6e2cd077
--- /dev/null
+++ b/ext/dba/dba_ndbm.c
@@ -0,0 +1,169 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if DBA_NDBM
+#include "php3_ndbm.h"
+
+#include <fcntl.h>
+
+#if NDBM_DB1_NDBM_H
+#include <db1/ndbm.h>
+#elif NDBM_NDBM_H
+#include <ndbm.h>
+#endif
+
+#define NDBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
+
+DBA_OPEN_FUNC(ndbm)
+{
+ DBM *dbf;
+ int gmode = 0;
+ int filemode = 0644;
+ dba_info *pinfo = (dba_info *) info;
+
+ switch(info->mode) {
+ case DBA_READER:
+ gmode = O_RDONLY;
+ break;
+ case DBA_WRITER:
+ gmode = O_RDWR;
+ break;
+ case DBA_CREAT:
+ gmode = O_RDWR | O_CREAT;
+ break;
+ case DBA_TRUNC:
+ gmode = O_RDWR | O_CREAT | O_TRUNC;
+ break;
+ default:
+ return FAILURE;
+ }
+
+ if(info->argc > 0) {
+ convert_to_long(info->argv[0]);
+ filemode = info->argv[0]->value.lval;
+ }
+
+ dbf = dbm_open(info->path, gmode, filemode);
+
+ if(dbf) {
+ pinfo->dbf = dbf;
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_CLOSE_FUNC(ndbm)
+{
+ dbm_close(info->dbf);
+}
+
+DBA_FETCH_FUNC(ndbm)
+{
+ datum gval;
+ char *new = NULL;
+
+ NDBM_GKEY;
+ gval = dbm_fetch(info->dbf, gkey);
+ if(gval.dptr) {
+ if(newlen) *newlen = gval.dsize;
+ new = estrndup(gval.dptr, gval.dsize);
+ }
+ return new;
+}
+
+DBA_UPDATE_FUNC(ndbm)
+{
+ datum gval;
+
+ NDBM_GKEY;
+ gval.dptr = (char *) val;
+ gval.dsize = vallen;
+
+ if(!dbm_store(info->dbf, gkey, gval, mode == 1 ? DBM_INSERT : DBM_REPLACE))
+ return SUCCESS;
+ return FAILURE;
+}
+
+DBA_EXISTS_FUNC(ndbm)
+{
+ datum gval;
+ NDBM_GKEY;
+ gval = dbm_fetch(info->dbf, gkey);
+ if(gval.dptr) {
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+DBA_DELETE_FUNC(ndbm)
+{
+ NDBM_GKEY;
+ return(dbm_delete(info->dbf, gkey) == -1 ? FAILURE : SUCCESS);
+}
+
+DBA_FIRSTKEY_FUNC(ndbm)
+{
+ datum gkey;
+ char *key = NULL;
+
+ gkey = dbm_firstkey(info->dbf);
+ if(gkey.dptr) {
+ if(newlen) *newlen = gkey.dsize;
+ key = estrndup(gkey.dptr, gkey.dsize);
+ }
+ return key;
+}
+
+DBA_NEXTKEY_FUNC(ndbm)
+{
+ datum gkey;
+ char *nkey = NULL;
+
+ gkey = dbm_nextkey(info->dbf);
+ if(gkey.dptr) {
+ if(newlen) *newlen = gkey.dsize;
+ nkey = estrndup(gkey.dptr, gkey.dsize);
+ }
+ return nkey;
+}
+
+DBA_OPTIMIZE_FUNC(ndbm)
+{
+ return SUCCESS;
+}
+
+DBA_SYNC_FUNC(ndbm)
+{
+ return SUCCESS;
+}
+#endif
diff --git a/ext/dba/php3_cdb.h b/ext/dba/php3_cdb.h
new file mode 100644
index 0000000000..162fa8bdb2
--- /dev/null
+++ b/ext/dba/php3_cdb.h
@@ -0,0 +1,12 @@
+#ifndef _PHP3_CDB_H
+#define _PHP3_CDB_H
+
+#if DBA_CDB
+
+#include "php3_dba.h"
+
+DBA_FUNCS(cdb);
+
+#endif
+
+#endif
diff --git a/ext/dba/php3_db2.h b/ext/dba/php3_db2.h
new file mode 100644
index 0000000000..0f8c458db9
--- /dev/null
+++ b/ext/dba/php3_db2.h
@@ -0,0 +1,12 @@
+#ifndef _PHP3_DB2_H
+#define _PHP3_DB2_H
+
+#if DBA_DB2
+
+#include "php3_dba.h"
+
+DBA_FUNCS(db2);
+
+#endif
+
+#endif
diff --git a/ext/dba/php3_dba.h b/ext/dba/php3_dba.h
new file mode 100644
index 0000000000..caa7bfed05
--- /dev/null
+++ b/ext/dba/php3_dba.h
@@ -0,0 +1,115 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-1999 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Sascha Schumann <sas@schell.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef _DBA_H
+#define _DBA_H
+
+#if HAVE_DBA
+
+typedef enum {
+ DBA_READER = 1,
+ DBA_WRITER,
+ DBA_TRUNC,
+ DBA_CREAT
+} dba_mode_t;
+
+typedef struct dba_info {
+ /* public */
+ void *dbf; /* ptr to private data or whatever */
+ char *path;
+ dba_mode_t mode;
+ /* arg[cv] are only available when the dba_open handler is called! */
+ int argc;
+ pval **argv;
+ /* private */
+ struct dba_handler *hnd;
+} dba_info;
+
+extern php3_module_entry dba_module_entry;
+#define dba_module_ptr &dba_module_entry
+
+/* common prototypes which must be supplied by modules */
+
+#define DBA_OPEN_FUNC(x) \
+ int dba_open_##x(dba_info *info)
+#define DBA_CLOSE_FUNC(x) \
+ void dba_close_##x(dba_info *info)
+#define DBA_FETCH_FUNC(x) \
+ char *dba_fetch_##x(dba_info *info, char *key, int keylen, int *newlen)
+#define DBA_UPDATE_FUNC(x) \
+ int dba_update_##x(dba_info *info, char *key, int keylen, char *val, int vallen, int mode)
+#define DBA_EXISTS_FUNC(x) \
+ int dba_exists_##x(dba_info *info, char *key, int keylen)
+#define DBA_DELETE_FUNC(x) \
+ int dba_delete_##x(dba_info *info, char *key, int keylen)
+#define DBA_FIRSTKEY_FUNC(x) \
+ char *dba_firstkey_##x(dba_info *info, int *newlen)
+#define DBA_NEXTKEY_FUNC(x) \
+ char *dba_nextkey_##x(dba_info *info, int *newlen)
+#define DBA_OPTIMIZE_FUNC(x) \
+ int dba_optimize_##x(dba_info *info)
+#define DBA_SYNC_FUNC(x) \
+ int dba_sync_##x(dba_info *info)
+
+#define DBA_FUNCS(x) \
+ DBA_OPEN_FUNC(x); \
+ DBA_CLOSE_FUNC(x); \
+ DBA_FETCH_FUNC(x); \
+ DBA_UPDATE_FUNC(x); \
+ DBA_DELETE_FUNC(x); \
+ DBA_EXISTS_FUNC(x); \
+ DBA_FIRSTKEY_FUNC(x); \
+ DBA_NEXTKEY_FUNC(x); \
+ DBA_OPTIMIZE_FUNC(x); \
+ DBA_SYNC_FUNC(x)
+
+#define VALLEN(p) (p)->value.str.val, (p)->value.str.len
+
+PHP_FUNCTION(dba_open);
+PHP_FUNCTION(dba_popen);
+PHP_FUNCTION(dba_close);
+PHP_FUNCTION(dba_firstkey);
+PHP_FUNCTION(dba_nextkey);
+PHP_FUNCTION(dba_replace);
+PHP_FUNCTION(dba_insert);
+PHP_FUNCTION(dba_delete);
+PHP_FUNCTION(dba_exists);
+PHP_FUNCTION(dba_fetch);
+PHP_FUNCTION(dba_optimize);
+PHP_FUNCTION(dba_sync);
+
+#else
+#define dba_module_ptr NULL
+#endif
+
+#define phpext_dba_ptr dba_module_ptr
+
+#endif
diff --git a/ext/dba/php3_dbm.h b/ext/dba/php3_dbm.h
new file mode 100644
index 0000000000..5007c84b3e
--- /dev/null
+++ b/ext/dba/php3_dbm.h
@@ -0,0 +1,12 @@
+#ifndef _PHP3_DBM_H
+#define _PHP3_DBM_H
+
+#if DBA_DBM
+
+#include "php3_dba.h"
+
+DBA_FUNCS(dbm);
+
+#endif
+
+#endif
diff --git a/ext/dba/php3_gdbm.h b/ext/dba/php3_gdbm.h
new file mode 100644
index 0000000000..9a18b531d4
--- /dev/null
+++ b/ext/dba/php3_gdbm.h
@@ -0,0 +1,12 @@
+#ifndef _PHP3_GDBM_H
+#define _PHP3_GDBM_H
+
+#if DBA_GDBM
+
+#include "php3_dba.h"
+
+DBA_FUNCS(gdbm);
+
+#endif
+
+#endif
diff --git a/ext/dba/php3_ndbm.h b/ext/dba/php3_ndbm.h
new file mode 100644
index 0000000000..398b8e39a1
--- /dev/null
+++ b/ext/dba/php3_ndbm.h
@@ -0,0 +1,12 @@
+#ifndef _PHP3_NDBM_H
+#define _PHP3_NDBM_H
+
+#if DBA_NDBM
+
+#include "php3_dba.h"
+
+DBA_FUNCS(ndbm);
+
+#endif
+
+#endif
diff --git a/ext/dba/setup.stub b/ext/dba/setup.stub
new file mode 100644
index 0000000000..0df17de7d1
--- /dev/null
+++ b/ext/dba/setup.stub
@@ -0,0 +1,6 @@
+# $Source$
+# $Id$
+
+define_option with-dba 'dba support?' yesnodir no \
+' Whether to build the dba extension.'
+