]> granicus.if.org Git - php/commitdiff
initial import of DBA
authorSascha Schumann <sas@php.net>
Wed, 21 Jul 1999 15:12:32 +0000 (15:12 +0000)
committerSascha Schumann <sas@php.net>
Wed, 21 Jul 1999 15:12:32 +0000 (15:12 +0000)
17 files changed:
MODULES_STATUS
ext/dba/Makefile.am [new file with mode: 0644]
ext/dba/config.h.stub [new file with mode: 0644]
ext/dba/config.m4 [new file with mode: 0644]
ext/dba/dba.c [new file with mode: 0644]
ext/dba/dba_cdb.c [new file with mode: 0644]
ext/dba/dba_db2.c [new file with mode: 0644]
ext/dba/dba_dbm.c [new file with mode: 0644]
ext/dba/dba_gdbm.c [new file with mode: 0644]
ext/dba/dba_ndbm.c [new file with mode: 0644]
ext/dba/php3_cdb.h [new file with mode: 0644]
ext/dba/php3_db2.h [new file with mode: 0644]
ext/dba/php3_dba.h [new file with mode: 0644]
ext/dba/php3_dbm.h [new file with mode: 0644]
ext/dba/php3_gdbm.h [new file with mode: 0644]
ext/dba/php3_ndbm.h [new file with mode: 0644]
ext/dba/setup.stub [new file with mode: 0644]

index 4c4ed405e586f49278644f9d62bbd7446569b305..f80ef2ad411c0a3382c817c419b01989d3c10280 100644 (file)
@@ -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 (file)
index 0000000..b609be3
--- /dev/null
@@ -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 (file)
index 0000000..f65ae9b
--- /dev/null
@@ -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 (file)
index 0000000..c3e9b60
--- /dev/null
@@ -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 (file)
index 0000000..25dc7a5
--- /dev/null
@@ -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 (file)
index 0000000..5568359
--- /dev/null
@@ -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 (file)
index 0000000..c522ef7
--- /dev/null
@@ -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 (file)
index 0000000..5858e8e
--- /dev/null
@@ -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 (file)
index 0000000..0e5f145
--- /dev/null
@@ -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 (file)
index 0000000..0c6e2cd
--- /dev/null
@@ -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 (file)
index 0000000..162fa8b
--- /dev/null
@@ -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 (file)
index 0000000..0f8c458
--- /dev/null
@@ -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 (file)
index 0000000..caa7bfe
--- /dev/null
@@ -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 (file)
index 0000000..5007c84
--- /dev/null
@@ -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 (file)
index 0000000..9a18b53
--- /dev/null
@@ -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 (file)
index 0000000..398b8e3
--- /dev/null
@@ -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 (file)
index 0000000..0df17de
--- /dev/null
@@ -0,0 +1,6 @@
+# $Source$
+# $Id$
+
+define_option with-dba 'dba support?' yesnodir no \
+'    Whether to build the dba extension.'
+