2
+----------------------------------------------------------------------+
4
+----------------------------------------------------------------------+
5
| Copyright (c) 1997-2004 The PHP Group |
6
+----------------------------------------------------------------------+
7
| This source file is subject to version 3.0 of the PHP license, |
8
| that is bundled with this package in the file LICENSE, and is |
9
| available through the world-wide-web at the following url: |
10
| http://www.php.net/license/3_0.txt. |
11
| If you did not receive a copy of the PHP license and are unable to |
12
| obtain it through the world-wide-web, please send a note to |
13
| license@php.net so we can mail you a copy immediately. |
14
+----------------------------------------------------------------------+
15
| Author: Jim Winstead <jimw@php.net> |
16
+----------------------------------------------------------------------+
19
/* $Id: dbase.c,v 1.72.2.1 2005/02/04 14:29:05 derick Exp $ */
26
#include "safe_mode.h"
27
#include "fopen_wrappers.h"
28
#include "php_globals.h"
32
#ifdef HAVE_SYS_TYPES_H
33
#include <sys/types.h>
37
#include "php_dbase.h"
39
#if defined(THREAD_SAFE)
41
static int numthreads=0;
44
typedef struct dbase_global_struct{
48
#define DBase_GLOBAL(a) dbase_globals->a
50
#define DBase_TLS_VARS \
51
dbase_global_struct *dbase_globals; \
52
dbase_globals=TlsGetValue(DbaseTls);
56
#define DBase_GLOBAL(a) a
57
#define DBase_TLS_VARS
64
static void _close_dbase(zend_rsrc_list_entry *rsrc TSRMLS_DC)
66
dbhead_t *dbhead = (dbhead_t *)rsrc->ptr;
69
free_dbf_head(dbhead);
73
PHP_MINIT_FUNCTION(dbase)
75
#if defined(THREAD_SAFE)
76
dbase_global_struct *dbase_globals;
77
#ifdef COMPILE_DL_DBASE
78
CREATE_MUTEX(dbase_mutex, "DBase_TLS");
79
SET_MUTEX(dbase_mutex);
82
if ((DbaseTls=TlsAlloc())==0xFFFFFFFF){
83
FREE_MUTEX(dbase_mutex);
86
FREE_MUTEX(dbase_mutex);
88
dbase_globals = (dbase_global_struct *) LocalAlloc(LPTR, sizeof(dbase_global_struct));
89
TlsSetValue(DbaseTls, (void *) dbase_globals);
91
DBase_GLOBAL(le_dbhead) =
92
zend_register_list_destructors_ex(_close_dbase, NULL, "dbase", module_number);
96
static PHP_MSHUTDOWN_FUNCTION(dbase)
98
#if defined(THREAD_SAFE)
99
dbase_global_struct *dbase_globals;
100
dbase_globals = TlsGetValue(DbaseTls);
101
if (dbase_globals != 0)
102
LocalFree((HLOCAL) dbase_globals);
103
#ifdef COMPILE_DL_DBASE
104
SET_MUTEX(dbase_mutex);
107
if (!TlsFree(DbaseTls)){
108
FREE_MUTEX(dbase_mutex);
111
FREE_MUTEX(dbase_mutex);
117
/* {{{ proto int dbase_open(string name, int mode)
118
Opens a dBase-format database file */
119
PHP_FUNCTION(dbase_open)
121
zval **dbf_name, **options;
126
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbf_name, &options) == FAILURE) {
129
convert_to_string_ex(dbf_name);
130
convert_to_long_ex(options);
132
if (Z_LVAL_PP(options) == 1) {
133
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open %s in write-only mode", Z_STRVAL_PP(dbf_name));
137
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(dbf_name), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
141
if (php_check_open_basedir(Z_STRVAL_PP(dbf_name) TSRMLS_CC)) {
145
dbh = dbf_open(Z_STRVAL_PP(dbf_name), Z_LVAL_PP(options) TSRMLS_CC);
147
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to open database %s", Z_STRVAL_PP(dbf_name));
151
handle = zend_list_insert(dbh, DBase_GLOBAL(le_dbhead));
156
/* {{{ proto bool dbase_close(int identifier)
157
Closes an open dBase-format database file */
158
PHP_FUNCTION(dbase_close)
165
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
168
convert_to_long_ex(dbh_id);
169
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
170
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
171
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
175
zend_list_delete(Z_LVAL_PP(dbh_id));
180
/* {{{ proto int dbase_numrecords(int identifier)
181
Returns the number of records in the database */
182
PHP_FUNCTION(dbase_numrecords)
189
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
192
convert_to_long_ex(dbh_id);
193
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
194
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
195
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
199
RETURN_LONG(dbh->db_records);
203
/* {{{ proto int dbase_numfields(int identifier)
204
Returns the number of fields (columns) in the database */
205
PHP_FUNCTION(dbase_numfields)
212
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &dbh_id) == FAILURE) {
215
convert_to_long_ex(dbh_id);
216
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
217
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
218
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
222
RETURN_LONG(dbh->db_nfields);
226
/* {{{ proto bool dbase_pack(int identifier)
227
Packs the database (deletes records marked for deletion) */
228
PHP_FUNCTION(dbase_pack)
235
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &dbh_id) == FAILURE) {
238
convert_to_long_ex(dbh_id);
239
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
240
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
241
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
251
/* {{{ proto bool dbase_add_record(int identifier, array data)
252
Adds a record to the database */
253
PHP_FUNCTION(dbase_add_record)
255
zval **dbh_id, **fields, **field;
260
dbfield_t *dbf, *cur_f;
265
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbh_id, &fields) == FAILURE) {
268
convert_to_long_ex(dbh_id);
269
if (Z_TYPE_PP(fields) != IS_ARRAY) {
270
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
274
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
275
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
276
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
280
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
282
if (num_fields != dbh->db_nfields) {
283
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified");
287
cp = t_cp = (char *)emalloc(dbh->db_rlen + 1);
288
*t_cp++ = VALID_RECORD;
290
dbf = dbh->db_fields;
291
for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
293
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
294
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error");
300
zval_copy_ctor(&tmp);
301
convert_to_string(&tmp);
302
snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL(tmp));
304
t_cp += cur_f->db_flen;
308
if (put_dbf_record(dbh, dbh->db_records, cp) < 0) {
309
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records);
321
/* {{{ proto bool dbase_replace_record(int identifier, array data, int recnum)
322
Replaces a record to the database */
323
PHP_FUNCTION(dbase_replace_record)
325
zval **dbh_id, **fields, **field, **recnum;
330
dbfield_t *dbf, *cur_f;
335
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &dbh_id, &fields, &recnum) == FAILURE) {
338
convert_to_long_ex(dbh_id);
339
convert_to_long_ex(recnum);
340
if (Z_TYPE_PP(fields) != IS_ARRAY) {
341
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
345
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
346
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
347
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
351
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
353
if (num_fields != dbh->db_nfields) {
354
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified");
358
cp = t_cp = (char *)emalloc(dbh->db_rlen + 1);
359
*t_cp++ = VALID_RECORD;
361
dbf = dbh->db_fields;
362
for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
363
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
364
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error");
368
convert_to_string_ex(field);
369
snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL_PP(field));
370
t_cp += cur_f->db_flen;
373
if (put_dbf_record(dbh, Z_LVAL_PP(recnum), cp) < 0) {
374
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records);
386
/* {{{ proto bool dbase_delete_record(int identifier, int record)
387
Marks a record to be deleted */
388
PHP_FUNCTION(dbase_delete_record)
390
zval **dbh_id, **record;
395
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &dbh_id, &record) == FAILURE)) {
398
convert_to_long_ex(dbh_id);
399
convert_to_long_ex(record);
401
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
402
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
403
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
407
if (del_dbf_record(dbh, Z_LVAL_PP(record)) < 0) {
408
if (Z_LVAL_PP(record) > dbh->db_records) {
409
php_error_docref(NULL TSRMLS_CC, E_WARNING, "record %ld out of bounds", Z_LVAL_PP(record));
411
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to delete record %ld", Z_LVAL_PP(record));
421
/* {{{ php_dbase_get_record
423
static void php_dbase_get_record(INTERNAL_FUNCTION_PARAMETERS, int assoc)
425
zval **dbh_id, **record;
428
dbfield_t *dbf, *cur_f;
429
char *data, *fnp, *str_value;
435
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &dbh_id, &record) == FAILURE)) {
438
convert_to_long_ex(dbh_id);
439
convert_to_long_ex(record);
441
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
442
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
443
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
447
if ((data = get_dbf_record(dbh, Z_LVAL_PP(record))) == NULL) {
448
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to read bad record %ld", Z_LVAL_PP(record));
452
dbf = dbh->db_fields;
454
array_init(return_value);
457
for (cur_f = dbf; cur_f < &dbf[dbh->db_nfields]; cur_f++) {
459
str_value = (char *)emalloc(cur_f->db_flen + 1);
461
if(cursize <= (unsigned)cur_f->db_flen) {
462
cursize = cur_f->db_flen + 1;
463
fnp = erealloc(fnp, cursize);
465
snprintf(str_value, cursize, cur_f->db_format, get_field_val(data, cur_f, fnp));
467
/* now convert it to the right php internal type */
468
switch (cur_f->db_type) {
472
add_next_index_string(return_value, str_value, 1);
474
add_assoc_string(return_value, cur_f->db_fname, str_value, 1);
477
case 'I': /* FALLS THROUGH */
479
if (cur_f->db_fdc == 0) {
480
/* Large integers in dbase can be larger than long */
482
overflow_test = strtol(str_value, NULL, 10);
483
if (errno == ERANGE) {
484
/* If the integer is too large, keep it as string */
486
add_next_index_string(return_value, str_value, 1);
488
add_assoc_string(return_value, cur_f->db_fname, str_value, 1);
492
add_next_index_long(return_value, overflow_test);
494
add_assoc_long(return_value, cur_f->db_fname, overflow_test);
500
add_next_index_double(return_value, atof(str_value));
502
add_assoc_double(return_value, cur_f->db_fname, atof(str_value));
506
case 'L': /* we used to FALL THROUGH, but now we check for T/Y and F/N
507
and insert 1 or 0, respectively. db_fdc is the number of
508
decimals, which we don't care about. 3/14/2001 LEW */
509
if ((*str_value == 'T') || (*str_value == 'Y')) {
511
add_next_index_long(return_value, strtol("1", NULL, 10));
513
add_assoc_long(return_value, cur_f->db_fname,strtol("1", NULL, 10));
516
if ((*str_value == 'F') || (*str_value == 'N')) {
518
add_next_index_long(return_value, strtol("0", NULL, 10));
520
add_assoc_long(return_value, cur_f->db_fname,strtol("0", NULL, 10));
524
add_next_index_long(return_value, strtol(" ", NULL, 10));
526
add_assoc_long(return_value, cur_f->db_fname,strtol(" ", NULL, 10));
532
/* this is a memo field. don't know how to deal with this yet */
535
/* should deal with this in some way */
543
/* mark whether this record was deleted */
544
if (data[0] == '*') {
545
add_assoc_long(return_value, "deleted", 1);
547
add_assoc_long(return_value, "deleted", 0);
554
/* {{{ proto array dbase_get_record(int identifier, int record)
555
Returns an array representing a record from the database */
556
PHP_FUNCTION(dbase_get_record)
558
php_dbase_get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
562
/* From Martin Kuba <makub@aida.inet.cz> */
563
/* {{{ proto array dbase_get_record_with_names(int identifier, int record)
564
Returns an associative array representing a record from the database */
565
PHP_FUNCTION(dbase_get_record_with_names)
567
php_dbase_get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
571
/* {{{ proto bool dbase_create(string filename, array fields)
572
Creates a new dBase-format database file */
573
PHP_FUNCTION(dbase_create)
575
zval **filename, **fields, **field, **value;
580
dbfield_t *dbf, *cur_f;
584
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &filename, &fields) == FAILURE)) {
587
convert_to_string_ex(filename);
589
if (Z_TYPE_PP(fields) != IS_ARRAY) {
590
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
594
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
598
if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) {
602
if ((fd = VCWD_OPEN_MODE(Z_STRVAL_PP(filename), O_BINARY|O_RDWR|O_CREAT, 0644)) < 0) {
603
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create database (%d): %s", errno, strerror(errno));
607
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
609
/* have to use regular malloc() because this gets free()d by
610
code in the dbase library */
611
dbh = (dbhead_t *)malloc(sizeof(dbhead_t));
612
dbf = (dbfield_t *)malloc(sizeof(dbfield_t) * num_fields);
614
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for header info");
618
/* initialize the header structure */
619
dbh->db_fields = dbf;
621
dbh->db_dbt = DBH_TYPE_NORMAL;
622
strcpy(dbh->db_date, "19930818");
624
dbh->db_nfields = num_fields;
625
dbh->db_hlen = sizeof(struct dbf_dhead) + 1 + num_fields * sizeof(struct dbf_dfield);
629
* Patch by greg@darkphoton.com
631
/* make sure that the db_format entries for all fields are set to NULL to ensure we
632
don't seg fault if there's an error and we need to call free_dbf_head() before all
633
fields have been defined. */
634
for (i = 0, cur_f = dbf; i < num_fields; i++, cur_f++) {
635
cur_f->db_format = NULL;
642
for (i = 0, cur_f = dbf; i < num_fields; i++, cur_f++) {
643
/* look up the first field */
644
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
645
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to find field %d", i);
650
if (Z_TYPE_PP (field) != IS_ARRAY) {
651
php_error_docref(NULL TSRMLS_CC, E_WARNING, "second parameter must be array of arrays");
657
if (zend_hash_index_find(Z_ARRVAL_PP(field), 0, (void **)&value) == FAILURE) {
658
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field name as first element of list in field %d", i);
662
convert_to_string_ex(value);
663
if (Z_STRLEN_PP(value) > 10 || Z_STRLEN_PP(value) == 0) {
664
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));
668
copy_crimp(cur_f->db_fname, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
671
if (zend_hash_index_find(Z_ARRVAL_PP (field), 1, (void **)&value) == FAILURE) {
672
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field type as second element of list in field %d", i);
675
convert_to_string_ex(value);
676
cur_f->db_type = toupper(*Z_STRVAL_PP(value));
680
/* verify the field length */
681
switch (cur_f->db_type) {
687
dbh->db_dbt = DBH_TYPE_MEMO;
688
/* should create the memo file here, probably */
696
if (zend_hash_index_find(Z_ARRVAL_PP (field), 2, (void **)&value) == FAILURE) {
697
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field length as third element of list in field %d", i);
701
convert_to_long_ex(value);
702
cur_f->db_flen = Z_LVAL_PP(value);
704
if (cur_f->db_type == 'N') {
705
if (zend_hash_index_find(Z_ARRVAL_PP (field), 3, (void **)&value) == FAILURE) {
706
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field precision as fourth element of list in field %d", i);
710
convert_to_long_ex(value);
711
cur_f->db_fdc = Z_LVAL_PP(value);
715
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown field type '%c'", cur_f->db_type);
717
cur_f->db_foffset = rlen;
718
rlen += cur_f->db_flen;
720
cur_f->db_format = get_dbf_f_fmt(cur_f);
726
handle = zend_list_insert(dbh, DBase_GLOBAL(le_dbhead));
731
/* {{{ dbase_functions[]
733
function_entry dbase_functions[] = {
734
PHP_FE(dbase_open, NULL)
735
PHP_FE(dbase_create, NULL)
736
PHP_FE(dbase_close, NULL)
737
PHP_FE(dbase_numrecords, NULL)
738
PHP_FE(dbase_numfields, NULL)
739
PHP_FE(dbase_add_record, NULL)
740
PHP_FE(dbase_replace_record, NULL)
741
PHP_FE(dbase_get_record, NULL)
742
PHP_FE(dbase_get_record_with_names, NULL)
743
PHP_FE(dbase_delete_record, NULL)
744
PHP_FE(dbase_pack, NULL)
745
PHP_FE(dbase_get_header_info, NULL)
750
/* Added by Zak Greant <zak@php.net> */
751
/* {{{ proto array dbase_get_header_info(int database_handle)
753
PHP_FUNCTION(dbase_get_header_info)
756
dbfield_t *dbf, *cur_f;
761
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
764
convert_to_long_ex(dbh_id);
766
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
767
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
768
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
772
array_init(return_value);
774
dbf = dbh->db_fields;
775
for (cur_f = dbf; cur_f < &dbh->db_fields[dbh->db_nfields]; ++cur_f) {
779
add_next_index_zval(return_value, row);
782
add_assoc_string(row, "name", cur_f->db_fname, 1);
785
switch (cur_f->db_type) {
786
case 'C': add_assoc_string(row, "type", "character", 1); break;
787
case 'D': add_assoc_string(row, "type", "date", 1); break;
788
case 'I': add_assoc_string(row, "type", "integer", 1); break;
789
case 'N': add_assoc_string(row, "type", "number", 1); break;
790
case 'L': add_assoc_string(row, "type", "boolean", 1); break;
791
case 'M': add_assoc_string(row, "type", "memo", 1); break;
792
default: add_assoc_string(row, "type", "unknown", 1); break;
795
/* length of field */
796
add_assoc_long(row, "length", cur_f->db_flen);
798
/* number of decimals in field */
799
switch (cur_f->db_type) {
802
add_assoc_long(row, "precision", cur_f->db_fdc);
805
add_assoc_long(row, "precision", 0);
808
/* format for printing %s etc */
809
add_assoc_string(row, "format", cur_f->db_format, 1);
811
/* offset within record */
812
add_assoc_long(row, "offset", cur_f->db_foffset);
817
zend_module_entry dbase_module_entry = {
818
STANDARD_MODULE_HEADER,
819
"dbase", dbase_functions, PHP_MINIT(dbase), PHP_MSHUTDOWN(dbase), NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
823
#ifdef COMPILE_DL_DBASE
824
ZEND_GET_MODULE(dbase)
826
#if defined(PHP_WIN32) && defined(THREAD_SAFE)
828
/*NOTE: You should have an odbc.def file where you
830
BOOL WINAPI DllMain(HANDLE hModule,
831
DWORD ul_reason_for_call,
846
* vim600: sw=4 ts=4 fdm=marker