]> granicus.if.org Git - php/commitdiff
Incorporate rewritten version of dbm from db extension.
authorMarcus Boerger <helly@php.net>
Wed, 6 Nov 2002 01:47:06 +0000 (01:47 +0000)
committerMarcus Boerger <helly@php.net>
Wed, 6 Nov 2002 01:47:06 +0000 (01:47 +0000)
# currently locks are missing :-(

ext/dba/config.m4
ext/dba/dba_dbm.c
ext/dba/libdbm/dbm.c [new file with mode: 0644]
ext/dba/libdbm/dbm.h [new file with mode: 0644]

index 859bd23403a07b1ebd6b9f17f4e954f146e2d205..9ecd88904311db72334b090c6306cad340f91c37 100644 (file)
@@ -190,7 +190,13 @@ AC_DBA_STD_RESULT
 
 AC_ARG_WITH(dbm,
 [  --with-dbm[=DIR]        Include DBM support],[
-  if test "$withval" != "no"; then
+  if test "$withval" = "yes"; then
+    PHP_ADD_BUILD_DIR($ext_builddir/libdbm)
+    AC_DEFINE(DBA_DBM_BUILTIN, 1, [ ])
+    AC_DEFINE(DBA_DBM, 1, [ ])
+    dbm_sources="libdbm/dbm.c"
+    THIS_RESULT="builtin"
+  elif test "$withval" != "no"; then
     for i in /usr/local /usr $withval; do
       if test -f "$i/include/dbm.h" ; then
         THIS_PREFIX=$i
@@ -245,7 +251,7 @@ AC_MSG_CHECKING(whether to enable DBA interface)
 if test "$HAVE_DBA" = "1"; then
   AC_MSG_RESULT(yes)
   AC_DEFINE(HAVE_DBA, 1, [ ])
-  PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c dba_ndbm.c dba_db3.c $cdb_sources, $ext_shared)
+  PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c dba_ndbm.c dba_db3.c $cdb_sources $dbm_sources, $ext_shared)
   PHP_SUBST(DBA_SHARED_LIBADD)
 else
   AC_MSG_RESULT(no)
index 5763fad41eb5a576a80b9491f32c039b24efa7b0..0dd0b52625c65021da4d04869b0f3b407daa56c5 100644 (file)
 #if DBA_DBM
 #include "php_dbm.h"
 
+#ifdef DBA_DBM_BUILTIN
+#include "libdbm/dbm.h"
+#else
 #include <dbm.h>
+#endif
 
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#ifndef DBA_DBM_BUILTIN
+typedef struct {
+       datum nextkey;
+} dba_dbm_data;
+#endif
+
 #define DBM_DATA dba_dbm_data *dba = info->dbf
 #define DBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
 
        close(fd);
 
 
-typedef struct {
-       datum nextkey;
-} dba_dbm_data;
-
 DBA_OPEN_FUNC(dbm)
 {
+#ifdef DBA_DBM_BUILTIN
+       char *fmode;
+       php_stream *fp;
+
+       info->dbf = ecalloc(sizeof(dba_dbm_data), 1);
+       if (!info->dbf) {
+               *error = "Out of memory";
+               return FAILURE;
+       }
+
+       switch(info->mode) {
+               case DBA_READER:
+                       fmode = "r";
+                       break;
+               case DBA_WRITER:
+                       fmode = "a+";
+                       break;
+               case DBA_CREAT:
+               case DBA_TRUNC:
+                       fmode = "w+";
+                       break;
+               default:
+                       return FAILURE; /* not possible */
+       }
+       fp = php_stream_open_wrapper(info->path, fmode, STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL);
+       if (!fp) {
+               *error = "Unable to open file";
+               return FAILURE;
+       }
+
+       ((dba_dbm_data*)info->dbf)->fp = fp;
+       return SUCCESS;
+#else
        int fd;
        int filemode = 0644;
 
@@ -84,24 +123,50 @@ DBA_OPEN_FUNC(dbm)
                return FAILURE;
        }
        return SUCCESS;
+#endif
 }
 
 DBA_CLOSE_FUNC(dbm)
 {
-       efree(info->dbf);
+       DBM_DATA;
+
+#ifdef DBA_DBM_BUILTIN
+       php_stream_close(dba->fp);
+       if (dba->nextkey.dptr)
+               efree(dba->nextkey.dptr);
+#else
        dbmclose();
+#endif
+       efree(dba);
 }
 
