Custom SQLite3 CDR records. More...
#include "asterisk.h"#include <time.h>#include <sqlite3.h>#include "asterisk/paths.h"#include "asterisk/channel.h"#include "asterisk/cdr.h"#include "asterisk/module.h"#include "asterisk/config.h"#include "asterisk/pbx.h"#include "asterisk/utils.h"#include "asterisk/cli.h"
Go to the source code of this file.
Data Structures | |
| struct | sql_values |
| struct | values |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static void | free_config (int reload) |
| static int | load_column_config (const char *tmp) |
| static int | load_config (int reload) |
| static int | load_module (void) |
| static int | load_values_config (const char *tmp) |
| static int | reload (void) |
| static int | sqlite3_log (struct ast_cdr *cdr) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "SQLite3 Custom CDR Module" , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static char * | columns |
| static const char | config_file [] = "cdr_sqlite3_custom.conf" |
| static sqlite3 * | db = NULL |
| static char * | desc = "Customizable SQLite3 CDR Backend" |
| static ast_mutex_t | lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| static char * | name = "cdr_sqlite3_custom" |
| static char | table [80] |
Custom SQLite3 CDR records.
Definition in file cdr_sqlite3_custom.c.
| static void __reg_module | ( | void | ) | [static] |
Definition at line 349 of file cdr_sqlite3_custom.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 349 of file cdr_sqlite3_custom.c.
| static void free_config | ( | int | reload | ) | [static] |
Definition at line 204 of file cdr_sqlite3_custom.c.
References ast_free, AST_LIST_REMOVE_HEAD, and values::list.
Referenced by load_config(), load_module(), and unload_module().
00205 { 00206 struct values *value; 00207 00208 if (!reload && db) { 00209 sqlite3_close(db); 00210 db = NULL; 00211 } 00212 00213 if (columns) { 00214 ast_free(columns); 00215 columns = NULL; 00216 } 00217 00218 while ((value = AST_LIST_REMOVE_HEAD(&sql_values, list))) { 00219 ast_free(value); 00220 } 00221 }
| static int load_column_config | ( | const char * | tmp | ) | [static] |
Definition at line 75 of file cdr_sqlite3_custom.c.
References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), ast_strdup, ast_strip(), ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.
Referenced by load_config().
00076 { 00077 char *col = NULL; 00078 char *cols = NULL, *save = NULL; 00079 char *escaped = NULL; 00080 struct ast_str *column_string = NULL; 00081 00082 if (ast_strlen_zero(tmp)) { 00083 ast_log(LOG_WARNING, "Column names not specified. Module not loaded.\n"); 00084 return -1; 00085 } 00086 if (!(column_string = ast_str_create(1024))) { 00087 ast_log(LOG_ERROR, "Out of memory creating temporary buffer for column list for table '%s.'\n", table); 00088 return -1; 00089 } 00090 if (!(save = cols = ast_strdup(tmp))) { 00091 ast_log(LOG_ERROR, "Out of memory creating temporary buffer for column list for table '%s.'\n", table); 00092 ast_free(column_string); 00093 return -1; 00094 } 00095 while ((col = strsep(&cols, ","))) { 00096 col = ast_strip(col); 00097 escaped = sqlite3_mprintf("%q", col); 00098 if (!escaped) { 00099 ast_log(LOG_ERROR, "Out of memory creating entry for column '%s' in table '%s.'\n", col, table); 00100 ast_free(column_string); 00101 ast_free(save); 00102 return -1; 00103 } 00104 ast_str_append(&column_string, 0, "%s%s", ast_str_strlen(column_string) ? "," : "", escaped); 00105 sqlite3_free(escaped); 00106 } 00107 if (!(columns = ast_strdup(ast_str_buffer(column_string)))) { 00108 ast_log(LOG_ERROR, "Out of memory copying columns string for table '%s.'\n", table); 00109 ast_free(column_string); 00110 ast_free(save); 00111 return -1; 00112 } 00113 ast_free(column_string); 00114 ast_free(save); 00115 00116 return 0; 00117 }
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 151 of file cdr_sqlite3_custom.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, free_config(), load_column_config(), load_values_config(), and LOG_WARNING.
Referenced by load_module(), and reload().
00152 { 00153 struct ast_config *cfg; 00154 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 00155 struct ast_variable *mappingvar; 00156 const char *tmp; 00157 00158 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 00159 ast_log(LOG_WARNING, "Failed to %sload configuration file. %s\n", reload ? "re" : "", reload ? "" : "Module not activated."); 00160 return -1; 00161 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 00162 return 0; 00163 } 00164 00165 if (reload) { 00166 free_config(1); 00167 } 00168 00169 if (!(mappingvar = ast_variable_browse(cfg, "master"))) { 00170 /* Nothing configured */ 00171 ast_config_destroy(cfg); 00172 return -1; 00173 } 00174 00175 /* Mapping must have a table name */ 00176 if (!ast_strlen_zero(tmp = ast_variable_retrieve(cfg, "master", "table"))) { 00177 ast_copy_string(table, tmp, sizeof(table)); 00178 } else { 00179 ast_log(LOG_WARNING, "Table name not specified. Assuming cdr.\n"); 00180 strcpy(table, "cdr"); 00181 } 00182 00183 /* Columns */ 00184 if (load_column_config(ast_variable_retrieve(cfg, "master", "columns"))) { 00185 ast_config_destroy(cfg); 00186 free_config(0); 00187 return -1; 00188 } 00189 00190 /* Values */ 00191 if (load_values_config(ast_variable_retrieve(cfg, "master", "values"))) { 00192 ast_config_destroy(cfg); 00193 free_config(0); 00194 return -1; 00195 } 00196 00197 ast_verb(3, "cdr_sqlite3_custom: Logging CDR records to table '%s' in 'master.db'\n", table); 00198 00199 ast_config_destroy(cfg); 00200 00201 return 0; 00202 }
| static int load_module | ( | void | ) | [static] |
Definition at line 287 of file cdr_sqlite3_custom.c.
References ast_cdr_register(), ast_config_AST_LOG_DIR, ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, free_config(), load_config(), LOG_ERROR, LOG_WARNING, and sqlite3_log().
00288 { 00289 char *error; 00290 char filename[PATH_MAX]; 00291 int res; 00292 char *sql; 00293 00294 if (load_config(0)) { 00295 return AST_MODULE_LOAD_DECLINE; 00296 } 00297 00298 /* is the database there? */ 00299 snprintf(filename, sizeof(filename), "%s/master.db", ast_config_AST_LOG_DIR); 00300 res = sqlite3_open(filename, &db); 00301 if (res != SQLITE_OK) { 00302 ast_log(LOG_ERROR, "Could not open database %s.\n", filename); 00303 free_config(0); 00304 return AST_MODULE_LOAD_DECLINE; 00305 } 00306 00307 /* is the table there? */ 00308 sql = sqlite3_mprintf("SELECT COUNT(AcctId) FROM %q;", table); 00309 res = sqlite3_exec(db, sql, NULL, NULL, NULL); 00310 sqlite3_free(sql); 00311 if (res != SQLITE_OK) { 00312 /* We don't use %q for the column list here since we already escaped when building it */ 00313 sql = sqlite3_mprintf("CREATE TABLE %q (AcctId INTEGER PRIMARY KEY, %s)", table, columns); 00314 res = sqlite3_exec(db, sql, NULL, NULL, &error); 00315 sqlite3_free(sql); 00316 if (res != SQLITE_OK) { 00317 ast_log(LOG_WARNING, "Unable to create table '%s': %s.\n", table, error); 00318 sqlite3_free(error); 00319 free_config(0); 00320 return AST_MODULE_LOAD_DECLINE; 00321 } 00322 } 00323 00324 res = ast_cdr_register(name, desc, sqlite3_log); 00325 if (res) { 00326 ast_log(LOG_ERROR, "Unable to register custom SQLite3 CDR handling\n"); 00327 free_config(0); 00328 return AST_MODULE_LOAD_DECLINE; 00329 } 00330 00331 return AST_MODULE_LOAD_SUCCESS; 00332 }
| static int load_values_config | ( | const char * | tmp | ) | [static] |
Definition at line 119 of file cdr_sqlite3_custom.c.
References ast_calloc, ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), values::expression, values::list, LOG_ERROR, and LOG_WARNING.
Referenced by load_config().
00120 { 00121 char *val = NULL; 00122 char *vals = NULL, *save = NULL; 00123 struct values *value = NULL; 00124 00125 if (ast_strlen_zero(tmp)) { 00126 ast_log(LOG_WARNING, "Values not specified. Module not loaded.\n"); 00127 return -1; 00128 } 00129 if (!(save = vals = ast_strdup(tmp))) { 00130 ast_log(LOG_ERROR, "Out of memory creating temporary buffer for value '%s'\n", tmp); 00131 return -1; 00132 } 00133 while ((val = strsep(&vals, ","))) { 00134 /* Strip the single quotes off if they are there */ 00135 val = ast_strip_quoted(val, "'", "'"); 00136 value = ast_calloc(sizeof(char), sizeof(*value) + strlen(val) + 1); 00137 if (!value) { 00138 ast_log(LOG_ERROR, "Out of memory creating entry for value '%s'\n", val); 00139 ast_free(save); 00140 return -1; 00141 } 00142 value->expression = (char *) value + sizeof(*value); 00143 ast_copy_string(value->expression, val, strlen(val) + 1); 00144 AST_LIST_INSERT_TAIL(&sql_values, value, list); 00145 } 00146 ast_free(save); 00147 00148 return 0; 00149 }
| static int reload | ( | void | ) | [static] |
Definition at line 334 of file cdr_sqlite3_custom.c.
References ast_mutex_lock(), ast_mutex_unlock(), load_config(), and lock.
00335 { 00336 int res = 0; 00337 00338 ast_mutex_lock(&lock); 00339 res = load_config(1); 00340 ast_mutex_unlock(&lock); 00341 00342 return res; 00343 }
| static int sqlite3_log | ( | struct ast_cdr * | cdr | ) | [static] |
Definition at line 223 of file cdr_sqlite3_custom.c.
References ast_debug, ast_free, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), ast_channel::cdr, values::expression, values::list, lock, LOG_ERROR, and pbx_substitute_variables_helper().
Referenced by load_module().
00224 { 00225 int res = 0; 00226 char *error = NULL; 00227 char *sql = NULL; 00228 struct ast_channel dummy = { 0, }; 00229 int count = 0; 00230 00231 if (db == NULL) { 00232 /* Should not have loaded, but be failsafe. */ 00233 return 0; 00234 } 00235 00236 ast_mutex_lock(&lock); 00237 00238 { /* Make it obvious that only sql should be used outside of this block */ 00239 char *escaped; 00240 char subst_buf[2048]; 00241 struct values *value; 00242 struct ast_str *value_string = ast_str_create(1024); 00243 dummy.cdr = cdr; 00244 AST_LIST_TRAVERSE(&sql_values, value, list) { 00245 pbx_substitute_variables_helper(&dummy, value->expression, subst_buf, sizeof(subst_buf) - 1); 00246 escaped = sqlite3_mprintf("%q", subst_buf); 00247 ast_str_append(&value_string, 0, "%s'%s'", ast_str_strlen(value_string) ? "," : "", escaped); 00248 sqlite3_free(escaped); 00249 } 00250 sql = sqlite3_mprintf("INSERT INTO %q (%s) VALUES (%s)", table, columns, ast_str_buffer(value_string)); 00251 ast_debug(1, "About to log: %s\n", sql); 00252 ast_free(value_string); 00253 } 00254 00255 /* XXX This seems awful arbitrary... */ 00256 for (count = 0; count < 5; count++) { 00257 res = sqlite3_exec(db, sql, NULL, NULL, &error); 00258 if (res != SQLITE_BUSY && res != SQLITE_LOCKED) { 00259 break; 00260 } 00261 usleep(200); 00262 } 00263 00264 if (error) { 00265 ast_log(LOG_ERROR, "%s. SQL: %s.\n", error, sql); 00266 sqlite3_free(error); 00267 } 00268 00269 if (sql) { 00270 sqlite3_free(sql); 00271 } 00272 00273 ast_mutex_unlock(&lock); 00274 00275 return res; 00276 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 278 of file cdr_sqlite3_custom.c.
References ast_cdr_unregister(), and free_config().
00279 { 00280 ast_cdr_unregister(name); 00281 00282 free_config(0); 00283 00284 return 0; 00285 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "SQLite3 Custom CDR Module" , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 349 of file cdr_sqlite3_custom.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 349 of file cdr_sqlite3_custom.c.
char* columns [static] |
Definition at line 64 of file cdr_sqlite3_custom.c.
const char config_file[] = "cdr_sqlite3_custom.conf" [static] |
Definition at line 57 of file cdr_sqlite3_custom.c.
sqlite3* db = NULL [static] |
Definition at line 61 of file cdr_sqlite3_custom.c.
char* desc = "Customizable SQLite3 CDR Backend" [static] |
Definition at line 59 of file cdr_sqlite3_custom.c.
ast_mutex_t lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 55 of file cdr_sqlite3_custom.c.
char* name = "cdr_sqlite3_custom" [static] |
Definition at line 60 of file cdr_sqlite3_custom.c.
char table[80] [static] |
Definition at line 63 of file cdr_sqlite3_custom.c.
1.6.2