📄 mssql.c
字号:
/* +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ | This program is free software; you can redistribute it and/or modify | | it under the terms of one of the following licenses: | | | | A) the GNU General Public License as published by the Free Software | | Foundation; either version 2 of the License, or (at your option) | | any later version. | | | | B) the PHP License as published by the PHP Development Team and | | included in the distribution in the file: LICENSE | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | GNU General Public License for more details. | | | | You should have received a copy of both licenses referred to here. | | If you did not, or have any questions about PHP licensing, please | | contact core@php.net. | +----------------------------------------------------------------------+ | Authors: Zeev Suraski <zeev@zend.com> Original sybase.c | | Frank M. Kromann <fmk@businesnet.dk> | +----------------------------------------------------------------------+ | php3_mssql_get_column_content_with_type() based on code by: | | Muhammad A Muquit <MA_Muquit@fccc.edu> | | Rasmus Lerdorf <rasmus@lerdorf.on.ca> | +----------------------------------------------------------------------+ *//* $Id: mssql.c,v 1.19 2000/05/23 18:13:28 fmk Exp $ */#define IS_EXT_MODULE#if !(WIN32|WINNT)#include "config.h"#endif#include "php.h"#include "internal_functions.h"#include "php3_mssql.h"#if HAVE_MSSQL#define SAFE_STRING(s) ((s)?(s):"")#include "functions/php3_string.h"#include "php3_list.h"#if BROKEN_MSSQL_PCONNECTS#include "http_log.h"#endiffunction_entry mssql_functions[] = { {"mssql_connect", php3_mssql_connect, NULL}, {"mssql_pconnect", php3_mssql_pconnect, NULL}, {"mssql_close", php3_mssql_close, NULL}, {"mssql_select_db", php3_mssql_select_db, NULL}, {"mssql_query", php3_mssql_query, NULL}, {"mssql_free_result", php3_mssql_free_result, NULL}, {"mssql_get_last_message", php3_mssql_get_last_message, NULL}, {"mssql_num_rows", php3_mssql_num_rows, NULL}, {"mssql_num_fields", php3_mssql_num_fields, NULL}, {"mssql_fetch_field", php3_mssql_fetch_field, NULL}, {"mssql_fetch_row", php3_mssql_fetch_row, NULL}, {"mssql_fetch_array", php3_mssql_fetch_array, NULL}, {"mssql_fetch_object", php3_mssql_fetch_object, NULL}, {"mssql_field_length", php3_mssql_field_length, NULL}, {"mssql_field_name", php3_mssql_field_name, NULL}, {"mssql_field_type", php3_mssql_field_type, NULL}, {"mssql_data_seek", php3_mssql_data_seek, NULL}, {"mssql_field_seek", php3_mssql_field_seek, NULL}, {"mssql_result", php3_mssql_result, NULL}, {"mssql_min_error_severity", php3_mssql_min_error_severity, NULL}, {"mssql_min_message_severity", php3_mssql_min_message_severity, NULL}, {NULL, NULL, NULL}};php3_module_entry mssql_module_entry = { "Microsoft SQL", mssql_functions, php3_minit_mssql, php3_mshutdown_mssql, php3_rinit_mssql, php3_rshutdown_mssql, php3_info_mssql, STANDARD_MODULE_PROPERTIES};#if COMPILE_DLDLEXPORT php3_module_entry *get_module(void) { return &mssql_module_entry; }#endif#define msSQL_GLOBAL(a) php3_mssql_module.a#define msSQL_TLS_VARSmssql_module php3_mssql_module;#define CHECK_LINK(link) { if (link==-1) { php3_error(E_WARNING,"MS SQL: A link to the server could not be established"); RETURN_FALSE; } }static void php3_mssql_get_column_content_with_type(mssql_link *mssql_ptr,int offset,pval *result, int column_type);static void php3_mssql_get_column_content_without_type(mssql_link *mssql_ptr,int offset,pval *result, int column_type);/* error handler */static int php3_mssql_error_handler(DBPROCESS *dbproc,int severity,int dberr, int oserr,char *dberrstr,char *oserrstr){ msSQL_TLS_VARS; if (severity >= msSQL_GLOBAL(min_error_severity)) { php3_error(E_WARNING,"MS SQL error: %s (severity %d)",dberrstr,severity); } return INT_CANCEL; }/* message handler */static int php3_mssql_message_handler(DBPROCESS *dbproc,DBINT msgno,int msgstate, int severity,char *msgtext,char *srvname, char *procname,DBUSMALLINT line){ msSQL_TLS_VARS; if (severity >= msSQL_GLOBAL(min_message_severity)) { php3_error(E_WARNING,"MS SQL message: %s (severity %d)",msgtext,severity); } STR_FREE(msSQL_GLOBAL(server_message)); msSQL_GLOBAL(server_message) = estrdup(msgtext); return 0;}static int _clean_invalid_results(list_entry *le){ msSQL_TLS_VARS; if (le->type == msSQL_GLOBAL(le_result)) { mssql_link *mssql_ptr = ((mssql_result *) le->ptr)->mssql_ptr; if (!mssql_ptr->valid) { return 1; } } return 0;}static void _free_mssql_result(mssql_result *result){ int i,j; if (result->data) { for (i=0; i<result->num_rows; i++) { for (j=0; j<result->num_fields; j++) { php3tls_pval_destructor(&result->data[i][j]); } efree(result->data[i]); } efree(result->data); } if (result->fields) { for (i=0; i<result->num_fields; i++) { STR_FREE(result->fields[i].name); STR_FREE(result->fields[i].column_source); } efree(result->fields); } efree(result);}static void _close_mssql_link(mssql_link *mssql_ptr){ msSQL_TLS_VARS; mssql_ptr->valid = 0; _php3_hash_apply(msSQL_GLOBAL(resource_list),(int (*)(void *))_clean_invalid_results); dbclose(mssql_ptr->link); dbfreelogin(mssql_ptr->login); efree(mssql_ptr); msSQL_GLOBAL(num_links--);}static void _close_mssql_plink(mssql_link *mssql_ptr){ msSQL_TLS_VARS; dbclose(mssql_ptr->link); dbfreelogin(mssql_ptr->login); free(mssql_ptr); msSQL_GLOBAL(num_persistent--); msSQL_GLOBAL(num_links--);}int php3_minit_mssql(INIT_FUNC_ARGS){/* char *interface_file; */ long compatability_mode,connecttimeout; if (dbinit()==FAIL) { return FAILURE; }#if WINNT|WIN32 dberrhandle((DBERRHANDLE_PROC) php3_mssql_error_handler); dbmsghandle((DBMSGHANDLE_PROC) php3_mssql_message_handler);#endif //if (cfg_get_string("mssql.interface_file",&interface_file)==SUCCESS) { //dbsetifile(interface_file); //} if (cfg_get_long("mssql.allow_persistent",&msSQL_GLOBAL(allow_persistent))==FAILURE) { msSQL_GLOBAL(allow_persistent)=1; } if (cfg_get_long("mssql.max_persistent",&msSQL_GLOBAL(max_persistent))==FAILURE) { msSQL_GLOBAL(max_persistent)=-1; } if (cfg_get_long("mssql.max_links",&msSQL_GLOBAL(max_links))==FAILURE) { msSQL_GLOBAL(max_links)=-1; } if (cfg_get_long("mssql.min_error_severity",&msSQL_GLOBAL(cfg_min_error_severity))==FAILURE) { msSQL_GLOBAL(cfg_min_error_severity)=10; } if (cfg_get_long("mssql.min_message_severity",&msSQL_GLOBAL(cfg_min_message_severity))==FAILURE) { msSQL_GLOBAL(cfg_min_message_severity)=10; } if (cfg_get_long("mssql.compatability_mode",&compatability_mode)==FAILURE) { compatability_mode = 0; } if (cfg_get_long("mssql.connect_timeout",&connecttimeout)==FAILURE) { connecttimeout = 5; } if (cfg_get_long("magic_quotes_runtime",&msSQL_GLOBAL(magic_quotes_runtime))==FAILURE) { msSQL_GLOBAL(magic_quotes_runtime) = 0; } if (compatability_mode) { msSQL_GLOBAL(get_column_content) = php3_mssql_get_column_content_with_type; } else { msSQL_GLOBAL(get_column_content) = php3_mssql_get_column_content_without_type; } if (cfg_get_long("mssql.textsize",&msSQL_GLOBAL(textsize))==FAILURE) { msSQL_GLOBAL(textsize) = -1; } if (cfg_get_long("mssql.textlimit",&msSQL_GLOBAL(textlimit))==FAILURE) { msSQL_GLOBAL(textlimit) = -1; } /* set a minimum timeout, and exclude infinite timeouts */ if(connecttimeout<1)connecttimeout=1; dbsetlogintime(connecttimeout); msSQL_GLOBAL(num_persistent)=0; msSQL_GLOBAL(le_link) = register_list_destructors(_close_mssql_link,NULL); msSQL_GLOBAL(le_plink) = register_list_destructors(NULL,_close_mssql_plink); msSQL_GLOBAL(le_result) = register_list_destructors(_free_mssql_result,NULL); return SUCCESS;}int php3_rinit_mssql(INIT_FUNC_ARGS){ msSQL_TLS_VARS; msSQL_GLOBAL(default_link)=-1; msSQL_GLOBAL(num_links) = msSQL_GLOBAL(num_persistent); msSQL_GLOBAL(appname) = "PHP"; msSQL_GLOBAL(server_message) = empty_string; msSQL_GLOBAL(min_error_severity) = msSQL_GLOBAL(cfg_min_error_severity); msSQL_GLOBAL(min_message_severity) = msSQL_GLOBAL(cfg_min_message_severity); return SUCCESS;}int php3_mshutdown_mssql(void){ msSQL_TLS_VARS; dbexit(); return SUCCESS;}int php3_rshutdown_mssql(void){ msSQL_TLS_VARS; STR_FREE(msSQL_GLOBAL(server_message)); return SUCCESS;}static void php3_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent){ char *user,*passwd,*host; char *hashed_details; int hashed_details_length; mssql_link mssql,*mssql_ptr; list_entry *le; char buffer[32]; msSQL_TLS_VARS; msSQL_GLOBAL(resource_list) = list; msSQL_GLOBAL(resource_plist) = plist; switch(ARG_COUNT(ht)) { case 0: /* defaults */ host=user=passwd=NULL; break; case 1: { pval *yyhost; if (getParameters(ht, 1, &yyhost)==FAILURE) { RETURN_FALSE; } convert_to_string(yyhost); host = yyhost->value.str.val; user=passwd=NULL; } break; case 2: { pval *yyhost,*yyuser; if (getParameters(ht, 2, &yyhost, &yyuser)==FAILURE) { RETURN_FALSE; } convert_to_string(yyhost); convert_to_string(yyuser); host = yyhost->value.str.val; user = yyuser->value.str.val; passwd=NULL; } break; case 3: { pval *yyhost,*yyuser,*yypasswd; if (getParameters(ht, 3, &yyhost, &yyuser, &yypasswd) == FAILURE) { RETURN_FALSE; } convert_to_string(yyhost); convert_to_string(yyuser); convert_to_string(yypasswd); host = yyhost->value.str.val; user = yyuser->value.str.val; passwd = yypasswd->value.str.val; } break; default: WRONG_PARAM_COUNT; break; } hashed_details_length = sizeof("mssql___")-1 + strlen(SAFE_STRING(host))+strlen(SAFE_STRING(user))+strlen(SAFE_STRING(passwd)); hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details,"mssql_%s_%s_%s",SAFE_STRING(host), SAFE_STRING(user), SAFE_STRING(passwd)); return_value->value.lval = 0; return_value->type = IS_LONG; /* set a DBLOGIN record */ if ((mssql.login=dblogin())==NULL) { php3_error(E_WARNING,"MS SQL: Unable to allocate login record"); RETURN_FALSE; } if (user) { DBSETLUSER(mssql.login,user); } if (passwd) { DBSETLPWD(mssql.login,passwd); } DBSETLAPP(mssql.login,msSQL_GLOBAL(appname)); mssql.valid = 1;#if WINNT|WIN32 DBSETLVERSION(mssql.login, DBVER60);#endif// DBSETLTIME(mssql.login, TIMEOUT_INFINITE); if (!msSQL_GLOBAL(allow_persistent)) { persistent=0; } if (persistent) { /* try to find if we already have this link in our persistent list */ if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */ list_entry new_le; if (msSQL_GLOBAL(max_links)!=-1 && msSQL_GLOBAL(num_links)>=msSQL_GLOBAL(max_links)) { php3_error(E_WARNING,"MS SQL: Too many open links (%d)",msSQL_GLOBAL(num_links)); efree(hashed_details); dbfreelogin(mssql.login); RETURN_FALSE; } if (msSQL_GLOBAL(max_persistent)!=-1 && msSQL_GLOBAL(num_persistent)>=msSQL_GLOBAL(max_persistent)) { php3_error(E_WARNING,"MS SQL: Too many open persistent links (%d)",msSQL_GLOBAL(num_persistent)); efree(hashed_details); dbfreelogin(mssql.login); RETURN_FALSE; } /* create the link */ if ((mssql.link=dbopen(mssql.login,host))==FAIL) { /*php3_error(E_WARNING,"MS SQL: Unable to connect to server: %s",mssql_error(mssql));*/ efree(hashed_details); dbfreelogin(mssql.login); RETURN_FALSE; } if (dbsetopt(mssql.link,DBBUFFER,"2" FREETDS_OPTION)==FAIL) { efree(hashed_details); dbfreelogin(mssql.login); dbclose(mssql.link); RETURN_FALSE; } if (msSQL_GLOBAL(textsize) != -1) { sprintf(buffer, "%li", msSQL_GLOBAL(textsize)); if (dbsetopt(mssql.link, DBTEXTSIZE, buffer FREETDS_OPTION)==FAIL) { efree(hashed_details); dbfreelogin(mssql.login); RETURN_FALSE; } } if (msSQL_GLOBAL(textlimit) != -1) { sprintf(buffer, "%li", msSQL_GLOBAL(textlimit)); if (dbsetopt(mssql.link, DBTEXTLIMIT, buffer FREETDS_OPTION)==FAIL) { efree(hashed_details); dbfreelogin(mssql.login); RETURN_FALSE; } } /* hash it up */ mssql_ptr = (mssql_link *) malloc(sizeof(mssql_link)); memcpy(mssql_ptr,&mssql,sizeof(mssql_link)); new_le.type = msSQL_GLOBAL(le_plink); new_le.ptr = mssql_ptr; if (_php3_hash_update(plist, hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry),NULL)==FAILURE) { free(mssql_ptr); efree(hashed_details); dbfreelogin(mssql.login); RETURN_FALSE; } msSQL_GLOBAL(num_persistent++); msSQL_GLOBAL(num_links++); } else { /* we do */ if (le->type != msSQL_GLOBAL(le_plink)) {#if BROKEN_MSSQL_PCONNECTS log_error("PHP/MS SQL: Hashed persistent link is not a MS SQL link!",php3_rqst->server);#endif php3_error(E_WARNING,"MS SQL: Hashed persistent link is not a MS SQL link!"); RETURN_FALSE; } mssql_ptr = (mssql_link *) le->ptr; /* test that the link hasn't died */ if (DBDEAD(mssql_ptr->link)==TRUE) {#if BROKEN_MSSQL_PCONNECTS log_error("PHP/MS SQL: Persistent link died, trying to reconnect...",php3_rqst->server);#endif if ((mssql_ptr->link=dbopen(mssql_ptr->login,host))==FAIL) {#if BROKEN_MSSQL_PCONNECTS log_error("PHP/MS SQL: Unable to reconnect!",php3_rqst->server);#endif php3_error(E_WARNING,"MS SQL: Link to server lost, unable to reconnect"); _php3_hash_del(plist, hashed_details, hashed_details_length+1); efree(hashed_details); RETURN_FALSE; }#if BROKEN_MSSQL_PCONNECTS log_error("PHP/MS SQL: Reconnect successful!",php3_rqst->server);#endif if (dbsetopt(mssql_ptr->link,DBBUFFER,"2" FREETDS_OPTION)==FAIL) {#if BROKEN_MSSQL_PCONNECTS log_error("PHP/MS SQL: Unable to set required options",php3_rqst->server);#endif _php3_hash_del(plist, hashed_details, hashed_details_length+1); efree(hashed_details); RETURN_FALSE; } } } return_value->value.lval = php3_list_insert(mssql_ptr,msSQL_GLOBAL(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 mssql link sits. * if it doesn't, open a new mssql link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) { int type,link; void *ptr; if (index_ptr->type != le_index_ptr) { RETURN_FALSE; } link = (int) index_ptr->ptr; ptr = php3_list_find(link,&type); /* check if the link is still there */ if (ptr && (type==msSQL_GLOBAL(le_link) || type==msSQL_GLOBAL(le_plink))) { return_value->value.lval = msSQL_GLOBAL(default_link) = link; return_value->type = IS_LONG; efree(hashed_details); return; } else { _php3_hash_del(list,hashed_details,hashed_details_length+1); } } if (msSQL_GLOBAL(max_links)!=-1 && msSQL_GLOBAL(num_links)>=msSQL_GLOBAL(max_links)) { php3_error(E_WARNING,"MS SQL: Too many open links (%d)",msSQL_GLOBAL(num_links)); efree(hashed_details); RETURN_FALSE; } if ((mssql.link=dbopen(mssql.login,host))==NULL) { /*php3_error(E_WARNING,"MS SQL: Unable to connect to server: %s",mssql_error(mssql));*/ efree(hashed_details); RETURN_FALSE; } if (dbsetopt(mssql.link,DBBUFFER,"2" FREETDS_OPTION)==FAIL) { efree(hashed_details); dbfreelogin(mssql.login); dbclose(mssql.link); RETURN_FALSE; } if (msSQL_GLOBAL(textlimit) != -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -