cvs: php4 /ext/dba CREDITS config.m4 dba.c dba_cdb.c install_cdb.sh /ext/dba/libcdb .cvsignore cdb.c cdb.h cdb_make.c cdb_make.h uint32.c uint32.h
/ext/dba/tests dba_cdb.phpt dba_cdb_make.phpt dba_cdb_read.phpt
| From: | Marcus B�rger | Date: | Mon, 04 Nov 2002 17:53:05 +0000 |
| Subject: | cvs: php4 /ext/dba CREDITS config.m4 dba.c dba_cdb.c install_cdb.sh /ext/dba/libcdb .cvsignore cdb.c cdb.h cdb_make.c cdb_make.h uint32.c uint32.h /ext/dba/tests dba_cdb.phpt dba_cdb_make.phpt dba_cdb_read.phpt |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-15784@lists.php.net to get a copy of this message | ||
helly Mon Nov 4 12:53:05 2002 EDT
Added files:
/php4/ext/dba/libcdb .cvsignore cdb.c cdb.h cdb_make.c cdb_make.h
uint32.c uint32.h
/php4/ext/dba/tests dba_cdb_make.phpt
Modified files:
/php4/ext/dba CREDITS config.m4 dba.c dba_cdb.c install_cdb.sh
/php4/ext/dba/tests dba_cdb.phpt dba_cdb_read.phpt
Log:
incorporate cdb-0.75 as suggested by D. J. Bernstein
#dba now supports cdb_make
Index: php4/ext/dba/CREDITS diff -u php4/ext/dba/CREDITS:1.1 php4/ext/dba/CREDITS:1.2 --- php4/ext/dba/CREDITS:1.1 Mon Nov 20 05:31:15 2000 +++ php4/ext/dba/CREDITS Mon Nov 4 12:53:04 2002 @@ -1,2 +1,2 @@ DBA -Sascha Schumann +Sascha Schumann, Marcus Boerger \ No newline at end of file Index: php4/ext/dba/config.m4 diff -u php4/ext/dba/config.m4:1.22 php4/ext/dba/config.m4:1.23 --- php4/ext/dba/config.m4:1.22 Thu Sep 19 00:18:20 2002 +++ php4/ext/dba/config.m4 Mon Nov 4 12:53:04 2002 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.22 2002/09/19 04:18:20 sas Exp $ +dnl $Id: config.m4,v 1.23 2002/11/04 17:53:04 helly Exp $ dnl AC_DEFUN(PHP_TEMP_LDFLAGS,[ @@ -38,9 +38,9 @@ dnl Print the result message AC_DEFUN(AC_DBA_STD_RESULT,[ - if test "$THIS_RESULT" = "yes"; then + if test "$THIS_RESULT" = "yes" -o "$THIS_RESULT" = "builtin"; then HAVE_DBA=1 - AC_MSG_RESULT(yes) + AC_MSG_RESULT($THIS_RESULT) else AC_MSG_RESULT(no) fi @@ -213,12 +213,18 @@ AC_ARG_WITH(cdb, [ --with-cdb[=DIR] Include CDB support],[ - if test "$withval" != "no"; then + if test "$withval" = "yes"; then + PHP_ADD_BUILD_DIR($ext_builddir/libcdb) + AC_DEFINE(DBA_CDB_MAKE, 1, [ ]) + AC_DEFINE(DBA_CDB, 1, [ ]) + cdb_sources="libcdb/cdb.c libcdb/cdb_make.c libcdb/uint32.c" + THIS_RESULT="builtin" + elif 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 + done for LIB in cdb c; do PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[ @@ -238,9 +244,8 @@ 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, $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, $ext_shared) PHP_SUBST(DBA_SHARED_LIBADD) else AC_MSG_RESULT(no) fi - Index: php4/ext/dba/dba.c diff -u php4/ext/dba/dba.c:1.49 php4/ext/dba/dba.c:1.50 --- php4/ext/dba/dba.c:1.49 Mon Nov 4 07:27:12 2002 +++ php4/ext/dba/dba.c Mon Nov 4 12:53:04 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba.c,v 1.49 2002/11/04 12:27:12 helly Exp $ */ +/* $Id: dba.c,v 1.50 2002/11/04 17:53:04 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -143,13 +143,15 @@ /* a DBA handler must have specific routines */ -#define DBA_HND(x) \ +#define DBA_NAMED_HND(name, x) \ {\ - #x, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ + #name, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ dba_exists_##x, dba_delete_##x, dba_firstkey_##x, dba_nextkey_##x, \ dba_optimize_##x, dba_sync_##x \ }, +#define DBA_HND(x) DBA_NAMED_HND(x, 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) { \ @@ -173,6 +175,9 @@ #endif #if DBA_CDB DBA_HND(cdb) +#endif +#if DBA_CDB_BUILTIN + DBA_NAMED_HND(cdb_make, cdb) #endif #if DBA_DB2 DBA_HND(db2) Index: php4/ext/dba/dba_cdb.c diff -u php4/ext/dba/dba_cdb.c:1.17 php4/ext/dba/dba_cdb.c:1.18 --- php4/ext/dba/dba_cdb.c:1.17 Sun Nov 3 11:50:08 2002 +++ php4/ext/dba/dba_cdb.c Mon Nov 4 12:53:04 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_cdb.c,v 1.17 2002/11/03 16:50:08 helly Exp $ */ +/* $Id: dba_cdb.c,v 1.18 2002/11/04 17:53:04 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -32,48 +32,95 @@ #include <unistd.h> #include <fcntl.h> +#if DBA_CDB_BUILTIN +#include "libcdb/cdb.h" +#include "libcdb/cdb_make.h" +#include "libcdb/uint32.h" +#else #include <cdb.h> #include <uint32.h> +#endif #define CDB_INFO \ dba_cdb *cdb = (dba_cdb *) info->dbf typedef struct { struct cdb c; - int fd; +#if DBA_CDB_BUILTIN + struct cdb_make m; + php_stream *file; + int make; +#else + int file; +#endif uint32 eod; /* size of constant database */ uint32 pos; /* current position for traversing */ } dba_cdb; DBA_OPEN_FUNC(cdb) { - int gmode = 0; - int fd; +#if DBA_CDB_BUILTIN + php_stream* file = 0; + int make; +#else + int file = 0; +#endif 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; +#if DBA_CDB_BUILTIN + make = 0; + file = php_stream_open_wrapper(info->path, "rb", STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); + if (!file) { + return FAILURE; + } +#else + file = VCWD_OPEN(info->path, O_RDONLY); + if (file < 0) { + return FAILURE; + } +#endif + break; +#if DBA_CDB_BUILTIN + case DBA_TRUNC: + case DBA_CREAT: + make = 1; + file = php_stream_open_wrapper(info->path, "wb", STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); + if (!file) { + return FAILURE; + } + break; + case DBA_WRITER: + return FAILURE; /* not supported */ #endif default: + /* currently not supported: */ return FAILURE; } - fd = VCWD_OPEN(info->path, gmode); - if (fd < 0) { + cdb = ecalloc(sizeof(dba_cdb), 1); + if (!cdb) { +#if DBA_CDB_BUILTIN + php_stream_close(cdb->file); +#else + close(cdb->file); +#endif return FAILURE; } - - cdb = emalloc(sizeof(dba_cdb)); - memset(cdb, 0, sizeof(dba_cdb)); - cdb_init(&cdb->c, fd); - cdb->fd = fd; +#if DBA_CDB_BUILTIN + if (make) { + cdb_make_start(&cdb->m, file TSRMLS_CC); + } else { + cdb_init(&cdb->c, file TSRMLS_CC); + } + cdb->make = make; +#else + cdb_init(&cdb->c, file); +#endif + cdb->file = file; pinfo->dbf = cdb; return SUCCESS; @@ -83,29 +130,51 @@ { CDB_INFO; - /* cdb_free does not close associated fd */ + /* cdb_free does not close associated file */ +#if DBA_CDB_BUILTIN + if (cdb->make) { + cdb_make_finish(&cdb->m TSRMLS_CC); + } else { + cdb_free(&cdb->c TSRMLS_CC); + } + php_stream_close(cdb->file); +#else cdb_free(&cdb->c); - close(cdb->fd); + close(cdb->file); +#endif efree(cdb); } +#if DBA_CDB_BUILTIN +# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos TSRMLS_CC) +# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len TSRMLS_CC) +# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len TSRMLS_CC) +#else +# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos) +# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len) +# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len) +#endif + DBA_FETCH_FUNC(cdb) { CDB_INFO; unsigned int len; char *new_entry = NULL; -/* cdb_findstart(&cdb->c); */ - if (cdb_find(&cdb->c, key, keylen) == 1) { +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + if (php_cdb_find(&cdb->c, key, keylen) == 1) { while(skip--) { - if (cdb_findnext(&cdb->c, key, keylen) != 1) { + if (php_cdb_findnext(&cdb->c, key, keylen) != 1) { return NULL; } } len = cdb_datalen(&cdb->c); new_entry = emalloc(len+1); - if (cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) { + if (php_cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) { efree(new_entry); return NULL; } @@ -119,7 +188,16 @@ DBA_UPDATE_FUNC(cdb) { - /* if anyone figures out cdbmake.c, let me know */ +#if DBA_CDB_BUILTIN + CDB_INFO; + + if (!cdb->make) + return FAILURE; /* database was opened readonly */ + if (!mode) + return FAILURE; /* cdb_make dosn't know replace */ + if (cdb_make_add(&cdb->m, key, keylen, val, vallen TSRMLS_CC) != -1) + return SUCCESS; +#endif return FAILURE; } @@ -127,24 +205,49 @@ { CDB_INFO; - if (cdb_find(&cdb->c, key, keylen) == 1) +#if DBA_CDB_BUILTIN + if (cdb->make) + return FAILURE; /* database was opened writeonly */ +#endif + if (php_cdb_find(&cdb->c, key, keylen) == 1) return SUCCESS; return FAILURE; } DBA_DELETE_FUNC(cdb) { - return FAILURE; + return FAILURE; /* cdb doesn't support delete */ } +/* {{{ cdb_file_read */ +#if DBA_CDB_BUILTIN +# define cdb_file_read(fildes, buf, size) php_stream_read(fildes, buf, size) +#else +# define cdb_file_read(fildes, buf, size) read(fildes, buf, size) +#endif +/* }}} */ #define CREAD(n) do { \ - if (read(cdb->fd, buf, n) < n) return NULL; \ + if (cdb_file_read(cdb->file, buf, n) < n) return NULL; \ } while (0) +/* {{{ cdb_file_lseek + php_stream_seek does not return actual position */ +#if DBA_CDB_BUILTIN +int cdb_file_lseek(php_stream *fp, off_t offset, int whence TSRMLS_DC) { + php_stream_seek(fp, offset, whence); + return php_stream_tell(fp); +} +#else +int cdb_file_lseek(int fd, off_t offset, int whence TSRMLS_DC) { + return lseek(fd, offset, whence); +} +#endif +/* }}} */ + #define CSEEK(n) do { \ if (n >= cdb->eod) return NULL; \ - if (lseek(cdb->fd, (off_t)n, SEEK_SET) != (off_t) n) return NULL; \ + if (cdb_file_lseek(cdb->file, (off_t)n, SEEK_SET TSRMLS_CC) != (off_t) n) return NULL; \ } while (0) @@ -155,6 +258,11 @@ char buf[8]; char *key; +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + cdb->eod = -1; CSEEK(0); CREAD(4); @@ -170,7 +278,7 @@ uint32_unpack(buf + 4, &dlen); key = emalloc(klen + 1); - if (read(cdb->fd, key, klen) < klen) { + if (cdb_file_read(cdb->file, key, klen) < klen) { efree(key); key = NULL; } else { @@ -191,13 +299,18 @@ char buf[8]; char *key; +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + CSEEK(cdb->pos); CREAD(8); uint32_unpack(buf, &klen); uint32_unpack(buf + 4, &dlen); key = emalloc(klen + 1); - if (read(cdb->fd, key, klen) < klen) { + if (cdb_file_read(cdb->file, key, klen) < klen) { efree(key); key = NULL; } else { Index: php4/ext/dba/install_cdb.sh diff -u php4/ext/dba/install_cdb.sh:1.1 php4/ext/dba/install_cdb.sh:1.2 --- php4/ext/dba/install_cdb.sh:1.1 Thu Sep 19 00:18:20 2002 +++ php4/ext/dba/install_cdb.sh Mon Nov 4 12:53:04 2002 @@ -1,10 +1,14 @@ #! /bin/sh +# You can use this script if you want to use an external cdb lib. If you +# compile php using --with-cdb the internal functions will be used and no +# external library is used so that this script is not necessary. +# # cdb-0.75 lacks support for installing header files and creating a # library which programs can link against. This shell script fills # the gap. # -# $Id: install_cdb.sh,v 1.1 2002/09/19 04:18:20 sas Exp $ +# $Id: install_cdb.sh,v 1.2 2002/11/04 17:53:04 helly Exp $ if test -r "cdb.a" && test -r "auto-str.c" && test -r "byte.a"; then : Index: php4/ext/dba/tests/dba_cdb.phpt diff -u php4/ext/dba/tests/dba_cdb.phpt:1.2 php4/ext/dba/tests/dba_cdb.phpt:1.3 --- php4/ext/dba/tests/dba_cdb.phpt:1.2 Sun Nov 3 10:22:32 2002 +++ php4/ext/dba/tests/dba_cdb.phpt Mon Nov 4 12:53:04 2002 @@ -4,7 +4,7 @@ <?php require_once('skipif.inc'); if (!in_array('cdb', dba_handlers())) die('skip CDB handler not available'); - die('skip CDB currently supports only reading'); + die('skip CDB does not support replace or delete'); ?> --FILE-- <?php Index: php4/ext/dba/tests/dba_cdb_read.phpt diff -u php4/ext/dba/tests/dba_cdb_read.phpt:1.3 php4/ext/dba/tests/dba_cdb_read.phpt:1.4 --- php4/ext/dba/tests/dba_cdb_read.phpt:1.3 Sun Nov 3 11:43:07 2002 +++ php4/ext/dba/tests/dba_cdb_read.phpt Mon Nov 4 12:53:04 2002 @@ -33,8 +33,8 @@ echo "\n#"; echo dba_fetch(1, $db_file); echo dba_fetch(1, $db_file); - echo dba_fetch(1, $db_file); - echo dba_fetch(1, $db_file); + echo dba_fetch(2, $db_file); + echo dba_fetch(2, $db_file); echo "\n?".$keys; // with skip = 0 dba_fetch must fetch the first result echo "\n#"; @@ -59,7 +59,7 @@ database handler: cdb 7YYYYNNN =1234 -#1111 +#1122 ?1212314 #1212314 =1231324 Index: php4/ext/dba/libcdb/.cvsignore +++ php4/ext/dba/libcdb/.cvsignore *.lo *.la deps *.plg *.opt *.ncb Release Release_inline Debug Release_TS Release_TSDbg Release_TS_inline Debug_TS Index: php4/ext/dba/libcdb/cdb.c +++ php4/ext/dba/libcdb/cdb.c /* +----------------------------------------------------------------------+ | 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: cdb.c,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> #include <string.h> #include <errno.h> #include "cdb.h" #ifndef EPROTO # define EPROTO -15 /* cdb 0.75's default for PROTOless systems */ #endif /* {{{ cdb_match */ static int cdb_match(struct cdb *c, char *key, unsigned int len, uint32 pos TSRMLS_DC) { char buf[32]; int n; while (len > 0) { n = sizeof(buf); if (n > len) n = len; if (cdb_read(c, buf, n, pos TSRMLS_CC) == -1) return -1; if (memcmp(buf, key, n)) return 0; pos += n; key += n; len -= n; } return 1; } /* }}} */ /* {{{ cdb_hashadd */ static uint32 cdb_hashadd(uint32 h, unsigned char c) { h += (h << 5); return h ^ c; } /* }}} */ /* {{{ cdb_hash */ PHPAPI uint32 cdb_hash(char *buf, unsigned int len) { uint32 h; h = CDB_HASHSTART; while (len) { h = cdb_hashadd(h, *buf++); --len; } return h; } /* }}} */ /* {{{ cdb_free */ PHPAPI void cdb_free(struct cdb *c TSRMLS_DC) { } /* }}} */ /* {{{ cdb_findstart */ PHPAPI void cdb_findstart(struct cdb *c TSRMLS_DC) { c->loop = 0; } /* }}} */ /* {{{ cdb_init */ PHPAPI void cdb_init(struct cdb *c, php_stream *fp TSRMLS_DC) { cdb_free(c TSRMLS_CC); cdb_findstart(c TSRMLS_CC); c->fp = fp; } /* }}} */ /* {{{ cdb_read */ PHPAPI int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos TSRMLS_DC) { if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) { errno = EPROTO; return -1; } while (len > 0) { int r; do { r = php_stream_read(c->fp, buf, len); } while ((r == -1) && (errno == EINTR)); if (r == -1) return -1; if (r == 0) { errno = EPROTO; return -1; } buf += r; len -= r; } return 0; } /* }}} */ /* {{{ cdb_findnext */ PHPAPI int cdb_findnext(struct cdb *c, char *key, unsigned int len TSRMLS_DC) { char buf[8]; uint32 pos; uint32 u; if (!c->loop) { u = cdb_hash(key, len); if (cdb_read(c, buf, 8, (u << 3) & 2047 TSRMLS_CC) == -1) return -1; uint32_unpack(buf + 4,&c->hslots); if (!c->hslots) return 0; uint32_unpack(buf, &c->hpos); c->khash = u; u >>= 8; u %= c->hslots; u <<= 3; c->kpos = c->hpos + u; } while (c->loop < c->hslots) { if (cdb_read(c, buf, 8, c->kpos TSRMLS_CC) == -1) return -1; uint32_unpack(buf + 4, &pos); if (!pos) return 0; c->loop += 1; c->kpos += 8; if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; uint32_unpack(buf, &u); if (u == c->khash) { if (cdb_read(c, buf, 8, pos TSRMLS_CC) == -1) return -1; uint32_unpack(buf, &u); if (u == len) switch(cdb_match(c, key, len, pos + 8 TSRMLS_CC)) { case -1: return -1; case 1: uint32_unpack(buf + 4, &c->dlen); c->dpos = pos + 8 + len; return 1; } } } return 0; } /* }}} */ /* {{{ cdb_find */ PHPAPI int cdb_find(struct cdb *c, char *key, unsigned int len TSRMLS_DC) { cdb_findstart(c TSRMLS_CC); return cdb_findnext(c, key, len TSRMLS_CC); } /* }}} */ Index: php4/ext/dba/libcdb/cdb.h +++ php4/ext/dba/libcdb/cdb.h /* +----------------------------------------------------------------------+ | 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: cdb.h,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifndef CDB_H #define CDB_H #include "uint32.h" #define CDB_HASHSTART 5381 struct cdb { php_stream *fp; uint32 loop; /* number of hash slots searched under this key */ uint32 khash; /* initialized if loop is nonzero */ uint32 kpos; /* initialized if loop is nonzero */ uint32 hpos; /* initialized if loop is nonzero */ uint32 hslots; /* initialized if loop is nonzero */ uint32 dpos; /* initialized if cdb_findnext() returns 1 */ uint32 dlen; /* initialized if cdb_findnext() returns 1 */ }; PHPAPI uint32 cdb_hash(char *, unsigned int); PHPAPI void cdb_free(struct cdb * TSRMLS_DC); PHPAPI void cdb_init(struct cdb *, php_stream *fp TSRMLS_DC); PHPAPI int cdb_read(struct cdb *, char *, unsigned int, uint32 TSRMLS_DC); PHPAPI void cdb_findstart(struct cdb * TSRMLS_DC); PHPAPI int cdb_findnext(struct cdb *, char *, unsigned int TSRMLS_DC); PHPAPI int cdb_find(struct cdb *, char *, unsigned int TSRMLS_DC); #define cdb_datapos(c) ((c)->dpos) #define cdb_datalen(c) ((c)->dlen) #endif Index: php4/ext/dba/libcdb/cdb_make.c +++ php4/ext/dba/libcdb/cdb_make.c /* +----------------------------------------------------------------------+ | 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: cdb_make.c,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include "cdb.h" #include "cdb_make.h" #include "uint32.h" /* {{{ cdb_make_write */ static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz TSRMLS_DC) { return php_stream_write(c->fp, buf, sz) == sz ? 0 : -1; } /* {{{ cdb_posplus */ static int cdb_posplus(struct cdb_make *c, uint32 len) { uint32 newpos = c->pos + len; if (newpos < len) { errno = ENOMEM; return -1; } c->pos = newpos; return 0; } /* }}} */ /* {{{ cdb_make_start */ PHPAPI int cdb_make_start(struct cdb_make *c, php_stream * f TSRMLS_DC) { c->head = 0; c->split = 0; c->hash = 0; c->numentries = 0; c->fp = f; c->pos = sizeof(c->final); if (php_stream_seek(f, c->pos, SEEK_SET) == -1) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Fseek failed"); return -1; } return php_stream_tell(c->fp); } /* }}} */ /* {{{ cdb_make_addend */ PHPAPI int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h TSRMLS_DC) { struct cdb_hplist *head; head = c->head; if (!head || (head->num >= CDB_HPLIST)) { head = (struct cdb_hplist *) emalloc(sizeof(struct cdb_hplist)); if (!head) return -1; head->num = 0; head->next = c->head; c->head = head; } head->hp[head->num].h = h; head->hp[head->num].p = c->pos; ++head->num; ++c->numentries; if (cdb_posplus(c,8) == -1) return -1; if (cdb_posplus(c, keylen) == -1) return -1; if (cdb_posplus(c, datalen) == -1) return -1; return 0; } /* }}} */ /* {{{ cdb_make_addbegin */ PHPAPI int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen TSRMLS_DC) { char buf[8]; if (keylen > 0xffffffff) { errno = ENOMEM; return -1; } if (datalen > 0xffffffff) { errno = ENOMEM; return -1; } uint32_pack(buf, keylen); uint32_pack(buf + 4, datalen); if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) return -1; return 0; } /* {{{ cdb_make_add */ PHPAPI int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen TSRMLS_DC) { if (cdb_make_addbegin(c, keylen, datalen TSRMLS_CC) == -1) return -1; if (cdb_make_write(c, key, keylen TSRMLS_CC) != 0) return -1; if (cdb_make_write(c, data, datalen TSRMLS_CC) != 0) return -1; return cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen) TSRMLS_CC); } /* }}} */ /* {{{ cdb_make_finish */ PHPAPI int cdb_make_finish(struct cdb_make *c TSRMLS_DC) { char buf[8]; int i; uint32 len; uint32 u; uint32 memsize; uint32 count; uint32 where; struct cdb_hplist *x; struct cdb_hp *hp; for (i = 0;i < 256;++i) c->count[i] = 0; for (x = c->head; x; x = x->next) { i = x->num; while (i--) ++c->count[255 & x->hp[i].h]; } memsize = 1; for (i = 0;i < 256;++i) { u = c->count[i] * 2; if (u > memsize) memsize = u; } memsize += c->numentries; /* no overflow possible up to now */ u = (uint32) 0 - (uint32) 1; u /= sizeof(struct cdb_hp); if (memsize > u) { errno = ENOMEM; return -1; } c->split = (struct cdb_hp *) emalloc(memsize * sizeof(struct cdb_hp)); if (!c->split) return -1; c->hash = c->split + c->numentries; u = 0; for (i = 0;i < 256;++i) { u += c->count[i]; /* bounded by numentries, so no overflow */ c->start[i] = u; } for (x = c->head; x; x = x->next) { i = x->num; while (i--) c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; } for (i = 0;i < 256;++i) { count = c->count[i]; len = count + count; /* no overflow possible */ uint32_pack(c->final + 8 * i,c->pos); uint32_pack(c->final + 8 * i + 4,len); for (u = 0;u < len;++u) c->hash[u].h = c->hash[u].p = 0; hp = c->split + c->start[i]; for (u = 0;u < count;++u) { where = (hp->h >> 8) % len; while (c->hash[where].p) if (++where == len) where = 0; c->hash[where] = *hp++; } for (u = 0;u < len;++u) { uint32_pack(buf, c->hash[u].h); uint32_pack(buf + 4, c->hash[u].p); if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) return -1; if (cdb_posplus(c, 8) == -1) return -1; } } if (c->split) efree(c->split); for (x = c->head; x; c->head = x) { x = x->next; efree(c->head); } if (php_stream_flush(c->fp) != 0) return -1; php_stream_rewind(c->fp); if (php_stream_tell(c->fp) != 0) return -1; if (cdb_make_write(c, c->final, sizeof(c->final) TSRMLS_CC) != 0) return -1; return php_stream_flush(c->fp); } /* }}} */ Index: php4/ext/dba/libcdb/cdb_make.h +++ php4/ext/dba/libcdb/cdb_make.h /* +----------------------------------------------------------------------+ | 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: cdb_make.h,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifndef CDB_MAKE_H #define CDB_MAKE_H #include <stdio.h> #include "uint32.h" #define CDB_HPLIST 1000 struct cdb_hp { uint32 h; uint32 p; }; struct cdb_hplist { struct cdb_hp hp[CDB_HPLIST]; struct cdb_hplist *next; int num; } ; struct cdb_make { /* char bspace[8192]; */ char final[2048]; uint32 count[256]; uint32 start[256]; struct cdb_hplist *head; struct cdb_hp *split; /* includes space for hash */ struct cdb_hp *hash; uint32 numentries; /* buffer b; */ uint32 pos; /* int fd; */ php_stream * fp; }; PHPAPI int cdb_make_start(struct cdb_make *, php_stream * TSRMLS_DC); PHPAPI int cdb_make_addbegin(struct cdb_make *, unsigned int, unsigned int TSRMLS_DC); PHPAPI int cdb_make_addend(struct cdb_make *, unsigned int, unsigned int, uint32 TSRMLS_DC); PHPAPI int cdb_make_add(struct cdb_make *, char *, unsigned int, char *, unsigned int TSRMLS_DC); PHPAPI int cdb_make_finish(struct cdb_make * TSRMLS_DC); #endif Index: php4/ext/dba/libcdb/uint32.c +++ php4/ext/dba/libcdb/uint32.c /* +----------------------------------------------------------------------+ | 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: uint32.c,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "uint32.h" /* {{{ uint32_pack */ PHPAPI void uint32_pack(char *out, uint32 in) { out[0] = in&0xff; in>>=8; out[1] = in&0xff; in>>=8; out[2] = in&0xff; in>>=8; out[3] = in&0xff; } /* }}} */ /* {{{ uint32_unpack */ PHPAPI void uint32_unpack(const char *in, uint32 *out) { *out = (((uint32)(unsigned char)in[3])<<24) | (((uint32)(unsigned char)in[2])<<16) | (((uint32)(unsigned char)in[1])<<8) | (((uint32)(unsigned char)in[0])); } /* }}} */ Index: php4/ext/dba/libcdb/uint32.h +++ php4/ext/dba/libcdb/uint32.h /* +----------------------------------------------------------------------+ | 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: uint32.h,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifndef UINT32_H #define UINT32_H #if SIZEOF_INT == 4 /* Most 32-bit and 64-bit systems have 32-bit ints */ typedef unsigned int uint32; #elif SIZEOF_LONG == 4 /* 16-bit systems? */ typedef unsigned long uint32; #else #error Need type which holds 32 bits #endif PHPAPI void uint32_pack(char *out, uint32 in); PHPAPI void uint32_unpack(const char *in, uint32 *out); #endif Index: php4/ext/dba/tests/dba_cdb_make.phpt +++ php4/ext/dba/tests/dba_cdb_make.phpt --TEST-- DBA CDB_MAKE handler test --SKIPIF-- <?php require_once('skipif.inc'); if (!in_array('cdb_make', dba_handlers())) die('skip CDB_MAKE handler not available'); ?> --FILE-- <?php require_once('test.inc'); $handler = 'cdb_make'; echo "database handler: $handler\n"; // print md5 checksum of test.cdb which is generated by cdb_make program var_dump(md5(implode('',file(dirname(__FILE__).'/test.cdb')))); if (($db_make=dba_open($db_file, "n", $handler))!==FALSE) { dba_insert("1", "1", $db_make); dba_insert("2", "2", $db_make); dba_insert("1", "3", $db_make); dba_insert("2", "1", $db_make); dba_insert("3", "3", $db_make); dba_insert("1", "2", $db_make); dba_insert("4", "4", $db_make); // dba_replace cdb_make doesn't know replace dba_close($db_make); // write md5 checksum of generated database file var_dump(md5(implode('',file($db_file)))); // no need to test created database: this is done by dba_cdb_read.phpt } else { echo "Error creating database\n"; } ?> --EXPECT-- database handler: cdb_make string(32) "723d19f39c1b15b3b455dd64323148d1" string(32) "723d19f39c1b15b3b455dd64323148d1"
Index: php4/ext/dba/CREDITS diff -u php4/ext/dba/CREDITS:1.1 php4/ext/dba/CREDITS:1.2 --- php4/ext/dba/CREDITS:1.1 Mon Nov 20 05:31:15 2000 +++ php4/ext/dba/CREDITS Mon Nov 4 12:53:04 2002 @@ -1,2 +1,2 @@ DBA -Sascha Schumann +Sascha Schumann, Marcus Boerger \ No newline at end of file Index: php4/ext/dba/config.m4 diff -u php4/ext/dba/config.m4:1.22 php4/ext/dba/config.m4:1.23 --- php4/ext/dba/config.m4:1.22 Thu Sep 19 00:18:20 2002 +++ php4/ext/dba/config.m4 Mon Nov 4 12:53:04 2002 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.22 2002/09/19 04:18:20 sas Exp $ +dnl $Id: config.m4,v 1.23 2002/11/04 17:53:04 helly Exp $ dnl AC_DEFUN(PHP_TEMP_LDFLAGS,[ @@ -38,9 +38,9 @@ dnl Print the result message AC_DEFUN(AC_DBA_STD_RESULT,[ - if test "$THIS_RESULT" = "yes"; then + if test "$THIS_RESULT" = "yes" -o "$THIS_RESULT" = "builtin"; then HAVE_DBA=1 - AC_MSG_RESULT(yes) + AC_MSG_RESULT($THIS_RESULT) else AC_MSG_RESULT(no) fi @@ -213,12 +213,18 @@ AC_ARG_WITH(cdb, [ --with-cdb[=DIR] Include CDB support],[ - if test "$withval" != "no"; then + if test "$withval" = "yes"; then + PHP_ADD_BUILD_DIR($ext_builddir/libcdb) + AC_DEFINE(DBA_CDB_MAKE, 1, [ ]) + AC_DEFINE(DBA_CDB, 1, [ ]) + cdb_sources="libcdb/cdb.c libcdb/cdb_make.c libcdb/uint32.c" + THIS_RESULT="builtin" + elif 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 + done for LIB in cdb c; do PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[ @@ -238,9 +244,8 @@ 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, $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, $ext_shared) PHP_SUBST(DBA_SHARED_LIBADD) else AC_MSG_RESULT(no) fi - Index: php4/ext/dba/dba.c diff -u php4/ext/dba/dba.c:1.49 php4/ext/dba/dba.c:1.50 --- php4/ext/dba/dba.c:1.49 Mon Nov 4 07:27:12 2002 +++ php4/ext/dba/dba.c Mon Nov 4 12:53:04 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba.c,v 1.49 2002/11/04 12:27:12 helly Exp $ */ +/* $Id: dba.c,v 1.50 2002/11/04 17:53:04 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -143,13 +143,15 @@ /* a DBA handler must have specific routines */ -#define DBA_HND(x) \ +#define DBA_NAMED_HND(name, x) \ {\ - #x, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ + #name, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ dba_exists_##x, dba_delete_##x, dba_firstkey_##x, dba_nextkey_##x, \ dba_optimize_##x, dba_sync_##x \ }, +#define DBA_HND(x) DBA_NAMED_HND(x, 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) { \ @@ -173,6 +175,9 @@ #endif #if DBA_CDB DBA_HND(cdb) +#endif +#if DBA_CDB_BUILTIN + DBA_NAMED_HND(cdb_make, cdb) #endif #if DBA_DB2 DBA_HND(db2) Index: php4/ext/dba/dba_cdb.c diff -u php4/ext/dba/dba_cdb.c:1.17 php4/ext/dba/dba_cdb.c:1.18 --- php4/ext/dba/dba_cdb.c:1.17 Sun Nov 3 11:50:08 2002 +++ php4/ext/dba/dba_cdb.c Mon Nov 4 12:53:04 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_cdb.c,v 1.17 2002/11/03 16:50:08 helly Exp $ */ +/* $Id: dba_cdb.c,v 1.18 2002/11/04 17:53:04 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -32,48 +32,95 @@ #include <unistd.h> #include <fcntl.h> +#if DBA_CDB_BUILTIN +#include "libcdb/cdb.h" +#include "libcdb/cdb_make.h" +#include "libcdb/uint32.h" +#else #include <cdb.h> #include <uint32.h> +#endif #define CDB_INFO \ dba_cdb *cdb = (dba_cdb *) info->dbf typedef struct { struct cdb c; - int fd; +#if DBA_CDB_BUILTIN + struct cdb_make m; + php_stream *file; + int make; +#else + int file; +#endif uint32 eod; /* size of constant database */ uint32 pos; /* current position for traversing */ } dba_cdb; DBA_OPEN_FUNC(cdb) { - int gmode = 0; - int fd; +#if DBA_CDB_BUILTIN + php_stream* file = 0; + int make; +#else + int file = 0; +#endif 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; +#if DBA_CDB_BUILTIN + make = 0; + file = php_stream_open_wrapper(info->path, "rb", STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); + if (!file) { + return FAILURE; + } +#else + file = VCWD_OPEN(info->path, O_RDONLY); + if (file < 0) { + return FAILURE; + } +#endif + break; +#if DBA_CDB_BUILTIN + case DBA_TRUNC: + case DBA_CREAT: + make = 1; + file = php_stream_open_wrapper(info->path, "wb", STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); + if (!file) { + return FAILURE; + } + break; + case DBA_WRITER: + return FAILURE; /* not supported */ #endif default: + /* currently not supported: */ return FAILURE; } - fd = VCWD_OPEN(info->path, gmode); - if (fd < 0) { + cdb = ecalloc(sizeof(dba_cdb), 1); + if (!cdb) { +#if DBA_CDB_BUILTIN + php_stream_close(cdb->file); +#else + close(cdb->file); +#endif return FAILURE; } - - cdb = emalloc(sizeof(dba_cdb)); - memset(cdb, 0, sizeof(dba_cdb)); - cdb_init(&cdb->c, fd); - cdb->fd = fd; +#if DBA_CDB_BUILTIN + if (make) { + cdb_make_start(&cdb->m, file TSRMLS_CC); + } else { + cdb_init(&cdb->c, file TSRMLS_CC); + } + cdb->make = make; +#else + cdb_init(&cdb->c, file); +#endif + cdb->file = file; pinfo->dbf = cdb; return SUCCESS; @@ -83,29 +130,51 @@ { CDB_INFO; - /* cdb_free does not close associated fd */ + /* cdb_free does not close associated file */ +#if DBA_CDB_BUILTIN + if (cdb->make) { + cdb_make_finish(&cdb->m TSRMLS_CC); + } else { + cdb_free(&cdb->c TSRMLS_CC); + } + php_stream_close(cdb->file); +#else cdb_free(&cdb->c); - close(cdb->fd); + close(cdb->file); +#endif efree(cdb); } +#if DBA_CDB_BUILTIN +# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos TSRMLS_CC) +# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len TSRMLS_CC) +# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len TSRMLS_CC) +#else +# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos) +# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len) +# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len) +#endif + DBA_FETCH_FUNC(cdb) { CDB_INFO; unsigned int len; char *new_entry = NULL; -/* cdb_findstart(&cdb->c); */ - if (cdb_find(&cdb->c, key, keylen) == 1) { +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + if (php_cdb_find(&cdb->c, key, keylen) == 1) { while(skip--) { - if (cdb_findnext(&cdb->c, key, keylen) != 1) { + if (php_cdb_findnext(&cdb->c, key, keylen) != 1) { return NULL; } } len = cdb_datalen(&cdb->c); new_entry = emalloc(len+1); - if (cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) { + if (php_cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) { efree(new_entry); return NULL; } @@ -119,7 +188,16 @@ DBA_UPDATE_FUNC(cdb) { - /* if anyone figures out cdbmake.c, let me know */ +#if DBA_CDB_BUILTIN + CDB_INFO; + + if (!cdb->make) + return FAILURE; /* database was opened readonly */ + if (!mode) + return FAILURE; /* cdb_make dosn't know replace */ + if (cdb_make_add(&cdb->m, key, keylen, val, vallen TSRMLS_CC) != -1) + return SUCCESS; +#endif return FAILURE; } @@ -127,24 +205,49 @@ { CDB_INFO; - if (cdb_find(&cdb->c, key, keylen) == 1) +#if DBA_CDB_BUILTIN + if (cdb->make) + return FAILURE; /* database was opened writeonly */ +#endif + if (php_cdb_find(&cdb->c, key, keylen) == 1) return SUCCESS; return FAILURE; } DBA_DELETE_FUNC(cdb) { - return FAILURE; + return FAILURE; /* cdb doesn't support delete */ } +/* {{{ cdb_file_read */ +#if DBA_CDB_BUILTIN +# define cdb_file_read(fildes, buf, size) php_stream_read(fildes, buf, size) +#else +# define cdb_file_read(fildes, buf, size) read(fildes, buf, size) +#endif +/* }}} */ #define CREAD(n) do { \ - if (read(cdb->fd, buf, n) < n) return NULL; \ + if (cdb_file_read(cdb->file, buf, n) < n) return NULL; \ } while (0) +/* {{{ cdb_file_lseek + php_stream_seek does not return actual position */ +#if DBA_CDB_BUILTIN +int cdb_file_lseek(php_stream *fp, off_t offset, int whence TSRMLS_DC) { + php_stream_seek(fp, offset, whence); + return php_stream_tell(fp); +} +#else +int cdb_file_lseek(int fd, off_t offset, int whence TSRMLS_DC) { + return lseek(fd, offset, whence); +} +#endif +/* }}} */ + #define CSEEK(n) do { \ if (n >= cdb->eod) return NULL; \ - if (lseek(cdb->fd, (off_t)n, SEEK_SET) != (off_t) n) return NULL; \ + if (cdb_file_lseek(cdb->file, (off_t)n, SEEK_SET TSRMLS_CC) != (off_t) n) return NULL; \ } while (0) @@ -155,6 +258,11 @@ char buf[8]; char *key; +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + cdb->eod = -1; CSEEK(0); CREAD(4); @@ -170,7 +278,7 @@ uint32_unpack(buf + 4, &dlen); key = emalloc(klen + 1); - if (read(cdb->fd, key, klen) < klen) { + if (cdb_file_read(cdb->file, key, klen) < klen) { efree(key); key = NULL; } else { @@ -191,13 +299,18 @@ char buf[8]; char *key; +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + CSEEK(cdb->pos); CREAD(8); uint32_unpack(buf, &klen); uint32_unpack(buf + 4, &dlen); key = emalloc(klen + 1); - if (read(cdb->fd, key, klen) < klen) { + if (cdb_file_read(cdb->file, key, klen) < klen) { efree(key); key = NULL; } else { Index: php4/ext/dba/install_cdb.sh diff -u php4/ext/dba/install_cdb.sh:1.1 php4/ext/dba/install_cdb.sh:1.2 --- php4/ext/dba/install_cdb.sh:1.1 Thu Sep 19 00:18:20 2002 +++ php4/ext/dba/install_cdb.sh Mon Nov 4 12:53:04 2002 @@ -1,10 +1,14 @@ #! /bin/sh +# You can use this script if you want to use an external cdb lib. If you +# compile php using --with-cdb the internal functions will be used and no +# external library is used so that this script is not necessary. +# # cdb-0.75 lacks support for installing header files and creating a # library which programs can link against. This shell script fills # the gap. # -# $Id: install_cdb.sh,v 1.1 2002/09/19 04:18:20 sas Exp $ +# $Id: install_cdb.sh,v 1.2 2002/11/04 17:53:04 helly Exp $ if test -r "cdb.a" && test -r "auto-str.c" && test -r "byte.a"; then : Index: php4/ext/dba/tests/dba_cdb.phpt diff -u php4/ext/dba/tests/dba_cdb.phpt:1.2 php4/ext/dba/tests/dba_cdb.phpt:1.3 --- php4/ext/dba/tests/dba_cdb.phpt:1.2 Sun Nov 3 10:22:32 2002 +++ php4/ext/dba/tests/dba_cdb.phpt Mon Nov 4 12:53:04 2002 @@ -4,7 +4,7 @@ <?php require_once('skipif.inc'); if (!in_array('cdb', dba_handlers())) die('skip CDB handler not available'); - die('skip CDB currently supports only reading'); + die('skip CDB does not support replace or delete'); ?> --FILE-- <?php Index: php4/ext/dba/tests/dba_cdb_read.phpt diff -u php4/ext/dba/tests/dba_cdb_read.phpt:1.3 php4/ext/dba/tests/dba_cdb_read.phpt:1.4 --- php4/ext/dba/tests/dba_cdb_read.phpt:1.3 Sun Nov 3 11:43:07 2002 +++ php4/ext/dba/tests/dba_cdb_read.phpt Mon Nov 4 12:53:04 2002 @@ -33,8 +33,8 @@ echo "\n#"; echo dba_fetch(1, $db_file); echo dba_fetch(1, $db_file); - echo dba_fetch(1, $db_file); - echo dba_fetch(1, $db_file); + echo dba_fetch(2, $db_file); + echo dba_fetch(2, $db_file); echo "\n?".$keys; // with skip = 0 dba_fetch must fetch the first result echo "\n#"; @@ -59,7 +59,7 @@ database handler: cdb 7YYYYNNN =1234 -#1111 +#1122 ?1212314 #1212314 =1231324 Index: php4/ext/dba/libcdb/.cvsignore +++ php4/ext/dba/libcdb/.cvsignore *.lo *.la deps *.plg *.opt *.ncb Release Release_inline Debug Release_TS Release_TSDbg Release_TS_inline Debug_TS Index: php4/ext/dba/libcdb/cdb.c +++ php4/ext/dba/libcdb/cdb.c /* +----------------------------------------------------------------------+ | 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: cdb.c,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> #include <string.h> #include <errno.h> #include "cdb.h" #ifndef EPROTO # define EPROTO -15 /* cdb 0.75's default for PROTOless systems */ #endif /* {{{ cdb_match */ static int cdb_match(struct cdb *c, char *key, unsigned int len, uint32 pos TSRMLS_DC) { char buf[32]; int n; while (len > 0) { n = sizeof(buf); if (n > len) n = len; if (cdb_read(c, buf, n, pos TSRMLS_CC) == -1) return -1; if (memcmp(buf, key, n)) return 0; pos += n; key += n; len -= n; } return 1; } /* }}} */ /* {{{ cdb_hashadd */ static uint32 cdb_hashadd(uint32 h, unsigned char c) { h += (h << 5); return h ^ c; } /* }}} */ /* {{{ cdb_hash */ PHPAPI uint32 cdb_hash(char *buf, unsigned int len) { uint32 h; h = CDB_HASHSTART; while (len) { h = cdb_hashadd(h, *buf++); --len; } return h; } /* }}} */ /* {{{ cdb_free */ PHPAPI void cdb_free(struct cdb *c TSRMLS_DC) { } /* }}} */ /* {{{ cdb_findstart */ PHPAPI void cdb_findstart(struct cdb *c TSRMLS_DC) { c->loop = 0; } /* }}} */ /* {{{ cdb_init */ PHPAPI void cdb_init(struct cdb *c, php_stream *fp TSRMLS_DC) { cdb_free(c TSRMLS_CC); cdb_findstart(c TSRMLS_CC); c->fp = fp; } /* }}} */ /* {{{ cdb_read */ PHPAPI int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos TSRMLS_DC) { if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) { errno = EPROTO; return -1; } while (len > 0) { int r; do { r = php_stream_read(c->fp, buf, len); } while ((r == -1) && (errno == EINTR)); if (r == -1) return -1; if (r == 0) { errno = EPROTO; return -1; } buf += r; len -= r; } return 0; } /* }}} */ /* {{{ cdb_findnext */ PHPAPI int cdb_findnext(struct cdb *c, char *key, unsigned int len TSRMLS_DC) { char buf[8]; uint32 pos; uint32 u; if (!c->loop) { u = cdb_hash(key, len); if (cdb_read(c, buf, 8, (u << 3) & 2047 TSRMLS_CC) == -1) return -1; uint32_unpack(buf + 4,&c->hslots); if (!c->hslots) return 0; uint32_unpack(buf, &c->hpos); c->khash = u; u >>= 8; u %= c->hslots; u <<= 3; c->kpos = c->hpos + u; } while (c->loop < c->hslots) { if (cdb_read(c, buf, 8, c->kpos TSRMLS_CC) == -1) return -1; uint32_unpack(buf + 4, &pos); if (!pos) return 0; c->loop += 1; c->kpos += 8; if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; uint32_unpack(buf, &u); if (u == c->khash) { if (cdb_read(c, buf, 8, pos TSRMLS_CC) == -1) return -1; uint32_unpack(buf, &u); if (u == len) switch(cdb_match(c, key, len, pos + 8 TSRMLS_CC)) { case -1: return -1; case 1: uint32_unpack(buf + 4, &c->dlen); c->dpos = pos + 8 + len; return 1; } } } return 0; } /* }}} */ /* {{{ cdb_find */ PHPAPI int cdb_find(struct cdb *c, char *key, unsigned int len TSRMLS_DC) { cdb_findstart(c TSRMLS_CC); return cdb_findnext(c, key, len TSRMLS_CC); } /* }}} */ Index: php4/ext/dba/libcdb/cdb.h +++ php4/ext/dba/libcdb/cdb.h /* +----------------------------------------------------------------------+ | 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: cdb.h,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifndef CDB_H #define CDB_H #include "uint32.h" #define CDB_HASHSTART 5381 struct cdb { php_stream *fp; uint32 loop; /* number of hash slots searched under this key */ uint32 khash; /* initialized if loop is nonzero */ uint32 kpos; /* initialized if loop is nonzero */ uint32 hpos; /* initialized if loop is nonzero */ uint32 hslots; /* initialized if loop is nonzero */ uint32 dpos; /* initialized if cdb_findnext() returns 1 */ uint32 dlen; /* initialized if cdb_findnext() returns 1 */ }; PHPAPI uint32 cdb_hash(char *, unsigned int); PHPAPI void cdb_free(struct cdb * TSRMLS_DC); PHPAPI void cdb_init(struct cdb *, php_stream *fp TSRMLS_DC); PHPAPI int cdb_read(struct cdb *, char *, unsigned int, uint32 TSRMLS_DC); PHPAPI void cdb_findstart(struct cdb * TSRMLS_DC); PHPAPI int cdb_findnext(struct cdb *, char *, unsigned int TSRMLS_DC); PHPAPI int cdb_find(struct cdb *, char *, unsigned int TSRMLS_DC); #define cdb_datapos(c) ((c)->dpos) #define cdb_datalen(c) ((c)->dlen) #endif Index: php4/ext/dba/libcdb/cdb_make.c +++ php4/ext/dba/libcdb/cdb_make.c /* +----------------------------------------------------------------------+ | 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: cdb_make.c,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include "cdb.h" #include "cdb_make.h" #include "uint32.h" /* {{{ cdb_make_write */ static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz TSRMLS_DC) { return php_stream_write(c->fp, buf, sz) == sz ? 0 : -1; } /* {{{ cdb_posplus */ static int cdb_posplus(struct cdb_make *c, uint32 len) { uint32 newpos = c->pos + len; if (newpos < len) { errno = ENOMEM; return -1; } c->pos = newpos; return 0; } /* }}} */ /* {{{ cdb_make_start */ PHPAPI int cdb_make_start(struct cdb_make *c, php_stream * f TSRMLS_DC) { c->head = 0; c->split = 0; c->hash = 0; c->numentries = 0; c->fp = f; c->pos = sizeof(c->final); if (php_stream_seek(f, c->pos, SEEK_SET) == -1) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Fseek failed"); return -1; } return php_stream_tell(c->fp); } /* }}} */ /* {{{ cdb_make_addend */ PHPAPI int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h TSRMLS_DC) { struct cdb_hplist *head; head = c->head; if (!head || (head->num >= CDB_HPLIST)) { head = (struct cdb_hplist *) emalloc(sizeof(struct cdb_hplist)); if (!head) return -1; head->num = 0; head->next = c->head; c->head = head; } head->hp[head->num].h = h; head->hp[head->num].p = c->pos; ++head->num; ++c->numentries; if (cdb_posplus(c,8) == -1) return -1; if (cdb_posplus(c, keylen) == -1) return -1; if (cdb_posplus(c, datalen) == -1) return -1; return 0; } /* }}} */ /* {{{ cdb_make_addbegin */ PHPAPI int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen TSRMLS_DC) { char buf[8]; if (keylen > 0xffffffff) { errno = ENOMEM; return -1; } if (datalen > 0xffffffff) { errno = ENOMEM; return -1; } uint32_pack(buf, keylen); uint32_pack(buf + 4, datalen); if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) return -1; return 0; } /* {{{ cdb_make_add */ PHPAPI int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen TSRMLS_DC) { if (cdb_make_addbegin(c, keylen, datalen TSRMLS_CC) == -1) return -1; if (cdb_make_write(c, key, keylen TSRMLS_CC) != 0) return -1; if (cdb_make_write(c, data, datalen TSRMLS_CC) != 0) return -1; return cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen) TSRMLS_CC); } /* }}} */ /* {{{ cdb_make_finish */ PHPAPI int cdb_make_finish(struct cdb_make *c TSRMLS_DC) { char buf[8]; int i; uint32 len; uint32 u; uint32 memsize; uint32 count; uint32 where; struct cdb_hplist *x; struct cdb_hp *hp; for (i = 0;i < 256;++i) c->count[i] = 0; for (x = c->head; x; x = x->next) { i = x->num; while (i--) ++c->count[255 & x->hp[i].h]; } memsize = 1; for (i = 0;i < 256;++i) { u = c->count[i] * 2; if (u > memsize) memsize = u; } memsize += c->numentries; /* no overflow possible up to now */ u = (uint32) 0 - (uint32) 1; u /= sizeof(struct cdb_hp); if (memsize > u) { errno = ENOMEM; return -1; } c->split = (struct cdb_hp *) emalloc(memsize * sizeof(struct cdb_hp)); if (!c->split) return -1; c->hash = c->split + c->numentries; u = 0; for (i = 0;i < 256;++i) { u += c->count[i]; /* bounded by numentries, so no overflow */ c->start[i] = u; } for (x = c->head; x; x = x->next) { i = x->num; while (i--) c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; } for (i = 0;i < 256;++i) { count = c->count[i]; len = count + count; /* no overflow possible */ uint32_pack(c->final + 8 * i,c->pos); uint32_pack(c->final + 8 * i + 4,len); for (u = 0;u < len;++u) c->hash[u].h = c->hash[u].p = 0; hp = c->split + c->start[i]; for (u = 0;u < count;++u) { where = (hp->h >> 8) % len; while (c->hash[where].p) if (++where == len) where = 0; c->hash[where] = *hp++; } for (u = 0;u < len;++u) { uint32_pack(buf, c->hash[u].h); uint32_pack(buf + 4, c->hash[u].p); if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) return -1; if (cdb_posplus(c, 8) == -1) return -1; } } if (c->split) efree(c->split); for (x = c->head; x; c->head = x) { x = x->next; efree(c->head); } if (php_stream_flush(c->fp) != 0) return -1; php_stream_rewind(c->fp); if (php_stream_tell(c->fp) != 0) return -1; if (cdb_make_write(c, c->final, sizeof(c->final) TSRMLS_CC) != 0) return -1; return php_stream_flush(c->fp); } /* }}} */ Index: php4/ext/dba/libcdb/cdb_make.h +++ php4/ext/dba/libcdb/cdb_make.h /* +----------------------------------------------------------------------+ | 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: cdb_make.h,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifndef CDB_MAKE_H #define CDB_MAKE_H #include <stdio.h> #include "uint32.h" #define CDB_HPLIST 1000 struct cdb_hp { uint32 h; uint32 p; }; struct cdb_hplist { struct cdb_hp hp[CDB_HPLIST]; struct cdb_hplist *next; int num; } ; struct cdb_make { /* char bspace[8192]; */ char final[2048]; uint32 count[256]; uint32 start[256]; struct cdb_hplist *head; struct cdb_hp *split; /* includes space for hash */ struct cdb_hp *hash; uint32 numentries; /* buffer b; */ uint32 pos; /* int fd; */ php_stream * fp; }; PHPAPI int cdb_make_start(struct cdb_make *, php_stream * TSRMLS_DC); PHPAPI int cdb_make_addbegin(struct cdb_make *, unsigned int, unsigned int TSRMLS_DC); PHPAPI int cdb_make_addend(struct cdb_make *, unsigned int, unsigned int, uint32 TSRMLS_DC); PHPAPI int cdb_make_add(struct cdb_make *, char *, unsigned int, char *, unsigned int TSRMLS_DC); PHPAPI int cdb_make_finish(struct cdb_make * TSRMLS_DC); #endif Index: php4/ext/dba/libcdb/uint32.c +++ php4/ext/dba/libcdb/uint32.c /* +----------------------------------------------------------------------+ | 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: uint32.c,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "uint32.h" /* {{{ uint32_pack */ PHPAPI void uint32_pack(char *out, uint32 in) { out[0] = in&0xff; in>>=8; out[1] = in&0xff; in>>=8; out[2] = in&0xff; in>>=8; out[3] = in&0xff; } /* }}} */ /* {{{ uint32_unpack */ PHPAPI void uint32_unpack(const char *in, uint32 *out) { *out = (((uint32)(unsigned char)in[3])<<24) | (((uint32)(unsigned char)in[2])<<16) | (((uint32)(unsigned char)in[1])<<8) | (((uint32)(unsigned char)in[0])); } /* }}} */ Index: php4/ext/dba/libcdb/uint32.h +++ php4/ext/dba/libcdb/uint32.h /* +----------------------------------------------------------------------+ | 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: uint32.h,v 1.1 2002/11/04 17:53:04 helly Exp $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ #ifndef UINT32_H #define UINT32_H #if SIZEOF_INT == 4 /* Most 32-bit and 64-bit systems have 32-bit ints */ typedef unsigned int uint32; #elif SIZEOF_LONG == 4 /* 16-bit systems? */ typedef unsigned long uint32; #else #error Need type which holds 32 bits #endif PHPAPI void uint32_pack(char *out, uint32 in); PHPAPI void uint32_unpack(const char *in, uint32 *out); #endif Index: php4/ext/dba/tests/dba_cdb_make.phpt +++ php4/ext/dba/tests/dba_cdb_make.phpt --TEST-- DBA CDB_MAKE handler test --SKIPIF-- <?php require_once('skipif.inc'); if (!in_array('cdb_make', dba_handlers())) die('skip CDB_MAKE handler not available'); ?> --FILE-- <?php require_once('test.inc'); $handler = 'cdb_make'; echo "database handler: $handler\n"; // print md5 checksum of test.cdb which is generated by cdb_make program var_dump(md5(implode('',file(dirname(__FILE__).'/test.cdb')))); if (($db_make=dba_open($db_file, "n", $handler))!==FALSE) { dba_insert("1", "1", $db_make); dba_insert("2", "2", $db_make); dba_insert("1", "3", $db_make); dba_insert("2", "1", $db_make); dba_insert("3", "3", $db_make); dba_insert("1", "2", $db_make); dba_insert("4", "4", $db_make); // dba_replace cdb_make doesn't know replace dba_close($db_make); // write md5 checksum of generated database file var_dump(md5(implode('',file($db_file)))); // no need to test created database: this is done by dba_cdb_read.phpt } else { echo "Error creating database\n"; } ?> --EXPECT-- database handler: cdb_make string(32) "723d19f39c1b15b3b455dd64323148d1" string(32) "723d19f39c1b15b3b455dd64323148d1"