apr_dbd_freetds.c
来自「linux网络服务器工具」· C语言 代码 · 共 796 行 · 第 1/2 页
C
796 行
stmt->sz = apr_palloc(pool, n*sizeof(int)); ret = 0; } else { int i; int sz = 0; int len = matches[1].rm_eo - matches[1].rm_so - 2; if (len > 255) { return 9999; } ret = recurse_args(pool, n+1, query+matches[0].rm_eo, stmt, offs+matches[0].rm_eo); memmove(stmt->fmt + offs + matches[1].rm_so, stmt->fmt + offs + matches[0].rm_eo-1, strlen(stmt->fmt+offs+matches[0].rm_eo)+2); /* compile untaint to a regex if found */ if (matches[1].rm_so == -1) { stmt->taint[n] = NULL; } else { strncpy(arg, query+matches[1].rm_so+1, matches[1].rm_eo - matches[1].rm_so - 2); arg[matches[1].rm_eo - matches[1].rm_so - 2] = '\0'; stmt->taint[n] = apr_palloc(pool, sizeof(regex_t)); if (regcomp(stmt->taint[n], arg, REG_ICASE|REG_EXTENDED) != 0) { ++ret; } else { apr_pool_cleanup_register(pool, stmt->taint[n], freetds_regfree, apr_pool_cleanup_null); } } /* record length if specified */ for (i=matches[2].rm_so; i<matches[2].rm_eo; ++i) { sz = 10*sz + (query[i]-'\0'); } } return ret;}static int dbd_freetds_prepare(apr_pool_t *pool, apr_dbd_t *sql, const char *query, const char *label, apr_dbd_prepared_t **statement){ apr_dbd_prepared_t *stmt; if (label == NULL) { label = apr_psprintf(pool, "%d", labelnum++); } if (!*statement) { *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t)); } stmt = *statement;#if 0 /* count args */ stmt->fmt = apr_pstrdup(pool, query); stmt->fmt = recurse_args(pool, 0, query, stmt, stmt->fmt); /* overestimate by a byte or two to simplify */ len = strlen("CREATE PROC apr.") + strlen(label) + stmt->nargs * strlen(" @arg1 varchar(len1),") + strlen(" AS begin ") + strlen(stmt->fmt) + strlen(" end "); /* extra byte for terminator */ pquery = apr_pcalloc(pool, len); sprintf(pquery, "CREATE PROC apr.%s", label); for (i=0; i<stmt->nargs; ++i) { sprintf(pquery+strlen(pquery), " @arg%d varchar(%d)", i, stmt->sz[i]); if (i < stmt->nargs-1) { pquery[strlen(pquery)] = ','; } } strcat(pquery, " AS BEGIN "); strcat(pquery, stmt->fmt); strcat(pquery, " END"); return (freetds_exec(sql->proc, pquery, 0, &i) == SUCCEED) ? 0 : 1;#else stmt->fmt = apr_pstrdup(pool, query); return recurse_args(pool, 0, query, stmt, 0);#endif}static int dbd_freetds_start_transaction(apr_pool_t *pool, apr_dbd_t *handle, apr_dbd_transaction_t **trans){ int dummy; /* XXX handle recursive transactions here */ handle->err = freetds_exec(handle->proc, "BEGIN TRANSACTION", 0, &dummy); if (dbd_freetds_is_success(handle->err)) { if (!*trans) { *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t)); } (*trans)->handle = handle; handle->trans = *trans; return 0; } return 1;}static int dbd_freetds_end_transaction(apr_dbd_transaction_t *trans){ int dummy; if (trans) { /* rollback on error or explicit rollback request */ if (trans->errnum) { trans->errnum = 0; trans->handle->err = freetds_exec(trans->handle->proc, "ROLLBACK", 0, &dummy); } else { trans->handle->err = freetds_exec(trans->handle->proc, "COMMIT", 0, &dummy); } trans->handle->trans = NULL; } return (trans->handle->err == SUCCEED) ? 0 : 1;}static DBPROCESS *freetds_open(apr_pool_t *pool, const char *params, const char **error){ char *server = NULL; DBPROCESS *process; LOGINREC *login; static const char *delims = " \r\n\t;|,"; char *ptr; char *key; char *value; int vlen; int klen; char *buf; char *databaseName = NULL; /* FIXME - this uses malloc */ /* FIXME - pass error message back to the caller in case of failure */ login = dblogin(); if (login == NULL) { return NULL; } /* now set login properties */ for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { /* don't dereference memory that may not belong to us */ if (ptr == params) { ++ptr; continue; } for (key = ptr-1; isspace(*key); --key); klen = 0; while (isalpha(*key)) { --key; ++klen; } ++key; for (value = ptr+1; isspace(*value); ++value); vlen = strcspn(value, delims); buf = apr_pstrndup(pool, value, vlen); /* NULL-terminated copy */ if (!strncasecmp(key, "username", klen)) { DBSETLUSER(login, buf); } else if (!strncasecmp(key, "password", klen)) { DBSETLPWD(login, buf); } else if (!strncasecmp(key, "appname", klen)) { DBSETLAPP(login, buf); } else if (!strncasecmp(key, "dbname", klen)) { databaseName = buf; } else if (!strncasecmp(key, "host", klen)) { DBSETLHOST(login, buf); } else if (!strncasecmp(key, "charset", klen)) { DBSETLCHARSET(login, buf); } else if (!strncasecmp(key, "lang", klen)) { DBSETLNATLANG(login, buf); } else if (!strncasecmp(key, "server", klen)) { server = buf; } else { /* unknown param */ } ptr = value+vlen; } process = dbopen(login, server); fprintf(stderr, "databaseName [%s]\n", databaseName); if (databaseName != NULL) { dbuse(process, databaseName); } dbloginfree(login); if (process == NULL) { return NULL; } return process;}static apr_dbd_t *dbd_freetds_open(apr_pool_t *pool, const char *params, const char **error){ apr_dbd_t *sql; /* FIXME - pass error message back to the caller in case of failure */ DBPROCESS *process = freetds_open(pool, params, error); if (process == NULL) { return NULL; } sql = apr_palloc (pool, sizeof (apr_dbd_t)); sql->pool = pool; sql->proc = process; sql->params = params; return sql;}static apr_status_t dbd_freetds_close(apr_dbd_t *handle){ dbclose(handle->proc); return APR_SUCCESS;}static apr_status_t dbd_freetds_check_conn(apr_pool_t *pool, apr_dbd_t *handle){ if (dbdead(handle->proc)) { /* try again */ dbclose(handle->proc); handle->proc = freetds_open(handle->pool, handle->params); if (!handle->proc || dbdead(handle->proc)) { return APR_EGENERAL; } } /* clear it, in case this is called in error handling */ dbcancel(handle->proc); return APR_SUCCESS;}static int dbd_freetds_select_db(apr_pool_t *pool, apr_dbd_t *handle, const char *name){ /* ouch, it's declared int. But we can use APR 0/nonzero */ return (dbuse(handle->proc, (char*)name) == SUCCEED) ? APR_SUCCESS : APR_EGENERAL;}static void *dbd_freetds_native(apr_dbd_t *handle){ return handle->proc;}static int dbd_freetds_num_cols(apr_dbd_results_t* res){ return res->sz;}static int dbd_freetds_num_tuples(apr_dbd_results_t* res){ if (res->random) { return res->ntuples; } else { return -1; }}static apr_status_t freetds_term(void *dummy){ dbexit(); regfree(&dbd_freetds_find_arg); return APR_SUCCESS;}static void dbd_freetds_init(apr_pool_t *pool){ int rv = regcomp(&dbd_freetds_find_arg, "%(\\{[^}]*\\})?([0-9]*)[A-Za-z]", REG_EXTENDED); if (rv != 0) { char errmsg[256]; regerror(rv, &dbd_freetds_find_arg, errmsg, 256); fprintf(stderr, "regcomp failed: %s\n", errmsg); } dbinit(); apr_pool_cleanup_register(pool, NULL, freetds_term, apr_pool_cleanup_null);}#ifdef COMPILE_STUBS/* get_name is the only one of these that is implemented */static const char *dbd_freetds_get_name(const apr_dbd_results_t *res, int n){ return (const char*) dbcolname(res->proc, n+1); /* numbering starts at 1 */}/* These are stubs: transaction modes not implemented here */#define DBD_NOTIMPL APR_ENOTIMPL;static int dbd_freetds_transaction_mode_get(apr_dbd_transaction_t *trans){ return trans ? trans->mode : APR_DBD_TRANSACTION_COMMIT;}static int dbd_freetds_transaction_mode_set(apr_dbd_transaction_t *trans, int mode){ if (trans) { trans->mode = mode & TXN_MODE_BITS; return trans->mode; } return APR_DBD_TRANSACTION_COMMIT;}static int dbd_freetds_pvbquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, apr_dbd_prepared_t *statement, va_list args){ return DBD_NOTIMPL;}static int dbd_freetds_pbquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, apr_dbd_prepared_t * statement, const void **values){ return DBD_NOTIMPL;}static int dbd_freetds_pvbselect(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **results, apr_dbd_prepared_t *statement, int seek, va_list args){ return DBD_NOTIMPL;}static int dbd_freetds_pbselect(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **results, apr_dbd_prepared_t *statement, int seek, const void **values){ return DBD_NOTIMPL;}static apr_status_t dbd_freetds_datum_get(const apr_dbd_row_t *row, int n, apr_dbd_type_e type, void *data){ return APR_ENOTIMPL;}#endifAPU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_freetds_driver = { "freetds", dbd_freetds_init, dbd_freetds_native, dbd_freetds_open, dbd_freetds_check_conn, dbd_freetds_close, dbd_freetds_select_db, dbd_freetds_start_transaction, dbd_freetds_end_transaction, dbd_freetds_query, dbd_freetds_select, dbd_freetds_num_cols, dbd_freetds_num_tuples, dbd_freetds_get_row, dbd_freetds_get_entry, dbd_freetds_error, dbd_freetds_escape, dbd_freetds_prepare, dbd_freetds_pvquery, dbd_freetds_pvselect, dbd_freetds_pquery, dbd_freetds_pselect, /* this is only implemented to support httpd/2.2 standard usage, * as in the original DBD implementation. Everything else is NOTIMPL. */#ifdef COMPILE_STUBS dbd_freetds_get_name, dbd_freetds_transaction_mode_get, dbd_freetds_transaction_mode_set, "", dbd_freetds_pvbquery, dbd_freetds_pvbselect, dbd_freetds_pbquery, dbd_freetds_pbselect, dbd_freetds_datum_get#endif};#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?