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)); \ 125 static 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';
153 if (!strcmp(cur->unique_name, whichdb)) {
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);
227 if ((result = mysql_store_result(&dbh->handle))) {
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,
' ')) {
382 ast_log(
LOG_WARNING,
"MySQL RealTime: Failed to query database: %s\n", mysql_error(&dbh->handle));
387 if ((result = mysql_store_result(&dbh->handle))) {
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,
' ')) {
513 ast_log(
LOG_WARNING,
"MySQL RealTime: Failed to query database: %s\n", mysql_error(&dbh->handle));
519 if ((result = mysql_store_result(&dbh->handle))) {
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);
554 static 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);
634 ast_log(
LOG_WARNING,
"MySQL RealTime: Failed to update database: %s\n", mysql_error(&dbh->handle));
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);
732 ast_log(
LOG_WARNING,
"MySQL RealTime: Failed to update database: %s\n", mysql_error(&dbh->handle));
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)) {
798 ast_log(
LOG_WARNING,
"MySQL RealTime: Failed to insert into database: %s\n", mysql_error(&dbh->handle));
805 ast_debug(1,
"MySQL RealTime: row inserted on table: %s\n", table);
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) {
857 ast_log(
LOG_WARNING,
"MySQL RealTime: Failed to delete from database: %s\n", mysql_error(&dbh->handle));
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));
917 if ((result = mysql_store_result(&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",
1002 database, tablename, column->
name, column->
type,
1004 type ==
RQ_DATETIME ?
"datetime" : type ==
RQ_DATE ?
"date" :
"a rather stiff drink");
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", \
1010 tablename, database, column->
name, size); \
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", \
1017 tablename, database, column->
name, size); \
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", \
1026 tablename, database, column->
name, size); \
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", \
1036 tablename, database, column->
name, size); \
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", \
1047 tablename, database, column->
name, size); \
1053 ast_log(
LOG_WARNING,
"Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
1054 database, tablename, column->
name, column->
type,
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", \
1063 tablename, database, column->
name, size); \
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", \
1070 tablename, database, column->
name, size); \
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", \
1079 tablename, database, column->
name, size); \
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", \
1089 tablename, database, column->
name, size); \
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", \
1100 tablename, database, column->
name, size); \
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");
1217 if (!strcmp(cur->unique_name, catg)) {
1223 if (!(cur =
ast_calloc(1,
sizeof(*cur) + strlen(catg) + 1))) {
1228 strcpy(cur->unique_name, catg);
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);
1314 ast_debug(1,
"MySQL RealTime host: %s\n", conn->host);
1315 ast_debug(1,
"MySQL RealTime port: %i\n", conn->port);
1317 ast_debug(1,
"MySQL RealTime socket: %s\n", conn->sock);
1318 ast_debug(1,
"MySQL RealTime database name: %s\n", conn->name);
1319 ast_debug(1,
"MySQL RealTime user: %s\n", conn->user);
1320 ast_debug(1,
"MySQL RealTime password: %s\n", conn->pass);
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);
1351 if (mysql_real_connect(&conn->handle, conn->host, conn->user, conn->pass, conn->name, conn->port, conn->sock, 0)) {
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;
1359 conn->connect_time = time(
NULL);
1362 ast_log(
LOG_ERROR,
"MySQL RealTime: Failed to connect database server %s on %s (err %d). Check debug for more info.\n", conn->name, !
ast_strlen_zero(conn->host) ? conn->host : conn->sock, mysql_errno(&conn->handle));
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;
1381 conn->connect_time = time(
NULL);
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";
1411 l = strlen(a->
word);
1416 if (!strcasecmp(a->
argv[3], cur->
database->unique_name) && !strncasecmp(a->
word, cur->
name, l) && ++which > a->
n) {
1426 if (!strncasecmp(a->
word, cur->unique_name, l) && ++which > a->
n) {
1443 }
else if (a->
argc == 4) {
1448 if (!strcasecmp(cur->
database->unique_name, a->
argv[3])) {
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");
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");
1513 ctime = time(
NULL) - cur->connect_time;
1515 snprintf(
type,
sizeof(
type),
"configured for");
1520 snprintf(status,
sizeof(status),
"%s %s %s@%s, port %d", cur->unique_name,
type, cur->name, cur->host, cur->port);
1522 snprintf(status,
sizeof(status),
"%s %s %s on socket file %s", cur->unique_name,
type, cur->name, cur->sock);
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);
1544 ast_cli(a->
fd,
"%s%s.\n", status, status2);
1551 ast_cli(a->
fd,
"No connections configured.\n");
1562 .requires =
"extconfig",
static int update2_mysql(const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
struct ast_variable * next
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
require_type
Types used in ast_realtime_require_field.
#define AST_CLI_DEFINE(fn, txt,...)
static struct columns * find_column(struct tables *table, const char *colname)
#define AST_LIST_LOCK(head)
Locks a list.
static struct ast_threadstorage scratch_buf
static char * decode_chunk(char *chunk)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
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 struct ast_threadstorage find_buf
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
String manipulation functions.
static int unload_module(void)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
descriptor for a cli entry.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define CONFIG_STATUS_FILEINVALID
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
Structure for variables, used for configurations and for channel variables.
#define RES_CONFIG_MYSQL_CONF_OLD
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
static char * ESCAPE_CLAUSE
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static char * handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ast_mutex_lock(a)
#define ast_strdup(str)
A wrapper for strdup()
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define RES_CONFIG_MYSQL_CONF
static int require_mysql(const char *database, const char *tablename, va_list ap)
Definitions to aid in the use of thread local storage.
void ast_cli(int fd, const char *fmt,...)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define ast_verb(level,...)
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)
Configuration engine structure, used to define realtime drivers.
#define ast_strlen_zero(foo)
static int parse_config(int reload)
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Configuration File Parser.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
void ast_category_rename(struct ast_category *cat, const char *name)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_config_load(filename, flags)
Load a config file.
General Asterisk PBX channel definitions.
static struct ast_threadstorage modify2_buf
struct sla_ringing_trunk * last
#define AST_RWLIST_TRAVERSE
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
static struct ast_config * realtime_multi_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
static struct ast_threadstorage modify_buf
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_variable_new(name, value, filename)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
static struct ast_config_engine mysql_engine
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
#define release_database(a)
#define CONFIG_STATUS_FILEUNCHANGED
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static time_t connect_time
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
struct sla_ringing_trunk * first
char * strcasestr(const char *, const char *)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
static struct columns columns
struct mysql_conn * database
#define ast_calloc(num, len)
A wrapper for calloc()
#define AST_RWLIST_REMOVE_HEAD
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
#define IS_SQL_LIKE_CLAUSE(x)
structure to hold users read from users.conf
Structure used to handle boolean flags.
#define ast_clear_flag(p, flag)
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int update_mysql(const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
#define ESCAPE_STRING(buf, var)
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
#define CONFIG_STATUS_FILEMISSING
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Appends a category to a config.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
#define AST_RWLIST_INSERT_TAIL
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
char * strsep(char **str, const char *delims)
static struct tables * find_table(const char *database, const char *tablename)
static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static struct ast_threadstorage scratch2_buf
static struct ast_cli_entry cli_realtime_mysql_status[]
static void destroy_table(struct tables *table)
struct tables::mysql_columns columns
static void release_table(struct tables *table)
Options provided by main asterisk program.
static struct ast_variable * realtime_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define ast_mutex_init(pmutex)
static struct ast_threadstorage sql_buf
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
#define ast_mutex_destroy(a)
static int load_module(void)
int ast_rq_is_int(require_type type)
Check if require type is an integer type.
static char * handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ASTERISK_GPL_KEY
The text the key() function should return.
static struct ast_threadstorage sql2_buf
Asterisk module definitions.
static struct mysql_conn * find_database(const char *database, int for_write)
Structure for mutex and tracking information.
static int mysql_reconnect(struct mysql_conn *conn)
static int unload_mysql(const char *database, const char *tablename)
#define ast_mutex_unlock(a)
static struct ast_threadstorage modify3_buf