1
0
mirror of https://github.com/php/php-src.git synced 2026-04-20 06:21:12 +02:00
Files
archived-php-src/ext/db/db.c
Zeev Suraski bc415d5a88 * Finalizing the PHP version of SAPI. Support POST and cookies among other things.
* Fully implement ISAPI support - POST and cookies among other things.
* Almost completely rewrote phpinfo().  Allow modules to easily display their
  information in phpinfo() without modifying phpinfo() itself (prototype for
  the module info function was changed, thus the large amount of updated module
  files).
* Initial extended SAPI support for Apache, completely untested.
* CGI now uses SAPI fully as well.
1999-05-09 08:48:05 +00:00

1173 lines
25 KiB
C

/*
+----------------------------------------------------------------------+
| PHP HTML Embedded Scripting Language Version 3.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997,1998 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: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
| Jim Winstead <jimw@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#define IS_EXT_MODULE
#if COMPILE_DL
#ifdef PHP_31
# include "../phpdl.h"
#else
# ifdef THREAD_SAFE
# undef THREAD_SAFE
# endif
# include "dl/phpdl.h"
#endif
#endif
#if 0
#include "php.h"
#include "php_globals.h"
#include "safe_mode.h"
#include "fopen-wrappers.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef PHP_31
#include "os/nt/flock.h"
#else
#if WIN32|WINNT
#include "win32/flock.h"
#else
#include <sys/file.h>
#endif
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if GDBM
#include <gdbm.h>
#define DBM_TYPE GDBM_FILE
#define DBM_MODE_TYPE int
#define DBM_WRITE_MODE GDBM_WRITER
#define DBM_CREATE_MODE GDBM_WRCREAT
#define DBM_NEW_MODE GDBM_NEWDB
#define DBM_DEFAULT_MODE GDBM_READER
#define DBM_OPEN(filename, mode) gdbm_open(filename, 512, mode, 0666, 0)
#define DBM_CLOSE(dbf) gdbm_close(dbf)
#define DBM_STORE(dbf, key, value, mode) gdbm_store(dbf, key, value, mode)
#define DBM_FETCH(dbf, key) gdbm_fetch(dbf, key)
#define DBM_EXISTS(dbf, key) gdbm_exists(dbf, key)
#define DBM_DELETE(dbf, key) gdbm_delete(dbf, key)
#define DBM_FIRSTKEY(dbf) gdbm_firstkey(dbf)
#define DBM_NEXTKEY(dbf, key) gdbm_nextkey(dbf, key)
#define DBM_INSERT GDBM_INSERT
#define DBM_REPLACE GDBM_REPLACE
#endif
#if NDBM && !GDBM
#if BSD2
#define DB_DBM_HSEARCH 1
#include <db.h>
#else
#include <ndbm.h>
#endif
#define DBM_TYPE DBM *
#define DBM_MODE_TYPE int
#define DBM_WRITE_MODE O_RDWR
#define DBM_CREATE_MODE O_RDWR | O_APPEND | O_CREAT
#define DBM_NEW_MODE O_RDWR | O_CREAT | O_TRUNC
#define DBM_DEFAULT_MODE O_RDONLY
#define DBM_OPEN(filename, mode) dbm_open(filename, mode, 0666)
#define DBM_CLOSE(dbf) dbm_close(dbf)
#define DBM_STORE(dbf, key, value, mode) dbm_store(dbf, key, value, mode)
#define DBM_FETCH(dbf, key) dbm_fetch(dbf, key)
#define DBM_EXISTS(dbf, key) _php3_dbm_exists(dbf, key)
#define DBM_DELETE(dbf, key) dbm_delete(dbf, key)
#define DBM_FIRSTKEY(dbf) dbm_firstkey(dbf)
#define DBM_NEXTKEY(dbf, key) dbm_nextkey(dbf)
static int _php3_dbm_exists(DBM *dbf, datum key_datum) {
datum value_datum;
int ret;
value_datum = dbm_fetch(dbf, key_datum);
if (value_datum.dptr)
ret = 1;
else
ret = 0;
return ret;
}
#endif
#if !NDBM && !GDBM
#define DBM_TYPE FILE *
#define DBM_MODE_TYPE char *
#define DBM_WRITE_MODE "r+b"
#define DBM_CREATE_MODE "a+b"
#define DBM_NEW_MODE "w+b"
#define DBM_DEFAULT_MODE "r"
#define DBM_OPEN(filename, mode) fopen(filename, mode)
#define DBM_CLOSE(dbf) fclose(dbf)
#define DBM_STORE(dbf, key, value, mode) flatfile_store(dbf, key, value, mode)
#define DBM_FETCH(dbf, key) flatfile_fetch(dbf, key)
#define DBM_EXISTS(dbf, key) flatfile_findkey(dbf, key)
#define DBM_DELETE(dbf, key) flatfile_delete(dbf, key)
#define DBM_FIRSTKEY(dbf) flatfile_firstkey(dbf)
#define DBM_NEXTKEY(dbf, key) flatfile_nextkey(dbf)
#define DBM_INSERT 0
#define DBM_REPLACE 1
typedef struct {
char *dptr;
int dsize;
} datum;
int flatfile_store(FILE *dbf, datum key, datum value, int mode);
datum flatfile_fetch(FILE *dbf, datum key);
int flatfile_findkey(FILE *dbf, datum key);
int flatfile_delete(FILE *dbf, datum key);
datum flatfile_firstkey(FILE *dbf);
datum flatfile_nextkey(FILE *dbf);
#endif
#include "php3_db.h"
#include "ext/standard/php3_string.h"
#if THREAD_SAFE
DWORD DbmTls;
static int numthreads=0;
typedef struct dbm_global_struct{
int le_db;
}dbm_global_struct;
#define DBM_GLOBAL(a) dbm_globals->a
#define DBM_TLS_VARS dbm_global_struct *dbm_globals = TlsGetValue(DbmTls);
#else
static int le_db;
#define DBM_GLOBAL(a) a
#define DBM_TLS_VARS
#endif
/*needed for blocking calls in windows*/
void *dbm_mutex;
dbm_info *_php3_finddbm(pval *id,HashTable *list)
{
list_entry *le;
dbm_info *info;
int numitems, i;
int info_type;
DBM_TLS_VARS;
if (id->type == IS_STRING) {
numitems = _php3_hash_num_elements(list);
for (i=1; i<=numitems; i++) {
if (_php3_hash_index_find(list, i, (void **) &le)==FAILURE) {
continue;
}
if (le->type == DBM_GLOBAL(le_db)) {
info = (dbm_info *)(le->ptr);
if (!strcmp(info->filename, id->value.str.val)) {
return (dbm_info *)(le->ptr);
}
}
}
}
/* didn't find it as a database filename, try as a number */
convert_to_long(id);
info = php3_list_find(id->value.lval, &info_type);
if (info_type != DBM_GLOBAL(le_db))
return NULL;
return info;
}
static char *php3_get_info_db(void)
{
static char temp1[128];
static char temp[256];
temp1[0]='\0';
temp[0]='\0';
#ifdef DB_VERSION_STRING /* using sleepycat dbm */
strcat(temp,DB_VERSION_STRING);
#endif
#if GDBM
sprintf(temp1,"%s",gdbm_version);
strcat(temp,temp1);
#endif
#if NDBM && !GDBM
strcat(temp,"ndbm support enabled");
#endif
#if !GDBM && !NDBM
strcat(temp,"flat file support enabled");
#endif
#if NFS_HACK
strcat(temp,"NFS hack in effect");
#endif
if (!*temp)
strcat(temp,"No database support");
return temp;
}
void php3_info_db(ZEND_MODULE_INFO_FUNC_ARGS)
{
php3_printf(php3_get_info_db());
}
void php3_dblist(INTERNAL_FUNCTION_PARAMETERS)
{
char *str = php3_get_info_db();
RETURN_STRING(str,1);
}
void php3_dbmopen(INTERNAL_FUNCTION_PARAMETERS) {
pval *filename, *mode;
dbm_info *info=NULL;
int ret;
DBM_TLS_VARS;
if (ARG_COUNT(ht)!=2 || getParameters(ht,2,&filename,&mode)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(filename);
convert_to_string(mode);
info = _php3_dbmopen(filename->value.str.val, mode->value.str.val);
if (info) {
ret = php3_list_insert(info, DBM_GLOBAL(le_db));
RETURN_LONG(ret);
} else {
RETURN_FALSE;
}
}
dbm_info *_php3_dbmopen(char *filename, char *mode) {
dbm_info *info;
int ret, lock=0;
char *lockfn = NULL;
int lockfd = 0;
#if NFS_HACK
int last_try = 0;
struct stat sb;
int retries = 0;
#endif
DBM_TYPE dbf=NULL;
DBM_MODE_TYPE imode;
if (filename == NULL) {
php3_error(E_WARNING, "NULL filename passed to _php3_dbmopen()");
return NULL;
}
if (PG(safe_mode) && (!_php3_checkuid(filename, 2))) {
return NULL;
}
if (_php3_check_open_basedir(filename)) {
return NULL;
}
switch (*mode) {
case 'w':
imode = DBM_WRITE_MODE;
lock = 1;
break;
case 'c':
imode = DBM_CREATE_MODE;
lock = 1;
break;
case 'n':
imode = DBM_NEW_MODE;
lock = 1;
break;
default:
imode = DBM_DEFAULT_MODE;
lock = 0;
break;
}
if (lock) {
lockfn = emalloc(strlen(filename) + 5);
strcpy(lockfn, filename);
strcat(lockfn, ".lck");
#if NFS_HACK
while((last_try = stat(lockfn,&sb))==0) {
retries++;
sleep(1);
if (retries>30) break;
}
if (last_try!=0) {
lockfd = open(lockfn,O_RDWR|O_CREAT,0644);
close(lockfd);
} else {
php3_error(E_WARNING, "File appears to be locked [%s]\n",lockfn);
return -1;
}
#else /* NFS_HACK */
lockfd = open(lockfn,O_RDWR|O_CREAT,0644);
if (lockfd) {
flock(lockfd,LOCK_EX);
close(lockfd);
} else {
php3_error(E_WARNING, "Unable to establish lock: %s",filename);
}
#endif /* else NFS_HACK */
}
dbf = DBM_OPEN(filename, imode);
#if !NDBM && !GDBM
if (dbf) {
setvbuf(dbf, NULL, _IONBF, 0);
}
#endif
if (dbf) {
info = (dbm_info *)emalloc(sizeof(dbm_info));
if (!info) {
php3_error(E_ERROR, "problem allocating memory!");
return NULL;
}
info->filename = estrdup(filename);
info->lockfn = lockfn;
info->lockfd = lockfd;
info->dbf = dbf;
return info;
} else {
#if GDBM
php3_error(E_WARNING, "dbmopen_gdbm(%s): %d [%s], %d [%s]",filename,gdbm_errno,gdbm_strerror(gdbm_errno),errno,strerror(errno));
if (gdbm_errno)
ret = gdbm_errno;
else if (errno)
ret = errno;
else
ret = -1;
#else
#if NDBM
#if DEBUG
php3_error(E_WARNING, "dbmopen_ndbm(%s): errno = %d [%s]\n",filename,errno,strerror(errno));
#endif
if (errno) ret=errno;
else ret = -1;
#else
#if DEBUG
php3_error(E_WARNING, "dbmopen_flatfile(%s): errno = %d [%s]\n",filename,errno,strerror(errno));
#endif
if (errno) ret=errno;
else ret = -1;
#endif
#endif
#if NFS_HACK
if (lockfn) {
unlink(lockfn);
}
#endif
if (lockfn) efree(lockfn);
}
return NULL;
}
void php3_dbmclose(INTERNAL_FUNCTION_PARAMETERS) {
pval *id;
if (ARG_COUNT(ht) != 1 || getParameters(ht,1,&id)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(id);
if (php3_list_delete(id->value.lval) == SUCCESS) {
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}
int _php3_dbmclose(dbm_info *info) {
int ret = 0;
DBM_TYPE dbf;
int lockfd;
dbf = info->dbf;
#if NFS_HACK
unlink(info->lockfn);
#else
if (info->lockfn) {
lockfd = open(info->lockfn,O_RDWR,0644);
flock(lockfd,LOCK_UN);
close(lockfd);
}
#endif
if (dbf)
DBM_CLOSE(dbf);
/* free the memory used by the dbm_info struct */
if (info->filename) efree(info->filename);
if (info->lockfn) efree(info->lockfn);
efree(info);
return(ret);
}
/*
* ret = -1 means that database was opened for read-only
* ret = 0 success
* ret = 1 key already exists - nothing done
*/
void php3_dbminsert(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id, *key, *value;
dbm_info *info;
int ret;
if (ARG_COUNT(ht)!=3||getParameters(ht,3,&id,&key,&value) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(key);
convert_to_string(value);
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
ret = _php3_dbminsert(info, key->value.str.val, value->value.str.val);
RETURN_LONG(ret);
}
int _php3_dbminsert(dbm_info *info, char *key, char *value) {
datum key_datum, value_datum;
int ret;
DBM_TYPE dbf;
_php3_stripslashes(key,NULL);
_php3_stripslashes(value,NULL);
value_datum.dptr = estrdup(value);
value_datum.dsize = strlen(value);
key_datum.dptr = estrdup(key);
key_datum.dsize = strlen(key);
#if GDBM_FIX
key_datum.dsize++;
#endif
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return 1;
}
ret = DBM_STORE(dbf, key_datum, value_datum, DBM_INSERT);
/* free the memory */
efree(key_datum.dptr); efree(value_datum.dptr);
return(ret);
}
void php3_dbmreplace(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id, *key, *value;
dbm_info *info;
int ret;
if (ARG_COUNT(ht)!=3||getParameters(ht,3,&id,&key,&value) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(key);
convert_to_string(value);
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
ret = _php3_dbmreplace(info, key->value.str.val, value->value.str.val);
RETURN_LONG(ret);
}
int _php3_dbmreplace(dbm_info *info, char *key, char *value) {
DBM_TYPE dbf;
int ret;
datum key_datum, value_datum;
PLS_FETCH();
if (PG(magic_quotes_runtime)) {
_php3_stripslashes(key,NULL);
_php3_stripslashes(value,NULL);
}
value_datum.dptr = estrdup(value);
value_datum.dsize = strlen(value);
key_datum.dptr = estrdup(key);
key_datum.dsize = strlen(key);
#if GDBM_FIX
key_datum.dsize++;
#endif
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return 1;
}
ret = DBM_STORE(dbf, key_datum, value_datum, DBM_REPLACE);
/* free the memory */
efree(key_datum.dptr); efree(value_datum.dptr);
return(ret);
}
void php3_dbmfetch(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id, *key;
dbm_info *info;
if (ARG_COUNT(ht)!=2||getParameters(ht,2,&id,&key)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(key);
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
return_value->value.str.val = _php3_dbmfetch(info, key->value.str.val);
if (return_value->value.str.val) {
return_value->value.str.len = strlen(return_value->value.str.val);
return_value->type = IS_STRING;
} else {
RETURN_FALSE;
}
}
char *_php3_dbmfetch(dbm_info *info, char *key) {
datum key_datum, value_datum;
char *ret;
DBM_TYPE dbf;
PLS_FETCH();
key_datum.dptr = key;
key_datum.dsize = strlen(key);
#if GDBM_FIX
key_datum.dsize++;
#endif
value_datum.dptr = NULL;
value_datum.dsize = 0;
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return(NULL);
}
value_datum = DBM_FETCH(dbf, key_datum);
if (value_datum.dptr) {
ret = (char *)emalloc(sizeof(char) * value_datum.dsize + 1);
strncpy(ret, value_datum.dptr, value_datum.dsize);
ret[value_datum.dsize] = '\0';
#if GDBM
/* all but NDBM use malloc to allocate the content blocks, so we need to free it */
free(value_datum.dptr);
#else
# if !NDBM
efree(value_datum.dptr);
# endif
#endif
}
else
ret = NULL;
if (ret && PG(magic_quotes_runtime)) {
ret = _php3_addslashes(ret, value_datum.dsize, NULL, 1);
}
return(ret);
}
void php3_dbmexists(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id, *key;
dbm_info *info;
int ret;
if (ARG_COUNT(ht)!=2||getParameters(ht,2,&id,&key)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(key);
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
ret = _php3_dbmexists(info, key->value.str.val);
RETURN_LONG(ret);
}
int _php3_dbmexists(dbm_info *info, char *key) {
datum key_datum;
int ret;
DBM_TYPE dbf;
key_datum.dptr = key;
key_datum.dsize = strlen(key);
#if GDBM_FIX
key_datum.dsize++;
#endif
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return(0);
}
ret = DBM_EXISTS(dbf, key_datum);
return(ret);
}
void php3_dbmdelete(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id, *key;
dbm_info *info;
int ret;
if (ARG_COUNT(ht)!=2||getParameters(ht,2,&id,&key)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(key);
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
ret = _php3_dbmdelete(info, key->value.str.val);
RETURN_LONG(ret);
}
int _php3_dbmdelete(dbm_info *info, char *key) {
datum key_datum;
int ret;
DBM_TYPE dbf;
key_datum.dptr = key;
key_datum.dsize = strlen(key);
#if GDBM_FIX
key_datum.dsize++;
#endif
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return(0);
}
ret = DBM_DELETE(dbf, key_datum);
return(ret);
}
void php3_dbmfirstkey(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id;
dbm_info *info;
char *ret;
if (ARG_COUNT(ht)!=1||getParameters(ht,1,&id)==FAILURE) {
WRONG_PARAM_COUNT;
}
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
ret = _php3_dbmfirstkey(info);
if (!ret) {
RETURN_FALSE;
} else {
return_value->value.str.val = ret;
return_value->value.str.len = strlen(ret);
return_value->type = IS_STRING;
}
}
char *_php3_dbmfirstkey(dbm_info *info) {
datum ret_datum;
char *ret;
DBM_TYPE dbf;
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return(NULL);
}
/* explicitly zero-out ret_datum */
ret_datum.dptr = NULL;
ret_datum.dsize = 0;
ret_datum = DBM_FIRSTKEY(dbf);
if (!ret_datum.dptr)
return NULL;
ret = (char *)emalloc((ret_datum.dsize + 1) * sizeof(char));
strncpy(ret, ret_datum.dptr, ret_datum.dsize);
ret[ret_datum.dsize] = '\0';
#if !NDBM & !GDBM
efree(ret_datum.dptr);
#endif
return (ret);
}
void php3_dbmnextkey(INTERNAL_FUNCTION_PARAMETERS)
{
pval *id, *key;
dbm_info *info;
char *ret;
if (ARG_COUNT(ht)!=2||getParameters(ht,2,&id,&key)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string(key);
info = _php3_finddbm(id,list);
if (!info) {
php3_error(E_WARNING, "not a valid database identifier %d", id->value.lval);
RETURN_FALSE;
}
ret = _php3_dbmnextkey(info, key->value.str.val);
if (!ret) {
RETURN_FALSE;
} else {
return_value->value.str.val = ret;
return_value->value.str.len = strlen(ret);
return_value->type = IS_STRING;
}
}
char *_php3_dbmnextkey(dbm_info *info, char *key) {
datum key_datum, ret_datum;
char *ret;
DBM_TYPE dbf;
PLS_FETCH();
key_datum.dptr = key;
key_datum.dsize = strlen(key);
#if GDBM_FIX
key_datum.dsize++;
#endif
dbf = info->dbf;
if (!dbf) {
php3_error(E_WARNING, "Unable to locate dbm file");
return(NULL);
}
/* explicitly zero-out ret_datum */
ret_datum.dptr = NULL;
ret_datum.dsize = 0;
ret_datum = DBM_NEXTKEY(dbf, key_datum);
if (ret_datum.dptr) {
ret = (char *)emalloc(sizeof(char) * ret_datum.dsize + 1);
strncpy(ret, ret_datum.dptr, ret_datum.dsize);
ret[ret_datum.dsize] = '\0';
#if GDBM
/* GDBM uses malloc to allocate the value_datum block, so we need to free it */
free(ret_datum.dptr);
#else
# if !NDBM
efree(ret_datum.dptr);
# endif
#endif
}
else ret=NULL;
if (ret && PG(magic_quotes_runtime)) {
ret = _php3_addslashes(ret, ret_datum.dsize, NULL, 1);
}
return(ret);
}
#if !GDBM && !NDBM
static long CurrentFlatFilePos = 0L;
int flatfile_store(FILE *dbf, datum key_datum, datum value_datum, int mode) {
int ret;
if (mode == DBM_INSERT) {
if (flatfile_findkey(dbf, key_datum)) {
return 1;
}
fseek(dbf,0L,SEEK_END);
fprintf(dbf,"%d\n",key_datum.dsize);
fflush(dbf);
ret = write(fileno(dbf),key_datum.dptr,key_datum.dsize);
fprintf(dbf,"%d\n",value_datum.dsize);
fflush(dbf);
ret = write(fileno(dbf),value_datum.dptr,value_datum.dsize);
} else { /* DBM_REPLACE */
flatfile_delete(dbf,key_datum);
fprintf(dbf,"%d\n",key_datum.dsize);
fflush(dbf);
ret = write(fileno(dbf),key_datum.dptr,key_datum.dsize);
fprintf(dbf,"%d\n",value_datum.dsize);
ret = write(fileno(dbf),value_datum.dptr,value_datum.dsize);
}
if (ret>0)
ret=0;
return ret;
}
datum flatfile_fetch(FILE *dbf, datum key_datum) {
datum value_datum = {NULL, 0};
int num=0, buf_size=1024;
char *buf;
if (flatfile_findkey(dbf,key_datum)) {
buf = emalloc((buf_size+1) * sizeof(char));
if (fgets(buf, 15, dbf)) {
num = atoi(buf);
if (num > buf_size) {
buf_size+=num;
buf = emalloc((buf_size+1)*sizeof(char));
}
read(fileno(dbf),buf,num);
value_datum.dptr = buf;
value_datum.dsize = num;
}
}
return value_datum;
}
int flatfile_delete(FILE *dbf, datum key_datum) {
char *key = key_datum.dptr;
int size = key_datum.dsize;
char *buf;
int num, buf_size = 1024;
long pos;
rewind(dbf);
buf = emalloc((buf_size + 1)*sizeof(char));
while(!feof(dbf)) {
/* read in the length of the key name */
if (!fgets(buf, 15, dbf))
break;
num = atoi(buf);
if (num > buf_size) {
buf_size += num;
if (buf) efree(buf);
buf = emalloc((buf_size+1)*sizeof(char));
}
pos = ftell(dbf);
/* read in the key name */
num = fread(buf, sizeof(char), num, dbf);
if (num<0) break;
*(buf+num) = '\0';
if (size == num && !memcmp(buf, key, size)) {
fseek(dbf, pos, SEEK_SET);
fputc(0, dbf);
fflush(dbf);
fseek(dbf, 0L, SEEK_END);
if (buf) efree(buf);
return SUCCESS;
}
/* read in the length of the value */
if (!fgets(buf,15,dbf))
break;
num = atoi(buf);
if (num > buf_size) {
buf_size+=num;
if (buf) efree(buf);
buf = emalloc((buf_size+1)*sizeof(char));
}
/* read in the value */
num = fread(buf, sizeof(char), num, dbf);
if (num<0)
break;
}
if (buf) efree(buf);
return FAILURE;
}
int flatfile_findkey(FILE *dbf, datum key_datum) {
char *buf = NULL;
int num;
int buf_size=1024;
int ret=0;
void *key = key_datum.dptr;
int size = key_datum.dsize;
rewind(dbf);
buf = emalloc((buf_size+1)*sizeof(char));
while (!feof(dbf)) {
if (!fgets(buf,15,dbf)) break;
num = atoi(buf);
if (num > buf_size) {
if (buf) efree(buf);
buf_size+=num;
buf = emalloc((buf_size+1)*sizeof(char));
}
num = fread(buf, sizeof(char), num, dbf);
if (num<0) break;
*(buf+num) = '\0';
if (size == num) {
if (!memcmp(buf,key,size)) {
ret = 1;
break;
}
}
if (!fgets(buf,15,dbf))
break;
num = atoi(buf);
if (num > buf_size) {
if (buf) efree(buf);
buf_size+=num;
buf = emalloc((buf_size+1)*sizeof(char));
}
num = fread(buf, sizeof(char), num, dbf);
if (num<0) break;
*(buf+num) = '\0';
}
if (buf) efree(buf);
return(ret);
}
datum flatfile_firstkey(FILE *dbf) {
datum buf;
int num;
int buf_size=1024;
rewind(dbf);
buf.dptr = emalloc((buf_size+1)*sizeof(char));
while(!feof(dbf)) {
if (!fgets(buf.dptr,15,dbf)) break;
num = atoi(buf.dptr);
if (num > buf_size) {
buf_size+=num;
if (buf.dptr) efree(buf.dptr);
buf.dptr = emalloc((buf_size+1)*sizeof(char));
}
num=read(fileno(dbf),buf.dptr,num);
if (num<0) break;
buf.dsize = num;
if (*(buf.dptr)!=0) {
CurrentFlatFilePos = ftell(dbf);
return(buf);
}
if (!fgets(buf.dptr,15,dbf)) break;
num = atoi(buf.dptr);
if (num > buf_size) {
buf_size+=num;
if (buf.dptr) efree(buf.dptr);
buf.dptr = emalloc((buf_size+1)*sizeof(char));
}
num=read(fileno(dbf),buf.dptr,num);
if (num<0) break;
}
if (buf.dptr) efree(buf.dptr);
buf.dptr = NULL;
return(buf);
}
datum flatfile_nextkey(FILE *dbf) {
datum buf;
int num;
int buf_size=1024;
fseek(dbf,CurrentFlatFilePos,SEEK_SET);
buf.dptr = emalloc((buf_size+1)*sizeof(char));
while(!feof(dbf)) {
if (!fgets(buf.dptr,15,dbf)) break;
num = atoi(buf.dptr);
if (num > buf_size) {
buf_size+=num;
if (buf.dptr) efree(buf.dptr);
buf.dptr = emalloc((buf_size+1)*sizeof(char));
}
num=read(fileno(dbf),buf.dptr,num);
if (num<0) break;
if (!fgets(buf.dptr,15,dbf)) break;
num = atoi(buf.dptr);
if (num > buf_size) {
buf_size+=num;
if (buf.dptr) efree(buf.dptr);
buf.dptr = emalloc((buf_size+1)*sizeof(char));
}
num=read(fileno(dbf),buf.dptr,num);
if (num<0) break;
buf.dsize = num;
if (*(buf.dptr)!=0) {
CurrentFlatFilePos = ftell(dbf);
return(buf);
}
}
if (buf.dptr) efree(buf.dptr);
buf.dptr = NULL;
return(buf);
}
#endif
int php3_minit_db(INIT_FUNC_ARGS)
{
#if defined(THREAD_SAFE)
dbm_global_struct *dbm_globals;
PHP3_MUTEX_ALLOC(dbm_mutex);
PHP3_MUTEX_LOCK(dbm_mutex);
numthreads++;
if (numthreads==1){
if (!PHP3_TLS_PROC_STARTUP(DbmTls)){
PHP3_MUTEX_UNLOCK(dbm_mutex);
PHP3_MUTEX_FREE(dbm_mutex);
return FAILURE;
}
}
PHP3_MUTEX_UNLOCK(dbm_mutex);
if(!PHP3_TLS_THREAD_INIT(DbmTls,dbm_globals,dbm_global_struct)){
PHP3_MUTEX_FREE(dbm_mutex);
return FAILURE;
}
#endif
DBM_GLOBAL(le_db) = register_list_destructors(_php3_dbmclose,NULL);
return SUCCESS;
}
static int php3_mend_db(void){
DBM_TLS_VARS;
#ifdef THREAD_SAFE
PHP3_TLS_THREAD_FREE(dbm_globals);
PHP3_MUTEX_LOCK(dbm_mutex);
numthreads--;
if (numthreads<1) {
PHP3_TLS_PROC_SHUTDOWN(DbmTls);
PHP3_MUTEX_UNLOCK(dbm_mutex);
PHP3_MUTEX_FREE(dbm_mutex);
return SUCCESS;
}
PHP3_MUTEX_UNLOCK(dbm_mutex);
#endif
return SUCCESS;
}
int php3_rinit_db(INIT_FUNC_ARGS) {
#if !GDBM && !NDBM
CurrentFlatFilePos = 0L;
#endif
return SUCCESS;
}
function_entry dbm_functions[] = {
{"dblist", php3_dblist, NULL},
{"dbmopen", php3_dbmopen, NULL},
{"dbmclose", php3_dbmclose, NULL},
{"dbminsert", php3_dbminsert, NULL},
{"dbmfetch", php3_dbmfetch, NULL},
{"dbmreplace", php3_dbmreplace, NULL},
{"dbmexists", php3_dbmexists, NULL},
{"dbmdelete", php3_dbmdelete, NULL},
{"dbmfirstkey", php3_dbmfirstkey, NULL},
{"dbmnextkey", php3_dbmnextkey, NULL},
{NULL,NULL,NULL}
};
php3_module_entry dbm_module_entry = {
"DBM", dbm_functions, php3_minit_db, php3_mend_db, php3_rinit_db, NULL, php3_info_db, STANDARD_MODULE_PROPERTIES
};
#if COMPILE_DL
DLEXPORT php3_module_entry *get_module(void) { return &dbm_module_entry; }
#endif
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/