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