+#ifdef DBA_DBM_BUILTIN
+#define DBM_FETCH(gkey)       dbm_file_fetch((dba_dbm_data*)info->dbf, gkey TSRMLS_CC)
+#define DBM_STORE(gkey, gval) dbm_file_store((dba_dbm_data*)info->dbf, gkey, gval, DBM_REPLACE TSRMLS_CC)
+#define DBM_DELETE(gkey)      dbm_file_delete((dba_dbm_data*)info->dbf, gkey TSRMLS_CC)
+#define DBM_FIRSTKEY()        dbm_file_firstkey((dba_dbm_data*)info->dbf TSRMLS_CC)
+#define DBM_NEXTKEY(gkey)     dbm_file_nextkey((dba_dbm_data*)info->dbf TSRMLS_CC)
+#else
+#define DBM_FETCH(gkey)       fetch(gkey)
+#define DBM_STORE(gkey, gval) store(gkey, gval)
+#define DBM_DELETE(gkey)      delete(gkey)
+#define DBM_FIRSTKEY()        firstkey()
+#define DBM_NEXTKEY(gkey)     nextkey(gkey)
+#endif
+
 DBA_FETCH_FUNC(dbm)
 {
        datum gval;
        char *new = NULL;
 
        DBM_GKEY;
-       gval = fetch(gkey);
+       gval = DBM_FETCH(gkey);
        if(gval.dptr) {
                if(newlen) *newlen = gval.dsize;
                new = estrndup(gval.dptr, gval.dsize);
+#ifdef DBA_DBM_BUILTIN
+               efree(gval.dptr);
+#endif
        }
        return new;
 }
@@ -114,7 +179,7 @@ DBA_UPDATE_FUNC(dbm)
        gval.dptr = (char *) val;
        gval.dsize = vallen;
        
-       return (store(gkey, gval) == -1 ? FAILURE : SUCCESS);
+       return (DBM_STORE(gkey, gval) == -1 ? FAILURE : SUCCESS);
 }
 
 DBA_EXISTS_FUNC(dbm)
@@ -122,8 +187,11 @@ DBA_EXISTS_FUNC(dbm)
        datum gval;
        DBM_GKEY;
        
-       gval = fetch(gkey);
+       gval = DBM_FETCH(gkey);
        if(gval.dptr) {
+#ifdef DBA_DBM_BUILTIN
+               efree(gval.dptr);
+#endif
                return SUCCESS;
        }
        return FAILURE;
