#include "asterisk.h"
#include <sqlite.h>
#include "asterisk/logger.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/cdr.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"
Go to the source code of this file.
Data Structures | |
struct | cfg_entry_args |
struct | rt_cfg_entry_args |
struct | rt_multi_cfg_entry_args |
struct | sqlite_cache_columns |
struct | sqlite_cache_tables |
struct | sqlite_cache_tables::_columns |
struct | sqlite_tables |
Defines | |
#define | MACRO_BEGIN do { |
#define | MACRO_END } while (0) |
#define | release_table(a) AST_RWLIST_UNLOCK(&((a)->columns)) |
#define | RES_CONFIG_SQLITE_BEGIN |
#define | RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf" |
#define | RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2" |
#define | RES_CONFIG_SQLITE_DRIVER "sqlite" |
#define | RES_CONFIG_SQLITE_END(error) |
#define | RES_CONFIG_SQLITE_MAX_LOOPS 10 |
#define | RES_CONFIG_SQLITE_NAME "res_config_sqlite" |
#define | SET_VAR(config, to, from) |
#define | sql_get_config_table |
#define | sql_table_structure "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'" |
Enumerations | |
enum | { RES_CONFIG_SQLITE_CONFIG_ID, RES_CONFIG_SQLITE_CONFIG_CAT_METRIC, RES_CONFIG_SQLITE_CONFIG_VAR_METRIC, RES_CONFIG_SQLITE_CONFIG_COMMENTED, RES_CONFIG_SQLITE_CONFIG_FILENAME, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL, RES_CONFIG_SQLITE_CONFIG_COLUMNS } |
Functions | |
static void | __init_sql_buf (void) |
static void | __init_where_buf (void) |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | add_cfg_entry (void *arg, int argc, char **argv, char **columnNames) |
SQLite callback function for static configuration. | |
static int | add_rt_cfg_entry (void *arg, int argc, char **argv, char **columnNames) |
SQLite callback function for RealTime configuration. | |
static int | add_rt_multi_cfg_entry (void *arg, int argc, char **argv, char **columnNames) |
SQLite callback function for RealTime configuration. | |
static int | cdr_handler (struct ast_cdr *cdr) |
Asterisk callback function for CDR support. | |
static int | check_vars (void) |
static struct ast_config * | config_handler (const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked) |
Asterisk callback function for static configuration. | |
static struct sqlite_cache_tables * | find_table (const char *tablename) |
static int | find_table_cb (void *vtblptr, int argc, char **argv, char **columnNames) |
static void | free_table (struct sqlite_cache_tables *tblptr) |
static size_t | get_params (va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn) |
Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values. | |
static char * | handle_cli_show_sqlite_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Asterisk callback function for the CLI status command. | |
static char * | handle_cli_sqlite_show_tables (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | load_config (void) |
Load the configuration file. | |
static int | load_module (void) |
static int | realtime_destroy_handler (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap) |
Asterisk callback function for RealTime configuration (destroys variable). | |
static struct ast_variable * | realtime_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration. | |
static struct ast_config * | realtime_multi_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration. | |
static int | realtime_require_handler (const char *database, const char *table, va_list ap) |
static int | realtime_store_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration (variable create/store). | |
static int | realtime_unload_handler (const char *unused, const char *tablename) |
static int | realtime_update2_handler (const char *database, const char *table, va_list ap) |
static int | realtime_update_handler (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap) |
Asterisk callback function for RealTime configuration (variable update). | |
static int | set_var (char **var, const char *name, const char *value) |
Allocate a variable. | |
static void | unload_config (void) |
Free resources related to configuration. | |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Realtime SQLite configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | cdr_registered |
static char * | cdr_table |
static struct ast_cli_entry | cli_status [] |
static int | cli_status_registered |
static char * | config_table |
static sqlite * | db |
static char * | dbfile |
static ast_mutex_t | mutex = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static struct ast_threadstorage | sql_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql_buf , .custom_init = NULL , } |
static char * | sql_create_cdr_table |
static struct ast_config_engine | sqlite_engine |
static int | use_cdr |
static struct ast_threadstorage | where_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_where_buf , .custom_init = NULL , } |
Definition in file res_config_sqlite.c.
#define MACRO_BEGIN do { |
Definition at line 94 of file res_config_sqlite.c.
#define MACRO_END } while (0) |
Definition at line 95 of file res_config_sqlite.c.
#define release_table | ( | a | ) | AST_RWLIST_UNLOCK(&((a)->columns)) |
Definition at line 709 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_BEGIN |
Value:
MACRO_BEGIN \ int __i; \ \ for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++) {
Definition at line 153 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), load_module(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), realtime_update2_handler(), and realtime_update_handler().
#define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf" |
#define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2" |
#define RES_CONFIG_SQLITE_DRIVER "sqlite" |
Definition at line 98 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_END | ( | error | ) |
Value:
if (error != SQLITE_BUSY) \ break; \ usleep(1000); \ } \ MACRO_END;
Definition at line 164 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), load_module(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), realtime_update2_handler(), and realtime_update_handler().
#define RES_CONFIG_SQLITE_MAX_LOOPS 10 |
Maximum number of loops before giving up executing a query. Calls to sqlite_xxx() functions which can return SQLITE_BUSY are enclosed by RES_CONFIG_SQLITE_BEGIN and RES_CONFIG_SQLITE_END, e.g.
char *errormsg; int error;
RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error)
if (error) ...;
Definition at line 146 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_NAME "res_config_sqlite" |
Definition at line 97 of file res_config_sqlite.c.
Referenced by load_module(), and unload_module().
#define SET_VAR | ( | config, | |||
to, | |||||
from | ) |
#define sql_get_config_table |
Value:
"SELECT *" \ " FROM '%q'" \ " WHERE filename = '%q' AND commented = 0" \ " ORDER BY cat_metric ASC, var_metric ASC;"
Definition at line 569 of file res_config_sqlite.c.
Referenced by config_handler().
#define sql_table_structure "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'" |
SQL query format to describe the table structure
Definition at line 561 of file res_config_sqlite.c.
anonymous enum |
Definition at line 102 of file res_config_sqlite.c.
00102 { 00103 RES_CONFIG_SQLITE_CONFIG_ID, 00104 RES_CONFIG_SQLITE_CONFIG_CAT_METRIC, 00105 RES_CONFIG_SQLITE_CONFIG_VAR_METRIC, 00106 RES_CONFIG_SQLITE_CONFIG_COMMENTED, 00107 RES_CONFIG_SQLITE_CONFIG_FILENAME, 00108 RES_CONFIG_SQLITE_CONFIG_CATEGORY, 00109 RES_CONFIG_SQLITE_CONFIG_VAR_NAME, 00110 RES_CONFIG_SQLITE_CONFIG_VAR_VAL, 00111 RES_CONFIG_SQLITE_CONFIG_COLUMNS, 00112 };
static void __init_sql_buf | ( | void | ) | [static] |
static void __init_where_buf | ( | void | ) | [static] |
static void __reg_module | ( | void | ) | [static] |
Definition at line 1875 of file res_config_sqlite.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1875 of file res_config_sqlite.c.
static int add_cfg_entry | ( | void * | arg, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
SQLite callback function for static configuration.
This function is passed to the SQLite engine as a callback function to parse a row and store it in a struct ast_config object. It relies on resulting rows being sorted by category.
arg | a pointer to a struct cfg_entry_args object | |
argc | number of columns | |
argv | values in the row | |
columnNames | names and types of the columns |
0 | on success | |
1 | if an error occurred |
Definition at line 856 of file res_config_sqlite.c.
References args, ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_internal_load(), ast_free, ast_log(), ast_strdup, ast_variable_append(), ast_variable_new(), LOG_WARNING, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_COLUMNS, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL, and var.
Referenced by config_handler().
00857 { 00858 struct cfg_entry_args *args; 00859 struct ast_variable *var; 00860 00861 if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) { 00862 ast_log(LOG_WARNING, "Corrupt table\n"); 00863 return 1; 00864 } 00865 00866 args = arg; 00867 00868 if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) { 00869 struct ast_config *cfg; 00870 char *val; 00871 00872 val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL]; 00873 cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked); 00874 00875 if (!cfg) { 00876 ast_log(LOG_WARNING, "Unable to include %s\n", val); 00877 return 1; 00878 } else { 00879 args->cfg = cfg; 00880 return 0; 00881 } 00882 } 00883 00884 if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) { 00885 args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999); 00886 00887 if (!args->cat) { 00888 ast_log(LOG_WARNING, "Unable to allocate category\n"); 00889 return 1; 00890 } 00891 00892 ast_free(args->cat_name); 00893 args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]); 00894 00895 if (!args->cat_name) { 00896 ast_category_destroy(args->cat); 00897 return 1; 00898 } 00899 00900 ast_category_append(args->cfg, args->cat); 00901 } 00902 00903 var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], ""); 00904 00905 if (!var) { 00906 ast_log(LOG_WARNING, "Unable to allocate variable\n"); 00907 return 1; 00908 } 00909 00910 ast_variable_append(args->cat, var); 00911 00912 return 0; 00913 }
static int add_rt_cfg_entry | ( | void * | arg, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
SQLite callback function for RealTime configuration.
This function is passed to the SQLite engine as a callback function to parse a row and store it in a linked list of struct ast_variable objects.
arg | a pointer to a struct rt_cfg_entry_args object | |
argc | number of columns | |
argv | values in the row | |
columnNames | names and types of the columns |
0 | on success. | |
1 | if an error occurred. |
Definition at line 1004 of file res_config_sqlite.c.
References args, ast_variable_new(), and var.
Referenced by realtime_handler().
01005 { 01006 struct rt_cfg_entry_args *args; 01007 struct ast_variable *var; 01008 int i; 01009 01010 args = arg; 01011 01012 for (i = 0; i < argc; i++) { 01013 if (!argv[i]) 01014 continue; 01015 01016 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) 01017 return 1; 01018 01019 if (!args->var) 01020 args->var = var; 01021 01022 if (!args->last) 01023 args->last = var; 01024 else { 01025 args->last->next = var; 01026 args->last = var; 01027 } 01028 } 01029 01030 return 0; 01031 }
static int add_rt_multi_cfg_entry | ( | void * | arg, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
SQLite callback function for RealTime configuration.
This function performs the same actions as add_rt_cfg_entry() except that the rt_multi_cfg_entry_args structure is designed to store categories in addition to variables.
arg | a pointer to a struct rt_multi_cfg_entry_args object | |
argc | number of columns | |
argv | values in the row | |
columnNames | names and types of the columns |
0 | on success. | |
1 | if an error occurred. |
Definition at line 1123 of file res_config_sqlite.c.
References args, ast_category_append(), ast_category_new(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, LOG_WARNING, and var.
Referenced by realtime_multi_handler().
01124 { 01125 struct rt_multi_cfg_entry_args *args; 01126 struct ast_category *cat; 01127 struct ast_variable *var; 01128 char *cat_name; 01129 size_t i; 01130 01131 args = arg; 01132 cat_name = NULL; 01133 01134 /* 01135 * cat_name should always be set here, since initfield is forged from 01136 * params[0] in realtime_multi_handler(), which is a search parameter 01137 * of the SQL query. 01138 */ 01139 for (i = 0; i < argc; i++) { 01140 if (!strcmp(args->initfield, columnNames[i])) 01141 cat_name = argv[i]; 01142 } 01143 01144 if (!cat_name) { 01145 ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n"); 01146 return 1; 01147 } 01148 01149 if (!(cat = ast_category_new(cat_name, "", 99999))) { 01150 ast_log(LOG_WARNING, "Unable to allocate category\n"); 01151 return 1; 01152 } 01153 01154 ast_category_append(args->cfg, cat); 01155 01156 for (i = 0; i < argc; i++) { 01157 if (!argv[i]) { 01158 continue; 01159 } 01160 01161 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) { 01162 ast_log(LOG_WARNING, "Unable to allocate variable\n"); 01163 return 1; 01164 } 01165 01166 ast_variable_append(cat, var); 01167 } 01168 01169 return 0; 01170 }
static int cdr_handler | ( | struct ast_cdr * | cdr | ) | [static] |
Asterisk callback function for CDR support.
cdr | the CDR entry Asterisk sends us. |
0 | on success | |
1 | if an error occurred |
Definition at line 790 of file res_config_sqlite.c.
References ast_cdr_getvar(), ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_RWLIST_TRAVERSE, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), sqlite_cache_tables::columns, find_table(), first, sqlite_cache_columns::isint, LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_columns::name, release_table, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
Referenced by load_module().
00791 { 00792 char *errormsg = NULL, *tmp, workspace[500]; 00793 int error, scannum; 00794 struct sqlite_cache_tables *tbl = find_table(cdr_table); 00795 struct sqlite_cache_columns *col; 00796 struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16); 00797 int first = 1; 00798 00799 if (!tbl) { 00800 ast_log(LOG_WARNING, "No such table: %s\n", cdr_table); 00801 return -1; 00802 } 00803 00804 ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table); 00805 ast_str_set(&sql2, 0, ") VALUES ("); 00806 00807 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) { 00808 if (col->isint) { 00809 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1); 00810 if (!tmp) { 00811 continue; 00812 } 00813 if (sscanf(tmp, "%30d", &scannum) == 1) { 00814 ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name); 00815 ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", scannum); 00816 } 00817 } else { 00818 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0); 00819 if (!tmp) { 00820 continue; 00821 } 00822 ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name); 00823 tmp = sqlite_mprintf("%Q", tmp); 00824 ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", tmp); 00825 sqlite_freemem(tmp); 00826 } 00827 first = 0; 00828 } 00829 release_table(tbl); 00830 00831 ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2)); 00832 ast_free(sql2); 00833 00834 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql1)); 00835 00836 ast_mutex_lock(&mutex); 00837 00838 RES_CONFIG_SQLITE_BEGIN 00839 error = sqlite_exec(db, ast_str_buffer(sql1), NULL, NULL, &errormsg); 00840 RES_CONFIG_SQLITE_END(error) 00841 00842 ast_mutex_unlock(&mutex); 00843 00844 ast_free(sql1); 00845 00846 if (error) { 00847 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 00848 sqlite_freemem(errormsg); 00849 return 1; 00850 } 00851 sqlite_freemem(errormsg); 00852 00853 return 0; 00854 }
static int check_vars | ( | void | ) | [static] |
static struct ast_config * config_handler | ( | const char * | database, | |
const char * | table, | |||
const char * | file, | |||
struct ast_config * | cfg, | |||
struct ast_flags | flags, | |||
const char * | suggested_incl, | |||
const char * | who_asked | |||
) | [static] |
Asterisk callback function for static configuration.
Asterisk will call this function when it loads its static configuration, which usually happens at startup and reload.
database | the database to use (ignored) | |
table | the table to use | |
file | the file to load from the database | |
cfg | the struct ast_config object to use when storing variables | |
flags | Optional flags. Not used. | |
suggested_incl | suggest include. | |
who_asked |
cfg | object | |
NULL | if an error occurred |
Definition at line 915 of file res_config_sqlite.c.
References add_cfg_entry(), args, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, cfg_entry_args::cfg, cfg_entry_args::flags, LOG_ERROR, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and sql_get_config_table.
00917 { 00918 struct cfg_entry_args args; 00919 char *query, *errormsg = NULL; 00920 int error; 00921 00922 if (!config_table) { 00923 if (!table) { 00924 ast_log(LOG_ERROR, "Table name unspecified\n"); 00925 return NULL; 00926 } 00927 } else 00928 table = config_table; 00929 00930 query = sqlite_mprintf(sql_get_config_table, table, file); 00931 00932 if (!query) { 00933 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 00934 return NULL; 00935 } 00936 00937 ast_debug(1, "SQL query: %s\n", query); 00938 args.cfg = cfg; 00939 args.cat = NULL; 00940 args.cat_name = NULL; 00941 args.flags = flags; 00942 args.who_asked = who_asked; 00943 00944 ast_mutex_lock(&mutex); 00945 00946 RES_CONFIG_SQLITE_BEGIN 00947 error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg); 00948 RES_CONFIG_SQLITE_END(error) 00949 00950 ast_mutex_unlock(&mutex); 00951 00952 ast_free(args.cat_name); 00953 sqlite_freemem(query); 00954 00955 if (error) { 00956 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 00957 sqlite_freemem(errormsg); 00958 return NULL; 00959 } 00960 sqlite_freemem(errormsg); 00961 00962 return cfg; 00963 }
static struct sqlite_cache_tables* find_table | ( | const char * | tablename | ) | [static] |
Definition at line 644 of file res_config_sqlite.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, sqlite_cache_tables::list, and sqlite_cache_tables::name.
00645 { 00646 struct sqlite_cache_tables *tblptr; 00647 int i, err; 00648 char *sql, *errstr = NULL; 00649 00650 AST_RWLIST_RDLOCK(&sqlite_tables); 00651 00652 for (i = 0; i < 2; i++) { 00653 AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) { 00654 if (strcmp(tblptr->name, tablename) == 0) { 00655 break; 00656 } 00657 } 00658 if (tblptr) { 00659 AST_RWLIST_RDLOCK(&(tblptr->columns)); 00660 AST_RWLIST_UNLOCK(&sqlite_tables); 00661 return tblptr; 00662 } 00663 00664 if (i == 0) { 00665 AST_RWLIST_UNLOCK(&sqlite_tables); 00666 AST_RWLIST_WRLOCK(&sqlite_tables); 00667 } 00668 } 00669 00670 /* Table structure not cached; build the structure now */ 00671 if (asprintf(&sql, sql_table_structure, tablename) < 0) { 00672 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00673 sql = NULL; 00674 } 00675 if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) { 00676 AST_RWLIST_UNLOCK(&sqlite_tables); 00677 ast_log(LOG_ERROR, "Memory error. Cannot cache table '%s'\n", tablename); 00678 return NULL; 00679 } 00680 tblptr->name = (char *)tblptr + sizeof(*tblptr); 00681 strcpy(tblptr->name, tablename); /* SAFE */ 00682 AST_RWLIST_HEAD_INIT(&(tblptr->columns)); 00683 00684 ast_debug(1, "About to query table structure: %s\n", sql); 00685 00686 ast_mutex_lock(&mutex); 00687 if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) { 00688 ast_mutex_unlock(&mutex); 00689 ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr); 00690 ast_free(errstr); 00691 free_table(tblptr); 00692 AST_RWLIST_UNLOCK(&sqlite_tables); 00693 return NULL; 00694 } 00695 ast_mutex_unlock(&mutex); 00696 00697 if (AST_LIST_EMPTY(&(tblptr->columns))) { 00698 free_table(tblptr); 00699 AST_RWLIST_UNLOCK(&sqlite_tables); 00700 return NULL; 00701 } 00702 00703 AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list); 00704 AST_RWLIST_RDLOCK(&(tblptr->columns)); 00705 AST_RWLIST_UNLOCK(&sqlite_tables); 00706 return tblptr; 00707 }
static int find_table_cb | ( | void * | vtblptr, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
Definition at line 589 of file res_config_sqlite.c.
References AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, AST_RWLIST_TRAVERSE, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, sqlite_cache_tables::columns, sqlite_cache_columns::isint, sqlite_cache_columns::name, strcasestr(), and sqlite_cache_columns::type.
00590 { 00591 struct sqlite_cache_tables *tblptr = vtblptr; 00592 char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder; 00593 int i; 00594 AST_DECLARE_APP_ARGS(fie, 00595 AST_APP_ARG(ld)[100]; /* This means we support up to 100 columns per table */ 00596 ); 00597 struct sqlite_cache_columns *col; 00598 00599 /* This is really fun. We get to parse an SQL statement to figure out 00600 * what columns are in the table. 00601 */ 00602 if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) { 00603 start++; 00604 *end = '\0'; 00605 } else { 00606 /* Abort */ 00607 return -1; 00608 } 00609 00610 AST_STANDARD_APP_ARGS(fie, start); 00611 for (i = 0; i < fie.argc; i++) { 00612 fie.ld[i] = ast_skip_blanks(fie.ld[i]); 00613 ast_debug(5, "Found field: %s\n", fie.ld[i]); 00614 if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) { 00615 *end = '\0'; 00616 AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) { 00617 if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) { 00618 col->isint = 1; 00619 } 00620 } 00621 continue; 00622 } 00623 /* type delimiter could be any space character */ 00624 for (type = fie.ld[i]; *type > 32; type++); 00625 *type++ = '\0'; 00626 type = ast_skip_blanks(type); 00627 for (remainder = type; *remainder > 32; remainder++); 00628 *remainder = '\0'; 00629 if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) { 00630 return -1; 00631 } 00632 col->name = (char *)col + sizeof(*col); 00633 col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1; 00634 strcpy(col->name, fie.ld[i]); /* SAFE */ 00635 strcpy(col->type, type); /* SAFE */ 00636 if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) { 00637 col->isint = 1; 00638 } 00639 AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list); 00640 } 00641 return 0; 00642 }
static void free_table | ( | struct sqlite_cache_tables * | tblptr | ) | [static] |
Definition at line 575 of file res_config_sqlite.c.
References ast_free, AST_RWLIST_HEAD_DESTROY, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and sqlite_cache_tables::columns.
Referenced by realtime_unload_handler(), and unload_config().
00576 { 00577 struct sqlite_cache_columns *col; 00578 00579 /* Obtain a write lock to ensure there are no read locks outstanding */ 00580 AST_RWLIST_WRLOCK(&(tblptr->columns)); 00581 while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) { 00582 ast_free(col); 00583 } 00584 AST_RWLIST_UNLOCK(&(tblptr->columns)); 00585 AST_RWLIST_HEAD_DESTROY(&(tblptr->columns)); 00586 ast_free(tblptr); 00587 }
static size_t get_params | ( | va_list | ap, | |
const char *** | params_ptr, | |||
const char *** | vals_ptr, | |||
int | warn | |||
) | [static] |
Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values.
ap must have the following format : param1 val1 param2 val2 param3 val3 ... arguments will be extracted to create 2 arrays:
The address of these arrays are stored in params_ptr and vals_ptr. It is the responsibility of the caller to release the memory of these arrays. It is considered an error that va_list has a null or odd number of strings.
ap | the va_list object to parse | |
params_ptr | where the address of the params array is stored | |
vals_ptr | where the address of the vals array is stored | |
warn |
the | number of elements in the arrays (which have the same size). | |
0 | if an error occurred. |
Definition at line 965 of file res_config_sqlite.c.
References ast_free, ast_log(), ast_realloc, and LOG_WARNING.
Referenced by auth_http_callback(), auth_manager_http_callback(), auth_mxml_http_callback(), auth_rawman_http_callback(), generic_http_callback(), manager_http_callback(), mxml_http_callback(), rawman_http_callback(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().
00966 { 00967 const char **tmp, *param, *val, **params, **vals; 00968 size_t params_count; 00969 00970 params = NULL; 00971 vals = NULL; 00972 params_count = 0; 00973 00974 while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) { 00975 if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) { 00976 ast_free(params); 00977 ast_free(vals); 00978 return 0; 00979 } 00980 params = tmp; 00981 00982 if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) { 00983 ast_free(params); 00984 ast_free(vals); 00985 return 0; 00986 } 00987 vals = tmp; 00988 00989 params[params_count] = param; 00990 vals[params_count] = val; 00991 params_count++; 00992 } 00993 00994 if (params_count > 0) { 00995 *params_ptr = params; 00996 *vals_ptr = vals; 00997 } else if (warn) { 00998 ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n"); 00999 } 01000 01001 return params_count; 01002 }
static char * handle_cli_show_sqlite_status | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Asterisk callback function for the CLI status command.
e | CLI command | |
cmd | ||
a | CLI argument list |
Definition at line 1669 of file res_config_sqlite.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
01670 { 01671 switch (cmd) { 01672 case CLI_INIT: 01673 e->command = "sqlite show status"; 01674 e->usage = 01675 "Usage: sqlite show status\n" 01676 " Show status information about the SQLite 2 driver\n"; 01677 return NULL; 01678 case CLI_GENERATE: 01679 return NULL; 01680 } 01681 01682 if (a->argc != 3) 01683 return CLI_SHOWUSAGE; 01684 01685 ast_cli(a->fd, "SQLite database path: %s\n", dbfile); 01686 ast_cli(a->fd, "config_table: "); 01687 01688 if (!config_table) 01689 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n"); 01690 else 01691 ast_cli(a->fd, "%s\n", config_table); 01692 01693 ast_cli(a->fd, "cdr_table: "); 01694 01695 if (!cdr_table) 01696 ast_cli(a->fd, "unspecified, CDR support disabled\n"); 01697 else 01698 ast_cli(a->fd, "%s\n", cdr_table); 01699 01700 return CLI_SUCCESS; 01701 }
static char * handle_cli_sqlite_show_tables | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1703 of file res_config_sqlite.c.
References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, sqlite_cache_tables::columns, ast_cli_entry::command, ast_cli_args::fd, sqlite_cache_columns::list, sqlite_cache_columns::name, sqlite_cache_tables::name, sqlite_cache_columns::type, and ast_cli_entry::usage.
01704 { 01705 struct sqlite_cache_tables *tbl; 01706 struct sqlite_cache_columns *col; 01707 int found = 0; 01708 01709 switch (cmd) { 01710 case CLI_INIT: 01711 e->command = "sqlite show tables"; 01712 e->usage = 01713 "Usage: sqlite show tables\n" 01714 " Show table information about the SQLite 2 driver\n"; 01715 return NULL; 01716 case CLI_GENERATE: 01717 return NULL; 01718 } 01719 01720 if (a->argc != 3) 01721 return CLI_SHOWUSAGE; 01722 01723 AST_RWLIST_RDLOCK(&sqlite_tables); 01724 AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) { 01725 found++; 01726 ast_cli(a->fd, "Table %s:\n", tbl->name); 01727 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) { 01728 fprintf(stderr, "%s\n", col->name); 01729 ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type); 01730 } 01731 } 01732 AST_RWLIST_UNLOCK(&sqlite_tables); 01733 01734 if (!found) { 01735 ast_cli(a->fd, "No tables currently in cache\n"); 01736 } 01737 01738 return CLI_SUCCESS; 01739 }
static int load_config | ( | void | ) | [static] |
Load the configuration file.
0 | on success | |
1 | if an error occurred |
Definition at line 738 of file res_config_sqlite.c.
References ast_config_load, ast_log(), ast_variable_browse(), config, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, LOG_ERROR, LOG_WARNING, RES_CONFIG_SQLITE_CONF_FILE, SET_VAR, and var.
00739 { 00740 struct ast_config *config; 00741 struct ast_variable *var; 00742 int error; 00743 struct ast_flags config_flags = { 0 }; 00744 00745 config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags); 00746 00747 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { 00748 ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n"); 00749 return 1; 00750 } 00751 00752 for (var = ast_variable_browse(config, "general"); var; var = var->next) { 00753 if (!strcasecmp(var->name, "dbfile")) 00754 SET_VAR(config, dbfile, var); 00755 else if (!strcasecmp(var->name, "config_table")) 00756 SET_VAR(config, config_table, var); 00757 else if (!strcasecmp(var->name, "cdr_table")) { 00758 SET_VAR(config, cdr_table, var); 00759 } else 00760 ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name); 00761 } 00762 00763 ast_config_destroy(config); 00764 error = check_vars(); 00765 00766 if (error) { 00767 unload_config(); 00768 return 1; 00769 } 00770 00771 return 0; 00772 }
static int load_module | ( | void | ) | [static] |
Definition at line 1759 of file res_config_sqlite.c.
References ARRAY_LEN, ast_cdr_register(), ast_cli_register_multiple(), ast_config_engine_register(), ast_debug, ast_log(), AST_MODULE_LOAD_DECLINE, cdr_handler(), cli_status, load_config(), LOG_ERROR, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_DESCRIPTION, RES_CONFIG_SQLITE_END, RES_CONFIG_SQLITE_NAME, S_OR, sql_create_cdr_table, sqlite_engine, and unload_module.
01760 { 01761 char *errormsg = NULL; 01762 int error; 01763 01764 db = NULL; 01765 cdr_registered = 0; 01766 cli_status_registered = 0; 01767 dbfile = NULL; 01768 config_table = NULL; 01769 cdr_table = NULL; 01770 error = load_config(); 01771 01772 if (error) 01773 return AST_MODULE_LOAD_DECLINE; 01774 01775 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) { 01776 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01777 sqlite_freemem(errormsg); 01778 unload_module(); 01779 return 1; 01780 } 01781 01782 sqlite_freemem(errormsg); 01783 errormsg = NULL; 01784 ast_config_engine_register(&sqlite_engine); 01785 01786 if (use_cdr) { 01787 char *query; 01788 01789 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01790 #undef QUERY 01791 #define QUERY "SELECT COUNT(id) FROM %Q;" 01792 /* \endcond */ 01793 01794 query = sqlite_mprintf(QUERY, cdr_table); 01795 01796 if (!query) { 01797 ast_log(LOG_ERROR, "Unable to allocate SQL query\n"); 01798 unload_module(); 01799 return 1; 01800 } 01801 01802 ast_debug(1, "SQL query: %s\n", query); 01803 01804 RES_CONFIG_SQLITE_BEGIN 01805 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01806 RES_CONFIG_SQLITE_END(error) 01807 01808 sqlite_freemem(query); 01809 01810 if (error) { 01811 /* 01812 * Unexpected error. 01813 */ 01814 if (error != SQLITE_ERROR) { 01815 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01816 sqlite_freemem(errormsg); 01817 unload_module(); 01818 return 1; 01819 } 01820 01821 sqlite_freemem(errormsg); 01822 errormsg = NULL; 01823 query = sqlite_mprintf(sql_create_cdr_table, cdr_table); 01824 01825 if (!query) { 01826 ast_log(LOG_ERROR, "Unable to allocate SQL query\n"); 01827 unload_module(); 01828 return 1; 01829 } 01830 01831 ast_debug(1, "SQL query: %s\n", query); 01832 01833 RES_CONFIG_SQLITE_BEGIN 01834 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01835 RES_CONFIG_SQLITE_END(error) 01836 01837 sqlite_freemem(query); 01838 01839 if (error) { 01840 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01841 sqlite_freemem(errormsg); 01842 unload_module(); 01843 return 1; 01844 } 01845 } 01846 sqlite_freemem(errormsg); 01847 errormsg = NULL; 01848 01849 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler); 01850 01851 if (error) { 01852 unload_module(); 01853 return 1; 01854 } 01855 01856 cdr_registered = 1; 01857 } 01858 01859 error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status)); 01860 01861 if (error) { 01862 unload_module(); 01863 return 1; 01864 } 01865 01866 cli_status_registered = 1; 01867 01868 return 0; 01869 }
static int realtime_destroy_handler | ( | const char * | database, | |
const char * | table, | |||
const char * | keyfield, | |||
const char * | entity, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration (destroys variable).
Asterisk will call this function each time a variable has been destroyed internally and must be removed from the backend engine. keyfield and entity are used to find the row to delete, e.g. DELETE FROM table WHERE keyfield = 'entity';
. ap is a list of parameters and values with the same format as the other realtime functions.
database | the database to use (ignored) | |
table | the table to use | |
keyfield | the column of the matching cell | |
entity | the value of the matching cell | |
ap | list of additional parameters for cell matching |
the | number of affected rows. | |
-1 | if an error occurred. |
Definition at line 1541 of file res_config_sqlite.c.
References ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01543 { 01544 char *query, *errormsg = NULL, *tmp_str; 01545 const char **params = NULL, **vals = NULL; 01546 size_t params_count; 01547 int error, rows_num; 01548 size_t i; 01549 01550 if (!table) { 01551 ast_log(LOG_WARNING, "Table name unspecified\n"); 01552 return -1; 01553 } 01554 01555 params_count = get_params(ap, ¶ms, &vals, 0); 01556 01557 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01558 #undef QUERY 01559 #define QUERY "DELETE FROM '%q' WHERE" 01560 /* \endcond */ 01561 01562 if (!(query = sqlite_mprintf(QUERY, table))) { 01563 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01564 ast_free(params); 01565 ast_free(vals); 01566 return -1; 01567 } 01568 01569 for (i = 0; i < params_count; i++) { 01570 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]); 01571 sqlite_freemem(query); 01572 01573 if (!tmp_str) { 01574 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01575 ast_free(params); 01576 ast_free(vals); 01577 return -1; 01578 } 01579 01580 query = tmp_str; 01581 } 01582 01583 ast_free(params); 01584 ast_free(vals); 01585 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) { 01586 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01587 sqlite_freemem(query); 01588 return -1; 01589 } 01590 sqlite_freemem(query); 01591 query = tmp_str; 01592 ast_debug(1, "SQL query: %s\n", query); 01593 01594 ast_mutex_lock(&mutex); 01595 01596 RES_CONFIG_SQLITE_BEGIN 01597 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01598 RES_CONFIG_SQLITE_END(error) 01599 01600 if (!error) { 01601 rows_num = sqlite_changes(db); 01602 } else { 01603 rows_num = -1; 01604 } 01605 01606 ast_mutex_unlock(&mutex); 01607 01608 sqlite_freemem(query); 01609 01610 if (error) { 01611 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01612 } 01613 sqlite_freemem(errormsg); 01614 01615 return rows_num; 01616 }
static struct ast_variable * realtime_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration.
Asterisk will call this function each time it requires a variable through the RealTime architecture. ap is a list of parameters and values used to find a specific row, e.g one parameter "name" and one value "123" so that the SQL query becomes SELECT * FROM table WHERE name = '123';
.
database | the database to use (ignored) | |
table | the table to use | |
ap | list of parameters and values to match |
a | linked list of struct ast_variable objects | |
NULL | if an error occurred |
Definition at line 1033 of file res_config_sqlite.c.
References add_rt_cfg_entry(), args, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_variables_destroy(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01034 { 01035 char *query, *errormsg = NULL, *op, *tmp_str; 01036 struct rt_cfg_entry_args args; 01037 const char **params, **vals; 01038 size_t params_count; 01039 int error; 01040 01041 if (!table) { 01042 ast_log(LOG_WARNING, "Table name unspecified\n"); 01043 return NULL; 01044 } 01045 01046 params_count = get_params(ap, ¶ms, &vals, 1); 01047 01048 if (params_count == 0) 01049 return NULL; 01050 01051 op = (strchr(params[0], ' ') == NULL) ? " =" : ""; 01052 01053 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01054 #undef QUERY 01055 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'" 01056 /* \endcond */ 01057 01058 query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", params[0], op, vals[0]); 01059 01060 if (!query) { 01061 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01062 ast_free(params); 01063 ast_free(vals); 01064 return NULL; 01065 } 01066 01067 if (params_count > 1) { 01068 size_t i; 01069 01070 for (i = 1; i < params_count; i++) { 01071 op = (strchr(params[i], ' ') == NULL) ? " =" : ""; 01072 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]); 01073 sqlite_freemem(query); 01074 01075 if (!tmp_str) { 01076 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01077 ast_free(params); 01078 ast_free(vals); 01079 return NULL; 01080 } 01081 01082 query = tmp_str; 01083 } 01084 } 01085 01086 ast_free(params); 01087 ast_free(vals); 01088 01089 tmp_str = sqlite_mprintf("%s LIMIT 1;", query); 01090 sqlite_freemem(query); 01091 01092 if (!tmp_str) { 01093 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01094 return NULL; 01095 } 01096 01097 query = tmp_str; 01098 ast_debug(1, "SQL query: %s\n", query); 01099 args.var = NULL; 01100 args.last = NULL; 01101 01102 ast_mutex_lock(&mutex); 01103 01104 RES_CONFIG_SQLITE_BEGIN 01105 error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg); 01106 RES_CONFIG_SQLITE_END(error) 01107 01108 ast_mutex_unlock(&mutex); 01109 01110 sqlite_freemem(query); 01111 01112 if (error) { 01113 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01114 sqlite_freemem(errormsg); 01115 ast_variables_destroy(args.var); 01116 return NULL; 01117 } 01118 sqlite_freemem(errormsg); 01119 01120 return args.var; 01121 }
static struct ast_config * realtime_multi_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration.
This function performs the same actions as realtime_handler() except that it can store variables per category, and can return several categories.
database | the database to use (ignored) | |
table | the table to use | |
ap | list of parameters and values to match |
a | struct ast_config object storing categories and variables. | |
NULL | if an error occurred. |
Definition at line 1172 of file res_config_sqlite.c.
References add_rt_multi_cfg_entry(), args, ast_config_destroy(), ast_config_new(), ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strdup, get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01174 { 01175 char *query, *errormsg = NULL, *op, *tmp_str, *initfield; 01176 struct rt_multi_cfg_entry_args args; 01177 const char **params, **vals; 01178 struct ast_config *cfg; 01179 size_t params_count; 01180 int error; 01181 01182 if (!table) { 01183 ast_log(LOG_WARNING, "Table name unspecified\n"); 01184 return NULL; 01185 } 01186 01187 if (!(cfg = ast_config_new())) { 01188 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n"); 01189 return NULL; 01190 } 01191 01192 if (!(params_count = get_params(ap, ¶ms, &vals, 1))) { 01193 ast_config_destroy(cfg); 01194 return NULL; 01195 } 01196 01197 if (!(initfield = ast_strdup(params[0]))) { 01198 ast_config_destroy(cfg); 01199 ast_free(params); 01200 ast_free(vals); 01201 return NULL; 01202 } 01203 01204 tmp_str = strchr(initfield, ' '); 01205 01206 if (tmp_str) 01207 *tmp_str = '\0'; 01208 01209 op = (!strchr(params[0], ' ')) ? " =" : ""; 01210 01211 /* 01212 * Asterisk sends us an already escaped string when searching for 01213 * "exten LIKE" (uh!). Handle it separately. 01214 */ 01215 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0]; 01216 01217 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01218 #undef QUERY 01219 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'" 01220 /* \endcond */ 01221 01222 if (!(query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", params[0], op, tmp_str))) { 01223 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01224 ast_config_destroy(cfg); 01225 ast_free(params); 01226 ast_free(vals); 01227 ast_free(initfield); 01228 return NULL; 01229 } 01230 01231 if (params_count > 1) { 01232 size_t i; 01233 01234 for (i = 1; i < params_count; i++) { 01235 op = (!strchr(params[i], ' ')) ? " =" : ""; 01236 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]); 01237 sqlite_freemem(query); 01238 01239 if (!tmp_str) { 01240 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01241 ast_config_destroy(cfg); 01242 ast_free(params); 01243 ast_free(vals); 01244 ast_free(initfield); 01245 return NULL; 01246 } 01247 01248 query = tmp_str; 01249 } 01250 } 01251 01252 ast_free(params); 01253 ast_free(vals); 01254 01255 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) { 01256 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01257 sqlite_freemem(query); 01258 ast_config_destroy(cfg); 01259 ast_free(initfield); 01260 return NULL; 01261 } 01262 01263 sqlite_freemem(query); 01264 query = tmp_str; 01265 ast_debug(1, "SQL query: %s\n", query); 01266 args.cfg = cfg; 01267 args.initfield = initfield; 01268 01269 ast_mutex_lock(&mutex); 01270 01271 RES_CONFIG_SQLITE_BEGIN 01272 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg); 01273 RES_CONFIG_SQLITE_END(error) 01274 01275 ast_mutex_unlock(&mutex); 01276 01277 sqlite_freemem(query); 01278 ast_free(initfield); 01279 01280 if (error) { 01281 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01282 sqlite_freemem(errormsg); 01283 ast_config_destroy(cfg); 01284 return NULL; 01285 } 01286 sqlite_freemem(errormsg); 01287 01288 return cfg; 01289 }
static int realtime_require_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Definition at line 1618 of file res_config_sqlite.c.
References ast_log(), ast_rq_is_int(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, sqlite_cache_tables::columns, find_table(), sqlite_cache_columns::isint, sqlite_cache_columns::list, LOG_WARNING, sqlite_cache_columns::name, and type.
01619 { 01620 struct sqlite_cache_tables *tbl = find_table(tablename); 01621 struct sqlite_cache_columns *col; 01622 char *elm; 01623 int type, res = 0; 01624 01625 if (!tbl) { 01626 return -1; 01627 } 01628 01629 while ((elm = va_arg(ap, char *))) { 01630 type = va_arg(ap, require_type); 01631 va_arg(ap, int); 01632 /* Check if the field matches the criteria */ 01633 AST_RWLIST_TRAVERSE(&tbl->columns, col, list) { 01634 if (strcmp(col->name, elm) == 0) { 01635 /* SQLite only has two types - the 32-bit integer field that 01636 * is the key column, and everything else (everything else 01637 * being a string). 01638 */ 01639 if (col->isint && !ast_rq_is_int(type)) { 01640 ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name); 01641 res = -1; 01642 } 01643 break; 01644 } 01645 } 01646 if (!col) { 01647 ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm); 01648 } 01649 } 01650 AST_RWLIST_UNLOCK(&(tbl->columns)); 01651 return res; 01652 }
static int realtime_store_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration (variable create/store).
Asterisk will call this function each time a variable has been created internally and must be stored in the backend engine. are used to find the row to update, e.g. ap is a list of parameters and values with the same format as the other realtime functions.
database | the database to use (ignored) | |
table | the table to use | |
ap | list of parameters and new values to insert into the database |
the | rowid of inserted row. | |
-1 | if an error occurred. |
Definition at line 1447 of file res_config_sqlite.c.
References ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01448 { 01449 char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL; 01450 const char **params, **vals; 01451 size_t params_count; 01452 int error, rows_id; 01453 size_t i; 01454 01455 if (!table) { 01456 ast_log(LOG_WARNING, "Table name unspecified\n"); 01457 return -1; 01458 } 01459 01460 if (!(params_count = get_params(ap, ¶ms, &vals, 1))) 01461 return -1; 01462 01463 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01464 #undef QUERY 01465 #define QUERY "INSERT into '%q' (%s) VALUES (%s);" 01466 /* \endcond */ 01467 01468 for (i = 0; i < params_count; i++) { 01469 if ( tmp_keys2 ) { 01470 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]); 01471 sqlite_freemem(tmp_keys2); 01472 } else { 01473 tmp_keys = sqlite_mprintf("%q", params[i]); 01474 } 01475 if (!tmp_keys) { 01476 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01477 sqlite_freemem(tmp_vals); 01478 ast_free(params); 01479 ast_free(vals); 01480 return -1; 01481 } 01482 01483 if ( tmp_vals2 ) { 01484 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, vals[i]); 01485 sqlite_freemem(tmp_vals2); 01486 } else { 01487 tmp_vals = sqlite_mprintf("'%q'", vals[i]); 01488 } 01489 if (!tmp_vals) { 01490 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01491 sqlite_freemem(tmp_keys); 01492 ast_free(params); 01493 ast_free(vals); 01494 return -1; 01495 } 01496 01497 01498 tmp_keys2 = tmp_keys; 01499 tmp_vals2 = tmp_vals; 01500 } 01501 01502 ast_free(params); 01503 ast_free(vals); 01504 01505 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) { 01506 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01507 sqlite_freemem(tmp_keys); 01508 sqlite_freemem(tmp_vals); 01509 return -1; 01510 } 01511 01512 sqlite_freemem(tmp_keys); 01513 sqlite_freemem(tmp_vals); 01514 01515 ast_debug(1, "SQL query: %s\n", tmp_str); 01516 01517 ast_mutex_lock(&mutex); 01518 01519 RES_CONFIG_SQLITE_BEGIN 01520 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg); 01521 RES_CONFIG_SQLITE_END(error) 01522 01523 if (!error) { 01524 rows_id = sqlite_last_insert_rowid(db); 01525 } else { 01526 rows_id = -1; 01527 } 01528 01529 ast_mutex_unlock(&mutex); 01530 01531 sqlite_freemem(tmp_str); 01532 01533 if (error) { 01534 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01535 } 01536 sqlite_freemem(errormsg); 01537 01538 return rows_id; 01539 }
static int realtime_unload_handler | ( | const char * | unused, | |
const char * | tablename | |||
) | [static] |
Definition at line 1654 of file res_config_sqlite.c.
References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), sqlite_cache_tables::list, and sqlite_cache_tables::name.
01655 { 01656 struct sqlite_cache_tables *tbl; 01657 AST_RWLIST_WRLOCK(&sqlite_tables); 01658 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) { 01659 if (!strcasecmp(tbl->name, tablename)) { 01660 AST_RWLIST_REMOVE_CURRENT(list); 01661 free_table(tbl); 01662 } 01663 } 01664 AST_RWLIST_TRAVERSE_SAFE_END 01665 AST_RWLIST_UNLOCK(&sqlite_tables); 01666 return 0; 01667 }
static int realtime_update2_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Definition at line 1373 of file res_config_sqlite.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), first, LOG_ERROR, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, sql_buf, value, and where_buf.
01375 { 01376 char *errormsg = NULL, *tmp1, *tmp2; 01377 int error, rows_num, first = 1; 01378 struct ast_str *sql = ast_str_thread_get(&sql_buf, 100); 01379 struct ast_str *where = ast_str_thread_get(&where_buf, 100); 01380 const char *param, *value; 01381 01382 if (!table) { 01383 ast_log(LOG_WARNING, "Table name unspecified\n"); 01384 return -1; 01385 } 01386 01387 if (!sql) { 01388 return -1; 01389 } 01390 01391 ast_str_set(&sql, 0, "UPDATE %s SET", table); 01392 ast_str_set(&where, 0, " WHERE"); 01393 01394 while ((param = va_arg(ap, const char *))) { 01395 value = va_arg(ap, const char *); 01396 ast_str_append(&where, 0, "%s %s = %s", 01397 first ? "" : " AND", 01398 tmp1 = sqlite_mprintf("%q", param), 01399 tmp2 = sqlite_mprintf("%Q", value)); 01400 sqlite_freemem(tmp1); 01401 sqlite_freemem(tmp2); 01402 first = 0; 01403 } 01404 01405 if (first) { 01406 ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database); 01407 return -1; 01408 } 01409 01410 first = 1; 01411 while ((param = va_arg(ap, const char *))) { 01412 value = va_arg(ap, const char *); 01413 ast_str_append(&sql, 0, "%s %s = %s", 01414 first ? "" : ",", 01415 tmp1 = sqlite_mprintf("%q", param), 01416 tmp2 = sqlite_mprintf("%Q", value)); 01417 sqlite_freemem(tmp1); 01418 sqlite_freemem(tmp2); 01419 first = 0; 01420 } 01421 01422 ast_str_append(&sql, 0, " %s", ast_str_buffer(where)); 01423 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql)); 01424 01425 ast_mutex_lock(&mutex); 01426 01427 RES_CONFIG_SQLITE_BEGIN 01428 error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg); 01429 RES_CONFIG_SQLITE_END(error) 01430 01431 if (!error) { 01432 rows_num = sqlite_changes(db); 01433 } else { 01434 rows_num = -1; 01435 } 01436 01437 ast_mutex_unlock(&mutex); 01438 01439 if (error) { 01440 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01441 } 01442 sqlite_freemem(errormsg); 01443 01444 return rows_num; 01445 }
static int realtime_update_handler | ( | const char * | database, | |
const char * | table, | |||
const char * | keyfield, | |||
const char * | entity, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration (variable update).
Asterisk will call this function each time a variable has been modified internally and must be updated in the backend engine. keyfield and entity are used to find the row to update, e.g. UPDATE table SET ... WHERE keyfield = 'entity';
. ap is a list of parameters and values with the same format as the other realtime functions.
database | the database to use (ignored) | |
table | the table to use | |
keyfield | the column of the matching cell | |
entity | the value of the matching cell | |
ap | list of parameters and new values to update in the database |
the | number of affected rows. | |
-1 | if an error occurred. |
Definition at line 1291 of file res_config_sqlite.c.
References ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01293 { 01294 char *query, *errormsg = NULL, *tmp_str; 01295 const char **params, **vals; 01296 size_t params_count; 01297 int error, rows_num; 01298 01299 if (!table) { 01300 ast_log(LOG_WARNING, "Table name unspecified\n"); 01301 return -1; 01302 } 01303 01304 if (!(params_count = get_params(ap, ¶ms, &vals, 1))) 01305 return -1; 01306 01307 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01308 #undef QUERY 01309 #define QUERY "UPDATE '%q' SET %q = '%q'" 01310 /* \endcond */ 01311 01312 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) { 01313 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01314 ast_free(params); 01315 ast_free(vals); 01316 return -1; 01317 } 01318 01319 if (params_count > 1) { 01320 size_t i; 01321 01322 for (i = 1; i < params_count; i++) { 01323 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]); 01324 sqlite_freemem(query); 01325 01326 if (!tmp_str) { 01327 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01328 ast_free(params); 01329 ast_free(vals); 01330 return -1; 01331 } 01332 01333 query = tmp_str; 01334 } 01335 } 01336 01337 ast_free(params); 01338 ast_free(vals); 01339 01340 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) { 01341 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01342 sqlite_freemem(query); 01343 return -1; 01344 } 01345 01346 sqlite_freemem(query); 01347 query = tmp_str; 01348 ast_debug(1, "SQL query: %s\n", query); 01349 01350 ast_mutex_lock(&mutex); 01351 01352 RES_CONFIG_SQLITE_BEGIN 01353 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01354 RES_CONFIG_SQLITE_END(error) 01355 01356 if (!error) 01357 rows_num = sqlite_changes(db); 01358 else 01359 rows_num = -1; 01360 01361 ast_mutex_unlock(&mutex); 01362 01363 sqlite_freemem(query); 01364 01365 if (error) { 01366 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01367 } 01368 sqlite_freemem(errormsg); 01369 01370 return rows_num; 01371 }
static int set_var | ( | char ** | var, | |
const char * | name, | |||
const char * | value | |||
) | [static] |
Allocate a variable.
var | the address of the variable to set (it will be allocated) | |
name | the name of the variable (for error handling) | |
value | the value to store in var |
0 | on success | |
1 | if an allocation error occurred |
Definition at line 711 of file res_config_sqlite.c.
References ast_free, ast_log(), ast_strdup, and LOG_WARNING.
00712 { 00713 if (*var) 00714 ast_free(*var); 00715 00716 *var = ast_strdup(value); 00717 00718 if (!*var) { 00719 ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name); 00720 return 1; 00721 } 00722 00723 return 0; 00724 }
static void unload_config | ( | void | ) | [static] |
Free resources related to configuration.
Definition at line 774 of file res_config_sqlite.c.
References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), and sqlite_cache_tables::list.
Referenced by unload_module().
00775 { 00776 struct sqlite_cache_tables *tbl; 00777 ast_free(dbfile); 00778 dbfile = NULL; 00779 ast_free(config_table); 00780 config_table = NULL; 00781 ast_free(cdr_table); 00782 cdr_table = NULL; 00783 AST_RWLIST_WRLOCK(&sqlite_tables); 00784 while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) { 00785 free_table(tbl); 00786 } 00787 AST_RWLIST_UNLOCK(&sqlite_tables); 00788 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1741 of file res_config_sqlite.c.
References ARRAY_LEN, ast_cdr_unregister(), ast_cli_unregister_multiple(), ast_config_engine_deregister(), cli_status, RES_CONFIG_SQLITE_NAME, sqlite_engine, and unload_config().
01742 { 01743 if (cli_status_registered) 01744 ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status)); 01745 01746 if (cdr_registered) 01747 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME); 01748 01749 ast_config_engine_deregister(&sqlite_engine); 01750 01751 if (db) 01752 sqlite_close(db); 01753 01754 unload_config(); 01755 01756 return 0; 01757 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Realtime SQLite configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static] |
Definition at line 1875 of file res_config_sqlite.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1875 of file res_config_sqlite.c.
int cdr_registered [static] |
Set to 1 if the CDR callback function was registered.
Definition at line 468 of file res_config_sqlite.c.
char* cdr_table [static] |
The name of the table used to store CDR entries.
Definition at line 480 of file res_config_sqlite.c.
struct ast_cli_entry cli_status[] [static] |
Initial value:
{ { .handler = handle_cli_show_sqlite_status , .summary = "Show status information about the SQLite 2 driver" ,__VA_ARGS__ }, { .handler = handle_cli_sqlite_show_tables , .summary = "Cached table information about the SQLite 2 driver" ,__VA_ARGS__ }, }
Definition at line 509 of file res_config_sqlite.c.
int cli_status_registered [static] |
Set to 1 if the CLI status command callback function was registered.
Definition at line 471 of file res_config_sqlite.c.
char* config_table [static] |
The name of the static configuration table.
Definition at line 477 of file res_config_sqlite.c.
sqlite* db [static] |
The SQLite database object.
Definition at line 462 of file res_config_sqlite.c.
char* dbfile [static] |
The path of the database file.
Definition at line 474 of file res_config_sqlite.c.
ast_mutex_t mutex = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
The mutex used to prevent simultaneous access to the SQLite database.
Definition at line 503 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), realtime_update2_handler(), and realtime_update_handler().
struct ast_threadstorage sql_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql_buf , .custom_init = NULL , } [static] |
Definition at line 127 of file res_config_sqlite.c.
char* sql_create_cdr_table [static] |
SQL query format to create the CDR table if non existent.
Definition at line 534 of file res_config_sqlite.c.
Referenced by load_module().
struct ast_config_engine sqlite_engine [static] |
The structure specifying all callback functions used by Asterisk for static and RealTime configuration.
Definition at line 486 of file res_config_sqlite.c.
Referenced by load_module(), and unload_module().
int use_cdr [static] |
Set to 1 if CDR support is enabled.
Definition at line 465 of file res_config_sqlite.c.
struct ast_threadstorage where_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_where_buf , .custom_init = NULL , } [static] |
Definition at line 128 of file res_config_sqlite.c.