1999-07-21 15:12:32 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 15:32:16 +00:00
| PHP Version 4 |
1999-07-21 15:12:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 15:32:16 +00:00
| Copyright ( c ) 1997 - 2002 The PHP Group |
1999-07-21 15:12:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-06-06 13:06:12 +00:00
| 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 . |
1999-07-21 15:12:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2002-11-11 12:04:12 +00:00
| Authors : Sascha Schumann < sascha @ schumann . cx > |
| Marcus Boerger < helly @ php . net > |
1999-07-21 15:12:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
2001-05-24 10:07:29 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
1999-07-21 15:12:32 +00:00
# include "php.h"
# if HAVE_DBA
2002-11-08 01:03:53 +00:00
# include "ext/standard/flock_compat.h"
# include <stdio.h>
# include <fcntl.h>
# ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
# endif
1999-12-04 19:19:57 +00:00
# include "php_dba.h"
2000-04-05 22:30:19 +00:00
# include "ext/standard/info.h"
2002-11-14 21:09:41 +00:00
# include "ext/standard/php_string.h"
1999-07-21 15:12:32 +00:00
1999-12-04 19:19:57 +00:00
# include "php_gdbm.h"
# include "php_ndbm.h"
# include "php_dbm.h"
# include "php_cdb.h"
# include "php_db2.h"
# include "php_db3.h"
2002-11-06 09:17:51 +00:00
# include "php_flatfile.h"
1999-07-21 15:12:32 +00:00
2001-06-05 13:12:10 +00:00
/* {{{ dba_functions[]
*/
1999-07-21 15:12:32 +00:00
function_entry dba_functions [ ] = {
PHP_FE ( dba_open , NULL )
PHP_FE ( dba_popen , NULL )
PHP_FE ( dba_close , NULL )
PHP_FE ( dba_delete , NULL )
PHP_FE ( dba_exists , NULL )
PHP_FE ( dba_fetch , NULL )
PHP_FE ( dba_insert , NULL )
PHP_FE ( dba_replace , NULL )
PHP_FE ( dba_firstkey , NULL )
PHP_FE ( dba_nextkey , NULL )
PHP_FE ( dba_optimize , NULL )
PHP_FE ( dba_sync , NULL )
2002-10-24 20:43:03 +00:00
PHP_FE ( dba_handlers , NULL )
2002-10-25 10:06:35 +00:00
PHP_FE ( dba_list , NULL )
2001-08-11 16:39:07 +00:00
{ NULL , NULL , NULL }
1999-07-21 15:12:32 +00:00
} ;
2001-06-05 13:12:10 +00:00
/* }}} */
1999-07-21 15:12:32 +00:00
2002-08-23 22:24:02 +00:00
PHP_MINIT_FUNCTION ( dba ) ;
PHP_MINFO_FUNCTION ( dba ) ;
1999-07-21 15:12:32 +00:00
1999-12-17 20:55:31 +00:00
zend_module_entry dba_module_entry = {
2002-08-23 22:24:02 +00:00
STANDARD_MODULE_HEADER ,
2001-10-11 23:33:59 +00:00
" dba " ,
2002-08-23 22:24:02 +00:00
dba_functions ,
2000-03-06 18:44:01 +00:00
PHP_MINIT ( dba ) ,
2001-10-11 23:33:59 +00:00
NULL ,
2002-08-23 22:24:02 +00:00
NULL ,
NULL ,
2000-03-06 18:44:01 +00:00
PHP_MINFO ( dba ) ,
2002-08-23 22:24:02 +00:00
NO_VERSION_YET ,
2000-03-06 18:44:01 +00:00
STANDARD_MODULE_PROPERTIES
1999-07-21 15:12:32 +00:00
} ;
2000-05-02 03:38:26 +00:00
# ifdef COMPILE_DL_DBA
ZEND_GET_MODULE ( dba )
# endif
1999-07-21 15:12:32 +00:00
typedef struct dba_handler {
2002-11-08 01:03:53 +00:00
char * name ; /* handler name */
2002-11-10 17:58:46 +00:00
int flags ; /* whether and how dba does locking and other flags*/
2002-11-05 14:46:36 +00:00
int ( * open ) ( dba_info * , char * * error TSRMLS_DC ) ;
2002-11-04 12:27:13 +00:00
void ( * close ) ( dba_info * TSRMLS_DC ) ;
char * ( * fetch ) ( dba_info * , char * , int , int , int * TSRMLS_DC ) ;
int ( * update ) ( dba_info * , char * , int , char * , int , int TSRMLS_DC ) ;
int ( * exists ) ( dba_info * , char * , int TSRMLS_DC ) ;
int ( * delete ) ( dba_info * , char * , int TSRMLS_DC ) ;
char * ( * firstkey ) ( dba_info * , int * TSRMLS_DC ) ;
char * ( * nextkey ) ( dba_info * , int * TSRMLS_DC ) ;
int ( * optimize ) ( dba_info * TSRMLS_DC ) ;
int ( * sync ) ( dba_info * TSRMLS_DC ) ;
1999-07-21 15:12:32 +00:00
} dba_handler ;
/* {{{ macromania */
1999-09-17 09:56:30 +00:00
# define DBA_ID_PARS \
2002-08-23 22:24:02 +00:00
zval * * id ; \
1999-09-17 09:56:30 +00:00
dba_info * info = NULL ; \
2002-08-23 22:24:02 +00:00
int ac = ZEND_NUM_ARGS ( )
1999-07-21 15:12:32 +00:00
/* these are used to get the standard arguments */
1999-09-17 09:56:30 +00:00
# define DBA_GET1 \
1999-12-18 22:40:35 +00:00
if ( ac ! = 1 | | zend_get_parameters_ex ( ac , & id ) ! = SUCCESS ) { \
1999-09-17 09:56:30 +00:00
WRONG_PARAM_COUNT ; \
1999-07-21 15:12:32 +00:00
}
1999-09-17 09:56:30 +00:00
# define DBA_GET2 \
2002-08-23 22:24:02 +00:00
zval * * key ; \
1999-12-18 22:40:35 +00:00
if ( ac ! = 2 | | zend_get_parameters_ex ( ac , & key , & id ) ! = SUCCESS ) { \
1999-09-17 09:56:30 +00:00
WRONG_PARAM_COUNT ; \
} \
convert_to_string_ex ( key )
1999-07-21 15:12:32 +00:00
2002-11-03 16:43:07 +00:00
# define DBA_GET2_3 \
zval * * key ; \
zval * * tmp ; \
int skip = 0 ; \
switch ( ac ) { \
case 2 : \
if ( zend_get_parameters_ex ( ac , & key , & id ) ! = SUCCESS ) { \
WRONG_PARAM_COUNT ; \
} \
break ; \
case 3 : \
if ( zend_get_parameters_ex ( ac , & key , & tmp , & id ) ! = SUCCESS ) { \
WRONG_PARAM_COUNT ; \
} \
convert_to_long_ex ( tmp ) ; \
skip = Z_LVAL_PP ( tmp ) ; \
break ; \
default : \
WRONG_PARAM_COUNT ; \
} \
convert_to_string_ex ( key )
1999-09-17 09:56:30 +00:00
# define DBA_ID_GET \
2002-08-23 22:24:02 +00:00
ZEND_FETCH_RESOURCE2 ( info , dba_info * , id , - 1 , " DBA identifier " , le_db , le_pdb ) ;
1999-07-21 15:12:32 +00:00
2002-11-03 16:43:07 +00:00
# define DBA_ID_GET1 DBA_ID_PARS; DBA_GET1; DBA_ID_GET
# define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_ID_GET
# define DBA_ID_GET2_3 DBA_ID_PARS; DBA_GET2_3; DBA_ID_GET
1999-07-21 15:12:32 +00:00
/* a DBA handler must have specific routines */
2002-11-10 17:58:46 +00:00
# define DBA_NAMED_HND(name, x, flags) \
1999-07-21 15:12:32 +00:00
{ \
2002-11-10 17:58:46 +00:00
# name, flags, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \
1999-07-21 15:12:32 +00:00
dba_exists_ # # x , dba_delete_ # # x , dba_firstkey_ # # x , dba_nextkey_ # # x , \
dba_optimize_ # # x , dba_sync_ # # x \
} ,
2002-11-10 17:58:46 +00:00
# define DBA_HND(x, flags) DBA_NAMED_HND(x, x, flags)
2002-11-04 17:53:04 +00:00
1999-07-21 15:12:32 +00:00
/* check whether the user has write access */
# define DBA_WRITE_CHECK \
if ( info - > mode ! = DBA_WRITER & & info - > mode ! = DBA_TRUNC & & info - > mode ! = DBA_CREAT ) { \
2002-11-01 14:15:24 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " You cannot perform a modification to a database without proper access " ) ; \
1999-07-21 15:12:32 +00:00
RETURN_FALSE ; \
}
/* }}} */
/* {{{ globals */
static dba_handler handler [ ] = {
# if DBA_GDBM
2002-11-10 16:03:17 +00:00
DBA_HND ( gdbm , DBA_LOCK_EXT ) /* Locking done in library if set */
1999-07-21 15:12:32 +00:00
# endif
# if DBA_DBM
2002-11-10 16:03:17 +00:00
DBA_HND ( dbm , DBA_LOCK_ALL ) /* No lock in lib */
1999-07-21 15:12:32 +00:00
# endif
# if DBA_NDBM
2002-11-10 16:03:17 +00:00
DBA_HND ( ndbm , DBA_LOCK_ALL ) /* Could be done in library: filemode = 0644 + S_ENFMT */
1999-07-21 15:12:32 +00:00
# endif
# if DBA_CDB
2002-11-10 17:58:46 +00:00
DBA_HND ( cdb , DBA_STREAM_OPEN | DBA_LOCK_ALL ) /* No lock in lib */
1999-07-21 15:12:32 +00:00
# endif
2002-11-04 17:53:04 +00:00
# if DBA_CDB_BUILTIN
2002-11-10 17:58:46 +00:00
DBA_NAMED_HND ( cdb_make , cdb , DBA_STREAM_OPEN | DBA_LOCK_ALL ) /* No lock in lib */
2002-11-04 17:53:04 +00:00
# endif
1999-07-21 15:12:32 +00:00
# if DBA_DB2
2002-11-10 16:03:17 +00:00
DBA_HND ( db2 , DBA_LOCK_ALL ) /* No lock in lib */
1999-11-20 22:50:42 +00:00
# endif
# if DBA_DB3
2002-11-10 16:03:17 +00:00
DBA_HND ( db3 , DBA_LOCK_ALL ) /* No lock in lib */
2002-11-06 04:16:18 +00:00
# endif
# if DBA_FLATFILE
2002-11-10 17:58:46 +00:00
DBA_HND ( flatfile , DBA_STREAM_OPEN | DBA_LOCK_ALL ) /* No lock in lib */
1999-07-21 15:12:32 +00:00
# endif
2002-11-08 01:03:53 +00:00
{ NULL , 0 , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL }
1999-07-21 15:12:32 +00:00
} ;
static int le_db ;
static int le_pdb ;
/* }}} */
2001-06-05 13:12:10 +00:00
/* {{{ dba_close
*/
2002-11-04 12:27:13 +00:00
static void dba_close ( dba_info * info TSRMLS_DC )
1999-07-21 15:12:32 +00:00
{
2002-11-08 01:03:53 +00:00
if ( info - > hnd ) info - > hnd - > close ( info TSRMLS_CC ) ;
if ( info - > path ) efree ( info - > path ) ;
2002-11-10 17:58:46 +00:00
if ( info - > fp & & info - > fp ! = info - > lock . fp ) php_stream_close ( info - > fp ) ;
2002-11-08 01:03:53 +00:00
if ( info - > lock . fd ) {
2002-11-11 20:53:41 +00:00
php_flock ( info - > lock . fd , LOCK_UN ) ;
2002-11-08 01:03:53 +00:00
close ( info - > lock . fd ) ;
info - > lock . fd = 0 ;
}
if ( info - > lock . fp ) php_stream_close ( info - > lock . fp ) ;
if ( info - > lock . name ) efree ( info - > lock . name ) ;
2002-11-05 15:01:20 +00:00
efree ( info ) ;
1999-07-21 15:12:32 +00:00
}
/* }}} */
2001-06-05 13:12:10 +00:00
/* {{{ dba_close_rsrc
*/
2001-07-31 05:44:11 +00:00
static void dba_close_rsrc ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-10-26 17:38:01 +00:00
{
dba_info * info = ( dba_info * ) rsrc - > ptr ;
2001-07-31 05:44:11 +00:00
2002-11-04 12:27:13 +00:00
dba_close ( info TSRMLS_CC ) ;
2000-10-26 17:38:01 +00:00
}
2001-06-05 13:12:10 +00:00
/* }}} */
2000-10-26 17:38:01 +00:00
2001-06-05 13:12:10 +00:00
/* {{{ PHP_MINIT_FUNCTION
*/
2002-08-23 22:24:02 +00:00
PHP_MINIT_FUNCTION ( dba )
1999-07-21 15:12:32 +00:00
{
2002-08-23 22:24:02 +00:00
le_db = zend_register_list_destructors_ex ( dba_close_rsrc , NULL , " dba " , module_number ) ;
le_pdb = zend_register_list_destructors_ex ( NULL , dba_close_rsrc , " dba persistent " , module_number ) ;
1999-07-21 15:12:32 +00:00
return SUCCESS ;
}
2001-06-05 13:12:10 +00:00
/* }}} */
1999-07-21 15:12:32 +00:00
2001-06-05 13:12:10 +00:00
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
2002-08-23 22:24:02 +00:00
PHP_MSHUTDOWN_FUNCTION ( dba )
1999-07-21 15:12:32 +00:00
{
return SUCCESS ;
}
2001-06-05 13:12:10 +00:00
/* }}} */
1999-07-21 15:12:32 +00:00
2000-12-01 12:29:29 +00:00
# include "ext/standard/php_smart_str.h"
2000-12-01 01:25:36 +00:00
2001-06-05 13:12:10 +00:00
/* {{{ PHP_MINFO_FUNCTION
*/
2002-08-23 22:24:02 +00:00
PHP_MINFO_FUNCTION ( dba )
1999-07-21 15:12:32 +00:00
{
dba_handler * hptr ;
2000-12-01 12:29:29 +00:00
smart_str handlers = { 0 } ;
2000-12-01 01:25:36 +00:00
1999-07-21 15:12:32 +00:00
for ( hptr = handler ; hptr - > name ; hptr + + ) {
2000-12-01 12:29:29 +00:00
smart_str_appends ( & handlers , hptr - > name ) ;
smart_str_appendc ( & handlers , ' ' ) ;
2000-12-01 01:25:36 +00:00
}
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " DBA support " , " enabled " ) ;
2000-12-04 10:22:46 +00:00
if ( handlers . c ) {
smart_str_0 ( & handlers ) ;
php_info_print_table_row ( 2 , " Supported handlers " , handlers . c ) ;
smart_str_free ( & handlers ) ;
} else {
php_info_print_table_row ( 2 , " Supported handlers " , " none " ) ;
}
2000-12-01 01:25:36 +00:00
php_info_print_table_end ( ) ;
1999-07-21 15:12:32 +00:00
}
2001-06-05 13:12:10 +00:00
/* }}} */
2002-08-23 22:24:02 +00:00
2001-06-05 13:12:10 +00:00
/* {{{ php_dba_update
*/
1999-12-17 21:34:28 +00:00
static void php_dba_update ( INTERNAL_FUNCTION_PARAMETERS , int mode )
1999-07-21 15:12:32 +00:00
{
DBA_ID_PARS ;
2002-08-23 22:24:02 +00:00
zval * * val , * * key ;
1999-07-21 15:12:32 +00:00
1999-12-18 22:40:35 +00:00
if ( ac ! = 3 | | zend_get_parameters_ex ( ac , & key , & val , & id ) ! = SUCCESS ) {
1999-07-21 15:12:32 +00:00
WRONG_PARAM_COUNT ;
}
1999-09-17 09:56:30 +00:00
convert_to_string_ex ( key ) ;
convert_to_string_ex ( val ) ;
1999-07-21 15:12:32 +00:00
DBA_ID_GET ;
DBA_WRITE_CHECK ;
2002-11-04 12:27:13 +00:00
if ( info - > hnd - > update ( info , VALLEN ( key ) , VALLEN ( val ) , mode TSRMLS_CC ) = = SUCCESS )
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
RETURN_FALSE ;
}
2001-06-05 13:12:10 +00:00
/* }}} */
1999-07-21 15:12:32 +00:00
# define FREENOW if(args) efree(args); if(key) efree(key)
2002-11-14 14:32:39 +00:00
/* {{{ php_find_dbm
*/
dba_info * php_dba_find ( const char * path TSRMLS_DC )
{
list_entry * le ;
dba_info * info ;
int numitems , i ;
numitems = zend_hash_next_free_element ( & EG ( regular_list ) ) ;
for ( i = 1 ; i < numitems ; i + + ) {
if ( zend_hash_index_find ( & EG ( regular_list ) , i , ( void * * ) & le ) = = FAILURE ) {
continue ;
}
if ( Z_TYPE_P ( le ) = = le_db | | Z_TYPE_P ( le ) = = le_pdb ) {
info = ( dba_info * ) ( le - > ptr ) ;
if ( ! strcmp ( info - > path , path ) ) {
return ( dba_info * ) ( le - > ptr ) ;
}
}
}
return NULL ;
}
/* }}} */
2001-06-05 13:12:10 +00:00
/* {{{ php_dba_open
*/
1999-12-17 21:34:28 +00:00
static void php_dba_open ( INTERNAL_FUNCTION_PARAMETERS , int persistent )
1999-07-21 15:12:32 +00:00
{
2002-08-23 22:24:02 +00:00
zval * * * args = ( zval * * * ) NULL ;
2000-06-05 19:47:54 +00:00
int ac = ZEND_NUM_ARGS ( ) ;
1999-07-21 15:12:32 +00:00
dba_mode_t modenr ;
2002-11-14 14:32:39 +00:00
dba_info * info , * other ;
1999-07-21 15:12:32 +00:00
dba_handler * hptr ;
2002-11-05 14:46:36 +00:00
char * key = NULL , * error = NULL ;
1999-07-21 15:12:32 +00:00
int keylen = 0 ;
int i ;
2002-11-10 17:58:46 +00:00
int lock_mode , lock_flag , lock_dbf = 0 ;
char * file_mode ;
2002-11-11 12:04:12 +00:00
char mode [ 4 ] , * pmode , * lock_file_mode ;
1999-07-21 15:12:32 +00:00
if ( ac < 3 ) {
WRONG_PARAM_COUNT ;
}
/* we pass additional args to the respective handler */
2002-08-23 22:24:02 +00:00
args = emalloc ( ac * sizeof ( zval * ) ) ;
if ( zend_get_parameters_array_ex ( ac , args ) ! = SUCCESS ) {
1999-07-21 15:12:32 +00:00
FREENOW ;
WRONG_PARAM_COUNT ;
}
/* we only take string arguments */
2002-08-23 22:24:02 +00:00
for ( i = 0 ; i < ac ; i + + ) {
1999-09-17 09:56:30 +00:00
convert_to_string_ex ( args [ i ] ) ;
2000-11-22 21:47:15 +00:00
keylen + = Z_STRLEN_PP ( args [ i ] ) ;
1999-07-21 15:12:32 +00:00
}
2002-08-23 22:24:02 +00:00
if ( persistent ) {
list_entry * le ;
1999-07-21 15:12:32 +00:00
/* calculate hash */
key = emalloc ( keylen ) ;
keylen = 0 ;
for ( i = 0 ; i < ac ; i + + ) {
2001-08-11 16:39:07 +00:00
memcpy ( key + keylen , Z_STRVAL_PP ( args [ i ] ) , Z_STRLEN_PP ( args [ i ] ) ) ;
2000-11-22 21:47:15 +00:00
keylen + = Z_STRLEN_PP ( args [ i ] ) ;
1999-07-21 15:12:32 +00:00
}
2002-08-23 22:24:02 +00:00
/* try to find if we already have this link in our persistent list */
if ( zend_hash_find ( & EG ( persistent_list ) , key , keylen + 1 , ( void * * ) & le ) = = SUCCESS ) {
1999-07-21 15:12:32 +00:00
FREENOW ;
2002-08-23 22:24:02 +00:00
if ( Z_TYPE_P ( le ) ! = le_pdb ) {
RETURN_FALSE ;
}
info = ( dba_info * ) le - > ptr ;
ZEND_REGISTER_RESOURCE ( return_value , info , le_pdb ) ;
return ;
1999-07-21 15:12:32 +00:00
}
}
2002-08-23 22:24:02 +00:00
for ( hptr = handler ; hptr - > name & & strcasecmp ( hptr - > name , Z_STRVAL_PP ( args [ 2 ] ) ) ; hptr + + ) ;
1999-07-21 15:12:32 +00:00
2002-08-23 22:24:02 +00:00
if ( ! hptr - > name ) {
2002-11-05 14:46:36 +00:00
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " No such handler: %s " , Z_STRVAL_PP ( args [ 2 ] ) ) ;
1999-07-21 15:12:32 +00:00
FREENOW ;
RETURN_FALSE ;
}
2002-11-10 16:03:17 +00:00
/* Check mode: [rwnc][fl]?t?
* r : Read
* w : Write
* n : Create / Truncate
* c : Create
*
* d : force lock on database file
* l : force lock on lck file
*
* t : test open database , warning if locked
*/
2002-11-08 01:03:53 +00:00
strlcpy ( mode , Z_STRVAL_PP ( args [ 1 ] ) , sizeof ( mode ) ) ;
pmode = & mode [ 0 ] ;
2002-11-10 16:03:17 +00:00
if ( pmode [ 0 ] & & ( pmode [ 1 ] = = ' d ' | | pmode [ 1 ] = = ' l ' ) ) { /* force lock on db file or lck file */
if ( pmode [ 1 ] = = ' d ' ) {
2002-11-10 17:58:46 +00:00
if ( ( hptr - > flags & DBA_LOCK_ALL ) = = 0 ) {
2002-11-10 16:03:17 +00:00
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_NOTICE , " Handler %s does locking internally " , hptr - > name ) ;
}
lock_dbf = 1 ;
}
lock_flag = DBA_LOCK_ALL ;
} else {
2002-11-10 17:58:46 +00:00
lock_flag = ( hptr - > flags & DBA_LOCK_ALL ) ;
2002-11-10 16:03:17 +00:00
}
2002-11-08 01:03:53 +00:00
switch ( * pmode + + ) {
case ' r ' :
modenr = DBA_READER ;
2002-11-10 17:58:46 +00:00
lock_mode = ( lock_flag & DBA_LOCK_READER ) ? LOCK_SH : 0 ;
file_mode = " r " ;
1999-07-21 15:12:32 +00:00
break ;
case ' w ' :
modenr = DBA_WRITER ;
2002-11-10 17:58:46 +00:00
lock_mode = ( lock_flag & DBA_LOCK_WRITER ) ? LOCK_EX : 0 ;
file_mode = " r+b " ;
1999-07-21 15:12:32 +00:00
break ;
case ' n ' :
modenr = DBA_TRUNC ;
2002-11-10 17:58:46 +00:00
lock_mode = ( lock_flag & DBA_LOCK_TRUNC ) ? LOCK_EX : 0 ;
file_mode = " w+b " ;
2002-11-08 01:03:53 +00:00
break ;
case ' c ' :
modenr = DBA_CREAT ;
2002-11-10 17:58:46 +00:00
lock_mode = ( lock_flag & DBA_LOCK_CREAT ) ? LOCK_EX : 0 ;
file_mode = " a+b " ;
1999-07-21 15:12:32 +00:00
break ;
default :
2002-11-08 01:03:53 +00:00
modenr = 0 ;
2002-11-10 17:58:46 +00:00
lock_mode = 0 ;
file_mode = " " ;
2002-11-08 01:03:53 +00:00
}
2002-11-10 16:03:17 +00:00
if ( * pmode = = ' d ' | | * pmode = = ' l ' ) {
pmode + + ; /* done already - skip here */
}
2002-11-08 01:03:53 +00:00
if ( * pmode = = ' t ' ) {
pmode + + ;
2002-11-10 23:07:35 +00:00
if ( ! lock_mode ) {
if ( ( hptr - > flags & DBA_LOCK_ALL ) = = 0 ) {
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " Handler %s uses its own locking which doesn't support mode modifier t (testing) " , hptr - > name ) ;
FREENOW ;
RETURN_FALSE ;
} else {
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " Handler %s doesn't uses locking for this mode which makes modifier t (testing) obsolete " , hptr - > name ) ;
FREENOW ;
RETURN_FALSE ;
}
} else {
lock_mode | = LOCK_NB ; /* test =: non blocking */
}
2002-11-08 01:03:53 +00:00
}
if ( * pmode | | ! modenr ) {
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " Illegal DBA mode " ) ;
FREENOW ;
RETURN_FALSE ;
1999-07-21 15:12:32 +00:00
}
2002-11-06 17:59:03 +00:00
info = emalloc ( sizeof ( dba_info ) ) ;
memset ( info , 0 , sizeof ( dba_info ) ) ;
2002-11-05 15:01:20 +00:00
info - > path = estrdup ( Z_STRVAL_PP ( args [ 0 ] ) ) ;
1999-07-21 15:12:32 +00:00
info - > mode = modenr ;
info - > argc = ac - 3 ;
info - > argv = args + 3 ;
2002-11-14 14:32:39 +00:00
info - > flags = ( hptr - > flags & ~ DBA_LOCK_ALL ) | ( lock_flag & DBA_LOCK_ALL ) ;
info - > lock . mode = lock_mode ;
/* if any open call is a locking call:
* check if we already habe a locking call open that should block this call
* the problem is some systems would allow read during write
*/
if ( hptr - > flags & DBA_LOCK_ALL ) {
if ( ( other = php_dba_find ( info - > path TSRMLS_CC ) ) ! = NULL ) {
if ( ( ( lock_mode & LOCK_EX ) & & ( other - > lock . mode & ( LOCK_EX | LOCK_SH ) ) )
| | ( ( other - > lock . mode & LOCK_EX ) & & ( lock_mode & ( LOCK_EX | LOCK_SH ) ) )
) {
error = " Unable to establish lock (database file already open) " ; /* force failure exit */
}
}
}
1999-07-21 15:12:32 +00:00
2002-11-14 14:32:39 +00:00
if ( ! error & & lock_mode ) {
2002-11-11 12:04:12 +00:00
if ( lock_dbf ) {
2002-11-10 16:03:17 +00:00
info - > lock . name = estrdup ( info - > path ) ;
2002-11-11 12:04:12 +00:00
lock_file_mode = file_mode ;
} else {
2002-11-10 16:03:17 +00:00
spprintf ( & info - > lock . name , 0 , " %s.lck " , info - > path ) ;
2002-11-11 12:04:12 +00:00
lock_file_mode = " a+b " ;
}
info - > lock . fp = php_stream_open_wrapper ( info - > lock . name , lock_file_mode , STREAM_MUST_SEEK | REPORT_ERRORS | IGNORE_PATH | ENFORCE_SAFE_MODE , NULL ) ;
2002-11-10 17:58:46 +00:00
if ( ! info - > lock . fp ) {
2002-11-08 01:03:53 +00:00
dba_close ( info TSRMLS_CC ) ;
/* stream operation already wrote an error message */
FREENOW ;
RETURN_FALSE ;
}
2002-11-10 17:58:46 +00:00
if ( php_stream_cast ( info - > lock . fp , PHP_STREAM_AS_FD , ( void * ) & info - > lock . fd , 1 ) = = FAILURE ) {
dba_close ( info TSRMLS_CC ) ;
/* stream operation already wrote an error message */
FREENOW ;
RETURN_FALSE ;
}
2002-11-11 20:53:41 +00:00
if ( php_flock ( info - > lock . fd , lock_mode ) ) {
2002-11-08 01:03:53 +00:00
error = " Unable to establish lock " ; /* force failure exit */
}
}
2002-11-10 17:58:46 +00:00
/* centralised open stream for builtin */
if ( ! error & & ( hptr - > flags & DBA_STREAM_OPEN ) = = DBA_STREAM_OPEN ) {
if ( info - > lock . fp & & lock_dbf ) {
info - > fp = info - > lock . fp ; /* use the same stream for locking and database access */
} else {
info - > fp = php_stream_open_wrapper ( info - > path , file_mode , STREAM_MUST_SEEK | REPORT_ERRORS | IGNORE_PATH | ENFORCE_SAFE_MODE , NULL ) ;
}
if ( ! info - > fp ) {
dba_close ( info TSRMLS_CC ) ;
/* stream operation already wrote an error message */
FREENOW ;
RETURN_FALSE ;
}
}
2002-11-08 01:03:53 +00:00
if ( error | | hptr - > open ( info , & error TSRMLS_CC ) ! = SUCCESS ) {
2002-11-04 12:27:13 +00:00
dba_close ( info TSRMLS_CC ) ;
2002-11-05 14:46:36 +00:00
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " Driver initialization failed for handler: %s%s%s " , Z_STRVAL_PP ( args [ 2 ] ) , error ? " : " : " " , error ? error : " " ) ;
1999-07-21 15:12:32 +00:00
FREENOW ;
RETURN_FALSE ;
}
2002-08-23 22:24:02 +00:00
1999-07-21 15:12:32 +00:00
info - > hnd = hptr ;
info - > argc = 0 ;
info - > argv = NULL ;
2002-08-23 22:24:02 +00:00
if ( persistent ) {
list_entry new_le ;
Z_TYPE ( new_le ) = le_pdb ;
new_le . ptr = info ;
if ( zend_hash_update ( & EG ( persistent_list ) , key , keylen + 1 , & new_le , sizeof ( list_entry ) , NULL ) = = FAILURE ) {
FREENOW ;
RETURN_FALSE ;
}
1999-07-21 15:12:32 +00:00
}
2002-08-23 22:24:02 +00:00
ZEND_REGISTER_RESOURCE ( return_value , info , ( persistent ? le_pdb : le_db ) ) ;
1999-07-21 15:12:32 +00:00
FREENOW ;
}
/* }}} */
2001-06-05 13:12:10 +00:00
# undef FREENOW
1999-07-21 15:12:32 +00:00
2000-07-13 18:44:57 +00:00
/* {{{ proto int dba_popen(string path, string mode, string handlername [, string ...])
2000-02-24 16:30:42 +00:00
Opens path using the specified handler in mode persistently */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_popen )
{
1999-12-17 21:34:28 +00:00
php_dba_open ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-07-21 15:12:32 +00:00
}
/* }}} */
2000-07-13 18:44:57 +00:00
/* {{{ proto int dba_open(string path, string mode, string handlername [, string ...])
2000-02-24 16:30:42 +00:00
Opens path using the specified handler in mode */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_open )
{
1999-12-17 21:34:28 +00:00
php_dba_open ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-07-21 15:12:32 +00:00
}
/* }}} */
2002-08-23 22:24:02 +00:00
/* {{{ proto void dba_close(resource handle)
2000-02-24 16:30:42 +00:00
Closes database */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_close )
{
2002-08-23 22:24:02 +00:00
DBA_ID_GET1 ;
1999-07-21 15:12:32 +00:00
2002-08-23 22:24:02 +00:00
zend_list_delete ( Z_RESVAL_PP ( id ) ) ;
1999-07-21 15:12:32 +00:00
}
/* }}} */
/* {{{ proto bool dba_exists(string key, int handle)
2000-02-24 16:30:42 +00:00
Checks , if the specified key exists */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_exists )
{
DBA_ID_GET2 ;
2002-11-04 12:27:13 +00:00
if ( info - > hnd - > exists ( info , VALLEN ( key ) TSRMLS_CC ) = = SUCCESS ) {
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
2002-11-03 16:43:07 +00:00
/* {{{ proto string dba_fetch(string key, [int skip ,] int handle)
2000-02-24 16:30:42 +00:00
Fetches the data associated with key */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_fetch )
{
char * val ;
int len = 0 ;
2002-11-03 16:43:07 +00:00
DBA_ID_GET2_3 ;
1999-07-21 15:12:32 +00:00
2002-11-03 16:43:07 +00:00
if ( ac = = 3 & & strcmp ( info - > hnd - > name , " cdb " ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Handler %s does not support optional skip parameter " , info - > hnd - > name ) ;
}
2002-11-04 12:27:13 +00:00
if ( ( val = info - > hnd - > fetch ( info , VALLEN ( key ) , skip , & len TSRMLS_CC ) ) ! = NULL ) {
2002-11-14 21:09:41 +00:00
if ( val & & PG ( magic_quotes_runtime ) ) {
val = php_addslashes ( val , len , & len , 1 TSRMLS_CC ) ;
}
1999-07-21 15:12:32 +00:00
RETURN_STRINGL ( val , len , 0 ) ;
}
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto string dba_firstkey(int handle)
2000-02-24 16:30:42 +00:00
Resets the internal key pointer and returns the first key */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_firstkey )
{
char * fkey ;
int len ;
DBA_ID_GET1 ;
2002-11-04 12:27:13 +00:00
fkey = info - > hnd - > firstkey ( info , & len TSRMLS_CC ) ;
1999-07-21 15:12:32 +00:00
if ( fkey )
RETURN_STRINGL ( fkey , len , 0 ) ;
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto string dba_nextkey(int handle)
2000-02-24 16:30:42 +00:00
Returns the next key */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_nextkey )
{
char * nkey ;
int len ;
DBA_ID_GET1 ;
2002-11-04 12:27:13 +00:00
nkey = info - > hnd - > nextkey ( info , & len TSRMLS_CC ) ;
1999-07-21 15:12:32 +00:00
if ( nkey )
RETURN_STRINGL ( nkey , len , 0 ) ;
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto bool dba_delete(string key, int handle)
2000-02-24 16:30:42 +00:00
Deletes the entry associated with key */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_delete )
{
DBA_ID_GET2 ;
DBA_WRITE_CHECK ;
2002-11-04 12:27:13 +00:00
if ( info - > hnd - > delete ( info , VALLEN ( key ) TSRMLS_CC ) = = SUCCESS )
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto bool dba_insert(string key, string value, int handle)
2000-02-24 16:30:42 +00:00
Inserts value as key , returns false , if key exists already */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_insert )
{
1999-12-17 21:34:28 +00:00
php_dba_update ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-07-21 15:12:32 +00:00
}
/* }}} */
/* {{{ proto bool dba_replace(string key, string value, int handle)
2000-02-24 16:30:42 +00:00
Inserts value as key , replaces key , if key exists already */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_replace )
{
1999-12-17 21:34:28 +00:00
php_dba_update ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-07-21 15:12:32 +00:00
}
/* }}} */
/* {{{ proto bool dba_optimize(int handle)
2000-02-24 16:30:42 +00:00
Optimizes ( e . g . clean up , vacuum ) database */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_optimize )
{
DBA_ID_GET1 ;
DBA_WRITE_CHECK ;
2002-11-04 12:27:13 +00:00
if ( info - > hnd - > optimize ( info TSRMLS_CC ) = = SUCCESS ) {
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto bool dba_sync(int handle)
2000-02-24 16:30:42 +00:00
Synchronizes database */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_sync )
{
DBA_ID_GET1 ;
2002-11-04 12:27:13 +00:00
if ( info - > hnd - > sync ( info TSRMLS_CC ) = = SUCCESS ) {
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
2002-10-25 10:06:35 +00:00
/* {{{ proto array dba_handlers()
2002-10-24 20:43:03 +00:00
List configured databases */
PHP_FUNCTION ( dba_handlers )
{
dba_handler * hptr ;
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
ZEND_WRONG_PARAM_COUNT ( ) ;
RETURN_FALSE ;
}
if ( array_init ( return_value ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Unable to initialize array " ) ;
RETURN_FALSE ;
}
for ( hptr = handler ; hptr - > name ; hptr + + ) {
add_next_index_string ( return_value , hptr - > name , 1 ) ;
}
}
/* }}} */
2002-10-25 10:06:35 +00:00
/* {{{ proto array dba_list()
List configured databases */
PHP_FUNCTION ( dba_list )
{
ulong numitems , i ;
zend_rsrc_list_entry * le ;
dba_info * info ;
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
ZEND_WRONG_PARAM_COUNT ( ) ;
RETURN_FALSE ;
}
if ( array_init ( return_value ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Unable to initialize array " ) ;
RETURN_FALSE ;
}
numitems = zend_hash_next_free_element ( & EG ( regular_list ) ) ;
for ( i = 1 ; i < numitems ; i + + ) {
if ( zend_hash_index_find ( & EG ( regular_list ) , i , ( void * * ) & le ) = = FAILURE ) {
continue ;
}
if ( Z_TYPE_P ( le ) = = le_db | | Z_TYPE_P ( le ) = = le_pdb ) {
info = ( dba_info * ) ( le - > ptr ) ;
add_index_string ( return_value , i , info - > path , 1 ) ;
}
}
}
/* }}} */
1999-07-21 15:12:32 +00:00
# endif
2001-06-05 13:12:10 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2001-09-09 13:29:31 +00:00
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
2001-06-05 13:12:10 +00:00
*/