mirror of
https://github.com/php/php-src.git
synced 2026-04-20 06:21:12 +02:00
* 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.
1173 lines
25 KiB
C
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:
|
|
*/
|