📄 dbase.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.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. | +----------------------------------------------------------------------+ | Author: Jim Winstead <jimw@php.net> | +----------------------------------------------------------------------+ *//* $Id: dbase.c,v 1.60.2.5.2.2 2007/01/01 09:46:41 sebastian Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "safe_mode.h"#include "fopen_wrappers.h"#include "php_globals.h"#include <stdlib.h>#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if DBASE#include "php_dbase.h"#include "dbf.h"#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); #elsestatic int le_dbhead;#define DBase_GLOBAL(a) a#define DBase_TLS_VARS#endif#include <fcntl.h>#include <errno.h>static void _close_dbase(zend_rsrc_list_entry *rsrc TSRMLS_DC){ dbhead_t *dbhead = (dbhead_t *)rsrc->ptr; close(dbhead->db_fd); free_dbf_head(dbhead);}PHP_MINIT_FUNCTION(dbase){#if defined(THREAD_SAFE) dbase_global_struct *dbase_globals;#ifdef COMPILE_DL_DBASE CREATE_MUTEX(dbase_mutex, "DBase_TLS"); 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 DBase_GLOBAL(le_dbhead) = zend_register_list_destructors_ex(_close_dbase, NULL, "dbase", module_number); return SUCCESS;}static PHP_MSHUTDOWN_FUNCTION(dbase){#if defined(THREAD_SAFE) dbase_global_struct *dbase_globals; dbase_globals = TlsGetValue(DbaseTls); if (dbase_globals != 0) LocalFree((HLOCAL) dbase_globals); #ifdef COMPILE_DL_DBASE 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 */PHP_FUNCTION(dbase_open){ zval **dbf_name, **options; dbhead_t *dbh; int handle; DBase_TLS_VARS; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbf_name, &options) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(dbf_name); convert_to_long_ex(options); 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; } if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(dbf_name), NULL, CHECKUID_CHECK_FILE_AND_DIR))) { RETURN_FALSE; } if (php_check_open_basedir(Z_STRVAL_PP(dbf_name) TSRMLS_CC)) { RETURN_FALSE; } dbh = dbf_open(Z_STRVAL_PP(dbf_name), Z_LVAL_PP(options) TSRMLS_CC); if (dbh == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to open database %s", Z_STRVAL_PP(dbf_name)); RETURN_FALSE; } handle = zend_list_insert(dbh, DBase_GLOBAL(le_dbhead)); RETURN_LONG(handle);}/* }}} *//* {{{ proto bool dbase_close(int identifier) Closes an open dBase-format database file */PHP_FUNCTION(dbase_close){ zval **dbh_id; 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)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id)); RETURN_FALSE; } zend_list_delete(Z_LVAL_PP(dbh_id)); RETURN_TRUE;}/* }}} *//* {{{ proto int dbase_numrecords(int identifier) Returns the number of records in the database */PHP_FUNCTION(dbase_numrecords){ zval **dbh_id; 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)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id)); RETURN_FALSE; } RETURN_LONG(dbh->db_records);}/* }}} *//* {{{ proto int dbase_numfields(int identifier) Returns the number of fields (columns) in the database */PHP_FUNCTION(dbase_numfields){ zval **dbh_id; 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)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id)); RETURN_FALSE; } RETURN_LONG(dbh->db_nfields);}/* }}} *//* {{{ proto bool dbase_pack(int identifier) Packs the database (deletes records marked for deletion) */PHP_FUNCTION(dbase_pack){ zval **dbh_id; 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)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id)); 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 */PHP_FUNCTION(dbase_add_record){ zval **dbh_id, **fields, **field; dbhead_t *dbh; int dbh_type; int num_fields; dbfield_t *dbf, *cur_f; char *cp, *t_cp; int i; DBase_TLS_VARS; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbh_id, &fields) == FAILURE) { WRONG_PARAM_COUNT; } 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"); RETURN_FALSE; } dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type); if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id)); RETURN_FALSE; } num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields)); if (num_fields != dbh->db_nfields) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified"); 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++) { zval tmp; if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error"); efree(cp); RETURN_FALSE; } tmp = **field; zval_copy_ctor(&tmp); convert_to_string(&tmp); snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL(tmp)); zval_dtor(&tmp); t_cp += cur_f->db_flen; } dbh->db_records++; if (put_dbf_record(dbh, dbh->db_records, cp) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records); efree(cp); RETURN_FALSE; } put_dbf_info(dbh); efree(cp); RETURN_TRUE;}/* }}} *//* {{{ proto bool dbase_replace_record(int identifier, array data, int recnum) Replaces a record to the database */PHP_FUNCTION(dbase_replace_record){ zval **dbh_id, **fields, **field, **recnum; dbhead_t *dbh; int dbh_type; int num_fields; dbfield_t *dbf, *cur_f; char *cp, *t_cp; int i; DBase_TLS_VARS; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &dbh_id, &fields, &recnum) == FAILURE) { WRONG_PARAM_COUNT; } 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"); RETURN_FALSE; } dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type); if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id)); RETURN_FALSE; } num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields)); if (num_fields != dbh->db_nfields) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified"); 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++) { if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error"); efree(cp); RETURN_FALSE; } convert_to_string_ex(field); snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL_PP(field)); t_cp += cur_f->db_flen; } 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); efree(cp); RETURN_FALSE; } put_dbf_info(dbh); efree(cp); RETURN_TRUE;}/* }}} *//* {{{ proto bool dbase_delete_record(int identifier, int record) Marks a record to be deleted */PHP_FUNCTION(dbase_delete_record){ zval **dbh_id, **record; dbhead_t *dbh;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -