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: 159855 $")
00080 #include <sqlite.h>
00081
00082 #include "asterisk/logger.h"
00083 #include "asterisk/pbx.h"
00084 #include "asterisk/cdr.h"
00085 #include "asterisk/cli.h"
00086 #include "asterisk/lock.h"
00087 #include "asterisk/config.h"
00088 #include "asterisk/module.h"
00089 #include "asterisk/linkedlists.h"
00090
00091 #define MACRO_BEGIN do {
00092 #define MACRO_END } while (0)
00093
00094 #define RES_CONFIG_SQLITE_NAME "res_config_sqlite"
00095 #define RES_CONFIG_SQLITE_DRIVER "sqlite"
00096 #define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2"
00097 #define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf"
00098
00099 enum {
00100 RES_CONFIG_SQLITE_CONFIG_ID,
00101 RES_CONFIG_SQLITE_CONFIG_CAT_METRIC,
00102 RES_CONFIG_SQLITE_CONFIG_VAR_METRIC,
00103 RES_CONFIG_SQLITE_CONFIG_COMMENTED,
00104 RES_CONFIG_SQLITE_CONFIG_FILENAME,
00105 RES_CONFIG_SQLITE_CONFIG_CATEGORY,
00106 RES_CONFIG_SQLITE_CONFIG_VAR_NAME,
00107 RES_CONFIG_SQLITE_CONFIG_VAR_VAL,
00108 RES_CONFIG_SQLITE_CONFIG_COLUMNS,
00109 };
00110
00111 #define SET_VAR(config, to, from) \
00112 MACRO_BEGIN \
00113 int __error; \
00114 \
00115 __error = set_var(&to, #to, from->value); \
00116 \
00117 if (__error) { \
00118 ast_config_destroy(config); \
00119 unload_config(); \
00120 return 1; \
00121 } \
00122 MACRO_END
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 #define RES_CONFIG_SQLITE_MAX_LOOPS 10
00141
00142
00143
00144
00145
00146
00147 #define RES_CONFIG_SQLITE_BEGIN \
00148 MACRO_BEGIN \
00149 int __i; \
00150 \
00151 for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++) {
00152
00153
00154
00155
00156
00157
00158 #define RES_CONFIG_SQLITE_END(error) \
00159 if (error != SQLITE_BUSY && error != SQLITE_LOCKED) \
00160 break; \
00161 usleep(1000); \
00162 } \
00163 MACRO_END;
00164
00165
00166
00167
00168
00169
00170 struct cfg_entry_args {
00171 struct ast_config *cfg;
00172 struct ast_category *cat;
00173 char *cat_name;
00174 struct ast_flags flags;
00175 const char *who_asked;
00176 };
00177
00178
00179
00180
00181
00182
00183 struct rt_cfg_entry_args {
00184 struct ast_variable *var;
00185 struct ast_variable *last;
00186 };
00187
00188
00189
00190
00191
00192
00193
00194 struct rt_multi_cfg_entry_args {
00195 struct ast_config *cfg;
00196 char *initfield;
00197 };
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 static int set_var(char **var, const char *name, const char *value);
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 static int load_config(void);
00220
00221
00222
00223
00224
00225 static void unload_config(void);
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 static int cdr_handler(struct ast_cdr *cdr);
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames);
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 static struct ast_config * config_handler(const char *database, const char *table, const char *file,
00275 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked);
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 static size_t get_params(va_list ap, const char ***params_ptr,
00300 const char ***vals_ptr);
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 static int add_rt_cfg_entry(void *arg, int argc, char **argv,
00318 char **columnNames);
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 static struct ast_variable * realtime_handler(const char *database,
00338 const char *table, va_list ap);
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv,
00357 char **columnNames);
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 static struct ast_config * realtime_multi_handler(const char *database,
00375 const char *table, va_list ap);
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 static int realtime_update_handler(const char *database, const char *table,
00396 const char *keyfield, const char *entity, va_list ap);
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 static int realtime_store_handler(const char *database, const char *table,
00414 va_list ap);
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 static int realtime_destroy_handler(const char *database, const char *table,
00435 const char *keyfield, const char *entity, va_list ap);
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00446
00447
00448 static sqlite *db;
00449
00450
00451 static int use_cdr;
00452
00453
00454 static int cdr_registered;
00455
00456
00457 static int cli_status_registered;
00458
00459
00460 static char *dbfile;
00461
00462
00463 static char *config_table;
00464
00465
00466 static char *cdr_table;
00467
00468
00469
00470
00471
00472 static struct ast_config_engine sqlite_engine =
00473 {
00474 .name = RES_CONFIG_SQLITE_DRIVER,
00475 .load_func = config_handler,
00476 .realtime_func = realtime_handler,
00477 .realtime_multi_func = realtime_multi_handler,
00478 .store_func = realtime_store_handler,
00479 .destroy_func = realtime_destroy_handler,
00480 .update_func = realtime_update_handler
00481 };
00482
00483
00484
00485
00486 AST_MUTEX_DEFINE_STATIC(mutex);
00487
00488
00489
00490
00491
00492 static struct ast_cli_entry cli_status[] = {
00493 AST_CLI_DEFINE(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"),
00494 };
00495
00496
00497
00498
00499
00500
00501 static char *sql_create_cdr_table =
00502 "CREATE TABLE '%q' (\n"
00503 " id INTEGER,\n"
00504 " clid VARCHAR(80) NOT NULL DEFAULT '',\n"
00505 " src VARCHAR(80) NOT NULL DEFAULT '',\n"
00506 " dst VARCHAR(80) NOT NULL DEFAULT '',\n"
00507 " dcontext VARCHAR(80) NOT NULL DEFAULT '',\n"
00508 " channel VARCHAR(80) NOT NULL DEFAULT '',\n"
00509 " dstchannel VARCHAR(80) NOT NULL DEFAULT '',\n"
00510 " lastapp VARCHAR(80) NOT NULL DEFAULT '',\n"
00511 " lastdata VARCHAR(80) NOT NULL DEFAULT '',\n"
00512 " start DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00513 " answer DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00514 " end DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00515 " duration INT(11) NOT NULL DEFAULT 0,\n"
00516 " billsec INT(11) NOT NULL DEFAULT 0,\n"
00517 " disposition VARCHAR(45) NOT NULL DEFAULT '',\n"
00518 " amaflags INT(11) NOT NULL DEFAULT 0,\n"
00519 " accountcode VARCHAR(20) NOT NULL DEFAULT '',\n"
00520 " uniqueid VARCHAR(32) NOT NULL DEFAULT '',\n"
00521 " userfield VARCHAR(255) NOT NULL DEFAULT '',\n"
00522 " PRIMARY KEY (id)\n"
00523 ");";
00524
00525
00526 #define sql_add_cdr_entry \
00527 "INSERT INTO '%q' (" \
00528 " clid," \
00529 " src," \
00530 " dst," \
00531 " dcontext," \
00532 " channel," \
00533 " dstchannel," \
00534 " lastapp," \
00535 " lastdata," \
00536 " start," \
00537 " answer," \
00538 " end," \
00539 " duration," \
00540 " billsec," \
00541 " disposition," \
00542 " amaflags," \
00543 " accountcode," \
00544 " uniqueid," \
00545 " userfield" \
00546 ") VALUES (" \
00547 " '%q'," \
00548 " '%q'," \
00549 " '%q'," \
00550 " '%q'," \
00551 " '%q'," \
00552 " '%q'," \
00553 " '%q'," \
00554 " '%q'," \
00555 " datetime(%d,'unixepoch','localtime')," \
00556 " datetime(%d,'unixepoch','localtime')," \
00557 " datetime(%d,'unixepoch','localtime')," \
00558 " '%ld'," \
00559 " '%ld'," \
00560 " '%ld'," \
00561 " '%ld'," \
00562 " '%q'," \
00563 " '%q'," \
00564 " '%q'" \
00565 ");"
00566
00567
00568
00569
00570
00571
00572
00573 #define sql_get_config_table \
00574 "SELECT *" \
00575 " FROM '%q'" \
00576 " WHERE filename = '%q' AND commented = 0" \
00577 " ORDER BY cat_metric ASC, var_metric ASC;"
00578
00579 static int set_var(char **var, const char *name, const char *value)
00580 {
00581 if (*var)
00582 ast_free(*var);
00583
00584 *var = ast_strdup(value);
00585
00586 if (!*var) {
00587 ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00588 return 1;
00589 }
00590
00591 return 0;
00592 }
00593
00594 static int check_vars(void)
00595 {
00596 if (!dbfile) {
00597 ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00598 return 1;
00599 }
00600
00601 use_cdr = (cdr_table != NULL);
00602
00603 return 0;
00604 }
00605
00606 static int load_config(void)
00607 {
00608 struct ast_config *config;
00609 struct ast_variable *var;
00610 int error;
00611 struct ast_flags config_flags = { 0 };
00612
00613 config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00614
00615 if (!config) {
00616 ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00617 return 1;
00618 }
00619
00620 for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00621 if (!strcasecmp(var->name, "dbfile"))
00622 SET_VAR(config, dbfile, var);
00623 else if (!strcasecmp(var->name, "config_table"))
00624 SET_VAR(config, config_table, var);
00625 else if (!strcasecmp(var->name, "cdr_table"))
00626 SET_VAR(config, cdr_table, var);
00627 else
00628 ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00629 }
00630
00631 ast_config_destroy(config);
00632 error = check_vars();
00633
00634 if (error) {
00635 unload_config();
00636 return 1;
00637 }
00638
00639 return 0;
00640 }
00641
00642 static void unload_config(void)
00643 {
00644 ast_free(dbfile);
00645 dbfile = NULL;
00646 ast_free(config_table);
00647 config_table = NULL;
00648 ast_free(cdr_table);
00649 cdr_table = NULL;
00650 }
00651
00652 static int cdr_handler(struct ast_cdr *cdr)
00653 {
00654 char *query, *errormsg;
00655 int error;
00656
00657 query = sqlite_mprintf(sql_add_cdr_entry, cdr_table, cdr->clid,
00658 cdr->src, cdr->dst, cdr->dcontext, cdr->channel,
00659 cdr->dstchannel, cdr->lastapp, cdr->lastdata,
00660 cdr->start.tv_sec, cdr->answer.tv_sec,
00661 cdr->end.tv_sec, cdr->duration, cdr->billsec,
00662 cdr->disposition, cdr->amaflags, cdr->accountcode,
00663 cdr->uniqueid, cdr->userfield);
00664
00665 if (!query) {
00666 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00667 return 1;
00668 }
00669
00670 ast_debug(1, "SQL query: %s\n", query);
00671
00672 ast_mutex_lock(&mutex);
00673
00674 RES_CONFIG_SQLITE_BEGIN
00675 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
00676 RES_CONFIG_SQLITE_END(error)
00677
00678 ast_mutex_unlock(&mutex);
00679
00680 sqlite_freemem(query);
00681
00682 if (error) {
00683 ast_log(LOG_ERROR, "%s\n", errormsg);
00684 sqlite_freemem(errormsg);
00685 return 1;
00686 }
00687
00688 return 0;
00689 }
00690
00691 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00692 {
00693 struct cfg_entry_args *args;
00694 struct ast_variable *var;
00695
00696 if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) {
00697 ast_log(LOG_WARNING, "Corrupt table\n");
00698 return 1;
00699 }
00700
00701 args = arg;
00702
00703 if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) {
00704 struct ast_config *cfg;
00705 char *val;
00706
00707 val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL];
00708 cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked);
00709
00710 if (!cfg) {
00711 ast_log(LOG_WARNING, "Unable to include %s\n", val);
00712 return 1;
00713 } else {
00714 args->cfg = cfg;
00715 return 0;
00716 }
00717 }
00718
00719 if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) {
00720 args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999);
00721
00722 if (!args->cat) {
00723 ast_log(LOG_WARNING, "Unable to allocate category\n");
00724 return 1;
00725 }
00726
00727 ast_free(args->cat_name);
00728 args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]);
00729
00730 if (!args->cat_name) {
00731 ast_category_destroy(args->cat);
00732 return 1;
00733 }
00734
00735 ast_category_append(args->cfg, args->cat);
00736 }
00737
00738 var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], "");
00739
00740 if (!var) {
00741 ast_log(LOG_WARNING, "Unable to allocate variable");
00742 return 1;
00743 }
00744
00745 ast_variable_append(args->cat, var);
00746
00747 return 0;
00748 }
00749
00750 static struct ast_config *config_handler(const char *database, const char *table, const char *file,
00751 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
00752 {
00753 struct cfg_entry_args args;
00754 char *query, *errormsg;
00755 int error;
00756
00757 if (!config_table) {
00758 if (!table) {
00759 ast_log(LOG_ERROR, "Table name unspecified\n");
00760 return NULL;
00761 }
00762 } else
00763 table = config_table;
00764
00765 query = sqlite_mprintf(sql_get_config_table, table, file);
00766
00767 if (!query) {
00768 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00769 return NULL;
00770 }
00771
00772 ast_debug(1, "SQL query: %s\n", query);
00773 args.cfg = cfg;
00774 args.cat = NULL;
00775 args.cat_name = NULL;
00776 args.flags = flags;
00777 args.who_asked = who_asked;
00778
00779 ast_mutex_lock(&mutex);
00780
00781 RES_CONFIG_SQLITE_BEGIN
00782 error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00783 RES_CONFIG_SQLITE_END(error)
00784
00785 ast_mutex_unlock(&mutex);
00786
00787 ast_free(args.cat_name);
00788 sqlite_freemem(query);
00789
00790 if (error) {
00791 ast_log(LOG_ERROR, "%s\n", errormsg);
00792 sqlite_freemem(errormsg);
00793 return NULL;
00794 }
00795
00796 return cfg;
00797 }
00798
00799 static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr)
00800 {
00801 const char **tmp, *param, *val, **params, **vals;
00802 size_t params_count;
00803
00804 params = NULL;
00805 vals = NULL;
00806 params_count = 0;
00807
00808 while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00809 if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00810 ast_free(params);
00811 ast_free(vals);
00812 return 0;
00813 }
00814 params = tmp;
00815
00816 if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00817 ast_free(params);
00818 ast_free(vals);
00819 return 0;
00820 }
00821 vals = tmp;
00822
00823 params[params_count] = param;
00824 vals[params_count] = val;
00825 params_count++;
00826 }
00827
00828 if (params_count > 0) {
00829 *params_ptr = params;
00830 *vals_ptr = vals;
00831 } else
00832 ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
00833
00834 return params_count;
00835 }
00836
00837 static int add_rt_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00838 {
00839 struct rt_cfg_entry_args *args;
00840 struct ast_variable *var;
00841 int i;
00842
00843 args = arg;
00844
00845 for (i = 0; i < argc; i++) {
00846 if (!argv[i])
00847 continue;
00848
00849 if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
00850 return 1;
00851
00852 if (!args->var)
00853 args->var = var;
00854
00855 if (!args->last)
00856 args->last = var;
00857 else {
00858 args->last->next = var;
00859 args->last = var;
00860 }
00861 }
00862
00863 return 0;
00864 }
00865
00866 static struct ast_variable * realtime_handler(const char *database, const char *table, va_list ap)
00867 {
00868 char *query, *errormsg, *op, *tmp_str;
00869 struct rt_cfg_entry_args args;
00870 const char **params, **vals;
00871 size_t params_count;
00872 int error;
00873
00874 if (!table) {
00875 ast_log(LOG_WARNING, "Table name unspecified\n");
00876 return NULL;
00877 }
00878
00879 params_count = get_params(ap, ¶ms, &vals);
00880
00881 if (params_count == 0)
00882 return NULL;
00883
00884 op = (strchr(params[0], ' ') == NULL) ? " =" : "";
00885
00886
00887 #undef QUERY
00888 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
00889
00890
00891 query = sqlite_mprintf(QUERY, table, params[0], op, vals[0]);
00892
00893 if (!query) {
00894 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00895 ast_free(params);
00896 ast_free(vals);
00897 return NULL;
00898 }
00899
00900 if (params_count > 1) {
00901 size_t i;
00902
00903 for (i = 1; i < params_count; i++) {
00904 op = (strchr(params[i], ' ') == NULL) ? " =" : "";
00905 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
00906 sqlite_freemem(query);
00907
00908 if (!tmp_str) {
00909 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
00910 ast_free(params);
00911 ast_free(vals);
00912 return NULL;
00913 }
00914
00915 query = tmp_str;
00916 }
00917 }
00918
00919 ast_free(params);
00920 ast_free(vals);
00921
00922 tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
00923 sqlite_freemem(query);
00924
00925 if (!tmp_str) {
00926 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
00927 return NULL;
00928 }
00929
00930 query = tmp_str;
00931 ast_debug(1, "SQL query: %s\n", query);
00932 args.var = NULL;
00933 args.last = NULL;
00934
00935 ast_mutex_lock(&mutex);
00936
00937 RES_CONFIG_SQLITE_BEGIN
00938 error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
00939 RES_CONFIG_SQLITE_END(error)
00940
00941 ast_mutex_unlock(&mutex);
00942
00943 sqlite_freemem(query);
00944
00945 if (error) {
00946 ast_log(LOG_WARNING, "%s\n", errormsg);
00947 sqlite_freemem(errormsg);
00948 ast_variables_destroy(args.var);
00949 return NULL;
00950 }
00951
00952 return args.var;
00953 }
00954
00955 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00956 {
00957 struct rt_multi_cfg_entry_args *args;
00958 struct ast_category *cat;
00959 struct ast_variable *var;
00960 char *cat_name;
00961 size_t i;
00962
00963 args = arg;
00964 cat_name = NULL;
00965
00966
00967
00968
00969
00970
00971 for (i = 0; i < argc; i++) {
00972 if (!strcmp(args->initfield, columnNames[i]))
00973 cat_name = argv[i];
00974 }
00975
00976 if (!cat_name) {
00977 ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
00978 return 1;
00979 }
00980
00981 if (!(cat = ast_category_new(cat_name, "", 99999))) {
00982 ast_log(LOG_WARNING, "Unable to allocate category\n");
00983 return 1;
00984 }
00985
00986 ast_category_append(args->cfg, cat);
00987
00988 for (i = 0; i < argc; i++) {
00989 if (!argv[i] || !strcmp(args->initfield, columnNames[i]))
00990 continue;
00991
00992 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
00993 ast_log(LOG_WARNING, "Unable to allocate variable\n");
00994 return 1;
00995 }
00996
00997 ast_variable_append(cat, var);
00998 }
00999
01000 return 0;
01001 }
01002
01003 static struct ast_config *realtime_multi_handler(const char *database,
01004 const char *table, va_list ap)
01005 {
01006 char *query, *errormsg, *op, *tmp_str, *initfield;
01007 struct rt_multi_cfg_entry_args args;
01008 const char **params, **vals;
01009 struct ast_config *cfg;
01010 size_t params_count;
01011 int error;
01012
01013 if (!table) {
01014 ast_log(LOG_WARNING, "Table name unspecified\n");
01015 return NULL;
01016 }
01017
01018 if (!(cfg = ast_config_new())) {
01019 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01020 return NULL;
01021 }
01022
01023 if (!(params_count = get_params(ap, ¶ms, &vals))) {
01024 ast_config_destroy(cfg);
01025 return NULL;
01026 }
01027
01028 if (!(initfield = ast_strdup(params[0]))) {
01029 ast_config_destroy(cfg);
01030 ast_free(params);
01031 ast_free(vals);
01032 return NULL;
01033 }
01034
01035 tmp_str = strchr(initfield, ' ');
01036
01037 if (tmp_str)
01038 *tmp_str = '\0';
01039
01040 op = (!strchr(params[0], ' ')) ? " =" : "";
01041
01042
01043
01044
01045
01046 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01047
01048
01049 #undef QUERY
01050 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01051
01052
01053 if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) {
01054 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01055 ast_config_destroy(cfg);
01056 ast_free(params);
01057 ast_free(vals);
01058 ast_free(initfield);
01059 return NULL;
01060 }
01061
01062 if (params_count > 1) {
01063 size_t i;
01064
01065 for (i = 1; i < params_count; i++) {
01066 op = (!strchr(params[i], ' ')) ? " =" : "";
01067 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01068 sqlite_freemem(query);
01069
01070 if (!tmp_str) {
01071 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01072 ast_config_destroy(cfg);
01073 ast_free(params);
01074 ast_free(vals);
01075 ast_free(initfield);
01076 return NULL;
01077 }
01078
01079 query = tmp_str;
01080 }
01081 }
01082
01083 ast_free(params);
01084 ast_free(vals);
01085
01086 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01087 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01088 sqlite_freemem(query);
01089 ast_config_destroy(cfg);
01090 ast_free(initfield);
01091 return NULL;
01092 }
01093
01094 sqlite_freemem(query);
01095 query = tmp_str;
01096 ast_debug(1, "SQL query: %s\n", query);
01097 args.cfg = cfg;
01098 args.initfield = initfield;
01099
01100 ast_mutex_lock(&mutex);
01101
01102 RES_CONFIG_SQLITE_BEGIN
01103 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01104 RES_CONFIG_SQLITE_END(error)
01105
01106 ast_mutex_unlock(&mutex);
01107
01108 sqlite_freemem(query);
01109 ast_free(initfield);
01110
01111 if (error) {
01112 ast_log(LOG_WARNING, "%s\n", errormsg);
01113 sqlite_freemem(errormsg);
01114 ast_config_destroy(cfg);
01115 return NULL;
01116 }
01117
01118 return cfg;
01119 }
01120
01121 static int realtime_update_handler(const char *database, const char *table,
01122 const char *keyfield, const char *entity, va_list ap)
01123 {
01124 char *query, *errormsg, *tmp_str;
01125 const char **params, **vals;
01126 size_t params_count;
01127 int error, rows_num;
01128
01129 if (!table) {
01130 ast_log(LOG_WARNING, "Table name unspecified\n");
01131 return -1;
01132 }
01133
01134 if (!(params_count = get_params(ap, ¶ms, &vals)))
01135 return -1;
01136
01137
01138 #undef QUERY
01139 #define QUERY "UPDATE '%q' SET %q = '%q'"
01140
01141
01142 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01143 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01144 ast_free(params);
01145 ast_free(vals);
01146 return -1;
01147 }
01148
01149 if (params_count > 1) {
01150 size_t i;
01151
01152 for (i = 1; i < params_count; i++) {
01153 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01154 sqlite_freemem(query);
01155
01156 if (!tmp_str) {
01157 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01158 ast_free(params);
01159 ast_free(vals);
01160 return -1;
01161 }
01162
01163 query = tmp_str;
01164 }
01165 }
01166
01167 ast_free(params);
01168 ast_free(vals);
01169
01170 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01171 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01172 sqlite_freemem(query);
01173 return -1;
01174 }
01175
01176 sqlite_freemem(query);
01177 query = tmp_str;
01178 ast_debug(1, "SQL query: %s\n", query);
01179
01180 ast_mutex_lock(&mutex);
01181
01182 RES_CONFIG_SQLITE_BEGIN
01183 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01184 RES_CONFIG_SQLITE_END(error)
01185
01186 if (!error)
01187 rows_num = sqlite_changes(db);
01188 else
01189 rows_num = -1;
01190
01191 ast_mutex_unlock(&mutex);
01192
01193 sqlite_freemem(query);
01194
01195 if (error) {
01196 ast_log(LOG_WARNING, "%s\n", errormsg);
01197 sqlite_freemem(errormsg);
01198 }
01199
01200 return rows_num;
01201 }
01202
01203 static int realtime_store_handler(const char *database, const char *table, va_list ap)
01204 {
01205 char *errormsg, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01206 const char **params, **vals;
01207 size_t params_count;
01208 int error, rows_id;
01209 size_t i;
01210
01211 if (!table) {
01212 ast_log(LOG_WARNING, "Table name unspecified\n");
01213 return -1;
01214 }
01215
01216 if (!(params_count = get_params(ap, ¶ms, &vals)))
01217 return -1;
01218
01219
01220 #undef QUERY
01221 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01222
01223
01224 for (i = 0; i < params_count; i++) {
01225 if ( tmp_keys2 ) {
01226 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01227 sqlite_freemem(tmp_keys2);
01228 } else {
01229 tmp_keys = sqlite_mprintf("%q", params[i]);
01230 }
01231 if (!tmp_keys) {
01232 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01233 sqlite_freemem(tmp_vals);
01234 ast_free(params);
01235 ast_free(vals);
01236 return -1;
01237 }
01238
01239 if ( tmp_vals2 ) {
01240 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, params[i]);
01241 sqlite_freemem(tmp_vals2);
01242 } else {
01243 tmp_vals = sqlite_mprintf("'%q'", params[i]);
01244 }
01245 if (!tmp_vals) {
01246 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01247 sqlite_freemem(tmp_keys);
01248 ast_free(params);
01249 ast_free(vals);
01250 return -1;
01251 }
01252
01253
01254 tmp_keys2 = tmp_keys;
01255 tmp_vals2 = tmp_vals;
01256 }
01257
01258 ast_free(params);
01259 ast_free(vals);
01260
01261 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01262 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01263 sqlite_freemem(tmp_keys);
01264 sqlite_freemem(tmp_vals);
01265 return -1;
01266 }
01267
01268 sqlite_freemem(tmp_keys);
01269 sqlite_freemem(tmp_vals);
01270
01271 ast_debug(1, "SQL query: %s\n", tmp_str);
01272
01273 ast_mutex_lock(&mutex);
01274
01275 RES_CONFIG_SQLITE_BEGIN
01276 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01277 RES_CONFIG_SQLITE_END(error)
01278
01279 if (!error) {
01280 rows_id = sqlite_last_insert_rowid(db);
01281 } else {
01282 rows_id = -1;
01283 }
01284
01285 ast_mutex_unlock(&mutex);
01286
01287 sqlite_freemem(tmp_str);
01288
01289 if (error) {
01290 ast_log(LOG_WARNING, "%s\n", errormsg);
01291 sqlite_freemem(errormsg);
01292 }
01293
01294 return rows_id;
01295 }
01296
01297 static int realtime_destroy_handler(const char *database, const char *table,
01298 const char *keyfield, const char *entity, va_list ap)
01299 {
01300 char *query, *errormsg, *tmp_str;
01301 const char **params, **vals;
01302 size_t params_count;
01303 int error, rows_num;
01304 size_t i;
01305
01306 if (!table) {
01307 ast_log(LOG_WARNING, "Table name unspecified\n");
01308 return -1;
01309 }
01310
01311 if (!(params_count = get_params(ap, ¶ms, &vals)))
01312 return -1;
01313
01314
01315 #undef QUERY
01316 #define QUERY "DELETE FROM '%q' WHERE"
01317
01318
01319 if (!(query = sqlite_mprintf(QUERY, table))) {
01320 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01321 ast_free(params);
01322 ast_free(vals);
01323 return -1;
01324 }
01325
01326 for (i = 0; i < params_count; i++) {
01327 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01328 sqlite_freemem(query);
01329
01330 if (!tmp_str) {
01331 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01332 ast_free(params);
01333 ast_free(vals);
01334 return -1;
01335 }
01336
01337 query = tmp_str;
01338 }
01339
01340 ast_free(params);
01341 ast_free(vals);
01342 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01343 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01344 sqlite_freemem(query);
01345 return -1;
01346 }
01347 sqlite_freemem(query);
01348 query = tmp_str;
01349 ast_debug(1, "SQL query: %s\n", query);
01350
01351 ast_mutex_lock(&mutex);
01352
01353 RES_CONFIG_SQLITE_BEGIN
01354 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01355 RES_CONFIG_SQLITE_END(error)
01356
01357 if (!error)
01358 rows_num = sqlite_changes(db);
01359 else
01360 rows_num = -1;
01361
01362 ast_mutex_unlock(&mutex);
01363
01364 sqlite_freemem(query);
01365
01366 if (error) {
01367 ast_log(LOG_WARNING, "%s\n", errormsg);
01368 sqlite_freemem(errormsg);
01369 }
01370
01371 return rows_num;
01372 }
01373
01374 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01375 {
01376 switch (cmd) {
01377 case CLI_INIT:
01378 e->command = "sqlite show status";
01379 e->usage =
01380 "Usage: sqlite show status\n"
01381 " Show status information about the SQLite 2 driver\n";
01382 return NULL;
01383 case CLI_GENERATE:
01384 return NULL;
01385 }
01386
01387 if (a->argc != 3)
01388 return CLI_SHOWUSAGE;
01389
01390 ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01391 ast_cli(a->fd, "config_table: ");
01392
01393 if (!config_table)
01394 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01395 else
01396 ast_cli(a->fd, "%s\n", config_table);
01397
01398 ast_cli(a->fd, "cdr_table: ");
01399
01400 if (!cdr_table)
01401 ast_cli(a->fd, "unspecified, CDR support disabled\n");
01402 else
01403 ast_cli(a->fd, "%s\n", cdr_table);
01404
01405 return CLI_SUCCESS;
01406 }
01407
01408 static int unload_module(void)
01409 {
01410 if (cli_status_registered)
01411 ast_cli_unregister_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
01412
01413 if (cdr_registered)
01414 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01415
01416 ast_config_engine_deregister(&sqlite_engine);
01417
01418 if (db)
01419 sqlite_close(db);
01420
01421 unload_config();
01422
01423 return 0;
01424 }
01425
01426 static int load_module(void)
01427 {
01428 char *errormsg;
01429 int error;
01430
01431 db = NULL;
01432 cdr_registered = 0;
01433 cli_status_registered = 0;
01434 dbfile = NULL;
01435 config_table = NULL;
01436 cdr_table = NULL;
01437 error = load_config();
01438
01439 if (error)
01440 return AST_MODULE_LOAD_DECLINE;
01441
01442 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01443 ast_log(LOG_ERROR, "%s\n", errormsg);
01444 sqlite_freemem(errormsg);
01445 unload_module();
01446 return 1;
01447 }
01448
01449 ast_config_engine_register(&sqlite_engine);
01450
01451 if (use_cdr) {
01452 char *query;
01453
01454
01455 #undef QUERY
01456 #define QUERY "SELECT COUNT(id) FROM %Q;"
01457
01458
01459 query = sqlite_mprintf(QUERY, cdr_table);
01460
01461 if (!query) {
01462 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01463 unload_module();
01464 return 1;
01465 }
01466
01467 ast_debug(1, "SQL query: %s\n", query);
01468
01469 RES_CONFIG_SQLITE_BEGIN
01470 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01471 RES_CONFIG_SQLITE_END(error)
01472
01473 sqlite_freemem(query);
01474
01475 if (error) {
01476
01477
01478
01479 if (error != SQLITE_ERROR) {
01480 ast_log(LOG_ERROR, "%s\n", errormsg);
01481 sqlite_freemem(errormsg);
01482 unload_module();
01483 return 1;
01484 }
01485
01486 sqlite_freemem(errormsg);
01487 query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01488
01489 if (!query) {
01490 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01491 unload_module();
01492 return 1;
01493 }
01494
01495 ast_debug(1, "SQL query: %s\n", query);
01496
01497 RES_CONFIG_SQLITE_BEGIN
01498 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01499 RES_CONFIG_SQLITE_END(error)
01500
01501 sqlite_freemem(query);
01502
01503 if (error) {
01504 ast_log(LOG_ERROR, "%s\n", errormsg);
01505 sqlite_freemem(errormsg);
01506 unload_module();
01507 return 1;
01508 }
01509 }
01510
01511 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01512
01513 if (error) {
01514 unload_module();
01515 return 1;
01516 }
01517
01518 cdr_registered = 1;
01519 }
01520
01521 error = ast_cli_register_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
01522
01523 if (error) {
01524 unload_module();
01525 return 1;
01526 }
01527
01528 cli_status_registered = 1;
01529
01530 return 0;
01531 }
01532
01533 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Realtime SQLite configuration",
01534 .load = load_module,
01535 .unload = unload_module,
01536 );