📄 php_sybase_ct.c
字号:
}PHP_RINIT_FUNCTION(sybase){ SybCtG(default_link)=-1; SybCtG(num_links) = SybCtG(num_persistent); SybCtG(appname) = estrndup("PHP " PHP_VERSION, sizeof("PHP " PHP_VERSION)); SybCtG(server_message) = empty_string; return SUCCESS;}PHP_MSHUTDOWN_FUNCTION(sybase){ UNREGISTER_INI_ENTRIES();#if 0 ct_exit(context, CS_UNUSED); cs_ctx_drop(context);#endif return SUCCESS;}PHP_RSHUTDOWN_FUNCTION(sybase){ efree(SybCtG(appname)); SybCtG(appname) = NULL; if (SybCtG(callback_name)) { zval_ptr_dtor(&SybCtG(callback_name)); SybCtG(callback_name)= NULL; } STR_FREE(SybCtG(server_message)); SybCtG(server_message) = NULL; return SUCCESS;}static int php_sybase_do_connect_internal(sybase_link *sybase, char *host, char *user, char *passwd, char *charset, char *appname){ CS_LOCALE *tmp_locale; TSRMLS_FETCH(); /* set a CS_CONNECTION record */ if (ct_con_alloc(SybCtG(context), &sybase->connection)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to allocate connection record"); return 0; } /* Note - this saves a copy of sybase, not a pointer to it. */ if (ct_con_props(sybase->connection, CS_SET, CS_USERDATA, &sybase, CS_SIZEOF(sybase), NULL)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to set userdata"); ct_con_drop(sybase->connection); return 0; } if (user) { ct_con_props(sybase->connection, CS_SET, CS_USERNAME, user, CS_NULLTERM, NULL); } if (passwd) { ct_con_props(sybase->connection, CS_SET, CS_PASSWORD, passwd, CS_NULLTERM, NULL); } if (appname) { ct_con_props(sybase->connection, CS_SET, CS_APPNAME, appname, CS_NULLTERM, NULL); } else { ct_con_props(sybase->connection, CS_SET, CS_APPNAME, SybCtG(appname), CS_NULLTERM, NULL); } if (SybCtG(hostname)) { ct_con_props(sybase->connection, CS_SET, CS_HOSTNAME, SybCtG(hostname), CS_NULLTERM, NULL); } if (charset) { if (cs_loc_alloc(SybCtG(context), &tmp_locale)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to allocate locale information."); } else { if (cs_locale(SybCtG(context), CS_SET, tmp_locale, CS_LC_ALL, NULL, CS_NULLTERM, NULL)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to load default locale data."); } else { if (cs_locale(SybCtG(context), CS_SET, tmp_locale, CS_SYB_CHARSET, charset, CS_NULLTERM, NULL)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to update character set."); } else { if (ct_con_props(sybase->connection, CS_SET, CS_LOC_PROP, tmp_locale, CS_UNUSED, NULL)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to update connection properties."); } } } } } /* Set the login timeout. Actually, the login timeout is per context * and not per connection, but we will update the context here to * allow for code such as the following: * * ini_set('sybct.login_timeout', $timeout); * sybase_connect(...) * * Note that preceding calls to sybase_connect() will now use the * updated value and not the default one! * * The default value for CS_LOGIN_TIMEOUT is 60 (1 minute). */ if (SybCtG(login_timeout) != -1) { CS_INT cs_login_timeout = SybCtG(login_timeout); if (ct_config(SybCtG(context), CS_SET, CS_LOGIN_TIMEOUT, &cs_login_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to update the login timeout"); } } sybase->valid = 1; sybase->dead = 0; sybase->active_result_index = 0; sybase->callback_name = NULL; /* create the link */ if (ct_connect(sybase->connection, host, CS_NULLTERM)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to connect"); ct_con_drop(sybase->connection); return 0; } if (ct_cmd_alloc(sybase->connection, &sybase->cmd)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to allocate command record"); ct_close(sybase->connection, CS_UNUSED); ct_con_drop(sybase->connection); return 0; } return 1;}static void php_sybase_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent){ char *user, *passwd, *host, *charset, *appname; char *hashed_details; int hashed_details_length; sybase_link *sybase_ptr; switch(ZEND_NUM_ARGS()) { case 0: /* defaults */ host=user=passwd=charset=appname=NULL; hashed_details_length=6+5; hashed_details = (char *) emalloc(hashed_details_length+1); strcpy(hashed_details, "sybase_____"); break; case 1: { zval **yyhost; if (zend_get_parameters_ex(1, &yyhost) == FAILURE) { RETURN_FALSE; } convert_to_string_ex(yyhost); host = Z_STRVAL_PP(yyhost); user=passwd=charset=appname=NULL; hashed_details_length = Z_STRLEN_PP(yyhost)+6+5; hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details, "sybase_%s____", Z_STRVAL_PP(yyhost)); } break; case 2: { zval **yyhost, **yyuser; if (zend_get_parameters_ex(2, &yyhost, &yyuser) == FAILURE) { RETURN_FALSE; } convert_to_string_ex(yyhost); convert_to_string_ex(yyuser); host = Z_STRVAL_PP(yyhost); user = Z_STRVAL_PP(yyuser); passwd=charset=appname=NULL; hashed_details_length = Z_STRLEN_PP(yyhost)+Z_STRLEN_PP(yyuser)+6+5; hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details, "sybase_%s_%s___", Z_STRVAL_PP(yyhost), Z_STRVAL_PP(yyuser)); } break; case 3: { zval **yyhost, **yyuser, **yypasswd; if (zend_get_parameters_ex(3, &yyhost, &yyuser, &yypasswd) == FAILURE) { RETURN_FALSE; } convert_to_string_ex(yyhost); convert_to_string_ex(yyuser); convert_to_string_ex(yypasswd); host = Z_STRVAL_PP(yyhost); user = Z_STRVAL_PP(yyuser); passwd = Z_STRVAL_PP(yypasswd); charset=appname=NULL; hashed_details_length = Z_STRLEN_PP(yyhost)+Z_STRLEN_PP(yyuser)+Z_STRLEN_PP(yypasswd)+6+5; hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details, "sybase_%s_%s_%s__", Z_STRVAL_PP(yyhost), Z_STRVAL_PP(yyuser), Z_STRVAL_PP(yypasswd)); } break; case 4: { zval **yyhost, **yyuser, **yypasswd, **yycharset; if (zend_get_parameters_ex(4, &yyhost, &yyuser, &yypasswd, &yycharset) == FAILURE) { RETURN_FALSE; } convert_to_string_ex(yyhost); convert_to_string_ex(yyuser); convert_to_string_ex(yypasswd); convert_to_string_ex(yycharset); host = Z_STRVAL_PP(yyhost); user = Z_STRVAL_PP(yyuser); passwd = Z_STRVAL_PP(yypasswd); charset = Z_STRVAL_PP(yycharset); appname=NULL; hashed_details_length = Z_STRLEN_PP(yyhost)+Z_STRLEN_PP(yyuser)+Z_STRLEN_PP(yypasswd)+Z_STRLEN_PP(yycharset)+6+5; hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details, "sybase_%s_%s_%s_%s_", Z_STRVAL_PP(yyhost), Z_STRVAL_PP(yyuser), Z_STRVAL_PP(yypasswd), Z_STRVAL_PP(yycharset)); } break; case 5: { zval **yyhost, **yyuser, **yypasswd, **yycharset, **yyappname; if (zend_get_parameters_ex(5, &yyhost, &yyuser, &yypasswd, &yycharset, &yyappname) == FAILURE) { RETURN_FALSE; } convert_to_string_ex(yyhost); convert_to_string_ex(yyuser); convert_to_string_ex(yypasswd); convert_to_string_ex(yycharset); convert_to_string_ex(yyappname); host = Z_STRVAL_PP(yyhost); user = Z_STRVAL_PP(yyuser); passwd = Z_STRVAL_PP(yypasswd); charset = Z_STRVAL_PP(yycharset); appname = Z_STRVAL_PP(yyappname); hashed_details_length = Z_STRLEN_PP(yyhost)+Z_STRLEN_PP(yyuser)+Z_STRLEN_PP(yypasswd)+Z_STRLEN_PP(yycharset)+Z_STRLEN_PP(yyappname)+6+5; hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details, "sybase_%s_%s_%s_%s_%s", Z_STRVAL_PP(yyhost), Z_STRVAL_PP(yyuser), Z_STRVAL_PP(yypasswd), Z_STRVAL_PP(yycharset), Z_STRVAL_PP(yyappname)); } break; default: WRONG_PARAM_COUNT; break; } if (!SybCtG(allow_persistent)) { persistent=0; } if (persistent) { list_entry *le; /* try to find if we already have this link in our persistent list */ if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */ list_entry new_le; if (SybCtG(max_links)!=-1 && SybCtG(num_links)>=SybCtG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Too many open links (%ld)", SybCtG(num_links)); efree(hashed_details); RETURN_FALSE; } if (SybCtG(max_persistent)!=-1 && SybCtG(num_persistent)>=SybCtG(max_persistent)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Too many open persistent links (%ld)", SybCtG(num_persistent)); efree(hashed_details); RETURN_FALSE; } sybase_ptr = (sybase_link *) malloc(sizeof(sybase_link)); if (!php_sybase_do_connect_internal(sybase_ptr, host, user, passwd, charset, appname)) { free(sybase_ptr); efree(hashed_details); RETURN_FALSE; } /* hash it up */ Z_TYPE(new_le) = le_plink; new_le.ptr = sybase_ptr; if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) { ct_close(sybase_ptr->connection, CS_UNUSED); ct_con_drop(sybase_ptr->connection); free(sybase_ptr); efree(hashed_details); RETURN_FALSE; } SybCtG(num_persistent)++; SybCtG(num_links)++; } else { /* we do */ CS_INT con_status; if (Z_TYPE_P(le) != le_plink) { efree(hashed_details); RETURN_FALSE; } sybase_ptr = (sybase_link *) le->ptr; /* If the link has died, close it and overwrite it with a new one. */ if (ct_con_props(sybase_ptr->connection, CS_GET, CS_CON_STATUS, &con_status, CS_UNUSED, NULL)!=CS_SUCCEED) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Unable to get connection status"); efree(hashed_details); RETURN_FALSE; } if (!(con_status & CS_CONSTAT_CONNECTED) || (con_status & CS_CONSTAT_DEAD) || sybase_ptr->dead) { sybase_link sybase; if (con_status & CS_CONSTAT_CONNECTED) { ct_close(sybase_ptr->connection, CS_FORCE_CLOSE); } /* Create a new connection, then replace the old * connection. If we fail to create a new connection, * put the old one back so there will be a connection, * even if it is a non-functional one. This is because * code may still be holding an id for this connection * so we can't free the CS_CONNECTION. * (This is actually totally hokey, it would be better * to just ct_con_drop() the connection and set * sybase_ptr->connection to NULL, then test it for * NULL before trying to use it elsewhere . . .) */ memcpy(&sybase, sybase_ptr, sizeof(sybase_link)); if (!php_sybase_do_connect_internal(sybase_ptr, host, user, passwd, charset, appname)) { memcpy(sybase_ptr, &sybase, sizeof(sybase_link)); efree(hashed_details); RETURN_FALSE; } ct_con_drop(sybase.connection); /* drop old connection */ } } ZEND_REGISTER_RESOURCE(return_value, sybase_ptr, le_plink); } else { /* non persistent */ list_entry *index_ptr, new_index_ptr; /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual sybase link sits. * if it doesn't, open a new sybase 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, link; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { efree(hashed_details); RETURN_FALSE; } link = (int) index_ptr->ptr; ptr = zend_list_find(link, &type); /* check if the link is still there */ if (ptr && (type==le_link || type==le_plink)) { zend_list_addref(link); Z_LVAL_P(return_value) = SybCtG(default_link) = link; Z_TYPE_P(return_value) = IS_RESOURCE; efree(hashed_details); return; } else { zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1); } } if (SybCtG(max_links)!=-1 && SybCtG(num_links)>=SybCtG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Too many open links (%ld)", SybCtG(num_links)); efree(hashed_details); RETURN_FALSE; } sybase_ptr = (sybase_link *) emalloc(sizeof(sybase_link)); if (!php_sybase_do_connect_internal(sybase_ptr, host, user, passwd, charset, appname)) { efree(sybase_ptr); efree(hashed_details); RETURN_FALSE; } /* add it to the list */ ZEND_REGISTER_RESOURCE(return_value, sybase_ptr, le_link); /* 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) { ct_close(sybase_ptr->connection, CS_UNUSED); ct_con_drop(sybase_ptr->connection); efree(sybase_ptr); efree(hashed_details); RETURN_FALSE; } SybCtG(num_links)++; } efree(hashed_details); SybCtG(default_link)=Z_LVAL_P(return_value); zend_list_addref(SybCtG(default_link));}static int php_sybase_get_default_link(INTERNAL_FUNCTION_PARAMETERS){ if (SybCtG(default_link)==-1) { /* no link opened yet, implicitly open one */ ht = 0; php_sybase_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } return SybCtG(default_link);}/* {{{ proto int sybase_connect([string host [, string user [, string password [, string charset [, string appname]]]]]) Open Sybase server connection */PHP_FUNCTION(sybase_connect){ php_sybase_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto int sybase_pconnect([string host [, string user [, string password [, string charset [, string appname]]]]]) Open persistent Sybase connection */PHP_FUNCTION(sybase_pconnect){ php_sybase_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto bool sybase_close([int link_id]) Close Sybase connection */PHP_FUNCTION(sybase_close){ zval **sybase_link_index = 0; int id; sybase_link *sybase_ptr; switch (ZEND_NUM_ARGS()) { case 0: id = SybCtG(default_link); break; case 1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -