00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #include "asterisk.h"
00079 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 211569 $")
00080
00081 #include <sqlite.h>
00082
00083 #include "asterisk/logger.h"
00084 #include "asterisk/app.h"
00085 #include "asterisk/pbx.h"
00086 #include "asterisk/cdr.h"
00087 #include "asterisk/cli.h"
00088 #include "asterisk/lock.h"
00089 #include "asterisk/config.h"
00090 #include "asterisk/module.h"
00091 #include "asterisk/linkedlists.h"
00092
00093 #define MACRO_BEGIN do {
00094 #define MACRO_END } while (0)
00095
00096 #define RES_CONFIG_SQLITE_NAME "res_config_sqlite"
00097 #define RES_CONFIG_SQLITE_DRIVER "sqlite"
00098 #define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2"
00099 #define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf"
00100
00101 enum {
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 };
00112
00113 #define SET_VAR(config, to, from) \
00114 MACRO_BEGIN \
00115 int __error; \
00116 \
00117 __error = set_var(&to, #to, from->value); \
00118 \
00119 if (__error) { \
00120 ast_config_destroy(config); \
00121 unload_config(); \
00122 return 1; \
00123 } \
00124 MACRO_END
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 #define RES_CONFIG_SQLITE_MAX_LOOPS 10
00143
00144
00145
00146
00147
00148
00149 #define RES_CONFIG_SQLITE_BEGIN \
00150 MACRO_BEGIN \
00151 int __i; \
00152 \
00153 for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++) {
00154
00155
00156
00157
00158
00159
00160 #define RES_CONFIG_SQLITE_END(error) \
00161 if (error != SQLITE_BUSY) \
00162 break; \
00163 usleep(1000); \
00164 } \
00165 MACRO_END;
00166
00167
00168
00169
00170
00171
00172 struct cfg_entry_args {
00173 struct ast_config *cfg;
00174 struct ast_category *cat;
00175 char *cat_name;
00176 struct ast_flags flags;
00177 const char *who_asked;
00178 };
00179
00180
00181
00182
00183
00184
00185 struct rt_cfg_entry_args {
00186 struct ast_variable *var;
00187 struct ast_variable *last;
00188 };
00189
00190
00191
00192
00193
00194
00195
00196 struct rt_multi_cfg_entry_args {
00197 struct ast_config *cfg;
00198 char *initfield;
00199 };
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 static int set_var(char **var, const char *name, const char *value);
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 static int load_config(void);
00222
00223
00224
00225
00226
00227 static void unload_config(void);
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 static int cdr_handler(struct ast_cdr *cdr);
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames);
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 static struct ast_config * config_handler(const char *database, const char *table, const char *file,
00277 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked);
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 static size_t get_params(va_list ap, const char ***params_ptr,
00302 const char ***vals_ptr);
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 static int add_rt_cfg_entry(void *arg, int argc, char **argv,
00320 char **columnNames);
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 static struct ast_variable * realtime_handler(const char *database,
00340 const char *table, va_list ap);
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv,
00359 char **columnNames);
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 static struct ast_config * realtime_multi_handler(const char *database,
00377 const char *table, va_list ap);
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 static int realtime_update_handler(const char *database, const char *table,
00398 const char *keyfield, const char *entity, va_list ap);
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 static int realtime_store_handler(const char *database, const char *table,
00416 va_list ap);
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 static int realtime_destroy_handler(const char *database, const char *table,
00437 const char *keyfield, const char *entity, va_list ap);
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00448 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00449
00450 static int realtime_require_handler(const char *database, const char *table, va_list ap);
00451 static int realtime_unload_handler(const char *unused, const char *tablename);
00452
00453
00454 static sqlite *db;
00455
00456
00457 static int use_cdr;
00458
00459
00460 static int cdr_registered;
00461
00462
00463 static int cli_status_registered;
00464
00465
00466 static char *dbfile;
00467
00468
00469 static char *config_table;
00470
00471
00472 static char *cdr_table;
00473
00474
00475
00476
00477
00478 static struct ast_config_engine sqlite_engine =
00479 {
00480 .name = RES_CONFIG_SQLITE_DRIVER,
00481 .load_func = config_handler,
00482 .realtime_func = realtime_handler,
00483 .realtime_multi_func = realtime_multi_handler,
00484 .store_func = realtime_store_handler,
00485 .destroy_func = realtime_destroy_handler,
00486 .update_func = realtime_update_handler,
00487 .require_func = realtime_require_handler,
00488 .unload_func = realtime_unload_handler,
00489 };
00490
00491
00492
00493
00494 AST_MUTEX_DEFINE_STATIC(mutex);
00495
00496
00497
00498
00499
00500 static struct ast_cli_entry cli_status[] = {
00501 AST_CLI_DEFINE(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"),
00502 AST_CLI_DEFINE(handle_cli_sqlite_show_tables, "Cached table information about the SQLite 2 driver"),
00503 };
00504
00505 struct sqlite_cache_columns {
00506 char *name;
00507 char *type;
00508 unsigned char isint;
00509 AST_RWLIST_ENTRY(sqlite_cache_columns) list;
00510 };
00511
00512 struct sqlite_cache_tables {
00513 char *name;
00514 AST_RWLIST_HEAD(_columns, sqlite_cache_columns) columns;
00515 AST_RWLIST_ENTRY(sqlite_cache_tables) list;
00516 };
00517
00518 static AST_RWLIST_HEAD_STATIC(sqlite_tables, sqlite_cache_tables);
00519
00520
00521
00522
00523
00524
00525 static char *sql_create_cdr_table =
00526 "CREATE TABLE '%q' (\n"
00527 " id INTEGER,\n"
00528 " clid VARCHAR(80) NOT NULL DEFAULT '',\n"
00529 " src VARCHAR(80) NOT NULL DEFAULT '',\n"
00530 " dst VARCHAR(80) NOT NULL DEFAULT '',\n"
00531 " dcontext VARCHAR(80) NOT NULL DEFAULT '',\n"
00532 " channel VARCHAR(80) NOT NULL DEFAULT '',\n"
00533 " dstchannel VARCHAR(80) NOT NULL DEFAULT '',\n"
00534 " lastapp VARCHAR(80) NOT NULL DEFAULT '',\n"
00535 " lastdata VARCHAR(80) NOT NULL DEFAULT '',\n"
00536 " start DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00537 " answer DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00538 " end DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00539 " duration INT(11) NOT NULL DEFAULT 0,\n"
00540 " billsec INT(11) NOT NULL DEFAULT 0,\n"
00541 " disposition VARCHAR(45) NOT NULL DEFAULT '',\n"
00542 " amaflags INT(11) NOT NULL DEFAULT 0,\n"
00543 " accountcode VARCHAR(20) NOT NULL DEFAULT '',\n"
00544 " uniqueid VARCHAR(32) NOT NULL DEFAULT '',\n"
00545 " userfield VARCHAR(255) NOT NULL DEFAULT '',\n"
00546 " PRIMARY KEY (id)\n"
00547 ");";
00548
00549
00550
00551
00552 #define sql_table_structure "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'"
00553
00554
00555
00556
00557
00558
00559
00560 #define sql_get_config_table \
00561 "SELECT *" \
00562 " FROM '%q'" \
00563 " WHERE filename = '%q' AND commented = 0" \
00564 " ORDER BY cat_metric ASC, var_metric ASC;"
00565
00566 static void free_table(struct sqlite_cache_tables *tblptr)
00567 {
00568 struct sqlite_cache_columns *col;
00569
00570
00571 AST_RWLIST_WRLOCK(&(tblptr->columns));
00572 while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) {
00573 ast_free(col);
00574 }
00575 AST_RWLIST_UNLOCK(&(tblptr->columns));
00576 AST_RWLIST_HEAD_DESTROY(&(tblptr->columns));
00577 ast_free(tblptr);
00578 }
00579
00580 static int find_table_cb(void *vtblptr, int argc, char **argv, char **columnNames)
00581 {
00582 struct sqlite_cache_tables *tblptr = vtblptr;
00583 char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder;
00584 int i;
00585 AST_DECLARE_APP_ARGS(fie,
00586 AST_APP_ARG(ld)[100];
00587 );
00588 struct sqlite_cache_columns *col;
00589
00590
00591
00592
00593 if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) {
00594 start++;
00595 *end = '\0';
00596 } else {
00597
00598 return -1;
00599 }
00600
00601 AST_STANDARD_APP_ARGS(fie, start);
00602 for (i = 0; i < fie.argc; i++) {
00603 fie.ld[i] = ast_skip_blanks(fie.ld[i]);
00604 ast_debug(5, "Found field: %s\n", fie.ld[i]);
00605 if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) {
00606 *end = '\0';
00607 AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) {
00608 if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) {
00609 col->isint = 1;
00610 }
00611 }
00612 continue;
00613 }
00614
00615 for (type = fie.ld[i]; *type > 32; type++);
00616 *type++ = '\0';
00617 type = ast_skip_blanks(type);
00618 for (remainder = type; *remainder > 32; remainder++);
00619 *remainder = '\0';
00620 if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) {
00621 return -1;
00622 }
00623 col->name = (char *)col + sizeof(*col);
00624 col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1;
00625 strcpy(col->name, fie.ld[i]);
00626 strcpy(col->type, type);
00627 if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) {
00628 col->isint = 1;
00629 }
00630 AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list);
00631 }
00632 return 0;
00633 }
00634
00635 static struct sqlite_cache_tables *find_table(const char *tablename)
00636 {
00637 struct sqlite_cache_tables *tblptr;
00638 int i, err;
00639 char *sql, *errstr = NULL;
00640
00641 AST_RWLIST_RDLOCK(&sqlite_tables);
00642
00643 for (i = 0; i < 2; i++) {
00644 AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) {
00645 if (strcmp(tblptr->name, tablename) == 0) {
00646 break;
00647 }
00648 }
00649 if (tblptr) {
00650 AST_RWLIST_RDLOCK(&(tblptr->columns));
00651 AST_RWLIST_UNLOCK(&sqlite_tables);
00652 return tblptr;
00653 }
00654
00655 if (i == 0) {
00656 AST_RWLIST_UNLOCK(&sqlite_tables);
00657 AST_RWLIST_WRLOCK(&sqlite_tables);
00658 }
00659 }
00660
00661
00662 if (asprintf(&sql, sql_table_structure, tablename) < 0) {
00663 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00664 sql = NULL;
00665 }
00666 if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) {
00667 AST_RWLIST_UNLOCK(&sqlite_tables);
00668 ast_log(LOG_ERROR, "Memory error. Cannot cache table '%s'\n", tablename);
00669 return NULL;
00670 }
00671 tblptr->name = (char *)tblptr + sizeof(*tblptr);
00672 strcpy(tblptr->name, tablename);
00673 AST_RWLIST_HEAD_INIT(&(tblptr->columns));
00674
00675 ast_debug(1, "About to query table structure: %s\n", sql);
00676
00677 ast_mutex_lock(&mutex);
00678 if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) {
00679 ast_mutex_unlock(&mutex);
00680 ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr);
00681 ast_free(errstr);
00682 free_table(tblptr);
00683 return NULL;
00684 }
00685 ast_mutex_unlock(&mutex);
00686
00687 if (AST_LIST_EMPTY(&(tblptr->columns))) {
00688 free_table(tblptr);
00689 return NULL;
00690 }
00691
00692 AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list);
00693 AST_RWLIST_RDLOCK(&(tblptr->columns));
00694 AST_RWLIST_UNLOCK(&sqlite_tables);
00695 return tblptr;
00696 }
00697
00698 #define release_table(a) AST_RWLIST_UNLOCK(&((a)->columns))
00699
00700 static int set_var(char **var, const char *name, const char *value)
00701 {
00702 if (*var)
00703 ast_free(*var);
00704
00705 *var = ast_strdup(value);
00706
00707 if (!*var) {
00708 ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00709 return 1;
00710 }
00711
00712 return 0;
00713 }
00714
00715 static int check_vars(void)
00716 {
00717 if (!dbfile) {
00718 ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00719 return 1;
00720 }
00721
00722 use_cdr = (cdr_table != NULL);
00723
00724 return 0;
00725 }
00726
00727 static int load_config(void)
00728 {
00729 struct ast_config *config;
00730 struct ast_variable *var;
00731 int error;
00732 struct ast_flags config_flags = { 0 };
00733
00734 config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00735
00736 if (!config) {
00737 ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00738 return 1;
00739 }
00740
00741 for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00742 if (!strcasecmp(var->name, "dbfile"))
00743 SET_VAR(config, dbfile, var);
00744 else if (!strcasecmp(var->name, "config_table"))
00745 SET_VAR(config, config_table, var);
00746 else if (!strcasecmp(var->name, "cdr_table")) {
00747 SET_VAR(config, cdr_table, var);
00748 } else
00749 ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00750 }
00751
00752 ast_config_destroy(config);
00753 error = check_vars();
00754
00755 if (error) {
00756 unload_config();
00757 return 1;
00758 }
00759
00760 return 0;
00761 }
00762
00763 static void unload_config(void)
00764 {
00765 struct sqlite_cache_tables *tbl;
00766 ast_free(dbfile);
00767 dbfile = NULL;
00768 ast_free(config_table);
00769 config_table = NULL;
00770 ast_free(cdr_table);
00771 cdr_table = NULL;
00772 AST_RWLIST_WRLOCK(&sqlite_tables);
00773 while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) {
00774 free_table(tbl);
00775 }
00776 AST_RWLIST_UNLOCK(&sqlite_tables);
00777 }
00778
00779 static int cdr_handler(struct ast_cdr *cdr)
00780 {
00781 char *errormsg = NULL, *tmp, workspace[500];
00782 int error, scannum;
00783 struct sqlite_cache_tables *tbl = find_table(cdr_table);
00784 struct sqlite_cache_columns *col;
00785 struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16);
00786
00787 if (!tbl) {
00788 ast_log(LOG_WARNING, "No such table: %s\n", cdr_table);
00789 return -1;
00790 }
00791
00792 ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table);
00793 ast_str_set(&sql2, 0, ") VALUES (");
00794
00795 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
00796 if (col->isint) {
00797 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1);
00798 if (!tmp) {
00799 continue;
00800 }
00801 if (sscanf(tmp, "%30d", &scannum) == 1) {
00802 ast_str_append(&sql1, 0, "%s,", col->name);
00803 ast_str_append(&sql2, 0, "%d,", scannum);
00804 }
00805 } else {
00806 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0);
00807 if (!tmp) {
00808 continue;
00809 }
00810 ast_str_append(&sql1, 0, "%s,", col->name);
00811 tmp = sqlite_mprintf("%Q", tmp);
00812 ast_str_append(&sql2, 0, "%s,", tmp);
00813 sqlite_freemem(tmp);
00814 }
00815 }
00816 release_table(tbl);
00817
00818 sql1->str[--sql1->used] = '\0';
00819 sql2->str[--sql2->used] = '\0';
00820 ast_str_append(&sql1, 0, "%s)", sql2->str);
00821 ast_free(sql2);
00822
00823 ast_debug(1, "SQL query: %s\n", sql1->str);
00824
00825 ast_mutex_lock(&mutex);
00826
00827 RES_CONFIG_SQLITE_BEGIN
00828 error = sqlite_exec(db, sql1->str, NULL, NULL, &errormsg);
00829 RES_CONFIG_SQLITE_END(error)
00830
00831 ast_mutex_unlock(&mutex);
00832
00833 ast_free(sql1);
00834
00835 if (error) {
00836 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00837 sqlite_freemem(errormsg);
00838 return 1;
00839 }
00840 sqlite_freemem(errormsg);
00841
00842 return 0;
00843 }
00844
00845 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00846 {
00847 struct cfg_entry_args *args;
00848 struct ast_variable *var;
00849
00850 if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) {
00851 ast_log(LOG_WARNING, "Corrupt table\n");
00852 return 1;
00853 }
00854
00855 args = arg;
00856
00857 if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) {
00858 struct ast_config *cfg;
00859 char *val;
00860
00861 val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL];
00862 cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked);
00863
00864 if (!cfg) {
00865 ast_log(LOG_WARNING, "Unable to include %s\n", val);
00866 return 1;
00867 } else {
00868 args->cfg = cfg;
00869 return 0;
00870 }
00871 }
00872
00873 if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) {
00874 args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999);
00875
00876 if (!args->cat) {
00877 ast_log(LOG_WARNING, "Unable to allocate category\n");
00878 return 1;
00879 }
00880
00881 ast_free(args->cat_name);
00882 args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]);
00883
00884 if (!args->cat_name) {
00885 ast_category_destroy(args->cat);
00886 return 1;
00887 }
00888
00889 ast_category_append(args->cfg, args->cat);
00890 }
00891
00892 var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], "");
00893
00894 if (!var) {
00895 ast_log(LOG_WARNING, "Unable to allocate variable");
00896 return 1;
00897 }
00898
00899 ast_variable_append(args->cat, var);
00900
00901 return 0;
00902 }
00903
00904 static struct ast_config *config_handler(const char *database, const char *table, const char *file,
00905 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
00906 {
00907 struct cfg_entry_args args;
00908 char *query, *errormsg = NULL;
00909 int error;
00910
00911 if (!config_table) {
00912 if (!table) {
00913 ast_log(LOG_ERROR, "Table name unspecified\n");
00914 return NULL;
00915 }
00916 } else
00917 table = config_table;
00918
00919 query = sqlite_mprintf(sql_get_config_table, table, file);
00920
00921 if (!query) {
00922 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00923 return NULL;
00924 }
00925
00926 ast_debug(1, "SQL query: %s\n", query);
00927 args.cfg = cfg;
00928 args.cat = NULL;
00929 args.cat_name = NULL;
00930 args.flags = flags;
00931 args.who_asked = who_asked;
00932
00933 ast_mutex_lock(&mutex);
00934
00935 RES_CONFIG_SQLITE_BEGIN
00936 error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00937 RES_CONFIG_SQLITE_END(error)
00938
00939 ast_mutex_unlock(&mutex);
00940
00941 ast_free(args.cat_name);
00942 sqlite_freemem(query);
00943
00944 if (error) {
00945 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00946 sqlite_freemem(errormsg);
00947 return NULL;
00948 }
00949 sqlite_freemem(errormsg);
00950
00951 return cfg;
00952 }
00953
00954 static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr)
00955 {
00956 const char **tmp, *param, *val, **params, **vals;
00957 size_t params_count;
00958
00959 params = NULL;
00960 vals = NULL;
00961 params_count = 0;
00962
00963 while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00964 if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00965 ast_free(params);
00966 ast_free(vals);
00967 return 0;
00968 }
00969 params = tmp;
00970
00971 if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00972 ast_free(params);
00973 ast_free(vals);
00974 return 0;
00975 }
00976 vals = tmp;
00977
00978 params[params_count] = param;
00979 vals[params_count] = val;
00980 params_count++;
00981 }
00982
00983 if (params_count > 0) {
00984 *params_ptr = params;
00985 *vals_ptr = vals;
00986 } else
00987 ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
00988
00989 return params_count;
00990 }
00991
00992 static int add_rt_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00993 {
00994 struct rt_cfg_entry_args *args;
00995 struct ast_variable *var;
00996 int i;
00997
00998 args = arg;
00999
01000 for (i = 0; i < argc; i++) {
01001 if (!argv[i])
01002 continue;
01003
01004 if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
01005 return 1;
01006
01007 if (!args->var)
01008 args->var = var;
01009
01010 if (!args->last)
01011 args->last = var;
01012 else {
01013 args->last->next = var;
01014 args->last = var;
01015 }
01016 }
01017
01018 return 0;
01019 }
01020
01021 static struct ast_variable * realtime_handler(const char *database, const char *table, va_list ap)
01022 {
01023 char *query, *errormsg = NULL, *op, *tmp_str;
01024 struct rt_cfg_entry_args args;
01025 const char **params, **vals;
01026 size_t params_count;
01027 int error;
01028
01029 if (!table) {
01030 ast_log(LOG_WARNING, "Table name unspecified\n");
01031 return NULL;
01032 }
01033
01034 params_count = get_params(ap, ¶ms, &vals);
01035
01036 if (params_count == 0)
01037 return NULL;
01038
01039 op = (strchr(params[0], ' ') == NULL) ? " =" : "";
01040
01041
01042 #undef QUERY
01043 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01044
01045
01046 query = sqlite_mprintf(QUERY, table, params[0], op, vals[0]);
01047
01048 if (!query) {
01049 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01050 ast_free(params);
01051 ast_free(vals);
01052 return NULL;
01053 }
01054
01055 if (params_count > 1) {
01056 size_t i;
01057
01058 for (i = 1; i < params_count; i++) {
01059 op = (strchr(params[i], ' ') == NULL) ? " =" : "";
01060 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01061 sqlite_freemem(query);
01062
01063 if (!tmp_str) {
01064 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01065 ast_free(params);
01066 ast_free(vals);
01067 return NULL;
01068 }
01069
01070 query = tmp_str;
01071 }
01072 }
01073
01074 ast_free(params);
01075 ast_free(vals);
01076
01077 tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
01078 sqlite_freemem(query);
01079
01080 if (!tmp_str) {
01081 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01082 return NULL;
01083 }
01084
01085 query = tmp_str;
01086 ast_debug(1, "SQL query: %s\n", query);
01087 args.var = NULL;
01088 args.last = NULL;
01089
01090 ast_mutex_lock(&mutex);
01091
01092 RES_CONFIG_SQLITE_BEGIN
01093 error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
01094 RES_CONFIG_SQLITE_END(error)
01095
01096 ast_mutex_unlock(&mutex);
01097
01098 sqlite_freemem(query);
01099
01100 if (error) {
01101 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01102 sqlite_freemem(errormsg);
01103 ast_variables_destroy(args.var);
01104 return NULL;
01105 }
01106 sqlite_freemem(errormsg);
01107
01108 return args.var;
01109 }
01110
01111 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01112 {
01113 struct rt_multi_cfg_entry_args *args;
01114 struct ast_category *cat;
01115 struct ast_variable *var;
01116 char *cat_name;
01117 size_t i;
01118
01119 args = arg;
01120 cat_name = NULL;
01121
01122
01123
01124
01125
01126
01127 for (i = 0; i < argc; i++) {
01128 if (!strcmp(args->initfield, columnNames[i]))
01129 cat_name = argv[i];
01130 }
01131
01132 if (!cat_name) {
01133 ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01134 return 1;
01135 }
01136
01137 if (!(cat = ast_category_new(cat_name, "", 99999))) {
01138 ast_log(LOG_WARNING, "Unable to allocate category\n");
01139 return 1;
01140 }
01141
01142 ast_category_append(args->cfg, cat);
01143
01144 for (i = 0; i < argc; i++) {
01145 if (!argv[i] || !strcmp(args->initfield, columnNames[i]))
01146 continue;
01147
01148 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01149 ast_log(LOG_WARNING, "Unable to allocate variable\n");
01150 return 1;
01151 }
01152
01153 ast_variable_append(cat, var);
01154 }
01155
01156 return 0;
01157 }
01158
01159 static struct ast_config *realtime_multi_handler(const char *database,
01160 const char *table, va_list ap)
01161 {
01162 char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01163 struct rt_multi_cfg_entry_args args;
01164 const char **params, **vals;
01165 struct ast_config *cfg;
01166 size_t params_count;
01167 int error;
01168
01169 if (!table) {
01170 ast_log(LOG_WARNING, "Table name unspecified\n");
01171 return NULL;
01172 }
01173
01174 if (!(cfg = ast_config_new())) {
01175 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01176 return NULL;
01177 }
01178
01179 if (!(params_count = get_params(ap, ¶ms, &vals))) {
01180 ast_config_destroy(cfg);
01181 return NULL;
01182 }
01183
01184 if (!(initfield = ast_strdup(params[0]))) {
01185 ast_config_destroy(cfg);
01186 ast_free(params);
01187 ast_free(vals);
01188 return NULL;
01189 }
01190
01191 tmp_str = strchr(initfield, ' ');
01192
01193 if (tmp_str)
01194 *tmp_str = '\0';
01195
01196 op = (!strchr(params[0], ' ')) ? " =" : "";
01197
01198
01199
01200
01201
01202 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01203
01204
01205 #undef QUERY
01206 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01207
01208
01209 if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) {
01210 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01211 ast_config_destroy(cfg);
01212 ast_free(params);
01213 ast_free(vals);
01214 ast_free(initfield);
01215 return NULL;
01216 }
01217
01218 if (params_count > 1) {
01219 size_t i;
01220
01221 for (i = 1; i < params_count; i++) {
01222 op = (!strchr(params[i], ' ')) ? " =" : "";
01223 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01224 sqlite_freemem(query);
01225
01226 if (!tmp_str) {
01227 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01228 ast_config_destroy(cfg);
01229 ast_free(params);
01230 ast_free(vals);
01231 ast_free(initfield);
01232 return NULL;
01233 }
01234
01235 query = tmp_str;
01236 }
01237 }
01238
01239 ast_free(params);
01240 ast_free(vals);
01241
01242 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01243 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01244 sqlite_freemem(query);
01245 ast_config_destroy(cfg);
01246 ast_free(initfield);
01247 return NULL;
01248 }
01249
01250 sqlite_freemem(query);
01251 query = tmp_str;
01252 ast_debug(1, "SQL query: %s\n", query);
01253 args.cfg = cfg;
01254 args.initfield = initfield;
01255
01256 ast_mutex_lock(&mutex);
01257
01258 RES_CONFIG_SQLITE_BEGIN
01259 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01260 RES_CONFIG_SQLITE_END(error)
01261
01262 ast_mutex_unlock(&mutex);
01263
01264 sqlite_freemem(query);
01265 ast_free(initfield);
01266
01267 if (error) {
01268 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01269 sqlite_freemem(errormsg);
01270 ast_config_destroy(cfg);
01271 return NULL;
01272 }
01273 sqlite_freemem(errormsg);
01274
01275 return cfg;
01276 }
01277
01278 static int realtime_update_handler(const char *database, const char *table,
01279 const char *keyfield, const char *entity, va_list ap)
01280 {
01281 char *query, *errormsg = NULL, *tmp_str;
01282 const char **params, **vals;
01283 size_t params_count;
01284 int error, rows_num;
01285
01286 if (!table) {
01287 ast_log(LOG_WARNING, "Table name unspecified\n");
01288 return -1;
01289 }
01290
01291 if (!(params_count = get_params(ap, ¶ms, &vals)))
01292 return -1;
01293
01294
01295 #undef QUERY
01296 #define QUERY "UPDATE '%q' SET %q = '%q'"
01297
01298
01299 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01300 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01301 ast_free(params);
01302 ast_free(vals);
01303 return -1;
01304 }
01305
01306 if (params_count > 1) {
01307 size_t i;
01308
01309 for (i = 1; i < params_count; i++) {
01310 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01311 sqlite_freemem(query);
01312
01313 if (!tmp_str) {
01314 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01315 ast_free(params);
01316 ast_free(vals);
01317 return -1;
01318 }
01319
01320 query = tmp_str;
01321 }
01322 }
01323
01324 ast_free(params);
01325 ast_free(vals);
01326
01327 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01328 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01329 sqlite_freemem(query);
01330 return -1;
01331 }
01332
01333 sqlite_freemem(query);
01334 query = tmp_str;
01335 ast_debug(1, "SQL query: %s\n", query);
01336
01337 ast_mutex_lock(&mutex);
01338
01339 RES_CONFIG_SQLITE_BEGIN
01340 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01341 RES_CONFIG_SQLITE_END(error)
01342
01343 if (!error)
01344 rows_num = sqlite_changes(db);
01345 else
01346 rows_num = -1;
01347
01348 ast_mutex_unlock(&mutex);
01349
01350 sqlite_freemem(query);
01351
01352 if (error) {
01353 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01354 }
01355 sqlite_freemem(errormsg);
01356
01357 return rows_num;
01358 }
01359
01360 static int realtime_store_handler(const char *database, const char *table, va_list ap)
01361 {
01362 char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01363 const char **params, **vals;
01364 size_t params_count;
01365 int error, rows_id;
01366 size_t i;
01367
01368 if (!table) {
01369 ast_log(LOG_WARNING, "Table name unspecified\n");
01370 return -1;
01371 }
01372
01373 if (!(params_count = get_params(ap, ¶ms, &vals)))
01374 return -1;
01375
01376
01377 #undef QUERY
01378 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01379
01380
01381 for (i = 0; i < params_count; i++) {
01382 if ( tmp_keys2 ) {
01383 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01384 sqlite_freemem(tmp_keys2);
01385 } else {
01386 tmp_keys = sqlite_mprintf("%q", params[i]);
01387 }
01388 if (!tmp_keys) {
01389 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01390 sqlite_freemem(tmp_vals);
01391 ast_free(params);
01392 ast_free(vals);
01393 return -1;
01394 }
01395
01396 if ( tmp_vals2 ) {
01397 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, params[i]);
01398 sqlite_freemem(tmp_vals2);
01399 } else {
01400 tmp_vals = sqlite_mprintf("'%q'", params[i]);
01401 }
01402 if (!tmp_vals) {
01403 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01404 sqlite_freemem(tmp_keys);
01405 ast_free(params);
01406 ast_free(vals);
01407 return -1;
01408 }
01409
01410
01411 tmp_keys2 = tmp_keys;
01412 tmp_vals2 = tmp_vals;
01413 }
01414
01415 ast_free(params);
01416 ast_free(vals);
01417
01418 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01419 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01420 sqlite_freemem(tmp_keys);
01421 sqlite_freemem(tmp_vals);
01422 return -1;
01423 }
01424
01425 sqlite_freemem(tmp_keys);
01426 sqlite_freemem(tmp_vals);
01427
01428 ast_debug(1, "SQL query: %s\n", tmp_str);
01429
01430 ast_mutex_lock(&mutex);
01431
01432 RES_CONFIG_SQLITE_BEGIN
01433 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01434 RES_CONFIG_SQLITE_END(error)
01435
01436 if (!error) {
01437 rows_id = sqlite_last_insert_rowid(db);
01438 } else {
01439 rows_id = -1;
01440 }
01441
01442 ast_mutex_unlock(&mutex);
01443
01444 sqlite_freemem(tmp_str);
01445
01446 if (error) {
01447 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01448 }
01449 sqlite_freemem(errormsg);
01450
01451 return rows_id;
01452 }
01453
01454 static int realtime_destroy_handler(const char *database, const char *table,
01455 const char *keyfield, const char *entity, va_list ap)
01456 {
01457 char *query, *errormsg = NULL, *tmp_str;
01458 const char **params, **vals;
01459 size_t params_count;
01460 int error, rows_num;
01461 size_t i;
01462
01463 if (!table) {
01464 ast_log(LOG_WARNING, "Table name unspecified\n");
01465 return -1;
01466 }
01467
01468 if (!(params_count = get_params(ap, ¶ms, &vals)))
01469 return -1;
01470
01471
01472 #undef QUERY
01473 #define QUERY "DELETE FROM '%q' WHERE"
01474
01475
01476 if (!(query = sqlite_mprintf(QUERY, table))) {
01477 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01478 ast_free(params);
01479 ast_free(vals);
01480 return -1;
01481 }
01482
01483 for (i = 0; i < params_count; i++) {
01484 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01485 sqlite_freemem(query);
01486
01487 if (!tmp_str) {
01488 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01489 ast_free(params);
01490 ast_free(vals);
01491 return -1;
01492 }
01493
01494 query = tmp_str;
01495 }
01496
01497 ast_free(params);
01498 ast_free(vals);
01499 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01500 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01501 sqlite_freemem(query);
01502 return -1;
01503 }
01504 sqlite_freemem(query);
01505 query = tmp_str;
01506 ast_debug(1, "SQL query: %s\n", query);
01507
01508 ast_mutex_lock(&mutex);
01509
01510 RES_CONFIG_SQLITE_BEGIN
01511 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01512 RES_CONFIG_SQLITE_END(error)
01513
01514 if (!error)
01515 rows_num = sqlite_changes(db);
01516 else
01517 rows_num = -1;
01518
01519 ast_mutex_unlock(&mutex);
01520
01521 sqlite_freemem(query);
01522
01523 if (error) {
01524 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01525 }
01526 sqlite_freemem(errormsg);
01527
01528 return rows_num;
01529 }
01530
01531 static int realtime_require_handler(const char *unused, const char *tablename, va_list ap)
01532 {
01533 struct sqlite_cache_tables *tbl = find_table(tablename);
01534 struct sqlite_cache_columns *col;
01535 char *elm;
01536 int type, size, res = 0;
01537
01538 if (!tbl) {
01539 return -1;
01540 }
01541
01542 while ((elm = va_arg(ap, char *))) {
01543 type = va_arg(ap, require_type);
01544 size = va_arg(ap, int);
01545
01546 AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01547 if (strcmp(col->name, elm) == 0) {
01548
01549
01550
01551
01552 if (col->isint && !ast_rq_is_int(type)) {
01553 ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01554 res = -1;
01555 }
01556 break;
01557 }
01558 }
01559 if (!col) {
01560 ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01561 }
01562 }
01563 AST_RWLIST_UNLOCK(&(tbl->columns));
01564 return res;
01565 }
01566
01567 static int realtime_unload_handler(const char *unused, const char *tablename)
01568 {
01569 struct sqlite_cache_tables *tbl;
01570 AST_RWLIST_WRLOCK(&sqlite_tables);
01571 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) {
01572 if (!strcasecmp(tbl->name, tablename)) {
01573 AST_RWLIST_REMOVE_CURRENT(list);
01574 free_table(tbl);
01575 }
01576 }
01577 AST_RWLIST_TRAVERSE_SAFE_END
01578 AST_RWLIST_UNLOCK(&sqlite_tables);
01579 return 0;
01580 }
01581
01582 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01583 {
01584 switch (cmd) {
01585 case CLI_INIT:
01586 e->command = "sqlite show status";
01587 e->usage =
01588 "Usage: sqlite show status\n"
01589 " Show status information about the SQLite 2 driver\n";
01590 return NULL;
01591 case CLI_GENERATE:
01592 return NULL;
01593 }
01594
01595 if (a->argc != 3)
01596 return CLI_SHOWUSAGE;
01597
01598 ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01599 ast_cli(a->fd, "config_table: ");
01600
01601 if (!config_table)
01602 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01603 else
01604 ast_cli(a->fd, "%s\n", config_table);
01605
01606 ast_cli(a->fd, "cdr_table: ");
01607
01608 if (!cdr_table)
01609 ast_cli(a->fd, "unspecified, CDR support disabled\n");
01610 else
01611 ast_cli(a->fd, "%s\n", cdr_table);
01612
01613 return CLI_SUCCESS;
01614 }
01615
01616 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01617 {
01618 struct sqlite_cache_tables *tbl;
01619 struct sqlite_cache_columns *col;
01620 int found = 0;
01621
01622 switch (cmd) {
01623 case CLI_INIT:
01624 e->command = "sqlite show tables";
01625 e->usage =
01626 "Usage: sqlite show tables\n"
01627 " Show table information about the SQLite 2 driver\n";
01628 return NULL;
01629 case CLI_GENERATE:
01630 return NULL;
01631 }
01632
01633 if (a->argc != 3)
01634 return CLI_SHOWUSAGE;
01635
01636 AST_RWLIST_RDLOCK(&sqlite_tables);
01637 AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01638 found++;
01639 ast_cli(a->fd, "Table %s:\n", tbl->name);
01640 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01641 fprintf(stderr, "%s\n", col->name);
01642 ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type);
01643 }
01644 }
01645 AST_RWLIST_UNLOCK(&sqlite_tables);
01646
01647 if (!found) {
01648 ast_cli(a->fd, "No tables currently in cache\n");
01649 }
01650
01651 return CLI_SUCCESS;
01652 }
01653
01654 static int unload_module(void)
01655 {
01656 if (cli_status_registered)
01657 ast_cli_unregister_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
01658
01659 if (cdr_registered)
01660 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01661
01662 ast_config_engine_deregister(&sqlite_engine);
01663
01664 if (db)
01665 sqlite_close(db);
01666
01667 unload_config();
01668
01669 return 0;
01670 }
01671
01672 static int load_module(void)
01673 {
01674 char *errormsg = NULL;
01675 int error;
01676
01677 db = NULL;
01678 cdr_registered = 0;
01679 cli_status_registered = 0;
01680 dbfile = NULL;
01681 config_table = NULL;
01682 cdr_table = NULL;
01683 error = load_config();
01684
01685 if (error)
01686 return AST_MODULE_LOAD_DECLINE;
01687
01688 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01689 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01690 sqlite_freemem(errormsg);
01691 unload_module();
01692 return 1;
01693 }
01694
01695 sqlite_freemem(errormsg);
01696 errormsg = NULL;
01697 ast_config_engine_register(&sqlite_engine);
01698
01699 if (use_cdr) {
01700 char *query;
01701
01702
01703 #undef QUERY
01704 #define QUERY "SELECT COUNT(id) FROM %Q;"
01705
01706
01707 query = sqlite_mprintf(QUERY, cdr_table);
01708
01709 if (!query) {
01710 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01711 unload_module();
01712 return 1;
01713 }
01714
01715 ast_debug(1, "SQL query: %s\n", query);
01716
01717 RES_CONFIG_SQLITE_BEGIN
01718 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01719 RES_CONFIG_SQLITE_END(error)
01720
01721 sqlite_freemem(query);
01722
01723 if (error) {
01724
01725
01726
01727 if (error != SQLITE_ERROR) {
01728 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01729 sqlite_freemem(errormsg);
01730 unload_module();
01731 return 1;
01732 }
01733
01734 sqlite_freemem(errormsg);
01735 errormsg = NULL;
01736 query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01737
01738 if (!query) {
01739 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01740 unload_module();
01741 return 1;
01742 }
01743
01744 ast_debug(1, "SQL query: %s\n", query);
01745
01746 RES_CONFIG_SQLITE_BEGIN
01747 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01748 RES_CONFIG_SQLITE_END(error)
01749
01750 sqlite_freemem(query);
01751
01752 if (error) {
01753 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01754 sqlite_freemem(errormsg);
01755 unload_module();
01756 return 1;
01757 }
01758 }
01759 sqlite_freemem(errormsg);
01760 errormsg = NULL;
01761
01762 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01763
01764 if (error) {
01765 unload_module();
01766 return 1;
01767 }
01768
01769 cdr_registered = 1;
01770 }
01771
01772 error = ast_cli_register_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
01773
01774 if (error) {
01775 unload_module();
01776 return 1;
01777 }
01778
01779 cli_status_registered = 1;
01780
01781 return 0;
01782 }
01783
01784 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Realtime SQLite configuration",
01785 .load = load_module,
01786 .unload = unload_module,
01787 );