35#include <mysql/mysql.h> 
   36#include <mysql/errmsg.h> 
   49#define RES_CONFIG_MYSQL_CONF "res_config_mysql.conf" 
   50#define RES_CONFIG_MYSQL_CONF_OLD "res_mysql.conf" 
   54#define ESCAPE_STRING(buf, var) \ 
   56        struct ast_str *semi = ast_str_thread_get(&scratch2_buf, strlen(var) * 3 + 1); \ 
   57        const char *chunk = var; \ 
   58        ast_str_reset(semi); \ 
   59        for (; *chunk; chunk++) { \ 
   60            if (strchr(";^", *chunk)) { \ 
   61                ast_str_append(&semi, 0, "^%02hhX", *chunk); \ 
   63                ast_str_append(&semi, 0, "%c", *chunk); \ 
   66        if (ast_str_strlen(semi) * 2 + 1 > ast_str_size(buf)) { \ 
   67            ast_str_make_space(&(buf), ast_str_strlen(semi) * 2 + 1); \ 
   69        mysql_real_escape_string(&dbh->handle, ast_str_buffer(buf), ast_str_buffer(semi), ast_str_strlen(semi)); \ 
 
  125static int require_mysql(
const char *database, 
const char *tablename, va_list ap);
 
  138    if ((ptr = strchr(database, 
'/'))) {
 
  144            strncpy(whichdb, database, ptr - database);
 
  145            whichdb[ptr - database] = 
'\0';
 
 
  162#define release_database(a) ast_mutex_unlock(&(a)->lock) 
  181    char *fname, *ftype, *flen, *fdflt, *fnull;
 
  192        if (!strcasecmp(table->
name, tablename)) {
 
  210        ast_log(
LOG_ERROR, 
"Failed to query database '%s', table '%s' columns: %s\n", database, tablename, mysql_error(&dbh->
handle));
 
  216    if (!(table = 
ast_calloc(1, 
sizeof(*table) + strlen(tablename) + 1))) {
 
  222    strcpy(table->
name, tablename); 
 
  228        while ((row = mysql_fetch_row(
result))) {
 
  233            ast_verb(4, 
"Found column '%s' of type '%s'\n", fname, ftype);
 
  239            if (!(column = 
ast_calloc(1, 
sizeof(*column) + strlen(fname) + strlen(ftype) + strlen(fdflt) + 3))) {
 
  240                ast_log(
LOG_ERROR, 
"Unable to allocate column element %s for %s\n", fname, tablename);
 
  247            if ((flen = strchr(ftype, 
'('))) {
 
  248                sscanf(flen, 
"(%30d)", &column->
len);
 
  254            column->
name = (
char *)column + 
sizeof(*column);
 
  255            column->
type = (
char *)column + 
sizeof(*column) + strlen(fname) + 1;
 
  256            column->
dflt = (
char *)column + 
sizeof(*column) + strlen(fname) + 1 + strlen(ftype) + 1;
 
  257            strcpy(column->
name, fname);
 
  258            strcpy(column->
type, ftype);
 
  259            strcpy(column->
dflt, fdflt);
 
  260            column->
null = (strcmp(fnull, 
"YES") == 0 ? 1 : 0);
 
  263        mysql_free_result(
result);
 
 
  285        if (strcmp(column->
name, colname) == 0) {
 
 
  296    for (; *chunk; chunk++) {
 
  297        if (*chunk == 
'^' && strchr(
"0123456789ABCDEFabcdef", chunk[1]) && strchr(
"0123456789ABCDEFabcdef", chunk[2])) {
 
  298            sscanf(chunk + 1, 
"%02hhX", chunk);
 
  299            memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
 
 
  305#define IS_SQL_LIKE_CLAUSE(x) ((x) && ast_ends_with(x, " LIKE")) 
  327        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: %s (check res_mysql.conf)\n", database);
 
  339        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 
  353    if (!strchr(field->
name, 
' ')) {
 
  364    while ((field = field->
next)) {
 
  366        if (!strchr(field->
name, 
' ')) {
 
  388        numFields = mysql_num_fields(
result);
 
  389        fields = mysql_fetch_fields(
result);
 
  391        while ((row = mysql_fetch_row(
result))) {
 
  392            for (i = 0; i < numFields; i++) {
 
  394                if (row[i] == 
NULL) {
 
  399                for (stringp = row[i], chunk = 
strsep(&stringp, 
";"); chunk; chunk = 
strsep(&stringp, 
";")) {
 
  411        ast_debug(1, 
"MySQL RealTime: Could not find any rows in table %s.\n", table);
 
  415    mysql_free_result(
result);
 
 
  429    const char *initfield = 
NULL;
 
  440        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  459        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 
  466    if ((op = strchr(initfield, 
' '))) {
 
  480    if (!strchr(field->
name, 
' ')) {
 
  491    while ((field = field->
next)) {
 
  493        if (!strchr(field->
name, 
' ')) {
 
  520        numFields = mysql_num_fields(
result);
 
  521        fields = mysql_fetch_fields(
result);
 
  523        while ((row = mysql_fetch_row(
result))) {
 
  529            for (i = 0; i < numFields; i++) {
 
  532                for (stringp = row[i], chunk = 
strsep(&stringp, 
";"); chunk; chunk = 
strsep(&stringp, 
";")) {
 
  534                        if (initfield && !strcmp(initfield, fields[i].
name)) {
 
  545        ast_debug(1, 
"MySQL RealTime: Could not find any rows in table %s.\n", table);
 
  549    mysql_free_result(
result);
 
 
  554static int update_mysql(
const char *database, 
const char *tablename, 
const char *keyfield, 
const char *lookup, 
const struct ast_variable *rt_fields)
 
  564        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  574    if (!(table = 
find_table(database, tablename))) {
 
  581        ast_log(
LOG_ERROR, 
"MySQL RealTime: Updating on column '%s', but that column does not exist within the table '%s' (db '%s')!\n", keyfield, tablename, database);
 
  589        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime update requires at least 1 parameter and 1 value to update.\n");
 
  597        ast_log(
LOG_ERROR, 
"MySQL RealTime: Updating column '%s', but that column does not exist within the table '%s' (first pair MUST exist)!\n", field->
name, tablename);
 
  616    while ((field = field->
next)) {
 
  619            ast_log(
LOG_WARNING, 
"Attempted to update column '%s' in table '%s', but column does not exist!\n", field->
name, tablename);
 
  640    numrows = mysql_affected_rows(&dbh->
handle);
 
  644    ast_debug(1, 
"MySQL RealTime: Updated %" PRIu64 
" rows on table: %s\n", numrows, tablename);
 
 
  676    if (!(table = 
find_table(database, tablename))) {
 
  682    if (!sql || !
buf || !where) {
 
  699    for (field = lookup_fields; field; field = field->
next) {
 
  701            ast_log(
LOG_ERROR, 
"Updating on column '%s', but that column does not exist within the table '%s'!\n", field->
name, tablename);
 
  712    for (field = update_fields; field; field = field->
next) {
 
  715            ast_log(
LOG_WARNING, 
"Attempted to update column '%s' in table '%s', but column does not exist!\n", field->
name, tablename);
 
  738    numrows = mysql_affected_rows(&dbh->
handle);
 
  741    ast_debug(1, 
"MySQL RealTime: Updated %" PRIu64 
" rows on table: %s\n", numrows, tablename);
 
 
  761        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  772        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime storage requires at least 1 parameter and 1 value to search on.\n");
 
  787    while ((field = field->
next)) {
 
  805    ast_debug(1, 
"MySQL RealTime: row inserted on table: %s\n", table);
 
 
  810static int destroy_mysql(
const char *database, 
const char *table, 
const char *keyfield, 
const char *lookup, 
const struct ast_variable *rt_fields)
 
  819        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  833        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime destroying requires at least 1 parameter and 1 value to search on.\n");
 
  848    for (field = rt_fields; field; field = field->
next) {
 
  862    numrows = mysql_affected_rows(&dbh->
handle);
 
  865    ast_debug(1, 
"MySQL RealTime: Deleted %" PRIu64 
" rows on table: %s\n", numrows, table);
 
 
  886    int last_cat_metric = 0;
 
  896        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  900    ast_str_set(&sql, 0, 
"SELECT category, var_name, var_val, cat_metric FROM %s WHERE filename='%s' and commented=0 ORDER BY filename, category, cat_metric desc, var_metric asc, var_name, var_val, id", table, file);
 
  910        ast_log(
LOG_WARNING, 
"MySQL RealTime: Failed to query database. Check debug for more info.\n");
 
  912        ast_debug(1, 
"MySQL RealTime: Query Failed because: %s\n", mysql_error(&dbh->
handle));
 
  918        num_rows = mysql_num_rows(
result);
 
  919        ast_debug(1, 
"MySQL RealTime: Found %" PRIu64 
" rows.\n", num_rows);
 
  924        while ((row = mysql_fetch_row(
result))) {
 
  925            if (!strcmp(row[1], 
"#include")) {
 
  927                    mysql_free_result(
result);
 
  934            if (strcmp(
last, row[0]) || last_cat_metric != atoi(row[3])) {
 
  939                strcpy(
last, row[0]);
 
  940                last_cat_metric = atoi(row[3]);
 
  948        ast_log(
LOG_WARNING, 
"MySQL RealTime: Could not find config '%s' in database.\n", file);
 
  951    mysql_free_result(
result);
 
 
  962        if (strcmp(cur->
name, tablename) == 0) {
 
 
  983        ast_log(
LOG_WARNING, 
"Table %s not found in database.  This table should exist if you're using realtime.\n", tablename);
 
  987    while ((elm = va_arg(ap, 
char *))) {
 
  989        size = va_arg(ap, 
int);
 
  992            if (strcmp(column->
name, elm) == 0) {
 
  994                if (strncmp(column->
type, 
"char", 4) == 0 || strncmp(column->
type, 
"varchar", 7) == 0) {
 
  995                    if ((size > column->
len) && column->
len != -1) {
 
  996                        ast_log(
LOG_WARNING, 
"Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", 
database, tablename, column->
name, size, column->
len);
 
 1001                        ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
 
 1006                    } 
else if (strncasecmp(column->
type, 
"tinyint", 1) == 0) {
 
 1008                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1009                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1013                    } 
else if (strncasecmp(column->
type, 
"smallint", 1) == 0) {
 
 1015                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1016                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1020                    } 
else if (strncasecmp(column->
type, 
"mediumint", 1) == 0) {
 
 1024                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1025                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1029                    } 
else if (strncasecmp(column->
type, 
"int", 1) == 0) {
 
 1034                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1035                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1039                    } 
else if (strncasecmp(column->
type, 
"bigint", 1) == 0) {
 
 1045                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1046                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1053                        ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
 
 1057                            "to get a life, rather than writing silly error messages");
 
 1059                    } 
else if (strncasecmp(column->
type, 
"tinyint", 1) == 0) {
 
 1061                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1062                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1066                    } 
else if (strncasecmp(column->
type, 
"smallint", 1) == 0) {
 
 1068                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1069                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1073                    } 
else if (strncasecmp(column->
type, 
"mediumint", 1) == 0) {
 
 1077                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1078                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1082                    } 
else if (strncasecmp(column->
type, 
"int", 1) == 0) {
 
 1087                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1088                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1092                    } 
else if (strncasecmp(column->
type, 
"bigint", 1) == 0) {
 
 1098                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1099                                "the required data length: %d (detected stringtype)\n",                                      \
 
 1104                } 
else if (strncmp(column->
type, 
"float", 5) == 0) {
 
 1109                } 
else if (strncmp(column->
type, 
"datetime", 8) == 0 || strncmp(column->
type, 
"timestamp", 9) == 0) {
 
 1114                } 
else if (strncmp(column->
type, 
"date", 4) == 0) {
 
 1128            ast_log(
LOG_WARNING, 
"Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
 
 
 1154    ast_verb(2, 
"MySQL RealTime driver loaded.\n");
 
 
 1166    ast_verb(2, 
"MySQL RealTime unloaded.\n");
 
 1170        mysql_close(&cur->
handle);
 
 
 1189    ast_verb(2, 
"MySQL RealTime reloaded.\n");
 
 
 1223            if (!(cur = 
ast_calloc(1, 
sizeof(*cur) + strlen(catg) + 1))) {
 
 
 1247        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database user found, using 'asterisk' as default.\n");
 
 1253        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database password found, using 'asterisk' as default.\n");
 
 1259        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database host found, using localhost via socket.\n");
 
 1265        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database name found, using 'asterisk' as default.\n");
 
 1271        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database port found, using 3306 as default.\n");
 
 1274        conn->port = atoi(s);
 
 1278            char *paths[3] = { 
"/tmp/mysql.sock", 
"/var/lib/mysql/mysql.sock", 
"/var/run/mysqld/mysqld.sock" };
 
 1281            for (i = 0; i < 3; i++) {
 
 1282                if (!stat(paths[i], &st)) {
 
 1283                    ast_log(
LOG_WARNING, 
"MySQL RealTime: No database socket found, using '%s' as default.\n", paths[i]);
 
 1288                ast_log(
LOG_WARNING, 
"MySQL RealTime: No database socket found (and unable to detect a suitable path).\n");
 
 1300        ast_log(
LOG_WARNING, 
"MySQL realtime: no requirements setting found, using 'warn' as default.\n");
 
 1302    } 
else if (!strcasecmp(s, 
"createclose")) {
 
 1304    } 
else if (!strcasecmp(s, 
"createchar")) {
 
 1306    } 
else if (!strcasecmp(s, 
"warn")) {
 
 1309        ast_log(
LOG_WARNING, 
"MySQL realtime: unrecognized requirements setting '%s', using 'warn'\n", s);
 
 1318    ast_debug(1, 
"MySQL RealTime database name: %s\n", 
conn->name);
 
 1322        ast_debug(1, 
"MySQL RealTime charset: %s\n", 
conn->charset);
 
 
 1329#ifdef MYSQL_OPT_RECONNECT 
 1330    my_bool trueval = 1;
 
 1337        if (!mysql_init(&
conn->handle)) {
 
 1338            ast_log(
LOG_WARNING, 
"MySQL RealTime: Insufficient memory to allocate MySQL resource.\n");
 
 1339            conn->connected = 0;
 
 1342        if(strlen(
conn->charset) > 2){
 
 1343            char set_names[255];
 
 1344            char statement[512];
 
 1345            snprintf(set_names, 
sizeof(set_names), 
"SET NAMES %s", 
conn->charset);
 
 1346            mysql_real_escape_string(&
conn->handle, statement, set_names, 
sizeof(set_names));
 
 1347            mysql_options(&
conn->handle, MYSQL_INIT_COMMAND, set_names);
 
 1348            mysql_options(&
conn->handle, MYSQL_SET_CHARSET_NAME, 
conn->charset);
 
 1352#ifdef MYSQL_OPT_RECONNECT 
 1355            mysql_options(&
conn->handle, MYSQL_OPT_RECONNECT, &trueval);
 
 1357            ast_debug(1, 
"MySQL RealTime: Successfully connected to database.\n");
 
 1358            conn->connected = 1;
 
 1363            ast_debug(1, 
"MySQL RealTime: Cannot Connect (%d): %s\n", mysql_errno(&
conn->handle), mysql_error(&
conn->handle));
 
 1364            conn->connected = 0;
 
 1365            conn->connect_time = 0;
 
 1371        if (mysql_ping(&
conn->handle) != 0 && (usleep(1) + 2 > 0) && mysql_ping(&
conn->handle) != 0) {
 
 1372            conn->connected = 0;
 
 1373            conn->connect_time = 0;
 
 1374            ast_log(
LOG_ERROR, 
"MySQL RealTime: Ping failed (%d).  Trying an explicit reconnect.\n", mysql_errno(&
conn->handle));
 
 1375            ast_debug(1, 
"MySQL RealTime: Server Error (%d): %s\n", mysql_errno(&
conn->handle), mysql_error(&
conn->handle));
 
 1376            goto reconnect_tryagain;
 
 1379        if (!
conn->connected) {
 
 1380            conn->connected = 1;
 
 1384        if (mysql_select_db(&
conn->handle, 
conn->name) != 0) {
 
 1385            ast_log(
LOG_WARNING, 
"MySQL RealTime: Unable to select database: %s. Still Connected (%u) - %s.\n", 
conn->name, mysql_errno(&
conn->handle), mysql_error(&
conn->handle));
 
 1389        ast_debug(1, 
"MySQL RealTime: Connection okay.\n");
 
 
 1402        e->
command = 
"realtime mysql cache";
 
 1404            "Usage: realtime mysql cache [<database> <table>]\n" 
 1405            "       Shows table cache for the MySQL RealTime driver\n";
 
 1408        if (
a->argc < 4 || 
a->argc > 5) {
 
 1411        l = strlen(
a->word);
 
 1426                if (!strncasecmp(
a->word, cur->
unique_name, l) && ++which > 
a->n) {
 
 1443    } 
else if (
a->argc == 4) {
 
 1455            ast_cli(
a->fd, 
"No tables cached within %s database\n", 
a->argv[3]);
 
 1457    } 
else if (
a->argc == 5) {
 
 1461            ast_cli(
a->fd, 
"Columns for Table Cache '%s':\n", 
a->argv[3]);
 
 1462            ast_cli(
a->fd, 
"%-20.20s %-20.20s %-3.3s\n", 
"Name", 
"Type", 
"Len");
 
 1468            ast_cli(
a->fd, 
"No such table '%s'\n", 
a->argv[3]);
 
 
 1476    char status[256], status2[100] = 
"", 
type[20];
 
 1478    int ctime = 0, found = 0;
 
 1480    int l = 0, which = 0;
 
 1484        e->
command = 
"realtime mysql status";
 
 1486            "Usage: realtime mysql status [<database>]\n" 
 1487            "       Shows connection information for the MySQL RealTime driver\n";
 
 1493                if (!strncasecmp(
a->word, cur->
unique_name, l) && ++which > 
a->n) {
 
 1508        if (
a->argc == 3 || (
a->argc == 4 && !strcasecmp(
a->argv[3], cur->
unique_name))) {
 
 1512                snprintf(
type, 
sizeof(
type), 
"connected to");
 
 1515                snprintf(
type, 
sizeof(
type), 
"configured for");
 
 1526                snprintf(status2, 
sizeof(status2), 
" with username %s", cur->
user);
 
 1531            if (ctime > 31536000) {
 
 1532                ast_cli(
a->fd, 
"%s%s for %.1f years.\n", 
status, status2, (
double)ctime / 31536000.0);
 
 1533            } 
else if (ctime > 86400 * 30) {
 
 1534                ast_cli(
a->fd, 
"%s%s for %d days.\n", 
status, status2, ctime / 86400);
 
 1535            } 
else if (ctime > 86400) {
 
 1536                ast_cli(
a->fd, 
"%s%s for %d days, %d hours.\n", 
status, status2, ctime / 86400, (ctime % 86400) / 3600);
 
 1537            } 
else if (ctime > 3600) {
 
 1538                ast_cli(
a->fd, 
"%s%s for %d hours, %d minutes.\n", 
status, status2, ctime / 3600, (ctime % 3600) / 60);
 
 1539            } 
else if (ctime > 60) {
 
 1540                ast_cli(
a->fd, 
"%s%s for %d minutes.\n", 
status, status2, ctime / 60);
 
 1541            } 
else if (ctime > -1) {
 
 1542                ast_cli(
a->fd, 
"%s%s for %d seconds.\n", 
status, status2, ctime);
 
 1551        ast_cli(
a->fd, 
"No connections configured.\n");
 
 
 1562    .
requires = 
"extconfig",
 
void ast_cli_unregister_multiple(void)
struct sla_ringing_trunk * first
struct sla_ringing_trunk * last
char * strsep(char **str, const char *delims)
char * strcasestr(const char *, const char *)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
static const char config[]
General Asterisk PBX channel definitions.
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
void ast_category_rename(struct ast_category *cat, const char *name)
#define CONFIG_STATUS_FILEMISSING
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
#define ast_variable_new(name, value, filename)
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
@ CONFIG_FLAG_FILEUNCHANGED
int ast_rq_is_int(require_type type)
Check if require type is an integer type.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
require_type
Types used in ast_realtime_require_field.
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
#define AST_RWLIST_REMOVE_HEAD
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_RWLIST_TRAVERSE
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_RWLIST_INSERT_TAIL
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Asterisk locking-related definitions:
#define ast_mutex_init(pmutex)
#define ast_mutex_unlock(a)
#define ast_mutex_destroy(a)
#define ast_mutex_lock(a)
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_REALTIME_DRIVER
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
Options provided by main asterisk program.
static int parse_config(void)
parse the configuration file
static struct ast_config_engine mysql_engine
#define ESCAPE_STRING(buf, var)
static struct tables * find_table(const char *database, const char *tablename)
static struct ast_cli_entry cli_realtime_mysql_status[]
static void destroy_table(struct tables *table)
static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn)
static struct columns * find_column(struct tables *table, const char *colname)
static struct ast_variable * realtime_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
#define RES_CONFIG_MYSQL_CONF_OLD
#define RES_CONFIG_MYSQL_CONF
static char * ESCAPE_CLAUSE
#define IS_SQL_LIKE_CLAUSE(x)
static char * handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int update2_mysql(const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
static struct mysql_conn * find_database(const char *database, int for_write)
static int mysql_reconnect(struct mysql_conn *conn)
static struct ast_config * realtime_multi_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
static struct ast_config * config_mysql(const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags config_flags, const char *unused, const char *who_asked)
static int load_module(void)
#define release_database(a)
static int unload_module(void)
static int require_mysql(const char *database, const char *tablename, va_list ap)
static int update_mysql(const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
static int unload_mysql(const char *database, const char *tablename)
static char * decode_chunk(char *chunk)
#define release_table(table)
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
descriptor for a cli entry.
Configuration engine structure, used to define realtime drivers.
Structure used to handle boolean flags.
Structure for mutex and tracking information.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
char host[MAXHOSTNAMELEN]
enum requirements requirements
struct mysql_conn::@4 list
struct mysql_conn * database
struct tables::mysql_columns columns
structure to hold users read from phoneprov_users.conf
Definitions to aid in the use of thread local storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
#define ast_clear_flag(p, flag)