Fri Aug 17 00:17:18 2018

Asterisk developer's documentation


res_config_sqlite.c

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

Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1