1999-07-21 15:12:32 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 08:18:22 +00:00
| PHP Version 5 |
1999-07-21 15:12:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 08:18:22 +00:00
| Copyright ( c ) 1997 - 2004 The PHP Group |
1999-07-21 15:12:32 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2003-06-10 20:04:29 +00:00
| This source file is subject to version 3.0 of the PHP license , |
2001-06-06 13:06:12 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
| http : //www.php.net/license/3_0.txt. |
2001-06-06 13:06:12 +00:00
| 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-12-29 15:31:00 +00:00
# include "php_ini.h"
2002-11-08 01:03:53 +00:00
# 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"
2003-06-16 09:11:31 +00:00
# include "ext/standard/flock_compat.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-26 12:05:59 +00:00
# include "php_db4.h"
2002-11-06 09:17:51 +00:00
# include "php_flatfile.h"
2003-02-22 17:20:06 +00:00
# include "php_inifile.h"
2003-12-18 20:25:21 +00:00
# include "php_qdbm.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 )
2003-04-13 19:50:28 +00:00
PHP_FE ( dba_popen , NULL )
1999-07-21 15:12:32 +00:00
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 )
2003-11-12 21:43:03 +00:00
PHP_FE ( dba_key_split , 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 ) ;
2002-12-29 15:31:00 +00:00
PHP_MSHUTDOWN_FUNCTION ( dba ) ;
2002-08-23 22:24:02 +00:00
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 ) ,
2002-12-29 15:31:00 +00:00
PHP_MSHUTDOWN ( dba ) ,
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
/* {{{ 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 \
2003-02-26 22:07:50 +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
}
2003-02-26 22:07:50 +00:00
/* {{{ php_dba_myke_key */
static size_t php_dba_make_key ( zval * * key , char * * key_str , char * * key_free TSRMLS_DC )
{
if ( Z_TYPE_PP ( key ) = = IS_ARRAY ) {
zval * * group , * * name ;
HashPosition pos ;
size_t len ;
if ( zend_hash_num_elements ( Z_ARRVAL_PP ( key ) ) ! = 2 ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Key does not have exactly two elements: (key, name) " ) ;
return - 1 ;
}
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_PP ( key ) , & pos ) ;
zend_hash_get_current_data_ex ( Z_ARRVAL_PP ( key ) , ( void * * ) & group , & pos ) ;
zend_hash_move_forward_ex ( Z_ARRVAL_PP ( key ) , & pos ) ;
zend_hash_get_current_data_ex ( Z_ARRVAL_PP ( key ) , ( void * * ) & name , & pos ) ;
convert_to_string_ex ( group ) ;
convert_to_string_ex ( name ) ;
if ( Z_STRLEN_PP ( group ) = = 0 ) {
* key_str = Z_STRVAL_PP ( name ) ;
* key_free = NULL ;
return Z_STRLEN_PP ( name ) ;
}
len = spprintf ( key_str , 0 , " [%s]%s " , Z_STRVAL_PP ( group ) , Z_STRVAL_PP ( name ) ) ;
* key_free = * key_str ;
return len ;
} else {
convert_to_string_ex ( key ) ;
* key_str = Z_STRVAL_PP ( key ) ;
* key_free = NULL ;
return Z_STRLEN_PP ( key ) ;
}
}
/* }}} */
1999-09-17 09:56:30 +00:00
# define DBA_GET2 \
2002-08-23 22:24:02 +00:00
zval * * key ; \
2003-02-26 22:07:50 +00:00
char * key_str , * key_free ; \
size_t key_len ; \
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 ; \
} \
2003-03-04 19:56:35 +00:00
if ( ( key_len = php_dba_make_key ( key , & key_str , & key_free TSRMLS_CC ) ) = = 0 ) { \
2003-02-26 22:07:50 +00:00
RETURN_FALSE ; \
}
1999-07-21 15:12:32 +00:00
2002-11-03 16:43:07 +00:00
# define DBA_GET2_3 \
zval * * key ; \
2003-02-26 22:07:50 +00:00
char * key_str , * key_free ; \
size_t key_len ; \
2002-11-03 16:43:07 +00:00
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 ; \
} \
2003-03-04 19:56:35 +00:00
if ( ( key_len = php_dba_make_key ( key , & key_str , & key_free TSRMLS_CC ) ) = = 0 ) { \
2003-02-26 22:07:50 +00:00
RETURN_FALSE ; \
}
# define DBA_GET3 \
zval * * key , * * val ; \
char * key_str , * key_free ; \
size_t key_len ; \
if ( ac ! = 3 | | zend_get_parameters_ex ( ac , & key , & val , & id ) ! = SUCCESS ) { \
WRONG_PARAM_COUNT ; \
} \
convert_to_string_ex ( val ) ; \
2003-03-04 19:56:35 +00:00
if ( ( key_len = php_dba_make_key ( key , & key_str , & key_free TSRMLS_CC ) ) = = 0 ) { \
2003-02-26 22:07:50 +00:00
RETURN_FALSE ; \
}
2002-11-03 16:43:07 +00:00
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
2003-02-26 22:07:50 +00:00
# define DBA_ID_GET3 DBA_ID_PARS; DBA_GET3; DBA_ID_GET
1999-07-21 15:12:32 +00:00
2003-02-26 22:07:50 +00:00
# define DBA_ID_DONE \
if ( key_free ) efree ( key_free )
1999-07-21 15:12:32 +00:00
/* a DBA handler must have specific routines */
2002-12-30 11:32:37 +00:00
# define DBA_NAMED_HND(alias, name, flags) \
1999-07-21 15:12:32 +00:00
{ \
2002-12-30 11:43:18 +00:00
# alias, flags, dba_open_##name, dba_close_##name, dba_fetch_##name, dba_update_##name, \
dba_exists_ # # name , dba_delete_ # # name , dba_firstkey_ # # name , dba_nextkey_ # # name , \
2002-12-30 13:07:30 +00:00
dba_optimize_ # # name , dba_sync_ # # name , dba_info_ # # name \
1999-07-21 15:12:32 +00:00
} ,
2002-12-30 11:32:37 +00:00
# define DBA_HND(name, flags) DBA_NAMED_HND(name, name, 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
2002-11-26 12:05:59 +00:00
# if DBA_DB4
DBA_HND ( db4 , DBA_LOCK_ALL ) /* No lock in lib */
# endif
2003-02-22 17:20:06 +00:00
# if DBA_INIFILE
2003-12-18 20:14:15 +00:00
DBA_HND ( inifile , DBA_STREAM_OPEN | DBA_LOCK_ALL | DBA_CAST_AS_FD ) /* No lock in lib */
2003-02-22 17:20:06 +00:00
# endif
2002-11-06 04:16:18 +00:00
# if DBA_FLATFILE
2003-12-18 20:14:15 +00:00
DBA_HND ( flatfile , DBA_STREAM_OPEN | DBA_LOCK_ALL | DBA_NO_APPEND ) /* No lock in lib */
2003-12-18 20:25:21 +00:00
# endif
# if DBA_QDBM
DBA_HND ( qdbm , DBA_LOCK_EXT )
1999-07-21 15:12:32 +00:00
# endif
2002-12-30 13:07:30 +00:00
{ NULL , 0 , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL }
1999-07-21 15:12:32 +00:00
} ;
2002-12-29 15:31:00 +00:00
# if DBA_FLATFILE
# define DBA_DEFAULT "flatfile"
# elif DBA_DB4
# define DBA_DEFAULT "db4"
# elif DBA_DB3
# define DBA_DEFAULT "db3"
# elif DBA_DB2
# define DBA_DEFAULT "db2"
# elif DBA_GDBM
# define DBA_DEFAULT "gdbm"
# elif DBA_NBBM
# define DBA_DEFAULT "ndbm"
# elif DBA_DBM
# define DBA_DEFAULT "dbm"
2003-12-18 20:25:21 +00:00
# elif DBA_QDBM
# define DBA_DEFAULT "qdbm"
2002-12-29 15:31:00 +00:00
# else
# define DBA_DEFAULT ""
# endif
2003-02-22 17:20:06 +00:00
/* cdb/cdb_make and ini are no option here */
2002-12-29 15:31:00 +00:00
ZEND_BEGIN_MODULE_GLOBALS ( dba )
char * default_handler ;
dba_handler * default_hptr ;
ZEND_END_MODULE_GLOBALS ( dba )
ZEND_DECLARE_MODULE_GLOBALS ( dba )
# ifdef ZTS
# define DBA_G(v) TSRMG(dba_globals_id, zend_dba_globals *, v)
# else
# define DBA_G(v) (dba_globals.v)
# endif
1999-07-21 15:12:32 +00:00
static int le_db ;
static int le_pdb ;
2003-02-26 22:07:50 +00:00
/* {{{ dba_fetch_resource
PHPAPI void dba_fetch_resource ( dba_info * * pinfo , zval * * id TSRMLS_DC )
{
dba_info * info ;
DBA_ID_FETCH
* pinfo = info ;
}
*/
/* }}} */
/* {{{ dba_get_handler
PHPAPI dba_handler * dba_get_handler ( const char * handler_name )
{
dba_handler * hptr ;
for ( hptr = handler ; hptr - > name & & strcasecmp ( hptr - > name , handler_name ) ; hptr + + ) ;
return hptr ;
}
*/
1999-07-21 15:12:32 +00:00
/* }}} */
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
{
2003-03-20 19:54:22 +00:00
if ( info - > hnd ) {
info - > hnd - > close ( info TSRMLS_CC ) ;
}
if ( info - > path ) {
pefree ( info - > path , info - > flags & DBA_PERSISTENT ) ;
}
if ( info - > fp & & info - > fp ! = info - > lock . fp ) {
2003-07-29 18:26:34 +00:00
if ( info - > flags & DBA_PERSISTENT ) {
php_stream_pclose ( info - > fp ) ;
} else {
php_stream_close ( info - > fp ) ;
}
2003-03-20 19:54:22 +00:00
}
if ( info - > lock . fp ) {
2003-07-29 18:26:34 +00:00
if ( info - > flags & DBA_PERSISTENT ) {
php_stream_pclose ( info - > lock . fp ) ;
} else {
php_stream_close ( info - > lock . fp ) ;
}
2003-03-20 19:54:22 +00:00
}
if ( info - > lock . name ) {
pefree ( info - > lock . name , info - > flags & DBA_PERSISTENT ) ;
}
2002-12-20 17:47:58 +00:00
pefree ( info , info - > flags & DBA_PERSISTENT ) ;
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
{
2002-12-20 17:47:58 +00:00
dba_info * info = ( dba_info * ) rsrc - > ptr ;
2003-04-13 19:50:28 +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
2003-04-13 19:50:28 +00:00
/* {{{ dba_close_pe_rsrc_deleter */
int dba_close_pe_rsrc_deleter ( list_entry * le , void * pDba TSRMLS_DC )
{
return le - > ptr = = pDba ;
}
/* }}} */
/* {{{ dba_close_pe_rsrc */
static void dba_close_pe_rsrc ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
{
dba_info * info = ( dba_info * ) rsrc - > ptr ;
/* closes the resource by calling dba_close_rsrc() */
zend_hash_apply_with_argument ( & EG ( persistent_list ) , ( apply_func_arg_t ) dba_close_pe_rsrc_deleter , info TSRMLS_CC ) ;
}
/* }}} */
2002-12-29 15:31:00 +00:00
/* {{{ PHP_INI
*/
2003-01-06 01:08:59 +00:00
ZEND_INI_MH ( OnUpdateDefaultHandler )
2002-12-29 15:31:00 +00:00
{
dba_handler * hptr ;
if ( ! strlen ( new_value ) ) {
DBA_G ( default_hptr ) = NULL ;
return OnUpdateString ( entry , new_value , new_value_length , mh_arg1 , mh_arg2 , mh_arg3 , stage TSRMLS_CC ) ;
}
for ( hptr = handler ; hptr - > name & & strcasecmp ( hptr - > name , new_value ) ; hptr + + ) ;
if ( ! hptr - > name ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " No such handler: %s " , new_value ) ;
return FAILURE ;
}
DBA_G ( default_hptr ) = hptr ;
return OnUpdateString ( entry , new_value , new_value_length , mh_arg1 , mh_arg2 , mh_arg3 , stage TSRMLS_CC ) ;
}
PHP_INI_BEGIN ( )
STD_PHP_INI_ENTRY ( " dba.default_handler " , DBA_DEFAULT , PHP_INI_ALL , OnUpdateDefaultHandler , default_handler , zend_dba_globals , dba_globals )
PHP_INI_END ( )
/* }}} */
/* {{{ php_dba_init_globals
*/
static void php_dba_init_globals ( zend_dba_globals * dba_globals )
{
dba_globals - > default_handler = " " ;
dba_globals - > default_hptr = NULL ;
}
/* }}} */
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-12-29 15:31:00 +00:00
ZEND_INIT_MODULE_GLOBALS ( dba , php_dba_init_globals , NULL ) ;
REGISTER_INI_ENTRIES ( ) ;
2002-08-23 22:24:02 +00:00
le_db = zend_register_list_destructors_ex ( dba_close_rsrc , NULL , " dba " , module_number ) ;
2003-04-13 19:50:28 +00:00
le_pdb = zend_register_list_destructors_ex ( dba_close_pe_rsrc , 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
{
2002-12-29 15:31:00 +00:00
UNREGISTER_INI_ENTRIES ( ) ;
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
{
2002-11-22 15:47:48 +00:00
char * v ;
int len ;
2003-02-26 22:07:50 +00:00
DBA_ID_GET3 ;
1999-07-21 15:12:32 +00:00
DBA_WRITE_CHECK ;
2002-11-22 15:47:48 +00:00
if ( PG ( magic_quotes_runtime ) ) {
len = Z_STRLEN_PP ( val ) ;
v = estrndup ( Z_STRVAL_PP ( val ) , len ) ;
php_stripslashes ( v , & len TSRMLS_CC ) ;
2003-02-26 22:07:50 +00:00
if ( info - > hnd - > update ( info , key_str , key_len , v , len , mode TSRMLS_CC ) = = SUCCESS ) {
2002-11-22 15:47:48 +00:00
efree ( v ) ;
2003-02-26 22:07:50 +00:00
DBA_ID_DONE ;
2002-11-22 15:47:48 +00:00
RETURN_TRUE ;
}
efree ( v ) ;
} else {
2003-02-26 22:07:50 +00:00
if ( info - > hnd - > update ( info , key_str , key_len , VALLEN ( val ) , mode TSRMLS_CC ) = = SUCCESS )
{
DBA_ID_DONE ;
2002-11-22 15:47:48 +00:00
RETURN_TRUE ;
2003-02-26 22:07:50 +00:00
}
2002-11-22 15:47:48 +00:00
}
2003-02-26 22:07:50 +00:00
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
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-12-29 15:31:00 +00:00
char mode [ 4 ] , * pmode , * lock_file_mode = NULL ;
2003-04-13 19:50:28 +00:00
int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0 ;
2003-06-21 18:17:20 +00:00
char * opened_path , * lock_name ;
1999-07-21 15:12:32 +00:00
2002-12-29 15:31:00 +00:00
if ( ac < 2 ) {
1999-07-21 15:12:32 +00:00
WRONG_PARAM_COUNT ;
}
/* we pass additional args to the respective handler */
2003-04-24 20:54:43 +00:00
args = safe_emalloc ( ac , sizeof ( zval * ) , 0 ) ;
2002-08-23 22:24:02 +00:00
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 */
2003-04-24 20:54:43 +00:00
key = safe_emalloc ( keylen , 1 , 1 ) ;
key [ keylen ] = ' \0 ' ;
1999-07-21 15:12:32 +00:00
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-12-29 15:31:00 +00:00
if ( ac = = 2 ) {
hptr = DBA_G ( default_hptr ) ;
if ( ! hptr ) {
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " No default handler selected " ) ;
FREENOW ;
RETURN_FALSE ;
}
} else {
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
2002-12-10 22:51:09 +00:00
* - : ignore locking
2002-11-10 16:03:17 +00:00
*
* 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-12-09 17:54:13 +00:00
if ( pmode [ 0 ] & & ( pmode [ 1 ] = = ' d ' | | pmode [ 1 ] = = ' l ' | | pmode [ 1 ] = = ' - ' ) ) { /* force lock on db file or lck file or disable locking */
switch ( pmode [ 1 ] ) {
case ' d ' :
2002-11-10 16:03:17 +00:00
lock_dbf = 1 ;
2002-12-30 11:32:37 +00:00
if ( ( hptr - > flags & DBA_LOCK_ALL ) = = 0 ) {
lock_flag = ( hptr - > flags & DBA_LOCK_ALL ) ;
break ;
}
2002-12-09 17:54:13 +00:00
/* no break */
case ' l ' :
lock_flag = DBA_LOCK_ALL ;
2002-12-11 10:37:38 +00:00
if ( ( hptr - > flags & DBA_LOCK_ALL ) = = 0 ) {
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 ) ;
}
2002-12-09 17:54:13 +00:00
break ;
default :
case ' - ' :
2002-12-11 10:37:38 +00:00
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 , " Locking cannot be disabled for handler %s " , hptr - > name ) ;
FREENOW ;
RETURN_FALSE ;
}
2002-12-09 17:54:13 +00:00
lock_flag = 0 ;
break ;
2002-11-10 16:03:17 +00:00
}
} else {
2002-11-10 17:58:46 +00:00
lock_flag = ( hptr - > flags & DBA_LOCK_ALL ) ;
2002-12-10 22:02:52 +00:00
lock_dbf = 1 ;
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 ;
2002-11-08 01:03:53 +00:00
case ' c ' :
modenr = DBA_CREAT ;
2002-11-10 17:58:46 +00:00
lock_mode = ( lock_flag & DBA_LOCK_CREAT ) ? LOCK_EX : 0 ;
2003-12-14 22:08:18 +00:00
if ( lock_mode ) {
if ( lock_dbf ) {
/* the create/append check will be done on the lock
* when the lib opens the file it is already created
*/
file_mode = " r+b " ; /* read & write, seek 0 */
lock_file_mode = " a+b " ; /* append */
} else {
file_mode = " a+b " ; /* append */
lock_file_mode = " w+b " ; /* create/truncate */
}
2003-06-21 18:17:20 +00:00
} else {
2003-12-14 22:08:18 +00:00
file_mode = " a+b " ;
2003-06-12 19:53:40 +00:00
}
2003-12-14 22:08:18 +00:00
/* In case of the 'a+b' append mode, the handler is responsible
* to handle any rewind problems ( see flatfile handler ) .
*/
2003-06-21 18:17:20 +00:00
break ;
2003-06-12 19:53:40 +00:00
case ' n ' :
modenr = DBA_TRUNC ;
lock_mode = ( lock_flag & DBA_LOCK_TRUNC ) ? LOCK_EX : 0 ;
file_mode = " w+b " ;
1999-07-21 15:12:32 +00:00
break ;
default :
2003-08-17 17:14:11 +00:00
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " Illegal DBA mode " ) ;
FREENOW ;
RETURN_FALSE ;
2002-11-08 01:03:53 +00:00
}
2003-06-21 18:17:20 +00:00
if ( ! lock_file_mode ) {
lock_file_mode = file_mode ;
}
2002-12-09 17:54:13 +00:00
if ( * pmode = = ' d ' | | * pmode = = ' l ' | | * pmode = = ' - ' ) {
2002-11-10 16:03:17 +00:00
pmode + + ; /* done already - skip here */
}
2002-11-08 01:03:53 +00:00
if ( * pmode = = ' t ' ) {
pmode + + ;
2002-12-09 17:54:13 +00:00
if ( ! lock_flag ) {
2003-08-28 17:56:41 +00:00
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " You cannot combine modifiers - (no lock) and t (test lock) " ) ;
2002-12-09 17:54:13 +00:00
FREENOW ;
RETURN_FALSE ;
}
2002-11-10 23:07:35 +00:00
if ( ! lock_mode ) {
if ( ( hptr - > flags & DBA_LOCK_ALL ) = = 0 ) {
2002-12-09 17:54:13 +00:00
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 (test lock) " , hptr - > name ) ;
2002-11-10 23:07:35 +00:00
FREENOW ;
RETURN_FALSE ;
} else {
2002-12-09 17:54:13 +00:00
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 (test lock) obsolete " , hptr - > name ) ;
2002-11-10 23:07:35 +00:00
FREENOW ;
RETURN_FALSE ;
}
} else {
lock_mode | = LOCK_NB ; /* test =: non blocking */
}
2002-11-08 01:03:53 +00:00
}
2003-08-17 17:14:11 +00:00
if ( * pmode ) {
2002-11-08 01:03:53 +00:00
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-12-20 16:45:34 +00:00
info = pemalloc ( sizeof ( dba_info ) , persistent ) ;
2002-11-06 17:59:03 +00:00
memset ( info , 0 , sizeof ( dba_info ) ) ;
2002-12-20 16:45:34 +00:00
info - > path = pestrdup ( Z_STRVAL_PP ( args [ 0 ] ) , persistent ) ;
1999-07-21 15:12:32 +00:00
info - > mode = modenr ;
info - > argc = ac - 3 ;
info - > argv = args + 3 ;
2002-12-20 17:47:58 +00:00
info - > flags = ( hptr - > flags & ~ DBA_LOCK_ALL ) | ( lock_flag & DBA_LOCK_ALL ) | ( persistent ? DBA_PERSISTENT : 0 ) ;
2002-11-14 14:32:39 +00:00
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 ) {
2003-06-21 18:43:25 +00:00
lock_name = Z_STRVAL_PP ( args [ 0 ] ) ;
2002-11-11 12:04:12 +00:00
} else {
2003-06-21 18:17:20 +00:00
spprintf ( & lock_name , 0 , " %s.lck " , info - > path ) ;
2002-12-10 22:49:33 +00:00
if ( ! strcmp ( file_mode , " r " ) ) {
/* when in read only mode try to use existing .lck file first */
/* do not log errors for .lck file while in read ony mode on .lck file */
lock_file_mode = " rb " ;
2003-06-21 18:17:20 +00:00
info - > lock . fp = php_stream_open_wrapper ( lock_name , lock_file_mode , STREAM_MUST_SEEK | IGNORE_PATH | ENFORCE_SAFE_MODE | persistent_flag , & opened_path ) ;
2002-12-10 22:49:33 +00:00
}
if ( ! info - > lock . fp ) {
/* when not in read mode or failed to open .lck file read only. now try again in create(write) mode and log errors */
lock_file_mode = " a+b " ;
2003-06-21 18:17:20 +00:00
} else {
if ( ! persistent ) {
info - > lock . name = opened_path ;
} else {
info - > lock . name = pestrdup ( opened_path , persistent ) ;
efree ( opened_path ) ;
}
2002-12-10 22:49:33 +00:00
}
2002-11-11 12:04:12 +00:00
}
2002-12-10 22:49:33 +00:00
if ( ! info - > lock . fp ) {
2003-06-21 18:17:20 +00:00
info - > lock . fp = php_stream_open_wrapper ( lock_name , lock_file_mode , STREAM_MUST_SEEK | REPORT_ERRORS | IGNORE_PATH | ENFORCE_SAFE_MODE | persistent_flag , & opened_path ) ;
if ( info - > lock . fp ) {
if ( lock_dbf ) {
/* replace the path info with the real path of the opened file */
pefree ( info - > path , persistent ) ;
info - > path = pestrdup ( opened_path , persistent ) ;
}
/* now store the name of the lock */
if ( ! persistent ) {
info - > lock . name = opened_path ;
} else {
info - > lock . name = pestrdup ( opened_path , persistent ) ;
efree ( opened_path ) ;
}
}
2002-12-10 22:02:52 +00:00
}
2003-06-21 18:43:25 +00:00
if ( ! lock_dbf ) {
efree ( lock_name ) ;
}
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 ;
}
2003-03-04 23:45:48 +00:00
if ( ! php_stream_supports_lock ( info - > lock . fp ) ) {
error = " Stream does not support locking " ;
2002-11-10 17:58:46 +00:00
}
2003-03-04 23:45:48 +00:00
if ( php_stream_lock ( info - > lock . fp , 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 {
2003-04-13 19:50:28 +00:00
info - > fp = php_stream_open_wrapper ( info - > path , file_mode , STREAM_MUST_SEEK | REPORT_ERRORS | IGNORE_PATH | ENFORCE_SAFE_MODE | persistent_flag , NULL ) ;
2002-11-10 17:58:46 +00:00
}
if ( ! info - > fp ) {
dba_close ( info TSRMLS_CC ) ;
/* stream operation already wrote an error message */
FREENOW ;
RETURN_FALSE ;
}
2003-12-18 20:14:15 +00:00
if ( hptr - > flags & ( DBA_NO_APPEND | DBA_CAST_AS_FD ) ) {
/* Needed becasue some systems do not allow to write to the original
* file contents with O_APPEND being set .
*/
if ( SUCCESS ! = php_stream_cast ( info - > fp , PHP_STREAM_AS_FD , ( void * ) & info - > fd , 1 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Could not cast stream " ) ;
dba_close ( info TSRMLS_CC ) ;
FREENOW ;
RETURN_FALSE ;
# ifdef F_SETFL
} else if ( modenr = = DBA_CREAT ) {
int flags = fcntl ( info - > fd , F_SETFL ) ;
fcntl ( info - > fd , F_SETFL , flags & ~ O_APPEND ) ;
# endif
}
}
2002-11-10 17:58:46 +00:00
}
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-12-29 15:31:00 +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 " , hptr - > name , 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 ) {
2003-04-13 19:50:28 +00:00
dba_close ( info TSRMLS_CC ) ;
php_error_docref2 ( NULL TSRMLS_CC , Z_STRVAL_PP ( args [ 0 ] ) , Z_STRVAL_PP ( args [ 1 ] ) , E_WARNING , " Could not register persistent resource " ) ;
2002-08-23 22:24:02 +00:00
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
2003-06-13 14:59:01 +00:00
/* {{{ proto resource 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
}
/* }}} */
2003-06-13 14:59:01 +00:00
/* {{{ proto resource 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
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto bool dba_exists(string key, resource 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 ;
2003-02-26 22:07:50 +00:00
if ( info - > hnd - > exists ( info , key_str , key_len TSRMLS_CC ) = = SUCCESS ) {
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
}
2003-02-26 22:07:50 +00:00
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
RETURN_FALSE ;
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto string dba_fetch(string key, [int skip ,] resource 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
2003-02-22 17:20:06 +00:00
if ( ac = = 3 ) {
if ( ! strcmp ( info - > hnd - > name , " cdb " ) ) {
if ( skip < 0 ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Handler %s accepts only skip values greater than or equal to zero, using skip=0 " , info - > hnd - > name ) ;
skip = 0 ;
}
} else if ( ! strcmp ( info - > hnd - > name , " inifile " ) ) {
/* "-1" is compareable to 0 but allows a non restrictive
* access which is fater . For example ' inifile ' uses this
* to allow faster access when the key was already found
* using firstkey / nextkey . However explicitly setting the
* value to 0 ensures the first value .
*/
if ( skip < - 1 ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Handler %s accepts only skip value -1 and greater, using skip=0 " , info - > hnd - > name ) ;
skip = 0 ;
}
} else {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Handler %s does not support optional skip parameter, the value will be ignored " , info - > hnd - > name ) ;
skip = 0 ;
}
} else {
skip = 0 ;
2002-11-03 16:43:07 +00:00
}
2003-02-26 22:07:50 +00:00
if ( ( val = info - > hnd - > fetch ( info , key_str , key_len , 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 ) ;
}
2003-02-26 22:07:50 +00:00
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
RETURN_STRINGL ( val , len , 0 ) ;
}
2003-02-26 22:07:50 +00:00
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
RETURN_FALSE ;
}
/* }}} */
2003-11-13 07:53:15 +00:00
/* {{{ proto array|false dba_key_split(string key)
Splits an inifile key into an array of the form array ( 0 = > group , 1 = > value_name ) but returns false if input is false or null */
2003-11-12 21:43:03 +00:00
PHP_FUNCTION ( dba_key_split )
{
2003-11-13 07:53:15 +00:00
zval * zkey ;
2003-11-12 21:43:03 +00:00
char * key , * name ;
int key_len ;
2003-11-13 07:53:15 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 ) {
WRONG_PARAM_COUNT ;
}
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & zkey ) = = SUCCESS ) {
if ( Z_TYPE_P ( zkey ) = = IS_NULL | | ( Z_TYPE_P ( zkey ) = = IS_BOOL & & ! Z_LVAL_P ( zkey ) ) ) {
RETURN_BOOL ( 0 ) ;
}
}
2003-11-12 21:43:03 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & key , & key_len ) = = FAILURE ) {
2003-11-13 07:53:15 +00:00
RETURN_BOOL ( 0 ) ;
2003-11-12 21:43:03 +00:00
}
array_init ( return_value ) ;
if ( key [ 0 ] = = ' [ ' & & ( name = strchr ( key , ' ] ' ) ) ! = NULL ) {
add_next_index_stringl ( return_value , key + 1 , name - ( key + 1 ) , 1 ) ;
add_next_index_stringl ( return_value , name + 1 , key_len - ( name - key + 1 ) , 1 ) ;
} else {
add_next_index_stringl ( return_value , " " , 0 , 1 ) ;
add_next_index_stringl ( return_value , key , key_len , 1 ) ;
}
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto string dba_firstkey(resource 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 ;
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto string dba_nextkey(resource 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 ;
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto bool dba_delete(string key, resource handle)
2003-02-22 17:20:06 +00:00
Deletes the entry associated with key
If inifile : remove all other key lines */
1999-07-21 15:12:32 +00:00
PHP_FUNCTION ( dba_delete )
{
DBA_ID_GET2 ;
DBA_WRITE_CHECK ;
2003-02-26 22:07:50 +00:00
if ( info - > hnd - > delete ( info , key_str , key_len TSRMLS_CC ) = = SUCCESS )
{
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
RETURN_TRUE ;
2003-02-26 22:07:50 +00:00
}
DBA_ID_DONE ;
1999-07-21 15:12:32 +00:00
RETURN_FALSE ;
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto bool dba_insert(string key, string value, resource handle)
2003-02-22 17:20:06 +00:00
If not inifile : Insert value as key , return false , if key exists already
If inifile : Add vakue as key ( next instance of key ) */
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
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto bool dba_replace(string key, string value, resource handle)
2003-02-22 17:20:06 +00:00
Inserts value as key , replaces key , if key exists already
If inifile : remove all other key lines */
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
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto bool dba_optimize(resource 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 ;
}
/* }}} */
2003-11-13 19:08:41 +00:00
/* {{{ proto bool dba_sync(resource 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-12-30 13:07:30 +00:00
/* {{{ proto array dba_handlers([bool full_info])
2003-05-19 22:52:27 +00:00
List configured database handlers */
2002-10-24 20:43:03 +00:00
PHP_FUNCTION ( dba_handlers )
{
dba_handler * hptr ;
2002-12-30 13:07:30 +00:00
zend_bool full_info = 0 ;
2002-10-24 20:43:03 +00:00
2002-12-30 13:07:30 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |b " , & full_info ) = = FAILURE ) {
2002-10-24 20:43:03 +00:00
ZEND_WRONG_PARAM_COUNT ( ) ;
RETURN_FALSE ;
}
2003-01-18 19:49:28 +00:00
array_init ( return_value ) ;
2002-10-24 20:43:03 +00:00
for ( hptr = handler ; hptr - > name ; hptr + + ) {
2002-12-30 13:07:30 +00:00
if ( full_info ) {
add_assoc_string ( return_value , hptr - > name , hptr - > info ( hptr , NULL TSRMLS_CC ) , 0 ) ;
} else {
add_next_index_string ( return_value , hptr - > name , 1 ) ;
}
2002-10-24 20:43:03 +00:00
}
}
/* }}} */
2002-10-25 10:06:35 +00:00
/* {{{ proto array dba_list()
2003-05-19 22:52:27 +00:00
List opened databases */
2002-10-25 10:06:35 +00:00
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 ;
}
2003-01-18 19:49:28 +00:00
array_init ( return_value ) ;
2002-10-25 10:06:35 +00:00
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 ) ;
}
}
}
/* }}} */
2002-12-29 15:31:00 +00:00
# endif /* HAVE_DBA */
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
*/