#include "asterisk.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "asterisk/module.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/res_odbc.h"
#include "asterisk/app.h"
Include dependency graph for func_odbc.c:

Go to the source code of this file.
Data Structures | |
| struct | acf_odbc_query |
Enumerations | |
| enum | { OPT_ESCAPECOMMAS = (1 << 0) } |
Functions | |
| static int | acf_escape (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| static int | acf_odbc_read (struct ast_channel *chan, char *cmd, char *s, char *buf, size_t len) |
| static int | acf_odbc_write (struct ast_channel *chan, char *cmd, char *s, const char *value) |
| AST_LIST_HEAD_STATIC (queries, acf_odbc_query) | |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"ODBC lookups",.load=load_module,.unload=unload_module,.reload=reload,) | |
| static int | free_acf_query (struct acf_odbc_query *query) |
| static SQLHSTMT | generic_prepare (struct odbc_obj *obj, void *data) |
| static int | init_acf_query (struct ast_config *cfg, char *catg, struct acf_odbc_query **query) |
| static int | load_module (void) |
| static int | odbc_load_module (void) |
| static int | odbc_unload_module (void) |
| static int | reload (void) |
| static int | unload_module (void) |
Variables | |
| static char * | config = "func_odbc.conf" |
| static struct ast_custom_function | escape_function |
| enum { ... } | odbc_option_flags |
Definition in file func_odbc.c.
| anonymous enum |
Definition at line 56 of file func_odbc.c.
00056 { 00057 OPT_ESCAPECOMMAS = (1 << 0), 00058 } odbc_option_flags;
| static int acf_escape | ( | struct ast_channel * | chan, | |
| char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 377 of file func_odbc.c.
00378 { 00379 char *out = buf; 00380 00381 for (; *data && out - buf < len; data++) { 00382 if (*data == '\'') { 00383 *out = '\''; 00384 out++; 00385 } 00386 *out++ = *data; 00387 } 00388 *out = '\0'; 00389 00390 return 0; 00391 }
| static int acf_odbc_read | ( | struct ast_channel * | chan, | |
| char * | cmd, | |||
| char * | s, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 216 of file func_odbc.c.
References AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_alloc(), ast_channel_free(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), AST_STANDARD_APP_ARGS, ast_test_flag, ast_verbose(), generic_prepare(), LOG_ERROR, LOG_WARNING, OPT_ESCAPECOMMAS, option_verbose, pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), and VERBOSE_PREFIX_4.
Referenced by init_acf_query().
00217 { 00218 struct odbc_obj *obj; 00219 struct acf_odbc_query *query; 00220 char sql[2048] = "", varname[15]; 00221 int res, x, buflen = 1, escapecommas, bogus_chan = 0; 00222 AST_DECLARE_APP_ARGS(args, 00223 AST_APP_ARG(field)[100]; 00224 ); 00225 SQLHSTMT stmt; 00226 SQLSMALLINT colcount=0; 00227 SQLLEN indicator; 00228 00229 AST_LIST_LOCK(&queries); 00230 AST_LIST_TRAVERSE(&queries, query, list) { 00231 if (!strcmp(query->acf->name, cmd)) { 00232 break; 00233 } 00234 } 00235 00236 if (!query) { 00237 ast_log(LOG_ERROR, "No such function '%s'\n", cmd); 00238 AST_LIST_UNLOCK(&queries); 00239 return -1; 00240 } 00241 00242 obj = ast_odbc_request_obj(query->dsn, 0); 00243 00244 if (!obj) { 00245 ast_log(LOG_ERROR, "No such DSN registered (or out of connections): %s (check res_odbc.conf)\n", query->dsn); 00246 AST_LIST_UNLOCK(&queries); 00247 return -1; 00248 } 00249 00250 if (!chan) { 00251 if ((chan = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/func_odbc"))) 00252 bogus_chan = 1; 00253 } 00254 00255 if (chan) 00256 ast_autoservice_start(chan); 00257 00258 AST_STANDARD_APP_ARGS(args, s); 00259 for (x = 0; x < args.argc; x++) { 00260 snprintf(varname, sizeof(varname), "ARG%d", x + 1); 00261 pbx_builtin_pushvar_helper(chan, varname, args.field[x]); 00262 } 00263 00264 pbx_substitute_variables_helper(chan, query->sql_read, sql, sizeof(sql) - 1); 00265 00266 /* Restore prior values */ 00267 for (x = 0; x < args.argc; x++) { 00268 snprintf(varname, sizeof(varname), "ARG%d", x + 1); 00269 pbx_builtin_setvar_helper(chan, varname, NULL); 00270 } 00271 00272 /* Save this flag, so we can release the lock */ 00273 escapecommas = ast_test_flag(query, OPT_ESCAPECOMMAS); 00274 00275 AST_LIST_UNLOCK(&queries); 00276 00277 stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, sql); 00278 00279 if (!stmt) { 00280 ast_odbc_release_obj(obj); 00281 if (chan) 00282 ast_autoservice_stop(chan); 00283 if (bogus_chan) 00284 ast_channel_free(chan); 00285 return -1; 00286 } 00287 00288 res = SQLNumResultCols(stmt, &colcount); 00289 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00290 ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); 00291 SQLCloseCursor(stmt); 00292 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00293 ast_odbc_release_obj(obj); 00294 if (chan) 00295 ast_autoservice_stop(chan); 00296 if (bogus_chan) 00297 ast_channel_free(chan); 00298 return -1; 00299 } 00300 00301 *buf = '\0'; 00302 00303 res = SQLFetch(stmt); 00304 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00305 int res1 = -1; 00306 if (res == SQL_NO_DATA) { 00307 if (option_verbose > 3) { 00308 ast_verbose(VERBOSE_PREFIX_4 "Found no rows [%s]\n", sql); 00309 } 00310 res1 = 0; 00311 } else if (option_verbose > 3) { 00312 ast_log(LOG_WARNING, "Error %d in FETCH [%s]\n", res, sql); 00313 } 00314 SQLCloseCursor(stmt); 00315 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00316 ast_odbc_release_obj(obj); 00317 if (chan) 00318 ast_autoservice_stop(chan); 00319 if (bogus_chan) 00320 ast_channel_free(chan); 00321 return res1; 00322 } 00323 00324 for (x = 0; x < colcount; x++) { 00325 int i; 00326 char coldata[256]; 00327 00328 buflen = strlen(buf); 00329 res = SQLGetData(stmt, x + 1, SQL_CHAR, coldata, sizeof(coldata), &indicator); 00330 if (indicator == SQL_NULL_DATA) { 00331 coldata[0] = '\0'; 00332 res = SQL_SUCCESS; 00333 } 00334 00335 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00336 ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); 00337 SQLCloseCursor(stmt); 00338 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00339 ast_odbc_release_obj(obj); 00340 if (chan) 00341 ast_autoservice_stop(chan); 00342 if (bogus_chan) 00343 ast_channel_free(chan); 00344 return -1; 00345 } 00346 00347 /* Copy data, encoding '\' and ',' for the argument parser */ 00348 for (i = 0; i < sizeof(coldata); i++) { 00349 if (escapecommas && (coldata[i] == '\\' || coldata[i] == ',')) { 00350 buf[buflen++] = '\\'; 00351 } 00352 buf[buflen++] = coldata[i]; 00353 00354 if (buflen >= len - 2) 00355 break; 00356 00357 if (coldata[i] == '\0') 00358 break; 00359 } 00360 00361 buf[buflen - 1] = ','; 00362 buf[buflen] = '\0'; 00363 } 00364 /* Trim trailing comma */ 00365 buf[buflen - 1] = '\0'; 00366 00367 SQLCloseCursor(stmt); 00368 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00369 ast_odbc_release_obj(obj); 00370 if (chan) 00371 ast_autoservice_stop(chan); 00372 if (bogus_chan) 00373 ast_channel_free(chan); 00374 return 0; 00375 }
| static int acf_odbc_write | ( | struct ast_channel * | chan, | |
| char * | cmd, | |||
| char * | s, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 97 of file func_odbc.c.
References AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_alloc(), ast_channel_free(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), AST_STANDARD_APP_ARGS, ast_strdupa, generic_prepare(), LOG_ERROR, pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), and t.
Referenced by init_acf_query().
00098 { 00099 struct odbc_obj *obj; 00100 struct acf_odbc_query *query; 00101 char *t, buf[2048]="", varname[15]; 00102 int i, bogus_chan = 0; 00103 AST_DECLARE_APP_ARGS(values, 00104 AST_APP_ARG(field)[100]; 00105 ); 00106 AST_DECLARE_APP_ARGS(args, 00107 AST_APP_ARG(field)[100]; 00108 ); 00109 SQLHSTMT stmt; 00110 SQLLEN rows=0; 00111 00112 AST_LIST_LOCK(&queries); 00113 AST_LIST_TRAVERSE(&queries, query, list) { 00114 if (!strcmp(query->acf->name, cmd)) { 00115 break; 00116 } 00117 } 00118 00119 if (!query) { 00120 ast_log(LOG_ERROR, "No such function '%s'\n", cmd); 00121 AST_LIST_UNLOCK(&queries); 00122 return -1; 00123 } 00124 00125 obj = ast_odbc_request_obj(query->dsn, 0); 00126 00127 if (!obj) { 00128 ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", query->dsn); 00129 AST_LIST_UNLOCK(&queries); 00130 return -1; 00131 } 00132 00133 if (!chan) { 00134 if ((chan = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/func_odbc"))) 00135 bogus_chan = 1; 00136 } 00137 00138 if (chan) 00139 ast_autoservice_start(chan); 00140 00141 /* Parse our arguments */ 00142 t = value ? ast_strdupa(value) : ""; 00143 00144 if (!s || !t) { 00145 ast_log(LOG_ERROR, "Out of memory\n"); 00146 AST_LIST_UNLOCK(&queries); 00147 if (chan) 00148 ast_autoservice_stop(chan); 00149 if (bogus_chan) 00150 ast_channel_free(chan); 00151 return -1; 00152 } 00153 00154 AST_STANDARD_APP_ARGS(args, s); 00155 for (i = 0; i < args.argc; i++) { 00156 snprintf(varname, sizeof(varname), "ARG%d", i + 1); 00157 pbx_builtin_pushvar_helper(chan, varname, args.field[i]); 00158 } 00159 00160 /* Parse values, just like arguments */ 00161 /* Can't use the pipe, because app Set removes them */ 00162 AST_NONSTANDARD_APP_ARGS(values, t, ','); 00163 for (i = 0; i < values.argc; i++) { 00164 snprintf(varname, sizeof(varname), "VAL%d", i + 1); 00165 pbx_builtin_pushvar_helper(chan, varname, values.field[i]); 00166 } 00167 00168 /* Additionally set the value as a whole (but push an empty string if value is NULL) */ 00169 pbx_builtin_pushvar_helper(chan, "VALUE", value ? value : ""); 00170 00171 pbx_substitute_variables_helper(chan, query->sql_write, buf, sizeof(buf) - 1); 00172 00173 /* Restore prior values */ 00174 for (i = 0; i < args.argc; i++) { 00175 snprintf(varname, sizeof(varname), "ARG%d", i + 1); 00176 pbx_builtin_setvar_helper(chan, varname, NULL); 00177 } 00178 00179 for (i = 0; i < values.argc; i++) { 00180 snprintf(varname, sizeof(varname), "VAL%d", i + 1); 00181 pbx_builtin_setvar_helper(chan, varname, NULL); 00182 } 00183 pbx_builtin_setvar_helper(chan, "VALUE", NULL); 00184 00185 AST_LIST_UNLOCK(&queries); 00186 00187 stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, buf); 00188 00189 if (stmt) { 00190 /* Rows affected */ 00191 SQLRowCount(stmt, &rows); 00192 } 00193 00194 /* Output the affected rows, for all cases. In the event of failure, we 00195 * flag this as -1 rows. Note that this is different from 0 affected rows 00196 * which would be the case if we succeeded in our query, but the values did 00197 * not change. */ 00198 snprintf(varname, sizeof(varname), "%d", (int)rows); 00199 pbx_builtin_setvar_helper(chan, "ODBCROWS", varname); 00200 00201 if (stmt) { 00202 SQLCloseCursor(stmt); 00203 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00204 } 00205 if (obj) 00206 ast_odbc_release_obj(obj); 00207 00208 if (chan) 00209 ast_autoservice_stop(chan); 00210 if (bogus_chan) 00211 ast_channel_free(chan); 00212 00213 return 0; 00214 }
| AST_LIST_HEAD_STATIC | ( | queries | , | |
| acf_odbc_query | ||||
| ) |
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_DEFAULT | , | |||
| "ODBC lookups" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| static int free_acf_query | ( | struct acf_odbc_query * | query | ) | [static] |
Definition at line 527 of file func_odbc.c.
References free.
Referenced by odbc_load_module(), odbc_unload_module(), and reload().
00528 { 00529 if (query) { 00530 if (query->acf) { 00531 if (query->acf->name) 00532 free((char *)query->acf->name); 00533 if (query->acf->syntax) 00534 free((char *)query->acf->syntax); 00535 if (query->acf->desc) 00536 free((char *)query->acf->desc); 00537 free(query->acf); 00538 } 00539 free(query); 00540 } 00541 return 0; 00542 }
| static SQLHSTMT generic_prepare | ( | struct odbc_obj * | obj, | |
| void * | data | |||
| ) | [static] |
Definition at line 71 of file func_odbc.c.
References ast_log(), odbc_obj::con, and LOG_WARNING.
Referenced by acf_odbc_read(), and acf_odbc_write().
00072 { 00073 int res; 00074 char *sql = data; 00075 SQLHSTMT stmt; 00076 00077 res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); 00078 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00079 ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); 00080 return NULL; 00081 } 00082 00083 res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS); 00084 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00085 ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); 00086 SQLCloseCursor(stmt); 00087 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00088 return NULL; 00089 } 00090 00091 return stmt; 00092 }
| static int init_acf_query | ( | struct ast_config * | cfg, | |
| char * | catg, | |||
| struct acf_odbc_query ** | query | |||
| ) | [static] |
Definition at line 405 of file func_odbc.c.
References acf_odbc_read(), acf_odbc_write(), asprintf, ast_calloc, ast_clear_flag, ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_variable_retrieve(), free, LOG_ERROR, LOG_WARNING, and OPT_ESCAPECOMMAS.
Referenced by odbc_load_module(), and reload().
00406 { 00407 const char *tmp; 00408 00409 if (!cfg || !catg) { 00410 return -1; 00411 } 00412 00413 *query = ast_calloc(1, sizeof(struct acf_odbc_query)); 00414 if (! (*query)) 00415 return -1; 00416 00417 if ((tmp = ast_variable_retrieve(cfg, catg, "dsn"))) { 00418 ast_copy_string((*query)->dsn, tmp, sizeof((*query)->dsn)); 00419 } else if ((tmp = ast_variable_retrieve(cfg, catg, "writehandle")) || (tmp = ast_variable_retrieve(cfg, catg, "readhandle"))) { 00420 ast_log(LOG_WARNING, "Separate read and write handles are not supported in this version of func_odbc.so\n"); 00421 ast_copy_string((*query)->dsn, tmp, sizeof((*query)->dsn)); 00422 } else { 00423 free(*query); 00424 *query = NULL; 00425 ast_log(LOG_ERROR, "No database handle was specified for func_odbc class '%s'\n", catg); 00426 return -1; 00427 } 00428 00429 if ((tmp = ast_variable_retrieve(cfg, catg, "read")) || (tmp = ast_variable_retrieve(cfg, catg, "readsql"))) { 00430 ast_copy_string((*query)->sql_read, tmp, sizeof((*query)->sql_read)); 00431 } 00432 00433 if ((tmp = ast_variable_retrieve(cfg, catg, "write")) || (tmp = ast_variable_retrieve(cfg, catg, "writesql"))) { 00434 ast_copy_string((*query)->sql_write, tmp, sizeof((*query)->sql_write)); 00435 } 00436 00437 /* Allow escaping of embedded commas in fields to be turned off */ 00438 ast_set_flag((*query), OPT_ESCAPECOMMAS); 00439 if ((tmp = ast_variable_retrieve(cfg, catg, "escapecommas"))) { 00440 if (ast_false(tmp)) 00441 ast_clear_flag((*query), OPT_ESCAPECOMMAS); 00442 } 00443 00444 (*query)->acf = ast_calloc(1, sizeof(struct ast_custom_function)); 00445 if (! (*query)->acf) { 00446 free(*query); 00447 *query = NULL; 00448 return -1; 00449 } 00450 00451 if ((tmp = ast_variable_retrieve(cfg, catg, "prefix")) && !ast_strlen_zero(tmp)) { 00452 asprintf((char **)&((*query)->acf->name), "%s_%s", tmp, catg); 00453 } else { 00454 asprintf((char **)&((*query)->acf->name), "ODBC_%s", catg); 00455 } 00456 00457 if (!((*query)->acf->name)) { 00458 free((*query)->acf); 00459 free(*query); 00460 *query = NULL; 00461 return -1; 00462 } 00463 00464 asprintf((char **)&((*query)->acf->syntax), "%s(<arg1>[...[,<argN>]])", (*query)->acf->name); 00465 00466 if (!((*query)->acf->syntax)) { 00467 free((char *)(*query)->acf->name); 00468 free((*query)->acf); 00469 free(*query); 00470 *query = NULL; 00471 return -1; 00472 } 00473 00474 (*query)->acf->synopsis = "Runs the referenced query with the specified arguments"; 00475 if (!ast_strlen_zero((*query)->sql_read) && !ast_strlen_zero((*query)->sql_write)) { 00476 asprintf((char **)&((*query)->acf->desc), 00477 "Runs the following query, as defined in func_odbc.conf, performing\n" 00478 "substitution of the arguments into the query as specified by ${ARG1},\n" 00479 "${ARG2}, ... ${ARGn}. When setting the function, the values are provided\n" 00480 "either in whole as ${VALUE} or parsed as ${VAL1}, ${VAL2}, ... ${VALn}.\n" 00481 "\nRead:\n%s\n\nWrite:\n%s\n", 00482 (*query)->sql_read, 00483 (*query)->sql_write); 00484 } else if (!ast_strlen_zero((*query)->sql_read)) { 00485 asprintf((char **)&((*query)->acf->desc), 00486 "Runs the following query, as defined in func_odbc.conf, performing\n" 00487 "substitution of the arguments into the query as specified by ${ARG1},\n" 00488 "${ARG2}, ... ${ARGn}. This function may only be read, not set.\n\nSQL:\n%s\n", 00489 (*query)->sql_read); 00490 } else if (!ast_strlen_zero((*query)->sql_write)) { 00491 asprintf((char **)&((*query)->acf->desc), 00492 "Runs the following query, as defined in func_odbc.conf, performing\n" 00493 "substitution of the arguments into the query as specified by ${ARG1},\n" 00494 "${ARG2}, ... ${ARGn}. The values are provided either in whole as\n" 00495 "${VALUE} or parsed as ${VAL1}, ${VAL2}, ... ${VALn}.\n" 00496 "This function may only be set.\nSQL:\n%s\n", 00497 (*query)->sql_write); 00498 } else { 00499 ast_log(LOG_ERROR, "No SQL was found for func_odbc class '%s'\n", catg); 00500 } 00501 00502 /* Could be out of memory, or could be we have neither sql_read nor sql_write */ 00503 if (! ((*query)->acf->desc)) { 00504 free((char *)(*query)->acf->syntax); 00505 free((char *)(*query)->acf->name); 00506 free((*query)->acf); 00507 free(*query); 00508 *query = NULL; 00509 return -1; 00510 } 00511 00512 if (ast_strlen_zero((*query)->sql_read)) { 00513 (*query)->acf->read = NULL; 00514 } else { 00515 (*query)->acf->read = acf_odbc_read; 00516 } 00517 00518 if (ast_strlen_zero((*query)->sql_write)) { 00519 (*query)->acf->write = NULL; 00520 } else { 00521 (*query)->acf->write = acf_odbc_write; 00522 } 00523 00524 return 0; 00525 }
| static int load_module | ( | void | ) | [static] |
Definition at line 645 of file func_odbc.c.
References odbc_load_module().
00646 { 00647 return odbc_load_module(); 00648 }
| static int odbc_load_module | ( | void | ) | [static] |
Definition at line 544 of file func_odbc.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_custom_function_register(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_MODULE_LOAD_DECLINE, escape_function, free_acf_query(), init_acf_query(), and LOG_NOTICE.
Referenced by load_module(), and reload().
00545 { 00546 int res = 0; 00547 struct ast_config *cfg; 00548 char *catg; 00549 00550 AST_LIST_LOCK(&queries); 00551 00552 cfg = ast_config_load(config); 00553 if (!cfg) { 00554 ast_log(LOG_NOTICE, "Unable to load config for func_odbc: %s\n", config); 00555 AST_LIST_UNLOCK(&queries); 00556 return AST_MODULE_LOAD_DECLINE; 00557 } 00558 00559 for (catg = ast_category_browse(cfg, NULL); 00560 catg; 00561 catg = ast_category_browse(cfg, catg)) { 00562 struct acf_odbc_query *query = NULL; 00563 00564 if (init_acf_query(cfg, catg, &query)) { 00565 free_acf_query(query); 00566 } else { 00567 AST_LIST_INSERT_HEAD(&queries, query, list); 00568 ast_custom_function_register(query->acf); 00569 } 00570 } 00571 00572 ast_config_destroy(cfg); 00573 ast_custom_function_register(&escape_function); 00574 00575 AST_LIST_UNLOCK(&queries); 00576 return res; 00577 }
| static int odbc_unload_module | ( | void | ) | [static] |
Definition at line 579 of file func_odbc.c.
References ast_custom_function_unregister(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, escape_function, and free_acf_query().
Referenced by reload(), and unload_module().
00580 { 00581 struct acf_odbc_query *query; 00582 00583 AST_LIST_LOCK(&queries); 00584 while (!AST_LIST_EMPTY(&queries)) { 00585 query = AST_LIST_REMOVE_HEAD(&queries, list); 00586 ast_custom_function_unregister(query->acf); 00587 free_acf_query(query); 00588 } 00589 00590 ast_custom_function_unregister(&escape_function); 00591 00592 /* Allow any threads waiting for this lock to pass (avoids a race) */ 00593 AST_LIST_UNLOCK(&queries); 00594 AST_LIST_LOCK(&queries); 00595 00596 AST_LIST_UNLOCK(&queries); 00597 return 0; 00598 }
| static int reload | ( | void | ) | [static] |
Definition at line 600 of file func_odbc.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_custom_function_register(), ast_custom_function_unregister(), AST_LIST_EMPTY, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), free_acf_query(), init_acf_query(), LOG_ERROR, and LOG_WARNING.
00601 { 00602 int res = 0; 00603 struct ast_config *cfg; 00604 struct acf_odbc_query *oldquery; 00605 char *catg; 00606 00607 AST_LIST_LOCK(&queries); 00608 00609 while (!AST_LIST_EMPTY(&queries)) { 00610 oldquery = AST_LIST_REMOVE_HEAD(&queries, list); 00611 ast_custom_function_unregister(oldquery->acf); 00612 free_acf_query(oldquery); 00613 } 00614 00615 cfg = ast_config_load(config); 00616 if (!cfg) { 00617 ast_log(LOG_WARNING, "Unable to load config for func_odbc: %s\n", config); 00618 goto reload_out; 00619 } 00620 00621 for (catg = ast_category_browse(cfg, NULL); 00622 catg; 00623 catg = ast_category_browse(cfg, catg)) { 00624 struct acf_odbc_query *query = NULL; 00625 00626 if (init_acf_query(cfg, catg, &query)) { 00627 ast_log(LOG_ERROR, "Cannot initialize query %s\n", catg); 00628 } else { 00629 AST_LIST_INSERT_HEAD(&queries, query, list); 00630 ast_custom_function_register(query->acf); 00631 } 00632 } 00633 00634 ast_config_destroy(cfg); 00635 reload_out: 00636 AST_LIST_UNLOCK(&queries); 00637 return res; 00638 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 640 of file func_odbc.c.
References odbc_unload_module().
00641 { 00642 return odbc_unload_module(); 00643 }
char* config = "func_odbc.conf" [static] |
Definition at line 54 of file func_odbc.c.
struct ast_custom_function escape_function [static] |
Definition at line 393 of file func_odbc.c.
Referenced by odbc_load_module(), and odbc_unload_module().
| enum { ... } odbc_option_flags |
1.5.1