1999-04-19 21:56:50 +08:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
2004-01-08 16:18:22 +08:00
|
|
|
| PHP Version 5 |
|
1999-04-19 21:56:50 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2004-01-08 16:18:22 +08:00
|
|
|
| Copyright (c) 1997-2004 The PHP Group |
|
1999-04-19 21:56:50 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2003-06-11 04:04:29 +08:00
|
|
|
| This source file is subject to version 3.0 of the PHP license, |
|
1999-07-16 21:13:16 +08:00
|
|
|
| that is bundled with this package in the file LICENSE, and is |
|
2003-06-11 04:04:29 +08:00
|
|
|
| available through the world-wide-web at the following url: |
|
|
|
|
| http://www.php.net/license/3_0.txt. |
|
1999-07-16 21:13:16 +08: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-04-19 21:56:50 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2002-02-28 16:29:35 +08:00
|
|
|
| Author: Jim Winstead <jimw@php.net> |
|
1999-04-19 21:56:50 +08:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
|
2001-06-05 21:12:10 +08:00
|
|
|
/* $Id$ */
|
|
|
|
|
2001-05-24 18:07:29 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
1999-06-28 05:23:17 +08:00
|
|
|
#endif
|
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
#include "php.h"
|
|
|
|
#include "safe_mode.h"
|
2001-02-24 06:07:16 +08:00
|
|
|
#include "fopen_wrappers.h"
|
1999-04-19 21:56:50 +08:00
|
|
|
#include "php_globals.h"
|
|
|
|
|
2001-05-24 18:07:29 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
#if DBASE
|
1999-05-21 16:20:13 +08:00
|
|
|
#include "php_dbase.h"
|
|
|
|
#include "dbf.h"
|
1999-04-19 21:56:50 +08:00
|
|
|
#if defined(THREAD_SAFE)
|
|
|
|
DWORD DbaseTls;
|
|
|
|
static int numthreads=0;
|
|
|
|
void *dbase_mutex;
|
|
|
|
|
|
|
|
typedef struct dbase_global_struct{
|
|
|
|
int le_dbhead;
|
|
|
|
}dbase_global_struct;
|
|
|
|
|
|
|
|
#define DBase_GLOBAL(a) dbase_globals->a
|
|
|
|
|
|
|
|
#define DBase_TLS_VARS \
|
|
|
|
dbase_global_struct *dbase_globals; \
|
|
|
|
dbase_globals=TlsGetValue(DbaseTls);
|
|
|
|
|
|
|
|
#else
|
|
|
|
static int le_dbhead;
|
|
|
|
#define DBase_GLOBAL(a) a
|
|
|
|
#define DBase_TLS_VARS
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
2001-07-31 13:44:11 +08:00
|
|
|
static void _close_dbase(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
1999-04-19 21:56:50 +08:00
|
|
|
{
|
2000-10-21 02:25:16 +08:00
|
|
|
dbhead_t *dbhead = (dbhead_t *)rsrc->ptr;
|
2001-07-31 13:44:11 +08:00
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
close(dbhead->db_fd);
|
|
|
|
free_dbf_head(dbhead);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-07-28 01:09:35 +08:00
|
|
|
PHP_MINIT_FUNCTION(dbase)
|
1999-04-19 21:56:50 +08:00
|
|
|
{
|
|
|
|
#if defined(THREAD_SAFE)
|
|
|
|
dbase_global_struct *dbase_globals;
|
2000-05-23 17:33:51 +08:00
|
|
|
#ifdef COMPILE_DL_DBASE
|
2001-08-12 00:39:07 +08:00
|
|
|
CREATE_MUTEX(dbase_mutex, "DBase_TLS");
|
1999-04-19 21:56:50 +08:00
|
|
|
SET_MUTEX(dbase_mutex);
|
|
|
|
numthreads++;
|
|
|
|
if (numthreads==1){
|
|
|
|
if ((DbaseTls=TlsAlloc())==0xFFFFFFFF){
|
|
|
|
FREE_MUTEX(dbase_mutex);
|
|
|
|
return 0;
|
|
|
|
}}
|
|
|
|
FREE_MUTEX(dbase_mutex);
|
|
|
|
#endif
|
|
|
|
dbase_globals = (dbase_global_struct *) LocalAlloc(LPTR, sizeof(dbase_global_struct));
|
|
|
|
TlsSetValue(DbaseTls, (void *) dbase_globals);
|
|
|
|
#endif
|
2000-10-21 02:25:16 +08:00
|
|
|
DBase_GLOBAL(le_dbhead) =
|
2000-10-26 01:44:02 +08:00
|
|
|
zend_register_list_destructors_ex(_close_dbase, NULL, "dbase", module_number);
|
1999-04-19 21:56:50 +08:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
1999-07-28 01:09:35 +08:00
|
|
|
static PHP_MSHUTDOWN_FUNCTION(dbase)
|
|
|
|
{
|
1999-04-19 21:56:50 +08:00
|
|
|
#if defined(THREAD_SAFE)
|
|
|
|
dbase_global_struct *dbase_globals;
|
|
|
|
dbase_globals = TlsGetValue(DbaseTls);
|
|
|
|
if (dbase_globals != 0)
|
|
|
|
LocalFree((HLOCAL) dbase_globals);
|
2000-05-23 17:33:51 +08:00
|
|
|
#ifdef COMPILE_DL_DBASE
|
1999-04-19 21:56:50 +08:00
|
|
|
SET_MUTEX(dbase_mutex);
|
|
|
|
numthreads--;
|
|
|
|
if (!numthreads){
|
|
|
|
if (!TlsFree(DbaseTls)){
|
|
|
|
FREE_MUTEX(dbase_mutex);
|
|
|
|
return 0;
|
|
|
|
}}
|
|
|
|
FREE_MUTEX(dbase_mutex);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* {{{ proto int dbase_open(string name, int mode)
|
|
|
|
Opens a dBase-format database file */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_open)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbf_name, **options;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int handle;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbf_name, &options) == FAILURE) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_string_ex(dbf_name);
|
|
|
|
convert_to_long_ex(options);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2005-02-04 22:28:50 +08:00
|
|
|
if (Z_LVAL_PP(options) == 1) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open %s in write-only mode", Z_STRVAL_PP(dbf_name));
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(dbf_name), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (php_check_open_basedir(Z_STRVAL_PP(dbf_name) TSRMLS_CC)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 21:48:07 +08:00
|
|
|
dbh = dbf_open(Z_STRVAL_PP(dbf_name), Z_LVAL_PP(options) TSRMLS_CC);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (dbh == NULL) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to open database %s", Z_STRVAL_PP(dbf_name));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-12-18 03:51:39 +08:00
|
|
|
handle = zend_list_insert(dbh, DBase_GLOBAL(le_dbhead));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_LONG(handle);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
/* {{{ proto bool dbase_close(int identifier)
|
|
|
|
Closes an open dBase-format database file */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_close)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbh_id;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
zend_list_delete(Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_TRUE;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
/* {{{ proto int dbase_numrecords(int identifier)
|
|
|
|
Returns the number of records in the database */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_numrecords)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbh_id;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN_LONG(dbh->db_records);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
/* {{{ proto int dbase_numfields(int identifier)
|
|
|
|
Returns the number of fields (columns) in the database */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_numfields)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbh_id;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &dbh_id) == FAILURE) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN_LONG(dbh->db_nfields);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
/* {{{ proto bool dbase_pack(int identifier)
|
|
|
|
Packs the database (deletes records marked for deletion) */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_pack)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbh_id;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &dbh_id) == FAILURE) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pack_dbf(dbh);
|
|
|
|
put_dbf_info(dbh);
|
|
|
|
RETURN_TRUE;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
/* {{{ proto bool dbase_add_record(int identifier, array data)
|
|
|
|
Adds a record to the database */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_add_record)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbh_id, **fields, **field;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
|
|
|
|
int num_fields;
|
|
|
|
dbfield_t *dbf, *cur_f;
|
|
|
|
char *cp, *t_cp;
|
|
|
|
int i;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbh_id, &fields) == FAILURE) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
if (Z_TYPE_PP(fields) != IS_ARRAY) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
if (num_fields != dbh->db_nfields) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified");
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cp = t_cp = (char *)emalloc(dbh->db_rlen + 1);
|
|
|
|
*t_cp++ = VALID_RECORD;
|
|
|
|
|
|
|
|
dbf = dbh->db_fields;
|
|
|
|
for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
|
2000-07-23 11:45:24 +08:00
|
|
|
zval tmp;
|
2003-01-15 10:31:16 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error");
|
1999-04-19 21:56:50 +08:00
|
|
|
efree(cp);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2000-07-23 11:45:24 +08:00
|
|
|
|
2000-08-14 01:41:20 +08:00
|
|
|
tmp = **field;
|
2000-07-23 11:45:24 +08:00
|
|
|
zval_copy_ctor(&tmp);
|
|
|
|
convert_to_string(&tmp);
|
2003-10-14 15:49:34 +08:00
|
|
|
snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL(tmp));
|
2000-07-23 11:45:24 +08:00
|
|
|
zval_dtor(&tmp);
|
1999-04-19 21:56:50 +08:00
|
|
|
t_cp += cur_f->db_flen;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbh->db_records++;
|
|
|
|
if (put_dbf_record(dbh, dbh->db_records, cp) < 0) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records);
|
1999-04-19 21:56:50 +08:00
|
|
|
efree(cp);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-10-14 15:49:34 +08:00
|
|
|
put_dbf_info(dbh);
|
1999-04-19 21:56:50 +08:00
|
|
|
efree(cp);
|
|
|
|
|
|
|
|
RETURN_TRUE;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
1999-06-28 05:15:12 +08:00
|
|
|
/* {{{ proto bool dbase_replace_record(int identifier, array data, int recnum)
|
|
|
|
Replaces a record to the database */
|
1999-12-18 05:34:28 +08:00
|
|
|
PHP_FUNCTION(dbase_replace_record)
|
|
|
|
{
|
2003-01-15 21:48:07 +08:00
|
|
|
zval **dbh_id, **fields, **field, **recnum;
|
1999-06-28 05:15:12 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
|
|
|
|
int num_fields;
|
|
|
|
dbfield_t *dbf, *cur_f;
|
|
|
|
char *cp, *t_cp;
|
|
|
|
int i;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &dbh_id, &fields, &recnum) == FAILURE) {
|
1999-06-28 05:15:12 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
convert_to_long_ex(recnum);
|
|
|
|
if (Z_TYPE_PP(fields) != IS_ARRAY) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
|
1999-06-28 05:15:12 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-06-28 05:15:12 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-06-28 05:15:12 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
|
1999-06-28 05:15:12 +08:00
|
|
|
|
|
|
|
if (num_fields != dbh->db_nfields) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified");
|
1999-06-28 05:15:12 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cp = t_cp = (char *)emalloc(dbh->db_rlen + 1);
|
|
|
|
*t_cp++ = VALID_RECORD;
|
|
|
|
|
|
|
|
dbf = dbh->db_fields;
|
|
|
|
for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
|
2003-01-15 10:31:16 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error");
|
1999-06-28 05:15:12 +08:00
|
|
|
efree(cp);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2001-08-17 07:44:10 +08:00
|
|
|
convert_to_string_ex(field);
|
2003-10-14 15:49:34 +08:00
|
|
|
snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL_PP(field));
|
1999-06-28 05:15:12 +08:00
|
|
|
t_cp += cur_f->db_flen;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (put_dbf_record(dbh, Z_LVAL_PP(recnum), cp) < 0) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records);
|
1999-06-28 05:15:12 +08:00
|
|
|
efree(cp);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
put_dbf_info(dbh);
|
|
|
|
efree(cp);
|
|
|
|
|
|
|
|
RETURN_TRUE;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
/* {{{ proto bool dbase_delete_record(int identifier, int record)
|
|
|
|
Marks a record to be deleted */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_delete_record)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **dbh_id, **record;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &dbh_id, &record) == FAILURE)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
convert_to_long_ex(record);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (del_dbf_record(dbh, Z_LVAL_PP(record)) < 0) {
|
|
|
|
if (Z_LVAL_PP(record) > dbh->db_records) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "record %ld out of bounds", Z_LVAL_PP(record));
|
1999-04-19 21:56:50 +08:00
|
|
|
} else {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to delete record %ld", Z_LVAL_PP(record));
|
1999-04-19 21:56:50 +08:00
|
|
|
}
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
put_dbf_info(dbh);
|
|
|
|
RETURN_TRUE;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2002-06-17 10:27:34 +08:00
|
|
|
/* {{{ php_dbase_get_record
|
|
|
|
*/
|
|
|
|
static void php_dbase_get_record(INTERNAL_FUNCTION_PARAMETERS, int assoc)
|
2001-08-05 09:43:02 +08:00
|
|
|
{
|
2003-01-15 21:48:07 +08:00
|
|
|
zval **dbh_id, **record;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
dbfield_t *dbf, *cur_f;
|
|
|
|
char *data, *fnp, *str_value;
|
1999-06-28 05:23:17 +08:00
|
|
|
size_t cursize = 0;
|
2001-12-14 12:22:01 +08:00
|
|
|
long overflow_test;
|
|
|
|
int errno_save;
|
1999-04-19 21:56:50 +08:00
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &dbh_id, &record) == FAILURE)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
convert_to_long_ex(record);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if ((data = get_dbf_record(dbh, Z_LVAL_PP(record))) == NULL) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to read bad record %ld", Z_LVAL_PP(record));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbf = dbh->db_fields;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
array_init(return_value);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2002-06-17 10:27:34 +08:00
|
|
|
fnp = NULL;
|
|
|
|
for (cur_f = dbf; cur_f < &dbf[dbh->db_nfields]; cur_f++) {
|
1999-04-19 21:56:50 +08:00
|
|
|
/* get the value */
|
|
|
|
str_value = (char *)emalloc(cur_f->db_flen + 1);
|
1999-06-28 05:23:17 +08:00
|
|
|
|
2002-03-05 08:28:20 +08:00
|
|
|
if(cursize <= (unsigned)cur_f->db_flen) {
|
1999-06-28 05:23:17 +08:00
|
|
|
cursize = cur_f->db_flen + 1;
|
|
|
|
fnp = erealloc(fnp, cursize);
|
|
|
|
}
|
2002-06-17 10:27:34 +08:00
|
|
|
snprintf(str_value, cursize, cur_f->db_format, get_field_val(data, cur_f, fnp));
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
/* now convert it to the right php internal type */
|
|
|
|
switch (cur_f->db_type) {
|
|
|
|
case 'C':
|
|
|
|
case 'D':
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_string(return_value, str_value, 1);
|
|
|
|
} else {
|
|
|
|
add_assoc_string(return_value, cur_f->db_fname, str_value, 1);
|
|
|
|
}
|
1999-04-19 21:56:50 +08:00
|
|
|
break;
|
2001-10-09 05:51:12 +08:00
|
|
|
case 'I': /* FALLS THROUGH */
|
2001-08-14 19:07:18 +08:00
|
|
|
case 'N':
|
1999-04-19 21:56:50 +08:00
|
|
|
if (cur_f->db_fdc == 0) {
|
2001-12-14 12:22:01 +08:00
|
|
|
/* Large integers in dbase can be larger than long */
|
|
|
|
errno_save = errno;
|
|
|
|
overflow_test = strtol(str_value, NULL, 10);
|
|
|
|
if (errno == ERANGE) {
|
|
|
|
/* If the integer is too large, keep it as string */
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_string(return_value, str_value, 1);
|
|
|
|
} else {
|
|
|
|
add_assoc_string(return_value, cur_f->db_fname, str_value, 1);
|
|
|
|
}
|
2001-12-14 12:22:01 +08:00
|
|
|
} else {
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_long(return_value, overflow_test);
|
|
|
|
} else {
|
|
|
|
add_assoc_long(return_value, cur_f->db_fname, overflow_test);
|
|
|
|
}
|
2001-12-14 12:22:01 +08:00
|
|
|
}
|
|
|
|
errno = errno_save;
|
1999-04-19 21:56:50 +08:00
|
|
|
} else {
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_double(return_value, atof(str_value));
|
|
|
|
} else {
|
|
|
|
add_assoc_double(return_value, cur_f->db_fname, atof(str_value));
|
|
|
|
}
|
1999-04-19 21:56:50 +08:00
|
|
|
}
|
|
|
|
break;
|
2001-08-14 19:07:18 +08:00
|
|
|
case 'L': /* we used to FALL THROUGH, but now we check for T/Y and F/N
|
|
|
|
and insert 1 or 0, respectively. db_fdc is the number of
|
|
|
|
decimals, which we don't care about. 3/14/2001 LEW */
|
|
|
|
if ((*str_value == 'T') || (*str_value == 'Y')) {
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_long(return_value, strtol("1", NULL, 10));
|
|
|
|
} else {
|
|
|
|
add_assoc_long(return_value, cur_f->db_fname,strtol("1", NULL, 10));
|
|
|
|
}
|
2001-08-14 19:07:18 +08:00
|
|
|
} else {
|
|
|
|
if ((*str_value == 'F') || (*str_value == 'N')) {
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_long(return_value, strtol("0", NULL, 10));
|
|
|
|
} else {
|
|
|
|
add_assoc_long(return_value, cur_f->db_fname,strtol("0", NULL, 10));
|
|
|
|
}
|
2001-08-14 19:07:18 +08:00
|
|
|
} else {
|
2002-06-17 10:27:34 +08:00
|
|
|
if (!assoc) {
|
|
|
|
add_next_index_long(return_value, strtol(" ", NULL, 10));
|
|
|
|
} else {
|
|
|
|
add_assoc_long(return_value, cur_f->db_fname,strtol(" ", NULL, 10));
|
|
|
|
}
|
2001-08-14 19:07:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
1999-04-19 21:56:50 +08:00
|
|
|
case 'M':
|
|
|
|
/* this is a memo field. don't know how to deal with this yet */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* should deal with this in some way */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
efree(str_value);
|
|
|
|
}
|
2002-06-17 10:27:34 +08:00
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
efree(fnp);
|
|
|
|
|
|
|
|
/* mark whether this record was deleted */
|
|
|
|
if (data[0] == '*') {
|
2001-08-12 00:39:07 +08:00
|
|
|
add_assoc_long(return_value, "deleted", 1);
|
1999-04-19 21:56:50 +08:00
|
|
|
} else {
|
2001-08-12 00:39:07 +08:00
|
|
|
add_assoc_long(return_value, "deleted", 0);
|
1999-04-19 21:56:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
/* }}} */
|
2002-06-17 10:27:34 +08:00
|
|
|
|
|
|
|
/* {{{ proto array dbase_get_record(int identifier, int record)
|
|
|
|
Returns an array representing a record from the database */
|
|
|
|
PHP_FUNCTION(dbase_get_record)
|
|
|
|
{
|
|
|
|
php_dbase_get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
/* From Martin Kuba <makub@aida.inet.cz> */
|
|
|
|
/* {{{ proto array dbase_get_record_with_names(int identifier, int record)
|
|
|
|
Returns an associative array representing a record from the database */
|
|
|
|
PHP_FUNCTION(dbase_get_record_with_names)
|
|
|
|
{
|
|
|
|
php_dbase_get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
|
|
|
|
}
|
|
|
|
/* }}} */
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
/* {{{ proto bool dbase_create(string filename, array fields)
|
|
|
|
Creates a new dBase-format database file */
|
2001-08-05 09:43:02 +08:00
|
|
|
PHP_FUNCTION(dbase_create)
|
|
|
|
{
|
2003-01-15 10:31:16 +08:00
|
|
|
zval **filename, **fields, **field, **value;
|
1999-04-19 21:56:50 +08:00
|
|
|
int fd;
|
|
|
|
dbhead_t *dbh;
|
|
|
|
|
|
|
|
int num_fields;
|
|
|
|
dbfield_t *dbf, *cur_f;
|
|
|
|
int i, rlen, handle;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &filename, &fields) == FAILURE)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
2003-01-15 10:31:16 +08:00
|
|
|
convert_to_string_ex(filename);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (Z_TYPE_PP(fields) != IS_ARRAY) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) {
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
if ((fd = VCWD_OPEN_MODE(Z_STRVAL_PP(filename), O_BINARY|O_RDWR|O_CREAT, 0644)) < 0) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create database (%d): %s", errno, strerror(errno));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-01-15 10:31:16 +08:00
|
|
|
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
/* have to use regular malloc() because this gets free()d by
|
|
|
|
code in the dbase library */
|
|
|
|
dbh = (dbhead_t *)malloc(sizeof(dbhead_t));
|
|
|
|
dbf = (dbfield_t *)malloc(sizeof(dbfield_t) * num_fields);
|
|
|
|
if (!dbh || !dbf) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for header info");
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize the header structure */
|
|
|
|
dbh->db_fields = dbf;
|
|
|
|
dbh->db_fd = fd;
|
|
|
|
dbh->db_dbt = DBH_TYPE_NORMAL;
|
|
|
|
strcpy(dbh->db_date, "19930818");
|
|
|
|
dbh->db_records = 0;
|
|
|
|
dbh->db_nfields = num_fields;
|
2001-12-31 17:13:08 +08:00
|
|
|
dbh->db_hlen = sizeof(struct dbf_dhead) + 1 + num_fields * sizeof(struct dbf_dfield);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
rlen = 1;
|
2000-07-01 06:44:20 +08:00
|
|
|
/**
|
|
|
|
* Patch by greg@darkphoton.com
|
|
|
|
**/
|
|
|
|
/* make sure that the db_format entries for all fields are set to NULL to ensure we
|
|
|
|
don't seg fault if there's an error and we need to call free_dbf_head() before all
|
|
|
|
fields have been defined. */
|
|
|
|
for (i = 0, cur_f = dbf; i < num_fields; i++, cur_f++) {
|
|
|
|
cur_f->db_format = NULL;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* end patch
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
for (i = 0, cur_f = dbf; i < num_fields; i++, cur_f++) {
|
|
|
|
/* look up the first field */
|
2003-01-15 10:31:16 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to find field %d", i);
|
1999-04-19 21:56:50 +08:00
|
|
|
free_dbf_head(dbh);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2000-07-20 10:48:44 +08:00
|
|
|
if (Z_TYPE_PP (field) != IS_ARRAY) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "second parameter must be array of arrays");
|
1999-04-19 21:56:50 +08:00
|
|
|
free_dbf_head(dbh);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* field name */
|
2000-07-20 10:48:44 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP(field), 0, (void **)&value) == FAILURE) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field name as first element of list in field %d", i);
|
1999-04-19 21:56:50 +08:00
|
|
|
free_dbf_head(dbh);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2000-07-01 05:21:17 +08:00
|
|
|
convert_to_string_ex(value);
|
2001-09-26 05:58:48 +08:00
|
|
|
if (Z_STRLEN_PP(value) > 10 || Z_STRLEN_PP(value) == 0) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid field name '%s' (must be non-empty and less than or equal to 10 characters)", Z_STRVAL_PP(value));
|
1999-04-19 21:56:50 +08:00
|
|
|
free_dbf_head(dbh);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2001-09-26 05:58:48 +08:00
|
|
|
copy_crimp(cur_f->db_fname, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
/* field type */
|
2001-08-12 00:39:07 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP (field), 1, (void **)&value) == FAILURE) {
|
2003-09-21 21:17:20 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field type as second element of list in field %d", i);
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2000-07-01 05:21:17 +08:00
|
|
|
convert_to_string_ex(value);
|
2001-09-26 05:58:48 +08:00
|
|
|
cur_f->db_type = toupper(*Z_STRVAL_PP(value));
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
cur_f->db_fdc = 0;
|
|
|
|
|
|
|
|
/* verify the field length */
|
|
|
|
switch (cur_f->db_type) {
|
|
|
|
case 'L':
|
|
|
|
cur_f->db_flen = 1;
|
|
|
|
break;
|
|
|
|
case 'M':
|
2001-12-31 18:23:30 +08:00
|
|
|
cur_f->db_flen = 10;
|
1999-04-19 21:56:50 +08:00
|
|
|
dbh->db_dbt = DBH_TYPE_MEMO;
|
|
|
|
/* should create the memo file here, probably */
|
|
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
cur_f->db_flen = 8;
|
|
|
|
break;
|
|
|
|
case 'N':
|
|
|
|
case 'C':
|
|
|
|
/* field length */
|
2001-08-12 00:39:07 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP (field), 2, (void **)&value) == FAILURE) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field length as third element of list in field %d", i);
|
1999-04-19 21:56:50 +08:00
|
|
|
free_dbf_head(dbh);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2000-07-01 05:21:17 +08:00
|
|
|
convert_to_long_ex(value);
|
2001-09-26 05:58:48 +08:00
|
|
|
cur_f->db_flen = Z_LVAL_PP(value);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
if (cur_f->db_type == 'N') {
|
2000-07-20 10:48:44 +08:00
|
|
|
if (zend_hash_index_find(Z_ARRVAL_PP (field), 3, (void **)&value) == FAILURE) {
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field precision as fourth element of list in field %d", i);
|
1999-04-19 21:56:50 +08:00
|
|
|
free_dbf_head(dbh);
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2000-07-01 05:21:17 +08:00
|
|
|
convert_to_long_ex(value);
|
2001-09-26 05:58:48 +08:00
|
|
|
cur_f->db_fdc = Z_LVAL_PP(value);
|
1999-04-19 21:56:50 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2003-01-15 10:31:16 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown field type '%c'", cur_f->db_type);
|
1999-04-19 21:56:50 +08:00
|
|
|
}
|
|
|
|
cur_f->db_foffset = rlen;
|
|
|
|
rlen += cur_f->db_flen;
|
|
|
|
|
|
|
|
cur_f->db_format = get_dbf_f_fmt(cur_f);
|
|
|
|
}
|
|
|
|
|
|
|
|
dbh->db_rlen = rlen;
|
2002-06-17 10:27:34 +08:00
|
|
|
put_dbf_info(dbh);
|
1999-04-19 21:56:50 +08:00
|
|
|
|
1999-12-18 03:51:39 +08:00
|
|
|
handle = zend_list_insert(dbh, DBase_GLOBAL(le_dbhead));
|
1999-04-19 21:56:50 +08:00
|
|
|
RETURN_LONG(handle);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2001-06-05 21:12:10 +08:00
|
|
|
/* {{{ dbase_functions[]
|
|
|
|
*/
|
1999-04-19 21:56:50 +08:00
|
|
|
function_entry dbase_functions[] = {
|
1999-07-28 01:17:05 +08:00
|
|
|
PHP_FE(dbase_open, NULL)
|
|
|
|
PHP_FE(dbase_create, NULL)
|
|
|
|
PHP_FE(dbase_close, NULL)
|
|
|
|
PHP_FE(dbase_numrecords, NULL)
|
|
|
|
PHP_FE(dbase_numfields, NULL)
|
|
|
|
PHP_FE(dbase_add_record, NULL)
|
|
|
|
PHP_FE(dbase_replace_record, NULL)
|
|
|
|
PHP_FE(dbase_get_record, NULL)
|
|
|
|
PHP_FE(dbase_get_record_with_names, NULL)
|
|
|
|
PHP_FE(dbase_delete_record, NULL)
|
|
|
|
PHP_FE(dbase_pack, NULL)
|
2003-07-16 02:19:51 +08:00
|
|
|
PHP_FE(dbase_get_header_info, NULL)
|
1999-04-19 21:56:50 +08:00
|
|
|
{NULL, NULL, NULL}
|
|
|
|
};
|
2001-06-05 21:12:10 +08:00
|
|
|
/* }}} */
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2003-07-16 02:19:51 +08:00
|
|
|
/* Added by Zak Greant <zak@php.net> */
|
|
|
|
/* {{{ proto array dbase_get_header_info(int database_handle)
|
|
|
|
*/
|
|
|
|
PHP_FUNCTION(dbase_get_header_info)
|
|
|
|
{
|
|
|
|
zval **dbh_id, *row;
|
|
|
|
dbfield_t *dbf, *cur_f;
|
|
|
|
dbhead_t *dbh;
|
|
|
|
int dbh_type;
|
|
|
|
DBase_TLS_VARS;
|
|
|
|
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
|
|
|
|
WRONG_PARAM_COUNT;
|
|
|
|
}
|
|
|
|
convert_to_long_ex(dbh_id);
|
|
|
|
|
|
|
|
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
|
|
|
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
2003-08-29 05:00:24 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
2003-07-16 02:19:51 +08:00
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
|
2003-08-01 02:28:47 +08:00
|
|
|
array_init(return_value);
|
2003-07-16 02:19:51 +08:00
|
|
|
|
|
|
|
dbf = dbh->db_fields;
|
|
|
|
for (cur_f = dbf; cur_f < &dbh->db_fields[dbh->db_nfields]; ++cur_f) {
|
|
|
|
MAKE_STD_ZVAL(row);
|
|
|
|
array_init(row);
|
|
|
|
|
|
|
|
add_next_index_zval(return_value, row);
|
|
|
|
|
|
|
|
/* field name */
|
|
|
|
add_assoc_string(row, "name", cur_f->db_fname, 1);
|
|
|
|
|
|
|
|
/* field type */
|
|
|
|
switch (cur_f->db_type) {
|
|
|
|
case 'C': add_assoc_string(row, "type", "character", 1); break;
|
|
|
|
case 'D': add_assoc_string(row, "type", "date", 1); break;
|
|
|
|
case 'I': add_assoc_string(row, "type", "integer", 1); break;
|
|
|
|
case 'N': add_assoc_string(row, "type", "number", 1); break;
|
|
|
|
case 'L': add_assoc_string(row, "type", "boolean", 1); break;
|
|
|
|
case 'M': add_assoc_string(row, "type", "memo", 1); break;
|
|
|
|
default: add_assoc_string(row, "type", "unknown", 1); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* length of field */
|
|
|
|
add_assoc_long(row, "length", cur_f->db_flen);
|
|
|
|
|
|
|
|
/* number of decimals in field */
|
2003-11-27 19:32:05 +08:00
|
|
|
switch (cur_f->db_type) {
|
|
|
|
case 'N':
|
|
|
|
case 'I':
|
|
|
|
add_assoc_long(row, "precision", cur_f->db_fdc);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
add_assoc_long(row, "precision", 0);
|
|
|
|
}
|
2003-07-16 02:19:51 +08:00
|
|
|
|
|
|
|
/* format for printing %s etc */
|
2003-07-16 19:08:03 +08:00
|
|
|
add_assoc_string(row, "format", cur_f->db_format, 1);
|
2003-07-16 02:19:51 +08:00
|
|
|
|
|
|
|
/* offset within record */
|
2003-07-16 19:08:03 +08:00
|
|
|
add_assoc_long(row, "offset", cur_f->db_foffset);
|
2003-07-16 02:19:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
1999-12-18 04:55:31 +08:00
|
|
|
zend_module_entry dbase_module_entry = {
|
2001-10-12 07:33:59 +08:00
|
|
|
STANDARD_MODULE_HEADER,
|
|
|
|
"dbase", dbase_functions, PHP_MINIT(dbase), PHP_MSHUTDOWN(dbase), NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
|
1999-04-19 21:56:50 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2000-05-23 17:33:51 +08:00
|
|
|
#ifdef COMPILE_DL_DBASE
|
2000-05-02 08:30:36 +08:00
|
|
|
ZEND_GET_MODULE(dbase)
|
1999-04-19 21:56:50 +08:00
|
|
|
|
2002-10-24 21:15:49 +08:00
|
|
|
#if defined(PHP_WIN32) && defined(THREAD_SAFE)
|
1999-04-19 21:56:50 +08:00
|
|
|
|
|
|
|
/*NOTE: You should have an odbc.def file where you
|
|
|
|
export DllMain*/
|
|
|
|
BOOL WINAPI DllMain(HANDLE hModule,
|
|
|
|
DWORD ul_reason_for_call,
|
|
|
|
LPVOID lpReserved)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
2001-06-05 21:12:10 +08:00
|
|
|
|
1999-04-19 21:56:50 +08:00
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* tab-width: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* End:
|
2001-09-09 21:29:31 +08:00
|
|
|
* vim600: sw=4 ts=4 fdm=marker
|
|
|
|
* vim<600: sw=4 ts=4
|
1999-04-19 21:56:50 +08:00
|
|
|
*/
|