@@ -132,41 +200,46 @@ DBA_EXISTS_FUNC(dbm)
 DBA_DELETE_FUNC(dbm)
 {
        DBM_GKEY;
-       return(delete(gkey) == -1 ? FAILURE : SUCCESS);
+       return(DBM_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;
+
+#ifdef DBA_DBM_BUILTIN
+       if (dba->nextkey.dptr)
+               efree(dba->nextkey.dptr);
+#endif
+       dba->nextkey = DBM_FIRSTKEY();
+       if(dba->nextkey.dptr) {
+               if(newlen) 
+                       *newlen = dba->nextkey.dsize;
+               return estrndup(dba->nextkey.dptr, dba->nextkey.dsize);
+       }
+       return NULL;
 }
 
 DBA_NEXTKEY_FUNC(dbm)
 {
        DBM_DATA;
-       datum gkey;
-       char *nkey = NULL;
+       datum lkey;
        
-       if(!dba->nextkey.dptr) return 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;
+       lkey = dba->nextkey;
+       dba->nextkey = DBM_NEXTKEY(lkey);
+#ifdef DBA_DBM_BUILTIN
+       if (lkey.dptr)
+               efree(lkey.dptr);
+#endif
+       if(dba->nextkey.dptr) {
+               if(newlen) 
+                       *newlen = dba->nextkey.dsize;
+               return estrndup(dba->nextkey.dptr, dba->nextkey.dsize);
+       }
+       return NULL;
 }
 
 DBA_OPTIMIZE_FUNC(dbm)
@@ -177,6 +250,7 @@ DBA_OPTIMIZE_FUNC(dbm)
 
 DBA_SYNC_FUNC(dbm)
 {
+       /* dummy */
        return SUCCESS;
 }
 
diff --git a/ext/dba/libdbm/dbm.c b/ext/dba/libdbm/dbm.c
new file mode 100644 (file)
index 0000000..fe86f46
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2002 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Marcus Boerger <helly@php.net>                              |
+   | based on ext/db/db.c by:                                             |
+   |          Rasmus Lerdorf <rasmus@php.net>                             |
+   |          Jim Winstead <jimw@php.net>                                 |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_globals.h"
+#include "safe_mode.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "dbm.h"
+
+/*
+ * ret = -1 means that database was opened for read-only
+ * ret = 0  success
+ * ret = 1  key already exists - nothing done
+ */
+
+/* {{{ dbm_file_store
+ */
+PHPAPI int dbm_file_store(dba_dbm_data *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) {
+       if (mode == DBM_INSERT) {
+               if (dbm_file_findkey(dba, key_datum TSRMLS_CC)) {
+                       return 1;
+               }
+               php_stream_seek(dba->fp, 0L, SEEK_END);
+               php_stream_printf(dba->fp TSRMLS_CC, "%d\n", key_datum.dsize);
+               php_stream_flush(dba->fp);
+               if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize)
+                       return -1;
+               php_stream_printf(dba->fp TSRMLS_CC, "%d\n", value_datum.dsize);
+               php_stream_flush(dba->fp);
+               if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize)
+                       return -1;
+       } else { /* DBM_REPLACE */
+               dbm_file_delete(dba, key_datum TSRMLS_CC);
+               php_stream_printf(dba->fp TSRMLS_CC, "%d\n", key_datum.dsize);
+               php_stream_flush(dba->fp);
+               if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize)
+                       return -1;
+               php_stream_printf(dba->fp TSRMLS_CC, "%d\n", value_datum.dsize);
+               if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize)
+                       return -1;
+       }
+
+       return 0;
+}
+/* }}} */
+
+/* {{{ dbm_file_fetch
+ */
+PHPAPI datum dbm_file_fetch(dba_dbm_data *dba, datum key_datum TSRMLS_DC) {
+       datum value_datum = {NULL, 0};
+       int num=0, buf_size=1024;
+       char *buf;      
+
+       if (dbm_file_findkey(dba, key_datum TSRMLS_CC)) {
+               buf = emalloc((buf_size+1) * sizeof(char));
+               if (php_stream_gets(dba->fp, buf, 15)) {
+                       num = atoi(buf);
+                       if (num > buf_size) {
+                               buf_size+=num;
+                               buf = erealloc(buf, (buf_size+1)*sizeof(char));
+                       }
+                       php_stream_read(dba->fp, buf, num);
+                       value_datum.dptr = buf;
+                       value_datum.dsize = num;
+               } else {
+                       value_datum.dptr = NULL;
+                       value_datum.dsize = 0;
+                       efree(buf);
+               }
+       }
+       return value_datum;
+}
+/* }}} */
+
+/* {{{ dbm_file_delete
+ */
+PHPAPI int dbm_file_delete(dba_dbm_data *dba, datum key_datum TSRMLS_DC) {
+       char *key = key_datum.dptr;
+       int size = key_datum.dsize;
+
+       char *buf;
+       int num, buf_size = 1024;
+       long pos;
+
+       php_stream_rewind(dba->fp);
+
+       buf = emalloc((buf_size + 1)*sizeof(char));
+       while(!php_stream_eof(dba->fp)) {
+               /* read in the length of the key name */
+               if (!php_stream_gets(dba->fp, buf, 15))
+                       break;
+               num = atoi(buf);
+               if (num > buf_size) {
+                       buf_size += num;
+                       buf = erealloc(buf, (buf_size+1)*sizeof(char));
+               }
+               pos = php_stream_tell(dba->fp);
+
+               /* read in the key name */
+               num = php_stream_read(dba->fp, buf, sizeof(char)*num);
+               if (num<0) 
+                       break;
+               *(buf+num) = '\0';
+
+               if (size == num && !memcmp(buf, key, size)) {
+                       php_stream_seek(dba->fp, pos, SEEK_SET);
+                       php_stream_putc(dba->fp, 0);
+                       php_stream_flush(dba->fp);
+                       php_stream_seek(dba->fp, 0L, SEEK_END);
+                       if (buf) 
+                               efree(buf);
+                       return SUCCESS;
+               }       
+
+               /* read in the length of the value */
+               if (!php_stream_gets(dba->fp, buf, 15))
+                       break;
+               num = atoi(buf);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf = erealloc(buf, (buf_size+1)*sizeof(char));
+               }
+               /* read in the value */
+               num = php_stream_read(dba->fp, buf, sizeof(char)*num);
+               if (num<0)
+                       break;
+       }
+       if (buf) 
+               efree(buf);
+       return FAILURE;
+}      
+/* }}} */
+
+/* {{{ dbm_file_findkey
+ */
+PHPAPI int dbm_file_findkey(dba_dbm_data *dba, datum key_datum TSRMLS_DC) {
+       char *buf = NULL;
+       int num;
+       int buf_size=1024;
+       int ret=0;
+       void *key = key_datum.dptr;
+       int size = key_datum.dsize;
+
+       php_stream_rewind(dba->fp);
+       buf = emalloc((buf_size+1)*sizeof(char));
+       while (!php_stream_eof(dba->fp)) {
+               if (!php_stream_gets(dba->fp, buf, 15)) 
+                       break;
+               num = atoi(buf);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf = erealloc(buf, (buf_size+1)*sizeof(char));
+               }
+               num = php_stream_read(dba->fp, buf, sizeof(char)*num);
+               if (num<0) break;
+               *(buf+num) = '\0';
+               if (size == num) {
+                       if (!memcmp(buf, key, size)) {
+                               ret = 1;
+                               break;
+                       }
+               }       
+               if (!php_stream_gets(dba->fp, buf, 15))
+                       break;
+               num = atoi(buf);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf = erealloc(buf, (buf_size+1)*sizeof(char));
+               }
+               num = php_stream_read(dba->fp, buf, sizeof(char)*num);
+               if (num<0) 
+                       break;
+               *(buf+num) = '\0';
+       }
+       if (buf) 
+               efree(buf);
+       return(ret);
+}
+/* }}} */
+
+/* {{{ dbm_file_firstkey
+ */
+PHPAPI datum dbm_file_firstkey(dba_dbm_data *dba TSRMLS_DC) {
+       datum buf;
+       int num;
+       int buf_size=1024;
+
+       php_stream_rewind(dba->fp);
+       buf.dptr = emalloc((buf_size+1)*sizeof(char));
+       while(!php_stream_eof(dba->fp)) {
+               if (!php_stream_gets(dba->fp, buf.dptr, 15)) break;
+               num = atoi(buf.dptr);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf.dptr = erealloc(buf.dptr, (buf_size+1)*sizeof(char));
+               }
+               num = php_stream_read(dba->fp, buf.dptr, num);
+               if (num<0) 
+                       break;
+               buf.dsize = num;
+               if (*(buf.dptr)!=0) {
+                       dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
+                       return(buf);
+               }
+               if (!php_stream_gets(dba->fp, buf.dptr, 15)) break;
+               num = atoi(buf.dptr);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf.dptr = erealloc(buf.dptr, (buf_size+1)*sizeof(char));
+               }
+               num = php_stream_read(dba->fp, buf.dptr, num);
+               if (num<0) 
+                       break;
+       }
+       if (buf.dptr) 
+               efree(buf.dptr);
+       buf.dptr = NULL;
+       return(buf);
+}
+/* }}} */
+
+/* {{{ latfile_nextkey
+ */
+PHPAPI datum dbm_file_nextkey(dba_dbm_data *dba TSRMLS_DC) {
+       datum buf;
+       int num;
+       int buf_size=1024;
+
+       php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
+       buf.dptr = emalloc((buf_size+1)*sizeof(char));
+       while(!php_stream_eof(dba->fp)) {
+               if (!php_stream_gets(dba->fp, buf.dptr, 15)) break;
+               num = atoi(buf.dptr);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf.dptr = erealloc(buf.dptr, (buf_size+1)*sizeof(char));
+               }
+               num = php_stream_read(dba->fp, buf.dptr, num);
+               if (num<0) 
+                       break;
+               if (!php_stream_gets(dba->fp, buf.dptr, 15)) 
+                       break;
+               num = atoi(buf.dptr);
+               if (num > buf_size) {
+                       buf_size+=num;
+                       buf.dptr = erealloc(buf.dptr, (buf_size+1)*sizeof(char));
+               }
+               num = php_stream_read(dba->fp, buf.dptr, num);
+               if (num<0) 
+                       break;
+               buf.dsize = num;
+               if (*(buf.dptr)!=0) {
+                       dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
+                       return(buf);
+               }
+       }
+       if (buf.dptr) 
+               efree(buf.dptr);
+       buf.dptr = NULL;
+       return(buf);
+}      
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
diff --git a/ext/dba/libdbm/dbm.h b/ext/dba/libdbm/dbm.h
new file mode 100644 (file)
index 0000000..739a927
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2002 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Marcus Boerger <helly@php.net>                               |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef PHP_LIBDBM_H
+#define PHP_LIBDBM_H
+
+typedef struct {
+       char *dptr;
+       int dsize;
+} datum;
+
+typedef struct {
+       php_stream *fp;
+       long CurrentFlatFilePos;
+       datum nextkey;
+} dba_dbm_data;
+
+#define DBM_INSERT 0
+#define DBM_REPLACE 1
+
+PHPAPI int dbm_file_store(dba_dbm_data *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC);
+PHPAPI datum dbm_file_fetch(dba_dbm_data *dba, datum key_datum TSRMLS_DC);
+PHPAPI int dbm_file_delete(dba_dbm_data *dba, datum key_datum TSRMLS_DC);
+PHPAPI int dbm_file_findkey(dba_dbm_data *dba, datum key_datum TSRMLS_DC);
+PHPAPI datum dbm_file_firstkey(dba_dbm_data *dba TSRMLS_DC);
+PHPAPI datum dbm_file_nextkey(dba_dbm_data *dba TSRMLS_DC);
+
+#endif