123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.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: Sascha Schumann <sascha@schumann.cx> |
- | Marcus Boerger <helly@php.net> |
- +----------------------------------------------------------------------+
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "php.h"
- #if DBA_CDB
- #include "php_cdb.h"
- #include <sys/types.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <fcntl.h>
- #if DBA_CDB_BUILTIN
- # include "libcdb/cdb.h"
- # include "libcdb/cdb_make.h"
- # include "libcdb/uint32.h"
- #else
- # ifdef CDB_INCLUDE_FILE
- # include CDB_INCLUDE_FILE
- # endif
- #endif
- #define CDB_INFO \
- dba_cdb *cdb = (dba_cdb *) info->dbf
- typedef struct {
- struct cdb c;
- #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)
- {
- #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:
- #if DBA_CDB_BUILTIN
- make = 0;
- file = info->fp;
- #else
- file = VCWD_OPEN(info->path, O_RDONLY);
- if (file < 0) {
- *error = "Unable to open file";
- return FAILURE;
- }
- #endif
- break;
- #if DBA_CDB_BUILTIN
- case DBA_TRUNC:
- make = 1;
- file = info->fp;
- break;
- case DBA_CREAT:
- case DBA_WRITER:
- *error = "Update operations are not supported";
- return FAILURE; /* not supported */
- #endif
- default:
- *error = "Currently not supported";
- return FAILURE;
- }
- cdb = pemalloc(sizeof(dba_cdb), info->flags&DBA_PERSISTENT);
- memset(cdb, 0, sizeof(dba_cdb));
- #if DBA_CDB_BUILTIN
- if (make) {
- cdb_make_start(&cdb->m, file);
- } else {
- cdb_init(&cdb->c, file);
- }
- cdb->make = make;
- #else
- cdb_init(&cdb->c, file);
- #endif
- cdb->file = file;
- pinfo->dbf = cdb;
- return SUCCESS;
- }
- DBA_CLOSE_FUNC(cdb)
- {
- CDB_INFO;
- /* cdb_free does not close associated file */
- #if DBA_CDB_BUILTIN
- if (cdb->make) {
- cdb_make_finish(&cdb->m);
- } else {
- cdb_free(&cdb->c);
- }
- #else
- cdb_free(&cdb->c);
- close(cdb->file);
- #endif
- pefree(cdb, info->flags&DBA_PERSISTENT);
- }
- #if DBA_CDB_BUILTIN
- # 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)
- #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;
- #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 (php_cdb_findnext(&cdb->c, key, keylen) != 1) {
- return NULL;
- }
- }
- len = cdb_datalen(&cdb->c);
- new_entry = safe_emalloc(len, 1, 1);
- if (php_cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) {
- efree(new_entry);
- return NULL;
- }
- new_entry[len] = 0;
- if (newlen)
- *newlen = len;
- }
- return new_entry;
- }
- DBA_UPDATE_FUNC(cdb)
- {
- #if DBA_CDB_BUILTIN
- CDB_INFO;
- if (!cdb->make)
- return FAILURE; /* database was opened readonly */
- if (!mode)
- return FAILURE; /* cdb_make doesn't know replace */
- if (cdb_make_add(&cdb->m, key, keylen, val, vallen) != -1)
- return SUCCESS;
- #endif
- return FAILURE;
- }
- DBA_EXISTS_FUNC(cdb)
- {
- CDB_INFO;
- #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; /* 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 (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
- zend_off_t cdb_file_lseek(php_stream *fp, zend_off_t offset, int whence) {
- php_stream_seek(fp, offset, whence);
- return php_stream_tell(fp);
- }
- #else
- zend_off_t cdb_file_lseek(int fd, zend_off_t offset, int whence) {
- return lseek(fd, offset, whence);
- }
- #endif
- /* }}} */
- #define CSEEK(n) do { \
- if (n >= cdb->eod) return NULL; \
- if (cdb_file_lseek(cdb->file, (zend_off_t)n, SEEK_SET) != (zend_off_t) n) return NULL; \
- } while (0)
- DBA_FIRSTKEY_FUNC(cdb)
- {
- CDB_INFO;
- uint32 klen, dlen;
- 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);
- /* Total length of file in bytes */
- uint32_unpack(buf, &cdb->eod);
- CSEEK(2048);
- CREAD(8);
- /* The first four bytes contain the length of the key */
- uint32_unpack(buf, &klen);
- uint32_unpack(buf + 4, &dlen);
- key = safe_emalloc(klen, 1, 1);
- if (cdb_file_read(cdb->file, key, klen) < klen) {
- efree(key);
- key = NULL;
- } else {
- key[klen] = '\0';
- if (newlen) *newlen = klen;
- }
- /* header + klenlen + dlenlen + klen + dlen */
- cdb->pos = 2048 + 4 + 4 + klen + dlen;
- return key;
- }
- DBA_NEXTKEY_FUNC(cdb)
- {
- CDB_INFO;
- uint32 klen, dlen;
- 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 = safe_emalloc(klen, 1, 1);
- if (cdb_file_read(cdb->file, key, klen) < klen) {
- efree(key);
- key = NULL;
- } else {
- key[klen] = '\0';
- if (newlen) *newlen = klen;
- }
- cdb->pos += 8 + klen + dlen;
- return key;
- }
- DBA_OPTIMIZE_FUNC(cdb)
- {
- return SUCCESS;
- }
- DBA_SYNC_FUNC(cdb)
- {
- /* this is read-only */
- return SUCCESS;
- }
- DBA_INFO_FUNC(cdb)
- {
- #if DBA_CDB_BUILTIN
- if (!strcmp(hnd->name, "cdb")) {
- return estrdup(cdb_version());
- } else {
- return estrdup(cdb_make_version());
- }
- #else
- return estrdup("External");
- #endif
- }
- #endif
|