abies Fri Feb 20 05:59:24 2004 EDT Modified files: /php-src/ext/interbase interbase.c php_ibase_includes.h Log: Fix some issues with persistent links
http://cvs.php.net/diff.php/php-src/ext/interbase/interbase.c?r1=1.202&r2=1.203&ty=u Index: php-src/ext/interbase/interbase.c diff -u php-src/ext/interbase/interbase.c:1.202 php-src/ext/interbase/interbase.c:1.203 --- php-src/ext/interbase/interbase.c:1.202 Tue Feb 17 07:53:53 2004 +++ php-src/ext/interbase/interbase.c Fri Feb 20 05:59:23 2004 @@ -14,11 +14,11 @@ +----------------------------------------------------------------------+ | Authors: Jouni Ahto <[EMAIL PROTECTED]> | | Andrew Avdeev <[EMAIL PROTECTED]> | - | Ard Biesheuvel <[EMAIL PROTECTED]> | + | Ard Biesheuvel <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: interbase.c,v 1.202 2004/02/17 12:53:53 abies Exp $ */ +/* $Id: interbase.c,v 1.203 2004/02/20 10:59:23 abies Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -30,12 +30,13 @@ #include "php.h" -#define FILE_REVISION "$Revision: 1.202 $" +#define FILE_REVISION "$Revision: 1.203 $" #if HAVE_IBASE #include "php_ini.h" #include "ext/standard/php_standard.h" +#include "ext/standard/md5.h" #include "php_interbase.h" #include "php_ibase_includes.h" @@ -49,10 +50,8 @@ #define IBDEBUG(a) #endif -#define SAFE_STRING(s) ((s)?(s):"") - -#define ISC_LONG_MIN (-ISC_LONG_MAX - 1) -#define ISC_LONG_MAX 2147483647 +#define ISC_LONG_MIN (1 << (8*sizeof(ISC_LONG)-1)) +#define ISC_LONG_MAX ~ISC_LONG_MIN #define QUERY_RESULT 1 #define EXECUTE_RESULT 2 @@ -64,8 +63,6 @@ #define FETCH_ROW 1 #define FETCH_ARRAY 2 -#define HASH_MASK "ibase_%s_%s_%s_%s_%s_%s_%s" - /* {{{ extension definition structures */ function_entry ibase_functions[] = { PHP_FE(ibase_connect, NULL) @@ -581,8 +578,10 @@ STD_PHP_INI_BOOLEAN("ibase.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_ibase_globals, ibase_globals) STD_PHP_INI_ENTRY_EX("ibase.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_ibase_globals, ibase_globals, display_link_numbers) STD_PHP_INI_ENTRY_EX("ibase.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_ibase_globals, ibase_globals, display_link_numbers) + STD_PHP_INI_ENTRY("ibase.default_db", NULL, PHP_INI_SYSTEM, OnUpdateString, default_db, zend_ibase_globals, ibase_globals) STD_PHP_INI_ENTRY("ibase.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_ibase_globals, ibase_globals) STD_PHP_INI_ENTRY("ibase.default_password", NULL, PHP_INI_ALL, OnUpdateString, default_password, zend_ibase_globals, ibase_globals) + STD_PHP_INI_ENTRY("ibase.default_charset", NULL, PHP_INI_ALL, OnUpdateString, default_charset, zend_ibase_globals, ibase_globals) STD_PHP_INI_ENTRY("ibase.timestampformat", "%m/%d/%Y %H:%M:%S", PHP_INI_ALL, OnUpdateString, cfg_timestampformat, zend_ibase_globals, ibase_globals) STD_PHP_INI_ENTRY("ibase.dateformat", "%m/%d/%Y", PHP_INI_ALL, OnUpdateString, cfg_dateformat, zend_ibase_globals, ibase_globals) STD_PHP_INI_ENTRY("ibase.timeformat", "%H:%M:%S", PHP_INI_ALL, OnUpdateString, cfg_timeformat, zend_ibase_globals, ibase_globals) @@ -839,60 +838,31 @@ } /* }}} */ -int _php_ibase_attach_db(char *server, char *uname, char *passwd, char *charset, /* {{{ */ - int buffers, char *role, isc_db_handle *db TSRMLS_DC) +enum connect_args { DB = 0, USER = 1, PASS = 2, CSET = 3, ROLE = 4, BUF = 0, DLECT = 1 }; + +static char const dpb_args[] = { 0, isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype +#ifdef isc_dpb_sql_role_name + , isc_dpb_sql_role_name +#endif +}; + +int _php_ibase_attach_db(char **args, int *len, long *largs, isc_db_handle *db TSRMLS_DC) { - char dpb_buffer[256], *dpb, *p; - int dpb_length, len; - - dpb = dpb_buffer; - - *dpb++ = isc_dpb_version1; - - if (uname != NULL && (len = strlen(uname))) { - *dpb++ = isc_dpb_user_name; - *dpb++ = len; - for (p = uname; *p;) { - *dpb++ = *p++; - } - } + short i; + char dpb_buffer[256] = { isc_dpb_version1 }, *dpb; - if (passwd != NULL && (len = strlen(passwd))) { - *dpb++ = isc_dpb_password; - *dpb++ = strlen(passwd); - for (p = passwd; *p;) { - *dpb++ = *p++; - } - } + dpb = dpb_buffer + 1; - if (charset != NULL && (len = strlen(charset))) { - *dpb++ = isc_dpb_lc_ctype; - *dpb++ = strlen(charset); - for (p = charset; *p;) { - *dpb++ = *p++; + for (i = 0; i < sizeof(dpb_args); ++i) { + if (dpb_args[i] && args[i]) { + dpb += sprintf(dpb, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]); } } - - if (buffers) { - *dpb++ = isc_dpb_num_buffers; - *dpb++ = 1; - *dpb++ = buffers; - } - -#ifdef isc_dpb_sql_role_name - if (role != NULL && (len = strlen(role))) { - *dpb++ = isc_dpb_sql_role_name; - *dpb++ = strlen(role); - for (p = role; *p;) { - *dpb++ = *p++; - } + if (largs[BUF]) { + dpb += sprintf(dpb, "%c\2%c%c", isc_dpb_num_buffers, + (char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff)); } -#endif - - dpb_length = dpb - dpb_buffer; - - if (isc_attach_database(IB_STATUS, (short)strlen(server), server, db, - (short)dpb_length, dpb_buffer)) { + if (isc_attach_database(IB_STATUS, len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) { _php_ibase_error(TSRMLS_C); return FAILURE; } @@ -902,210 +872,134 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ */ { - zval **args[7]; - char *ib_server = NULL, *ib_uname, *ib_passwd, *ib_charset = NULL, *ib_buffers = NULL, - *ib_dialect = NULL, *ib_role = NULL; - unsigned short sql_dialect = SQL_DIALECT_CURRENT; - int ib_uname_len, ib_passwd_len; + char hash[16], *args[] = { NULL, NULL, NULL, NULL, NULL }; + int i, len[] = { 0, 0, 0, 0, 0 }; + long largs[] = { 0, SQL_DIALECT_CURRENT }; + PHP_MD5_CTX hash_context; + list_entry new_index_ptr, *le; isc_db_handle db_handle = NULL; - char *hashed_details; - int hashed_details_length = 0; - ibase_db_link *ib_link = NULL; - + ibase_db_link *ib_link; + RESET_ERRMSG; - - ib_uname = IBG(default_user); - ib_passwd = IBG(default_password); - ib_uname_len = ib_uname ? strlen(ib_uname) : 0; - ib_passwd_len = ib_passwd ? strlen(ib_passwd) : 0; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sssslls", + &args[DB], &len[DB], &args[USER], &len[USER], &args[PASS], &len[PASS], + &args[CSET], &len[CSET], &largs[BUF], &largs[DLECT], &args[ROLE], &len[ROLE])) { + RETURN_FALSE; + } - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 7) { - WRONG_PARAM_COUNT; + /* restrict to the server/db in the .ini if in safe mode */ + if ((!len[DB] || PG(sql_safe_mode)) && IBG(default_db)) { + args[DB] = IBG(default_db); + len[DB] = strlen(IBG(default_db)); + } + if (!len[USER] && IBG(default_user)) { + args[USER] = IBG(default_user); + len[USER] = strlen(args[USER]); + } + if (!len[PASS] && IBG(default_password)) { + args[PASS] = IBG(default_password); + len[PASS] = strlen(args[PASS]); + } + if (!len[CSET] && IBG(default_charset)) { + args[CSET] = IBG(default_charset); + len[CSET] = strlen(args[CSET]); } - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { - RETURN_FALSE; + /* don't want usernames and passwords floating around */ + PHP_MD5Init(&hash_context); + for (i = 0; i < sizeof(args)/sizeof(char*); ++i) { + PHP_MD5Update(&hash_context,args[i],len[i]); } + for (i = 0; i < sizeof(largs)/sizeof(long); ++i) { + PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(long)); + } + PHP_MD5Final(hash, &hash_context); + + /* try to reuse a connection */ + if (SUCCESS == zend_hash_find(&EG(regular_list), hash, sizeof(hash), (void *) &le)) { + long xlink; + int type; - switch (ZEND_NUM_ARGS()) { - unsigned short d; - - case 7: - convert_to_string_ex(args[6]); - ib_role = Z_STRVAL_PP(args[6]); - hashed_details_length += Z_STRLEN_PP(args[6]); - /* fallout */ - case 6: - convert_to_string_ex(args[5]); - ib_dialect = Z_STRVAL_PP(args[5]); - if ((d = (unsigned short)strtoul(ib_dialect, NULL, 10))) - { - sql_dialect = d; - } - hashed_details_length += Z_STRLEN_PP(args[5]); - /* fallout */ - case 5: - convert_to_string_ex(args[4]); - ib_buffers = Z_STRVAL_PP(args[4]); - hashed_details_length += Z_STRLEN_PP(args[4]); - /* fallout */ - case 4: - convert_to_string_ex(args[3]); - ib_charset = Z_STRVAL_PP(args[3]); - hashed_details_length += Z_STRLEN_PP(args[3]); - /* fallout */ - case 3: - convert_to_string_ex(args[2]); - ib_passwd = Z_STRVAL_PP(args[2]); - hashed_details_length += Z_STRLEN_PP(args[2]); - /* fallout */ - case 2: - convert_to_string_ex(args[1]); - ib_uname = Z_STRVAL_PP(args[1]); - hashed_details_length += Z_STRLEN_PP(args[1]); - /* fallout */ - case 1: - convert_to_string_ex(args[0]); - ib_server = Z_STRVAL_PP(args[0]); - hashed_details_length += Z_STRLEN_PP(args[0]); - } /* case */ - - hashed_details = (char *)emalloc(hashed_details_length+sizeof(HASH_MASK)+1); - sprintf(hashed_details, HASH_MASK, SAFE_STRING(ib_server), SAFE_STRING(ib_uname), - SAFE_STRING(ib_passwd), SAFE_STRING(ib_charset), SAFE_STRING(ib_buffers), - SAFE_STRING(ib_dialect), SAFE_STRING(ib_role)); - - if (persistent) { - list_entry *le; - int open_new_connection = 1; - - if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, - (void *) &le) != FAILURE) { - static char info[] = {isc_info_base_level, isc_info_end}; - char result[8]; /* Enough? Hope so... */ - - if (Z_TYPE_P(le) != le_plink) { - RETURN_FALSE; - } - /* Check if connection has timed out */ - ib_link = (ibase_db_link *) le->ptr; - if (!isc_database_info(IB_STATUS, &ib_link->handle, sizeof(info), - info, sizeof(result), result)) { - open_new_connection = 0; - } + if (Z_TYPE_P(le) != le_index_ptr) { + RETURN_FALSE; } - - /* There was no previous connection to use or it has timed out */ - if (open_new_connection) { - list_entry new_le; - if ((IBG(max_links) != -1) && (IBG(num_links) >= IBG(max_links))) { - _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links)); - efree(hashed_details); - RETURN_FALSE; - } - if ((IBG(max_persistent) != -1) && (IBG(num_persistent) >= IBG(max_persistent))) { - _php_ibase_module_error("Too many open persistent links (%ld)" - TSRMLS_CC, IBG(num_persistent)); - efree(hashed_details); - RETURN_FALSE; - } + xlink = (long) le->ptr; + if (zend_list_find(xlink, &type) && ((!persistent && type == le_link) || type == le_plink)) { + zend_list_addref(xlink); + RETURN_RESOURCE(IBG(default_link) = xlink); + } else { + zend_hash_del(&EG(regular_list), hash, sizeof(hash)); + } + } + /* ... or a persistent one */ + if (SUCCESS == zend_hash_find(&EG(persistent_list), hash, sizeof(hash), (void *) &le)) { + static char info[] = { isc_info_base_level, isc_info_end }; + char result[8]; - /* create the ib_link */ + if (Z_TYPE_P(le) != le_plink) { + RETURN_FALSE; + } + /* check if connection has timed out */ + ib_link = (ibase_db_link *) le->ptr; + if (isc_database_info(IB_STATUS, &ib_link->handle, sizeof(info), info, sizeof(result), result)) { + zend_hash_del(&EG(persistent_list), hash, sizeof(hash)); + } else { + ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink); + goto register_link_resource; + } + } - if (_php_ibase_attach_db(ib_server, ib_uname, ib_passwd, ib_charset, - (ib_buffers ? strtoul(ib_buffers, NULL, 0) : 0), - ib_role, &db_handle TSRMLS_CC) == FAILURE) { - efree(hashed_details); - RETURN_FALSE; - } + /* no link found, so we have to open one */ - ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link)); - ib_link->handle = db_handle; - ib_link->dialect = sql_dialect; - ib_link->tr_list = NULL; - ib_link->event_head = NULL; - - /* hash it up */ - Z_TYPE(new_le) = le_plink; - new_le.ptr = ib_link; - if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, - (void *) &new_le, sizeof(list_entry), NULL) == FAILURE) { - efree(hashed_details); - free(ib_link); - RETURN_FALSE; - } - IBG(num_links)++; - IBG(num_persistent)++; - } + if (IBG(max_links) != -1 && IBG(num_links) >= IBG(max_links)) { + _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links)); + RETURN_FALSE; + } - ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink); + /* create the ib_link */ + if (FAILURE == _php_ibase_attach_db(args, len, largs, &db_handle TSRMLS_CC)) { + RETURN_FALSE; + } + /* use non-persistent if allowed number of persistent links is exceeded */ + if (!persistent || (IBG(max_persistent) != -1 && IBG(num_persistent) >= IBG(max_persistent))) { + ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link)); + ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link); } else { - list_entry *index_ptr, new_index_ptr; + list_entry new_le; - /* first we check the hash for the hashed_details key. if it exists, - * it should point us to the right offset where the actual ib_link sits. - * if it doesn't, open a new ib_link, add it to the resource list, - * and add a pointer to it with hashed_details as the key. - */ - if (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1, - (void *) &index_ptr) == SUCCESS) { - int type; - long xlink; - void *ptr; - - if (Z_TYPE_P(index_ptr) != le_index_ptr) { - RETURN_FALSE; - } - xlink = (long) index_ptr->ptr; - ptr = zend_list_find(xlink, &type); /* check if the xlink is still there */ - if (ptr && (type == le_link || type == le_plink)) { - zend_list_addref(xlink); - Z_LVAL_P(return_value) = xlink; - Z_TYPE_P(return_value) = IS_RESOURCE; - IBG(default_link) = Z_LVAL_P(return_value); - efree(hashed_details); - return; - } else { - zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length + 1); - } - } - if ((IBG(max_links) != -1) && (IBG(num_links) >= IBG(max_links))) { - _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links)); - efree(hashed_details); - RETURN_FALSE; - } - /* create the ib_link */ + ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link)); - if (_php_ibase_attach_db(ib_server, ib_uname, ib_passwd, ib_charset, - (ib_buffers ? strtoul(ib_buffers, NULL, 0) : 0), - ib_role, &db_handle TSRMLS_CC) == FAILURE) { - efree(hashed_details); + /* hash it up */ + Z_TYPE(new_le) = le_plink; + new_le.ptr = ib_link; + if (FAILURE == zend_hash_update(&EG(persistent_list), hash, sizeof(hash), + (void *) &new_le, sizeof(list_entry), NULL)) { + free(ib_link); RETURN_FALSE; } + ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink); + ++IBG(num_persistent); + } + ib_link->handle = db_handle; + ib_link->dialect = (unsigned short)largs[DLECT]; + ib_link->tr_list = NULL; + ib_link->event_head = NULL; - ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link)); - ib_link->handle = db_handle; - ib_link->dialect = sql_dialect; - ib_link->tr_list = NULL; - ib_link->event_head = NULL; - - ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link); + ++IBG(num_links); - /* add it to the hash */ - new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); - Z_TYPE(new_index_ptr) = le_index_ptr; - if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length + 1, - (void *) &new_index_ptr, sizeof(list_entry), NULL) == FAILURE) { - efree(hashed_details); - RETURN_FALSE; - } - IBG(num_links)++; +register_link_resource: + + /* add it to the hash */ + new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); + Z_TYPE(new_index_ptr) = le_index_ptr; + if (FAILURE == zend_hash_update(&EG(regular_list), hash, sizeof(hash), + (void *) &new_index_ptr, sizeof(list_entry), NULL)) { + RETURN_FALSE; } - efree(hashed_details); - zend_list_addref(Z_LVAL_P(return_value)); - IBG(default_link) = Z_LVAL_P(return_value); + zend_list_addref(IBG(default_link) = Z_LVAL_P(return_value)); } /* }}} */ @@ -1121,7 +1015,7 @@ Open a persistent connection to an InterBase database */ PHP_FUNCTION(ibase_pconnect) { - _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, IBG(allow_persistent)); } /* }}} */ http://cvs.php.net/diff.php/php-src/ext/interbase/php_ibase_includes.h?r1=1.2&r2=1.3&ty=u Index: php-src/ext/interbase/php_ibase_includes.h diff -u php-src/ext/interbase/php_ibase_includes.h:1.2 php-src/ext/interbase/php_ibase_includes.h:1.3 --- php-src/ext/interbase/php_ibase_includes.h:1.2 Tue Feb 17 07:53:53 2004 +++ php-src/ext/interbase/php_ibase_includes.h Fri Feb 20 05:59:24 2004 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ibase_includes.h,v 1.2 2004/02/17 12:53:53 abies Exp $ */ +/* $Id: php_ibase_includes.h,v 1.3 2004/02/20 10:59:24 abies Exp $ */ #ifndef INTERBASE_H #define INTERBASE_H @@ -61,13 +61,9 @@ long num_links, num_persistent; long max_links, max_persistent; long allow_persistent; - char *default_user, *default_password; - char *timestampformat; - char *cfg_timestampformat; - char *dateformat; - char *cfg_dateformat; - char *timeformat; - char *cfg_timeformat; + char *default_db, *default_user, *default_password, *default_charset; + char *timestampformat, *dateformat, *timeformat; + char *cfg_timestampformat, *cfg_dateformat, *cfg_timeformat; char errmsg[MAX_ERRMSG]; long sql_code; ZEND_END_MODULE_GLOBALS(ibase)
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php