50 #define RES_CONFIG_PGSQL_CONF "res_pgsql.conf" 54 #define has_schema_support (version > 70300 ? 1 : 0) 55 #define USE_BACKSLASH_AS_STRING (version >= 90100 ? 1 : 0) 57 #define MAX_DB_OPTION_SIZE 64 98 #define ESCAPE_STRING(buffer, stringname) \ 100 int len = strlen(stringname); \ 101 struct ast_str *semi = ast_str_thread_get(&semibuf_buf, len * 3 + 1); \ 102 const char *chunk = stringname; \ 103 ast_str_reset(semi); \ 104 for (; *chunk; chunk++) { \ 105 if (strchr(";^", *chunk)) { \ 106 ast_str_append(&semi, 0, "^%02hhX", *chunk); \ 108 ast_str_append(&semi, 0, "%c", *chunk); \ 111 if (ast_str_strlen(semi) > (ast_str_size(buffer) - 1) / 2) { \ 112 ast_str_make_space(&buffer, ast_str_strlen(semi) * 2 + 1); \ 114 PQescapeStringConn(pgsqlConn, ast_str_buffer(buffer), ast_str_buffer(semi), ast_str_size(buffer), &pgresult); \ 144 static int _pgsql_exec(
const char *database,
const char *tablename,
const char *sql, PGresult **
result)
146 ExecStatusType result_status;
149 ast_debug(1,
"PostgreSQL connection not defined, connecting\n");
157 ast_debug(1,
"PostgreSQL connection successful\n");
161 result_status = PQresultStatus(*result);
162 if (result_status != PGRES_COMMAND_OK
163 && result_status != PGRES_TUPLES_OK
164 && result_status != PGRES_NONFATAL_ERROR) {
166 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: Failed to query '%s@%s'.\n", tablename, database);
169 PQresultErrorMessage(*result),
170 PQresStatus(result_status));
174 if (PQstatus(
pgsqlConn) != CONNECTION_OK) {
184 ast_debug(1,
"PostgreSQL query successful: %s\n", sql);
218 static int pgsql_exec(
const char *database,
const char *tablename,
const char *sql, PGresult **
result)
227 while (attempts++ < 2) {
228 ast_debug(1,
"PostgreSQL query attempt %d\n", attempts);
229 res =
_pgsql_exec(database, tablename, sql, result);
244 ast_debug(1,
"PostgreSQL query attempt %d failed, trying again\n", attempts);
257 char *fname, *ftype, *flen, *fnotnull, *fdef;
262 if (!strcasecmp(table->
name, orig_tablename)) {
263 ast_debug(1,
"Found table in cache; now locking\n");
265 ast_debug(1,
"Lock cached table; now returning\n");
271 if (database ==
NULL) {
276 ast_debug(1,
"Table '%s' not found in cache, querying now\n", orig_tablename);
280 char *schemaname, *tablename, *tmp_schemaname, *tmp_tablename;
281 if (strchr(orig_tablename,
'.')) {
283 tmp_tablename = strchr(tmp_schemaname,
'.');
284 *tmp_tablename++ =
'\0';
290 tablename =
ast_alloca(strlen(tmp_tablename) * 2 + 1);
291 PQescapeStringConn(
pgsqlConn, tablename, tmp_tablename, strlen(tmp_tablename),
NULL);
292 schemaname =
ast_alloca(strlen(tmp_schemaname) * 2 + 1);
293 PQescapeStringConn(
pgsqlConn, schemaname, tmp_schemaname, strlen(tmp_schemaname),
NULL);
295 ast_str_set(&sql, 0,
"SELECT a.attname, t.typname, a.attlen, a.attnotnull, pg_catalog.pg_get_expr(d.adbin, d.adrelid) adsrc, a.atttypmod FROM (((pg_catalog.pg_class c INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND c.relname = '%s' AND n.nspname = %s%s%s) INNER JOIN pg_catalog.pg_attribute a ON (NOT a.attisdropped) AND a.attnum > 0 AND a.attrelid = c.oid) INNER JOIN pg_catalog.pg_type t ON t.oid = a.atttypid) LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum ORDER BY n.nspname, c.relname, attnum",
300 tablename =
ast_alloca(strlen(orig_tablename) * 2 + 1);
301 PQescapeStringConn(
pgsqlConn, tablename, orig_tablename, strlen(orig_tablename),
NULL);
303 ast_str_set(&sql, 0,
"SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", tablename);
309 ast_debug(1,
"Query of table structure complete. Now retrieving results.\n");
310 if (exec_result != 0) {
311 ast_log(
LOG_ERROR,
"Failed to query database columns for table %s\n", orig_tablename);
316 if (!(table =
ast_calloc(1,
sizeof(*table) + strlen(orig_tablename) + 1))) {
321 strcpy(table->
name, orig_tablename);
326 for (i = 0; i < rows; i++) {
327 fname = PQgetvalue(
result, i, 0);
328 ftype = PQgetvalue(
result, i, 1);
329 flen = PQgetvalue(
result, i, 2);
330 fnotnull = PQgetvalue(
result, i, 3);
331 fdef = PQgetvalue(
result, i, 4);
332 ast_verb(4,
"Found column '%s' of type '%s'\n", fname, ftype);
334 if (!(column =
ast_calloc(1,
sizeof(*column) + strlen(fname) + strlen(ftype) + 2))) {
335 ast_log(
LOG_ERROR,
"Unable to allocate column element for %s, %s\n", orig_tablename, fname);
341 if (strcmp(flen,
"-1") == 0) {
343 flen = PQgetvalue(
result, i, 5);
344 sscanf(flen,
"%30d", &column->
len);
347 sscanf(flen,
"%30d", &column->
len);
349 column->
name = (
char *)column +
sizeof(*column);
350 column->
type = (
char *)column +
sizeof(*column) + strlen(fname) + 1;
351 strcpy(column->
name, fname);
352 strcpy(column->
type, ftype);
353 if (*fnotnull ==
't') {
372 #define release_table(table) ast_rwlock_unlock(&(table)->lock); 380 if (strcmp(column->
name, colname) == 0) {
387 #define IS_SQL_LIKE_CLAUSE(x) ((x) && ast_ends_with(x, " LIKE")) 388 #define ESCAPE_CLAUSE (USE_BACKSLASH_AS_STRING ? " ESCAPE '\\'" : " ESCAPE '\\\\'") 427 "PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
438 if (!strchr(field->
name,
' ')) {
455 while ((field = field->
next)) {
457 if (!strchr(field->
name,
' ')) {
485 if (PQntuples(
result) > 0) {
487 int numFields = PQnfields(
result);
488 char **fieldnames =
NULL;
490 ast_debug(1,
"PostgreSQL RealTime: Found a row.\n");
492 if (!(fieldnames =
ast_calloc(1, numFields *
sizeof(
char *)))) {
496 for (i = 0; i < numFields; i++)
497 fieldnames[i] = PQfname(
result, i);
498 for (i = 0; i < numFields; i++) {
499 stringp = PQgetvalue(
result, 0, i);
501 chunk =
strsep(&stringp,
";");
516 ast_debug(1,
"Postgresql RealTime: Could not find any rows in table %s@%s.\n", tablename, database);
527 int num_rows = 0, pgresult;
531 const char *initfield =
NULL;
567 "PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
578 if ((op = strchr(initfield,
' '))) {
585 if (!strchr(field->
name,
' ')) {
604 while ((field = field->
next)) {
606 if (!strchr(field->
name,
' ')) {
637 ExecStatusType result_status = PQresultStatus(
result);
638 if (result_status != PGRES_COMMAND_OK
639 && result_status != PGRES_TUPLES_OK
640 && result_status != PGRES_NONFATAL_ERROR) {
642 "PostgreSQL RealTime: Failed to query %s@%s. Check debug for more info.\n", table, database);
644 ast_debug(1,
"PostgreSQL RealTime: Query Failed because: %s (%s)\n",
645 PQresultErrorMessage(
result), PQresStatus(result_status));
654 if ((num_rows = PQntuples(
result)) > 0) {
655 int numFields = PQnfields(
result);
658 char **fieldnames =
NULL;
660 ast_debug(1,
"PostgreSQL RealTime: Found %d rows.\n", num_rows);
662 if (!(fieldnames =
ast_calloc(1, numFields *
sizeof(
char *)))) {
667 for (i = 0; i < numFields; i++)
668 fieldnames[i] = PQfname(
result, i);
670 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
676 for (i = 0; i < numFields; i++) {
677 stringp = PQgetvalue(
result, rowIndex, i);
679 chunk =
strsep(&stringp,
";");
681 if (initfield && !strcmp(initfield, fieldnames[i])) {
693 ast_debug(1,
"PostgreSQL RealTime: Could not find any rows in table %s.\n", table);
701 static int update_pgsql(
const char *database,
const char *tablename,
const char *keyfield,
705 int numrows = 0, pgresult;
723 if (!(table =
find_table(database, tablename))) {
742 "PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
754 if (strcmp(column->
name, field->
name) == 0) {
760 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: Updating on column '%s', but that column does not exist within the table '%s'!\n", field->
name, tablename);
778 while ((field = field->
next)) {
780 ast_log(
LOG_NOTICE,
"Attempted to update column '%s' in table '%s', but column does not exist!\n", field->
name, tablename);
798 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: detected invalid input: '%s'\n", lookup);
812 ExecStatusType result_status = PQresultStatus(
result);
813 if (result_status != PGRES_COMMAND_OK
814 && result_status != PGRES_TUPLES_OK
815 && result_status != PGRES_NONFATAL_ERROR) {
817 "PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
819 ast_debug(1,
"PostgreSQL RealTime: Query Failed because: %s (%s)\n",
820 PQresultErrorMessage(
result), PQresStatus(result_status));
826 numrows = atoi(PQcmdTuples(
result));
829 ast_debug(1,
"PostgreSQL RealTime: Updated %d rows on table: %s\n", numrows, tablename);
838 return (
int) numrows;
846 int numrows = 0, pgresult,
first = 1;
864 if (!escapebuf || !sql || !where) {
869 if (!(table =
find_table(database, tablename))) {
888 for (field = lookup_fields; field; field = field->
next) {
890 ast_log(
LOG_ERROR,
"Attempted to update based on criteria column '%s' (%s@%s), but that column does not exist!\n", field->
name, tablename, database);
909 "PostgreSQL RealTime: Realtime update requires at least 1 parameter and 1 value to search on.\n");
921 for (field = update_fields; field; field = field->
next) {
924 ast_log(
LOG_NOTICE,
"Attempted to update column '%s' in table '%s@%s', but column does not exist!\n", field->
name, tablename, database);
951 numrows = atoi(PQcmdTuples(
result));
954 ast_debug(1,
"PostgreSQL RealTime: Updated %d rows on table: %s\n", numrows, tablename);
963 return (
int) numrows;
1003 "PostgreSQL RealTime: Realtime storage requires at least 1 parameter and 1 value to store.\n");
1018 while ((field = field->
next)) {
1034 numrows = atoi(PQcmdTuples(
result));
1037 ast_debug(1,
"PostgreSQL RealTime: row inserted on table: %s.\n", table);
1085 "PostgreSQL RealTime: Realtime destroy requires at least 1 parameter and 1 value to search on.\n");
1100 for (field = fields; field; field = field->
next) {
1114 numrows = atoi(PQcmdTuples(
result));
1117 ast_debug(1,
"PostgreSQL RealTime: Deleted %d rows on table: %s\n", numrows, table);
1126 return (
int) numrows;
1134 struct ast_flags flags,
const char *suggested_incl,
const char *who_asked)
1142 int last_cat_metric = 0;
1157 ast_str_set(&sql, 0,
"SELECT category, var_name, var_val, cat_metric FROM %s " 1158 "WHERE filename='%s' and commented=0 " 1159 "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ", table, file);
1171 if ((num_rows = PQntuples(
result)) > 0) {
1174 ast_debug(1,
"PostgreSQL RealTime: Found %ld rows.\n", num_rows);
1176 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
1177 char *field_category = PQgetvalue(
result, rowIndex, 0);
1178 char *field_var_name = PQgetvalue(
result, rowIndex, 1);
1179 char *field_var_val = PQgetvalue(
result, rowIndex, 2);
1180 char *field_cat_metric = PQgetvalue(
result, rowIndex, 3);
1181 if (!strcmp(field_var_name,
"#include")) {
1189 if (strcmp(last, field_category) || last_cat_metric != atoi(field_cat_metric)) {
1195 last_cat_metric = atoi(field_cat_metric);
1203 "PostgreSQL RealTime: Could not find config '%s' in database.\n", file);
1211 static int require_pgsql(
const char *database,
const char *tablename, va_list ap)
1227 ast_log(
LOG_WARNING,
"Table %s not found in database. This table should exist if you're using realtime.\n", tablename);
1231 while ((elm = va_arg(ap,
char *))) {
1233 size = va_arg(ap,
unsigned int);
1235 if (strcmp(column->
name, elm) == 0) {
1237 if ((strncmp(column->
type,
"char", 4) == 0 || strncmp(column->
type,
"varchar", 7) == 0 || strcmp(column->
type,
"bpchar") == 0)) {
1238 if ((size > column->
len) && column->
len != -1) {
1239 ast_log(
LOG_WARNING,
"Column '%s' should be at least %d long, but is only %d long.\n", column->
name, size, column->
len);
1242 }
else if (strncmp(column->
type,
"int", 3) == 0) {
1243 int typesize = atoi(column->
type + 3);
1249 ast_log(
LOG_WARNING,
"Column '%s' may not be large enough for the required data length: %d\n", column->
name, size);
1253 ast_log(
LOG_WARNING,
"Column '%s' may not be large enough for the required data length: %d\n", column->
name, size);
1256 ast_log(
LOG_WARNING,
"Column '%s' is of the incorrect type: (need %s(%d) but saw %s)\n",
1262 "a rather stiff drink ",
1263 size, column->
type);
1266 }
else if (strncmp(column->
type,
"float", 5) == 0) {
1271 }
else if (strncmp(column->
type,
"timestamp", 9) == 0) {
1286 ast_log(
LOG_WARNING,
"Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
1297 snprintf(fieldtype,
sizeof(fieldtype),
"CHAR(%u)",
1298 size < 15 ? size * 2 :
1299 (size * 3 / 2 > 255) ? 255 : size * 3 / 2);
1301 snprintf(fieldtype,
sizeof(fieldtype),
"INT2");
1303 snprintf(fieldtype,
sizeof(fieldtype),
"INT4");
1305 snprintf(fieldtype,
sizeof(fieldtype),
"INT8");
1308 snprintf(fieldtype,
sizeof(fieldtype),
"CHAR(20)");
1310 snprintf(fieldtype,
sizeof(fieldtype),
"FLOAT8");
1312 snprintf(fieldtype,
sizeof(fieldtype),
"DATE");
1314 snprintf(fieldtype,
sizeof(fieldtype),
"TIMESTAMP");
1320 ast_str_set(&sql, 0,
"ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, fieldtype);
1321 ast_debug(1,
"About to lock pgsql_lock (running alter on table '%s' to add column '%s')\n", tablename, elm);
1324 ast_debug(1,
"About to run ALTER query on table '%s' to add column '%s'\n", tablename, elm);
1332 ast_debug(1,
"Finished running ALTER query on table '%s'\n", tablename);
1333 if (PQresultStatus(result) != PGRES_COMMAND_OK) {
1357 ast_debug(2,
"About to lock table cache list\n");
1359 ast_debug(2,
"About to traverse table cache list\n");
1361 if (strcmp(cur->
name, tablename) == 0) {
1362 ast_debug(2,
"About to remove matching cache entry\n");
1364 ast_debug(2,
"About to destroy matching cache entry\n");
1366 ast_debug(1,
"Cache entry '%s@%s' destroyed\n", tablename, database);
1373 return cur ? 0 : -1;
1463 "PostgreSQL RealTime: No database user found, using 'asterisk' as default.\n");
1464 strcpy(
dbuser,
"asterisk");
1471 "PostgreSQL RealTime: No database password found, using 'asterisk' as default.\n");
1472 strcpy(
dbpass,
"asterisk");
1479 "PostgreSQL RealTime: No database host found, using localhost via socket.\n");
1487 "PostgreSQL RealTime: No database name found, using 'asterisk' as default.\n");
1488 strcpy(
dbname,
"asterisk");
1495 "PostgreSQL RealTime: No database port found, using 5432 as default.\n");
1511 "PostgreSQL RealTime: No database socket found, using '/tmp/.s.PGSQL.%d' as default.\n",
dbport);
1519 "PostgreSQL RealTime: no requirements setting found, using 'warn' as default.\n");
1521 }
else if (!strcasecmp(s,
"createclose")) {
1523 }
else if (!strcasecmp(s,
"createchar")) {
1543 "PostgreSQL RealTime: Couldn't establish connection. Check debug.\n");
1544 ast_debug(1,
"PostgreSQL RealTime: Cannot Connect: %s\n", PQerrorMessage(
pgsqlConn));
1547 ast_verb(2,
"PostgreSQL RealTime reloaded.\n");
1557 char my_database[50];
1564 if (PQstatus(
pgsqlConn) == CONNECTION_OK) {
1578 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: Failed to allocate memory for connection string.\n");
1582 ast_str_set(&conn_info, 0,
"host=%s port=%d dbname=%s user=%s",
1599 ast_debug(1,
"PostgreSQL RealTime: Successfully connected to database.\n");
1605 "PostgreSQL RealTime: Failed to connect database %s on %s: %s\n",
1606 my_database,
dbhost, PQresultErrorMessage(
NULL));
1610 ast_debug(1,
"PostgreSQL RealTime: One or more of the parameters in the config does not pass our validity checks.\n");
1623 e->
command =
"realtime show pgsql cache";
1625 "Usage: realtime show pgsql cache [<table>]\n" 1626 " Shows table cache for the PostgreSQL RealTime driver\n";
1632 l = strlen(a->
word);
1636 if (!strncasecmp(a->
word, cur->
name, l) && ++which > a->
n) {
1652 }
else if (a->
argc == 5) {
1656 ast_cli(a->
fd,
"Columns for Table Cache '%s':\n", a->
argv[4]);
1657 ast_cli(a->
fd,
"%-20.20s %-20.20s %-3.3s %-8.8s\n",
"Name",
"Type",
"Len",
"Nullable");
1671 char connection_info[256];
1672 char credentials[100] =
"";
1678 e->
command =
"realtime show pgsql status";
1680 "Usage: realtime show pgsql status\n" 1681 " Shows connection information for the PostgreSQL RealTime driver\n";
1691 snprintf(connection_info,
sizeof(connection_info),
"%s@%s, port %d",
dbname,
dbhost,
dbport);
1693 snprintf(connection_info,
sizeof(connection_info),
"%s on socket file %s",
dbname,
dbsock);
1695 snprintf(connection_info,
sizeof(connection_info),
"%s@%s",
dbname,
dbhost);
1698 snprintf(credentials,
sizeof(credentials),
" with username %s",
dbuser);
1705 snprintf(buf,
sizeof(buf),
"Connected to %s%s for ", connection_info, credentials);
1709 ast_cli(a->
fd,
"Unable to connect %s%s\n", connection_info, credentials);
1721 .requires =
"extconfig",
#define has_schema_support
struct ast_variable * next
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
static struct ast_config * config_pgsql(const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
require_type
Types used in ast_realtime_require_field.
char * ast_realtime_decode_chunk(char *chunk)
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a singl...
#define ast_rwlock_rdlock(a)
#define AST_CLI_DEFINE(fn, txt,...)
static struct ast_variable * realtime_pgsql(const char *database, const char *tablename, const struct ast_variable *fields)
#define AST_LIST_LOCK(head)
Locks a list.
static void destroy_table(struct tables *table)
Asterisk locking-related definitions:
static struct ast_config * realtime_multi_pgsql(const char *database, const char *table, const struct ast_variable *fields)
Asterisk main include file. File version handling, generic pbx functions.
static int store_pgsql(const char *database, const char *table, const struct ast_variable *fields)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
static PGconn * pgsqlConn
static struct ast_threadstorage escapebuf_buf
#define ast_rwlock_destroy(rwlock)
static char * handle_cli_realtime_pgsql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char dbname[MAX_DB_OPTION_SIZE]
#define release_table(table)
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
Structure for variables, used for configurations and for channel variables.
static int unload_pgsql(const char *database, const char *tablename)
static int _pgsql_exec(const char *database, const char *tablename, const char *sql, PGresult **result)
Helper function for pgsql_exec. For running querys, use pgsql_exec()
static int update_pgsql(const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *fields)
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
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 struct ast_threadstorage buf2
#define ast_mutex_lock(a)
#define ast_strdup(str)
A wrapper for strdup()
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
static ast_mutex_t pgsql_lock
void ast_cli(int fd, const char *fmt,...)
#define ast_rwlock_unlock(a)
static char dbpass[MAX_DB_OPTION_SIZE]
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
static struct tables * find_table(const char *database, const char *orig_tablename)
#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)
#define ESCAPE_STRING(buffer, stringname)
Configuration engine structure, used to define realtime drivers.
#define ast_strlen_zero(foo)
static enum @451 requirements
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
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.
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.
#define RES_CONFIG_PGSQL_CONF
General Asterisk PBX channel definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static char * handle_cli_realtime_pgsql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_threadstorage where_buf
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#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
static char dbappname[MAX_DB_OPTION_SIZE]
#define ast_variable_new(name, value, filename)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static int pgsql_reconnect(const char *database)
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Core PBX routines and definitions.
#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.
static int destroy_pgsql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *fields)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static struct ast_cli_entry cli_realtime[]
#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 ...
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
#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 ast_threadstorage semibuf_buf
static struct ast_threadstorage buf1
static struct columns columns
struct mysql_conn * database
#define ast_calloc(num, len)
A wrapper for calloc()
static struct ast_threadstorage findtable_buf
static int require_pgsql(const char *database, const char *tablename, va_list ap)
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
Module has failed to load, may be in an inconsistent state.
static int pgsql_exec(const char *database, const char *tablename, const char *sql, PGresult **result)
Do a postgres query, with reconnection support.
static int update2_pgsql(const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
Structure used to handle boolean flags.
static struct ast_threadstorage sql_buf
static char dbuser[MAX_DB_OPTION_SIZE]
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",)
void ast_cli_print_timestr_fromseconds(int fd, int seconds, const char *prefix)
Print on cli a duration in seconds in format s year(s), s week(s), s day(s), s hour(s), s second(s)
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.
#define ast_rwlock_wrlock(a)
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
char * strsep(char **str, const char *delims)
Structure for rwlock and tracking information.
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct tables::mysql_columns columns
static struct columns * find_column(struct tables *t, const char *colname)
static char dbsock[MAX_DB_OPTION_SIZE]
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
static int parse_config(int reload)
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
static struct ast_config_engine pgsql_engine
static time_t connect_time
int ast_rq_is_int(require_type type)
Check if require type is an integer type.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define DEBUG_ATLEAST(level)
static char dbhost[MAX_DB_OPTION_SIZE]
Asterisk module definitions.
#define IS_SQL_LIKE_CLAUSE(x)
static int load_module(void)
#define AST_MUTEX_DEFINE_STATIC(mutex)
#define MAX_DB_OPTION_SIZE
static int unload_module(void)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ast_mutex_unlock(a)