Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
cel_pgsql.c File Reference

PostgreSQL CEL logger. More...

#include "asterisk.h"
#include <libpq-fe.h>
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/cel.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
Include dependency graph for cel_pgsql.c:

Go to the source code of this file.

Data Structures

struct  columns
 
struct  psql_columns
 

Macros

#define CEL_SHOW_USERDEF_DEFAULT   0
 show_user_def is off by default More...
 
#define DATE_FORMAT   "%Y-%m-%d %T.%6q"
 
#define LENGTHEN_BUF(size, var_sql)
 
#define LENGTHEN_BUF1(size)   LENGTHEN_BUF(size, sql);
 
#define LENGTHEN_BUF2(size)   LENGTHEN_BUF(size, sql2);
 
#define PGSQL_BACKEND_NAME   "CEL PGSQL backend"
 
#define PGSQL_MIN_VERSION_SCHEMA   70300
 
#define SEP   (first ? "" : ",")
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static int my_load_module (int reload)
 
static int my_unload_module (void)
 
static void pgsql_log (struct ast_event *event)
 
static void pgsql_reconnect (void)
 
static int process_my_load_module (struct ast_config *cfg)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PostgreSQL CEL Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cel", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static unsigned char cel_show_user_def
 
static char * config = "cel_pgsql.conf"
 
static PGconn * conn = NULL
 
static int connected = 0
 
static int maxsize = 512
 
static int maxsize2 = 512
 
static char * pgappname
 
static char * pgdbname
 
static char * pgdbport
 
static char * pgdbuser
 
static char * pghostname
 
static char * pgpassword
 
static ast_mutex_t pgsql_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct psql_columns psql_columns = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static PGresult * result = NULL
 
static char * schema
 
static char * table
 
static int usegmtime = 0
 

Detailed Description

PostgreSQL CEL logger.

Author
Steve Murphy murf@.nosp@m.digi.nosp@m.um.co.nosp@m.m PostgreSQL http://www.postgresql.org/

See also

Definition in file cel_pgsql.c.

Macro Definition Documentation

◆ CEL_SHOW_USERDEF_DEFAULT

#define CEL_SHOW_USERDEF_DEFAULT   0

show_user_def is off by default

Definition at line 80 of file cel_pgsql.c.

Referenced by process_my_load_module().

◆ DATE_FORMAT

#define DATE_FORMAT   "%Y-%m-%d %T.%6q"

Definition at line 57 of file cel_pgsql.c.

Referenced by pgsql_log().

◆ LENGTHEN_BUF

#define LENGTHEN_BUF (   size,
  var_sql 
)

Definition at line 101 of file cel_pgsql.c.

◆ LENGTHEN_BUF1

#define LENGTHEN_BUF1 (   size)    LENGTHEN_BUF(size, sql);

Definition at line 115 of file cel_pgsql.c.

Referenced by pgsql_log().

◆ LENGTHEN_BUF2

#define LENGTHEN_BUF2 (   size)    LENGTHEN_BUF(size, sql2);

Definition at line 117 of file cel_pgsql.c.

Referenced by pgsql_log().

◆ PGSQL_BACKEND_NAME

#define PGSQL_BACKEND_NAME   "CEL PGSQL backend"

Definition at line 59 of file cel_pgsql.c.

Referenced by my_load_module(), and my_unload_module().

◆ PGSQL_MIN_VERSION_SCHEMA

#define PGSQL_MIN_VERSION_SCHEMA   70300

Definition at line 61 of file cel_pgsql.c.

Referenced by process_my_load_module().

◆ SEP

#define SEP   (first ? "" : ",")

Referenced by pgsql_log().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 713 of file cel_pgsql.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 713 of file cel_pgsql.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 713 of file cel_pgsql.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 696 of file cel_pgsql.c.

References my_load_module().

Referenced by reload().

697 {
698  return my_load_module(0);
699 }
static int my_load_module(int reload)
Definition: cel_pgsql.c:669

◆ my_load_module()

static int my_load_module ( int  reload)
static

Definition at line 669 of file cel_pgsql.c.

References ast_cel_backend_register(), ast_config_destroy(), ast_config_load, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_WARNING, my_unload_module(), NULL, PGSQL_BACKEND_NAME, pgsql_log(), and process_my_load_module().

Referenced by load_module(), and reload().

670 {
671  struct ast_config *cfg;
672  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
673 
674  if ((cfg = ast_config_load(config, config_flags)) == NULL || cfg == CONFIG_STATUS_FILEINVALID) {
675  ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CEL's: %s\n", config);
677  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
679  }
680 
681  if (reload) {
683  }
684 
686  ast_config_destroy(cfg);
687 
689  ast_log(LOG_WARNING, "Unable to subscribe to CEL events for pgsql\n");
691  }
692 
694 }
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
Definition: cel.c:1740
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
#define NULL
Definition: resample.c:96
static int my_unload_module(void)
Definition: cel_pgsql.c:404
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static int reload(void)
Definition: cel_pgsql.c:701
#define CONFIG_STATUS_FILEUNCHANGED
#define PGSQL_BACKEND_NAME
Definition: cel_pgsql.c:59
static int process_my_load_module(struct ast_config *cfg)
Definition: cel_pgsql.c:458
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Structure used to handle boolean flags.
Definition: utils.h:199
static char * config
Definition: cel_pgsql.c:63
static void pgsql_log(struct ast_event *event)
Definition: cel_pgsql.c:149

◆ my_unload_module()

static int my_unload_module ( void  )
static

Definition at line 404 of file cel_pgsql.c.

References ast_cel_backend_unregister(), ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, conn, columns::list, NULL, pgappname, pgdbname, pgdbport, pgdbuser, pghostname, pgpassword, PGSQL_BACKEND_NAME, schema, and table.

Referenced by my_load_module(), and unload_module().

405 {
406  struct columns *current;
407 
410  if (conn) {
411  PQfinish(conn);
412  conn = NULL;
413  }
414  if (pghostname) {
416  pghostname = NULL;
417  }
418  if (pgdbname) {
420  pgdbname = NULL;
421  }
422  if (pgdbuser) {
424  pgdbuser = NULL;
425  }
426  if (pgpassword) {
428  pgpassword = NULL;
429  }
430  if (pgappname) {
432  pgappname = NULL;
433  }
434  if (pgdbport) {
436  pgdbport = NULL;
437  }
438  if (table) {
439  ast_free(table);
440  table = NULL;
441  }
442  if (schema) {
443  ast_free(schema);
444  schema = NULL;
445  }
446  while ((current = AST_RWLIST_REMOVE_HEAD(&psql_columns, list))) {
447  ast_free(current);
448  }
450  return 0;
451 }
struct columns::@8 list
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static char * pgappname
Definition: cel_pgsql.c:69
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static char * table
Definition: cel_pgsql.c:71
static char * pgdbname
Definition: cel_pgsql.c:66
static PGconn * conn
Definition: cel_pgsql.c:87
#define NULL
Definition: resample.c:96
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition: cel.c:1728
#define PGSQL_BACKEND_NAME
Definition: cel_pgsql.c:59
static char * pghostname
Definition: cel_pgsql.c:65
static char * pgdbuser
Definition: cel_pgsql.c:67
#define ast_free(a)
Definition: astmm.h:182
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:843
static char * pgpassword
Definition: cel_pgsql.c:68
static char * pgdbport
Definition: cel_pgsql.c:70
static char * schema
Definition: cel_pgsql.c:72

◆ pgsql_log()

static void pgsql_log ( struct ast_event event)
static

Definition at line 149 of file cel_pgsql.c.

References ast_cel_event_record::account_code, ast_cel_event_record::amaflag, ast_cel_event_record::application_data, ast_cel_event_record::application_name, AST_CEL_EVENT_RECORD_VERSION, ast_cel_fill_record(), AST_CEL_USER_DEFINED, ast_debug, ast_free, ast_localtime(), ast_log, ast_malloc, ast_mutex_lock, ast_mutex_unlock, ast_realloc, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_strlen(), ast_strftime(), buf, ast_cel_event_record::caller_id_ani, ast_cel_event_record::caller_id_dnid, ast_cel_event_record::caller_id_name, ast_cel_event_record::caller_id_num, ast_cel_event_record::caller_id_rdnis, cel_show_user_def, ast_cel_event_record::channel_name, conn, connected, ast_cel_event_record::context, DATE_FORMAT, ast_cel_event_record::event_name, ast_cel_event_record::event_time, ast_cel_event_record::event_type, ast_cel_event_record::extension, ast_cel_event_record::extra, columns::first, LENGTHEN_BUF1, LENGTHEN_BUF2, ast_cel_event_record::linked_id, columns::list, LOG_ERROR, LOG_NOTICE, LOG_WARNING, maxsize, maxsize2, columns::name, NULL, ast_cel_event_record::peer, ast_cel_event_record::peer_account, pgdbname, pgdbuser, pghostname, pgpassword, pgsql_lock, pgsql_reconnect(), result, SEP, table, columns::type, ast_cel_event_record::unique_id, usegmtime, ast_cel_event_record::user_defined_name, ast_cel_event_record::user_field, value, and ast_cel_event_record::version.

Referenced by my_load_module().

150 {
151  struct ast_tm tm;
152  char timestr[128];
153  char *pgerror;
154  struct ast_cel_event_record record = {
156  };
157 
158  if (ast_cel_fill_record(event, &record)) {
159  return;
160  }
161 
163 
164  ast_localtime(&record.event_time, &tm, usegmtime ? "GMT" : NULL);
165  ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
166 
167  if ((!connected) && pghostname && pgdbuser && pgpassword && pgdbname) {
168  pgsql_reconnect();
169  if (PQstatus(conn) != CONNECTION_BAD) {
170  connected = 1;
171  } else {
172  pgerror = PQerrorMessage(conn);
173  ast_log(LOG_ERROR, "cel_pgsql: Unable to connect to database server %s. Calls will not be logged!\n", pghostname);
174  ast_log(LOG_ERROR, "cel_pgsql: Reason: %s\n", pgerror);
175  PQfinish(conn);
176  conn = NULL;
177  }
178  }
179  if (connected) {
180  struct columns *cur;
181  struct ast_str *sql = ast_str_create(maxsize), *sql2 = ast_str_create(maxsize2);
182  char buf[257];
183  char *escapebuf = NULL;
184  const char *value;
185  int first = 1;
186  size_t bufsize = 513;
187 
188  escapebuf = ast_malloc(bufsize);
189  if (!escapebuf || !sql || !sql2) {
190  goto ast_log_cleanup;
191  }
192 
193  ast_str_set(&sql, 0, "INSERT INTO %s (", table);
194  ast_str_set(&sql2, 0, " VALUES (");
195 
196 #define SEP (first ? "" : ",")
197 
199  AST_RWLIST_TRAVERSE(&psql_columns, cur, list) {
200  LENGTHEN_BUF1(strlen(cur->name) + 2);
201  ast_str_append(&sql, 0, "%s\"%s\"", SEP, cur->name);
202 
203  if (strcmp(cur->name, "eventtime") == 0) {
204  if (strncmp(cur->type, "int", 3) == 0) {
205  LENGTHEN_BUF2(13);
206  ast_str_append(&sql2, 0, "%s%ld", SEP, (long) record.event_time.tv_sec);
207  } else if (strncmp(cur->type, "float", 5) == 0) {
208  LENGTHEN_BUF2(31);
209  ast_str_append(&sql2, 0, "%s%f",
210  SEP,
211  (double) record.event_time.tv_sec +
212  (double) record.event_time.tv_usec / 1000000.0);
213  } else {
214  /* char, hopefully */
215  LENGTHEN_BUF2(31);
216  ast_localtime(&record.event_time, &tm, usegmtime ? "GMT" : NULL);
217  ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
218  ast_str_append(&sql2, 0, "%s'%s'", SEP, buf);
219  }
220  } else if (strcmp(cur->name, "eventtype") == 0) {
221  if (cur->type[0] == 'i') {
222  /* Get integer, no need to escape anything */
223  LENGTHEN_BUF2(5);
224  ast_str_append(&sql2, 0, "%s%d", SEP, (int) record.event_type);
225  } else if (strncmp(cur->type, "float", 5) == 0) {
226  LENGTHEN_BUF2(31);
227  ast_str_append(&sql2, 0, "%s%f", SEP, (double) record.event_type);
228  } else {
229  /* Char field, probably */
230  const char *event_name;
231 
232  event_name = (!cel_show_user_def
233  && record.event_type == AST_CEL_USER_DEFINED)
234  ? record.user_defined_name : record.event_name;
235  LENGTHEN_BUF2(strlen(event_name) + 1);
236  ast_str_append(&sql2, 0, "%s'%s'", SEP, event_name);
237  }
238  } else if (strcmp(cur->name, "amaflags") == 0) {
239  if (strncmp(cur->type, "int", 3) == 0) {
240  /* Integer, no need to escape anything */
241  LENGTHEN_BUF2(13);
242  ast_str_append(&sql2, 0, "%s%u", SEP, record.amaflag);
243  } else {
244  /* Although this is a char field, there are no special characters in the values for these fields */
245  LENGTHEN_BUF2(31);
246  ast_str_append(&sql2, 0, "%s'%u'", SEP, record.amaflag);
247  }
248  } else {
249  /* Arbitrary field, could be anything */
250  if (strcmp(cur->name, "userdeftype") == 0) {
251  value = record.user_defined_name;
252  } else if (strcmp(cur->name, "cid_name") == 0) {
253  value = record.caller_id_name;
254  } else if (strcmp(cur->name, "cid_num") == 0) {
255  value = record.caller_id_num;
256  } else if (strcmp(cur->name, "cid_ani") == 0) {
257  value = record.caller_id_ani;
258  } else if (strcmp(cur->name, "cid_rdnis") == 0) {
259  value = record.caller_id_rdnis;
260  } else if (strcmp(cur->name, "cid_dnid") == 0) {
261  value = record.caller_id_dnid;
262  } else if (strcmp(cur->name, "exten") == 0) {
263  value = record.extension;
264  } else if (strcmp(cur->name, "context") == 0) {
265  value = record.context;
266  } else if (strcmp(cur->name, "channame") == 0) {
267  value = record.channel_name;
268  } else if (strcmp(cur->name, "appname") == 0) {
269  value = record.application_name;
270  } else if (strcmp(cur->name, "appdata") == 0) {
271  value = record.application_data;
272  } else if (strcmp(cur->name, "accountcode") == 0) {
273  value = record.account_code;
274  } else if (strcmp(cur->name, "peeraccount") == 0) {
275  value = record.peer_account;
276  } else if (strcmp(cur->name, "uniqueid") == 0) {
277  value = record.unique_id;
278  } else if (strcmp(cur->name, "linkedid") == 0) {
279  value = record.linked_id;
280  } else if (strcmp(cur->name, "userfield") == 0) {
281  value = record.user_field;
282  } else if (strcmp(cur->name, "peer") == 0) {
283  value = record.peer;
284  } else if (strcmp(cur->name, "extra") == 0) {
285  value = record.extra;
286  } else {
287  value = NULL;
288  }
289 
290  if (value == NULL) {
291  ast_str_append(&sql2, 0, "%sDEFAULT", SEP);
292  } else if (strncmp(cur->type, "int", 3) == 0) {
293  long long whatever;
294  if (value && sscanf(value, "%30lld", &whatever) == 1) {
295  LENGTHEN_BUF2(26);
296  ast_str_append(&sql2, 0, "%s%lld", SEP, whatever);
297  } else {
298  LENGTHEN_BUF2(2);
299  ast_str_append(&sql2, 0, "%s0", SEP);
300  }
301  } else if (strncmp(cur->type, "float", 5) == 0) {
302  long double whatever;
303  if (value && sscanf(value, "%30Lf", &whatever) == 1) {
304  LENGTHEN_BUF2(51);
305  ast_str_append(&sql2, 0, "%s%30Lf", SEP, whatever);
306  } else {
307  LENGTHEN_BUF2(2);
308  ast_str_append(&sql2, 0, "%s0", SEP);
309  }
310  /* XXX Might want to handle dates, times, and other misc fields here XXX */
311  } else {
312  if (value) {
313  size_t required_size = strlen(value) * 2 + 1;
314 
315  /* If our argument size exceeds our buffer, grow it,
316  * as PQescapeStringConn() expects the buffer to be
317  * adequitely sized and does *NOT* do size checking.
318  */
319  if (required_size > bufsize) {
320  char *tmpbuf = ast_realloc(escapebuf, required_size);
321 
322  if (!tmpbuf) {
324  goto ast_log_cleanup;
325  }
326 
327  escapebuf = tmpbuf;
328  bufsize = required_size;
329  }
330  PQescapeStringConn(conn, escapebuf, value, strlen(value), NULL);
331  } else {
332  escapebuf[0] = '\0';
333  }
334  LENGTHEN_BUF2(strlen(escapebuf) + 3);
335  ast_str_append(&sql2, 0, "%s'%s'", SEP, escapebuf);
336  }
337  }
338  first = 0;
339  }
341  LENGTHEN_BUF1(ast_str_strlen(sql2) + 2);
342  ast_str_append(&sql, 0, ")%s)", ast_str_buffer(sql2));
343 
344  ast_debug(3, "Inserting a CEL record: [%s].\n", ast_str_buffer(sql));
345  /* Test to be sure we're still connected... */
346  /* If we're connected, and connection is working, good. */
347  /* Otherwise, attempt reconnect. If it fails... sorry... */
348  if (PQstatus(conn) == CONNECTION_OK) {
349  connected = 1;
350  } else {
351  ast_log(LOG_WARNING, "Connection was lost... attempting to reconnect.\n");
352  PQreset(conn);
353  if (PQstatus(conn) == CONNECTION_OK) {
354  ast_log(LOG_NOTICE, "Connection reestablished.\n");
355  connected = 1;
356  } else {
357  pgerror = PQerrorMessage(conn);
358  ast_log(LOG_ERROR, "Unable to reconnect to database server %s. Calls will not be logged!\n", pghostname);
359  ast_log(LOG_ERROR, "Reason: %s\n", pgerror);
360  PQfinish(conn);
361  conn = NULL;
362  connected = 0;
363  goto ast_log_cleanup;
364  }
365  }
366  result = PQexec(conn, ast_str_buffer(sql));
367  if (PQresultStatus(result) != PGRES_COMMAND_OK) {
368  pgerror = PQresultErrorMessage(result);
369  ast_log(LOG_WARNING, "Failed to insert call detail record into database!\n");
370  ast_log(LOG_WARNING, "Reason: %s\n", pgerror);
371  ast_log(LOG_WARNING, "Connection may have been lost... attempting to reconnect.\n");
372  PQreset(conn);
373  if (PQstatus(conn) == CONNECTION_OK) {
374  ast_log(LOG_NOTICE, "Connection reestablished.\n");
375  connected = 1;
376  PQclear(result);
377  result = PQexec(conn, ast_str_buffer(sql));
378  if (PQresultStatus(result) != PGRES_COMMAND_OK) {
379  pgerror = PQresultErrorMessage(result);
380  ast_log(LOG_ERROR, "HARD ERROR! Attempted reconnection failed. DROPPING CALL RECORD!\n");
381  ast_log(LOG_ERROR, "Reason: %s\n", pgerror);
382  }
383  }
384  }
385  PQclear(result);
386 
387  /* Next time, just allocate buffers that are that big to start with. */
388  if (ast_str_strlen(sql) > maxsize) {
389  maxsize = ast_str_strlen(sql);
390  }
391  if (ast_str_strlen(sql2) > maxsize2) {
392  maxsize2 = ast_str_strlen(sql2);
393  }
394 
395 ast_log_cleanup:
396  ast_free(sql);
397  ast_free(sql2);
398  ast_free(escapebuf);
399  }
400 
402 }
const char * account_code
Definition: cel.h:161
const char * caller_id_name
Definition: cel.h:151
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:136
const char * linked_id
Definition: cel.h:164
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:228
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const char * user_defined_name
Definition: cel.h:150
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const char * application_data
Definition: cel.h:160
const char * application_name
Definition: cel.h:159
#define LENGTHEN_BUF2(size)
Definition: cel_pgsql.c:117
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
static void pgsql_reconnect(void)
Definition: cel_pgsql.c:120
const char * extension
Definition: cel.h:156
static char * table
Definition: cel_pgsql.c:71
#define DATE_FORMAT
Definition: cel_pgsql.c:57
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * caller_id_num
Definition: cel.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
static char * pgdbname
Definition: cel_pgsql.c:66
static PGconn * conn
Definition: cel_pgsql.c:87
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
const char * extra
Definition: cel.h:168
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
const char * context
Definition: cel.h:157
#define LENGTHEN_BUF1(size)
Definition: cel_pgsql.c:115
uint32_t version
struct ABI version
Definition: cel.h:146
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static int maxsize
Definition: cel_pgsql.c:76
enum ast_cel_event_type event_type
Definition: cel.h:147
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static char * pghostname
Definition: cel_pgsql.c:65
const char * caller_id_rdnis
Definition: cel.h:154
static char * pgdbuser
Definition: cel_pgsql.c:67
const char * peer
Definition: cel.h:167
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
static int connected
Definition: cel_pgsql.c:74
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
const char * caller_id_ani
Definition: cel.h:153
const char * user_field
Definition: cel.h:166
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:141
const char * peer_account
Definition: cel.h:162
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define SEP
static char * pgpassword
Definition: cel_pgsql.c:68
static int usegmtime
Definition: cel_pgsql.c:77
static PGresult * result
Definition: cel_pgsql.c:88
const char * unique_id
Definition: cel.h:163
static int maxsize2
Definition: cel_pgsql.c:76
static unsigned char cel_show_user_def
Definition: cel_pgsql.c:83
static ast_mutex_t pgsql_lock
Definition: cel_pgsql.c:85
a user-defined event, the event name field should be set
Definition: cel.h:69
const char * caller_id_dnid
Definition: cel.h:155
const char * channel_name
Definition: cel.h:158
const char * event_name
Definition: cel.h:149
struct timeval event_time
Definition: cel.h:148
int ast_cel_fill_record(const struct ast_event *event, struct ast_cel_event_record *r)
Fill in an ast_cel_event_record from a CEL event.
Definition: cel.c:819
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ pgsql_reconnect()

static void pgsql_reconnect ( void  )
static

Definition at line 120 of file cel_pgsql.c.

References ast_free, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero, conn, LOG_ERROR, NULL, pgappname, pgdbname, pgdbport, pgdbuser, pghostname, and pgpassword.

Referenced by pgsql_log(), and process_my_load_module().

121 {
122  struct ast_str *conn_info = ast_str_create(128);
123  if (!conn_info) {
124  ast_log(LOG_ERROR, "Failed to allocate memory for connection string.\n");
125  return;
126  }
127 
128  if (conn) {
129  PQfinish(conn);
130  conn = NULL;
131  }
132 
133  ast_str_set(&conn_info, 0, "host=%s port=%s dbname=%s user=%s",
135 
136  if (!ast_strlen_zero(pgappname)) {
137  ast_str_append(&conn_info, 0, " application_name=%s", pgappname);
138  }
139 
140  if (!ast_strlen_zero(pgpassword)) {
141  ast_str_append(&conn_info, 0, " password=%s", pgpassword);
142  }
143 
144  conn = PQconnectdb(ast_str_buffer(conn_info));
145  ast_free(conn_info);
146 }
static char * pgappname
Definition: cel_pgsql.c:69
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
static char * pgdbname
Definition: cel_pgsql.c:66
static PGconn * conn
Definition: cel_pgsql.c:87
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static char * pghostname
Definition: cel_pgsql.c:65
static char * pgdbuser
Definition: cel_pgsql.c:67
#define ast_free(a)
Definition: astmm.h:182
static char * pgpassword
Definition: cel_pgsql.c:68
static char * pgdbport
Definition: cel_pgsql.c:70
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ process_my_load_module()

static int process_my_load_module ( struct ast_config cfg)
static

Definition at line 458 of file cel_pgsql.c.

References ast_alloca, ast_calloc, ast_debug, ast_free, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_RWLIST_INSERT_TAIL, ast_strdup, ast_strlen_zero, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, cel_show_user_def, CEL_SHOW_USERDEF_DEFAULT, conn, connected, DEBUG_ATLEAST, columns::hasdefault, columns::len, columns::list, LOG_DEBUG, LOG_ERROR, LOG_WARNING, columns::name, columns::notnull, NULL, pgappname, pgdbname, pgdbport, pgdbuser, pghostname, pgpassword, PGSQL_MIN_VERSION_SCHEMA, pgsql_reconnect(), result, schema, table, tmp(), columns::type, unload_module(), usegmtime, var, and version.

Referenced by my_load_module().

459 {
460  struct ast_variable *var;
461  char *pgerror;
462  const char *tmp;
463  PGresult *result;
464  struct columns *cur;
465 
466  if (!(var = ast_variable_browse(cfg, "global"))) {
467  ast_log(LOG_WARNING,"CEL pgsql config file missing global section.\n");
469  }
470  if (!(tmp = ast_variable_retrieve(cfg,"global","hostname"))) {
471  ast_log(LOG_WARNING,"PostgreSQL server hostname not specified. Assuming unix socket connection\n");
472  tmp = ""; /* connect via UNIX-socket by default */
473  }
474  if (pghostname)
476  if (!(pghostname = ast_strdup(tmp))) {
477  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying host info\n");
479  }
480  if (!(tmp = ast_variable_retrieve(cfg, "global", "dbname"))) {
481  ast_log(LOG_WARNING,"PostgreSQL database not specified. Assuming asterisk\n");
482  tmp = "asteriskceldb";
483  }
484  if (pgdbname)
486  if (!(pgdbname = ast_strdup(tmp))) {
487  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying dbname info\n");
489  }
490  if (!(tmp = ast_variable_retrieve(cfg, "global", "user"))) {
491  ast_log(LOG_WARNING,"PostgreSQL database user not specified. Assuming asterisk\n");
492  tmp = "asterisk";
493  }
494  if (pgdbuser)
496  if (!(pgdbuser = ast_strdup(tmp))) {
497  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying user info\n");
499  }
500  if (!(tmp = ast_variable_retrieve(cfg, "global", "password"))) {
501  ast_log(LOG_WARNING, "PostgreSQL database password not specified. Assuming blank\n");
502  tmp = "";
503  }
504  if (pgpassword)
506  if (!(pgpassword = ast_strdup(tmp))) {
507  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying password info\n");
509  }
510  if (!(tmp = ast_variable_retrieve(cfg, "global", "appname"))) {
511  tmp = "";
512  }
513  if (pgappname) {
515  }
516  if (!(pgappname = ast_strdup(tmp))) {
517  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying appname info\n");
519  }
520 
521  if (!(tmp = ast_variable_retrieve(cfg,"global","port"))) {
522  ast_log(LOG_WARNING,"PostgreSQL database port not specified. Using default 5432.\n");
523  tmp = "5432";
524  }
525  if (pgdbport)
527  if (!(pgdbport = ast_strdup(tmp))) {
528  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying port info\n");
530  }
531  if (!(tmp = ast_variable_retrieve(cfg, "global", "table"))) {
532  ast_log(LOG_WARNING,"CEL table not specified. Assuming cel\n");
533  tmp = "cel";
534  }
535  if (table)
536  ast_free(table);
537  if (!(table = ast_strdup(tmp))) {
539  }
541  if ((tmp = ast_variable_retrieve(cfg, "global", "show_user_defined"))) {
542  cel_show_user_def = ast_true(tmp) ? 1 : 0;
543  }
544  if ((tmp = ast_variable_retrieve(cfg, "global", "usegmtime"))) {
545  usegmtime = ast_true(tmp);
546  } else {
547  usegmtime = 0;
548  }
549  if (!(tmp = ast_variable_retrieve(cfg, "global", "schema"))) {
550  tmp = "";
551  }
552  if (schema) {
553  ast_free(schema);
554  }
555  if (!(schema = ast_strdup(tmp))) {
556  ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying schema info\n");
558  }
559  if (DEBUG_ATLEAST(3)) {
561  ast_log(LOG_DEBUG, "cel_pgsql: using default unix socket\n");
562  } else {
563  ast_log(LOG_DEBUG, "cel_pgsql: got hostname of %s\n", pghostname);
564  }
565  ast_log(LOG_DEBUG, "cel_pgsql: got port of %s\n", pgdbport);
566  ast_log(LOG_DEBUG, "cel_pgsql: got user of %s\n", pgdbuser);
567  ast_log(LOG_DEBUG, "cel_pgsql: got dbname of %s\n", pgdbname);
568  ast_log(LOG_DEBUG, "cel_pgsql: got password of %s\n", pgpassword);
569  ast_log(LOG_DEBUG, "cel_pgsql: got sql table name of %s\n", table);
570  ast_log(LOG_DEBUG, "cel_pgsql: got show_user_defined of %s\n",
571  cel_show_user_def ? "Yes" : "No");
572  }
573 
574  pgsql_reconnect();
575  if (PQstatus(conn) != CONNECTION_BAD) {
576  char sqlcmd[768];
577  char *fname, *ftype, *flen, *fnotnull, *fdef, *tablename, *tmp_tablename;
578  int i, rows, version;
579 
580  ast_debug(1, "Successfully connected to PostgreSQL database.\n");
581  connected = 1;
582 
583  version = PQserverVersion(conn);
584  /* Remove any schema name from the table */
585  if ((tmp_tablename = strrchr(table, '.'))) {
586  tmp_tablename++;
587  } else {
588  tmp_tablename = table;
589  }
590  tablename = ast_alloca(strlen(tmp_tablename) * 2 + 1);
591  PQescapeStringConn(conn, tablename, tmp_tablename, strlen(tmp_tablename), NULL);
592  if (version >= PGSQL_MIN_VERSION_SCHEMA) {
593  char *schemaname;
594  int lenschema;
595  lenschema = strlen(schema);
596  schemaname = ast_alloca(lenschema * 2 + 1);
597  PQescapeStringConn(conn, schemaname, schema, lenschema, NULL);
598 
599  snprintf(sqlcmd, sizeof(sqlcmd),
600  "SELECT a.attname, t.typname, a.attlen, a.attnotnull, pg_catalog.pg_get_expr(d.adbin, d.adrelid) adsrc, a.atttypmod "
601  "FROM (((pg_catalog.pg_class c INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
602  "AND c.relname = '%s' AND n.nspname = %s%s%s) "
603  "INNER JOIN pg_catalog.pg_attribute a ON ("
604  "NOT a.attisdropped) AND a.attnum > 0 AND a.attrelid = c.oid) "
605  "INNER JOIN pg_catalog.pg_type t ON t.oid = a.atttypid) "
606  "LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid "
607  "AND d.adnum = a.attnum "
608  "ORDER BY n.nspname, c.relname, attnum",
609  tablename,
610  lenschema == 0 ? "" : "'", lenschema == 0 ? "current_schema()" : schemaname, lenschema == 0 ? "" : "'");
611  } else {
612  snprintf(sqlcmd, sizeof(sqlcmd),
613  "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod "
614  "FROM pg_class c, pg_type t, pg_attribute a "
615  "LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid "
616  "AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid "
617  "AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", tablename);
618  }
619  /* Query the columns */
620  result = PQexec(conn, sqlcmd);
621  if (PQresultStatus(result) != PGRES_TUPLES_OK) {
622  pgerror = PQresultErrorMessage(result);
623  ast_log(LOG_ERROR, "Failed to query database columns: %s\n", pgerror);
624  PQclear(result);
625  unload_module();
627  }
628 
629  rows = PQntuples(result);
630  for (i = 0; i < rows; i++) {
631  fname = PQgetvalue(result, i, 0);
632  ftype = PQgetvalue(result, i, 1);
633  flen = PQgetvalue(result, i, 2);
634  fnotnull = PQgetvalue(result, i, 3);
635  fdef = PQgetvalue(result, i, 4);
636  ast_verb(4, "Found column '%s' of type '%s'\n", fname, ftype);
637  cur = ast_calloc(1, sizeof(*cur) + strlen(fname) + strlen(ftype) + 2);
638  if (cur) {
639  sscanf(flen, "%30d", &cur->len);
640  cur->name = (char *)cur + sizeof(*cur);
641  cur->type = (char *)cur + sizeof(*cur) + strlen(fname) + 1;
642  strcpy(cur->name, fname);
643  strcpy(cur->type, ftype);
644  if (*fnotnull == 't') {
645  cur->notnull = 1;
646  } else {
647  cur->notnull = 0;
648  }
649  if (!ast_strlen_zero(fdef)) {
650  cur->hasdefault = 1;
651  } else {
652  cur->hasdefault = 0;
653  }
655  }
656  }
657  PQclear(result);
658  } else {
659  pgerror = PQerrorMessage(conn);
660  ast_log(LOG_ERROR, "cel_pgsql: Unable to connect to database server %s. CALLS WILL NOT BE LOGGED!!\n", pghostname);
661  ast_log(LOG_ERROR, "cel_pgsql: Reason: %s\n", pgerror);
662  connected = 0;
663  PQfinish(conn);
664  conn = NULL;
665  }
667 }
unsigned int hasdefault
Definition: cdr_pgsql.c:98
struct columns::@8 list
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static char * pgappname
Definition: cel_pgsql.c:69
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static void pgsql_reconnect(void)
Definition: cel_pgsql.c:120
static char * table
Definition: cel_pgsql.c:71
static char * pgdbname
Definition: cel_pgsql.c:66
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static PGconn * conn
Definition: cel_pgsql.c:87
#define NULL
Definition: resample.c:96
#define LOG_DEBUG
Definition: logger.h:241
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static char * pghostname
Definition: cel_pgsql.c:65
static char * pgdbuser
Definition: cel_pgsql.c:67
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int connected
Definition: cel_pgsql.c:74
static int unload_module(void)
Definition: cel_pgsql.c:453
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
unsigned int notnull
Definition: cdr_pgsql.c:97
static char * pgpassword
Definition: cel_pgsql.c:68
static int usegmtime
Definition: cel_pgsql.c:77
static PGresult * result
Definition: cel_pgsql.c:88
static unsigned char cel_show_user_def
Definition: cel_pgsql.c:83
static char * pgdbport
Definition: cel_pgsql.c:70
static char * schema
Definition: cel_pgsql.c:72
#define PGSQL_MIN_VERSION_SCHEMA
Definition: cel_pgsql.c:61
#define CEL_SHOW_USERDEF_DEFAULT
show_user_def is off by default
Definition: cel_pgsql.c:80
#define DEBUG_ATLEAST(level)
Definition: logger.h:441

◆ reload()

static int reload ( void  )
static

Definition at line 701 of file cel_pgsql.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CDR_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_EXTENDED, ASTERISK_GPL_KEY, load_module(), my_load_module(), and unload_module().

702 {
703  return my_load_module(1);
704 }
static int my_load_module(int reload)
Definition: cel_pgsql.c:669

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 453 of file cel_pgsql.c.

References my_unload_module().

Referenced by process_my_load_module(), and reload().

454 {
455  return my_unload_module();
456 }
static int my_unload_module(void)
Definition: cel_pgsql.c:404

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PostgreSQL CEL Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cel", }
static

Definition at line 713 of file cel_pgsql.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 713 of file cel_pgsql.c.

◆ cel_show_user_def

unsigned char cel_show_user_def
static

TRUE if we should set the eventtype field to USER_DEFINED on user events.

Definition at line 83 of file cel_pgsql.c.

Referenced by pgsql_log(), and process_my_load_module().

◆ config

char* config = "cel_pgsql.conf"
static

Definition at line 63 of file cel_pgsql.c.

Referenced by my_load_module().

◆ conn

PGconn* conn = NULL
static

Definition at line 87 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_log(), pgsql_reconnect(), and process_my_load_module().

◆ connected

int connected = 0
static

Definition at line 74 of file cel_pgsql.c.

Referenced by pgsql_log(), and process_my_load_module().

◆ maxsize

int maxsize = 512
static

Definition at line 76 of file cel_pgsql.c.

Referenced by pgsql_log().

◆ maxsize2

int maxsize2 = 512
static

Definition at line 76 of file cel_pgsql.c.

Referenced by pgsql_log().

◆ pgappname

char* pgappname
static

Definition at line 69 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_reconnect(), and process_my_load_module().

◆ pgdbname

char* pgdbname
static

Definition at line 66 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_log(), pgsql_reconnect(), and process_my_load_module().

◆ pgdbport

char* pgdbport
static

Definition at line 70 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_reconnect(), and process_my_load_module().

◆ pgdbuser

char* pgdbuser
static

Definition at line 67 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_log(), pgsql_reconnect(), and process_my_load_module().

◆ pghostname

char* pghostname
static

Definition at line 65 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_log(), pgsql_reconnect(), and process_my_load_module().

◆ pgpassword

char* pgpassword
static

Definition at line 68 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_log(), pgsql_reconnect(), and process_my_load_module().

◆ pgsql_lock

ast_mutex_t pgsql_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 85 of file cel_pgsql.c.

Referenced by pgsql_log().

◆ psql_columns

struct psql_columns psql_columns = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ result

PGresult* result = NULL
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

Definition at line 88 of file cel_pgsql.c.

Referenced by __ast_channel_alloc(), __ast_string_field_alloc_space(), __astman_get_header(), acf_meetme_info(), action_updateconfig(), ast_build_string(), ast_build_string_va(), ast_config_internal_load(), ast_config_load2(), ast_format_cap_get_compatible_format(), ast_format_cap_get_format_framing(), ast_get_encoded_str(), ast_msg_has_destination(), ast_parse_arg(), ast_privacy_check(), ast_sip_str_to_dtmf(), ast_sip_will_uri_survive_restart(), ast_sockaddr_stringify_port(), ast_speech_results_free(), ast_stir_shaken_add_verification(), AST_TEST_DEFINE(), ast_websocket_client_create(), ast_xml_query(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), async_callback(), blackfilter_cmp_fn(), chat(), check_eval(), check_sip_domain(), cli_complete_registration(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), conf_find_bridge_profile(), conf_find_user_profile(), config_module(), config_mysql(), config_pgsql(), cops_connect(), db_get_common(), destroy_pgsql(), detect_callback(), detzcode(), detzcode64(), dial_exec_full(), dns_query_recurring_resolution_callback(), dtmf_to_str(), dundi_lookup_internal(), error(), evaluate_history_entry(), evaluate_like(), fax_detect_framehook(), fax_gateway_attach(), fax_gateway_detect_t38(), fax_gateway_framehook(), fax_gateway_start(), find_result(), find_table(), gen_match_to_pattern(), generic_fax_exec(), gmtsub(), handle_msg_cb(), handle_request_invite(), handle_skinny_set_debug(), handle_speechrecognize(), handle_standard_bridge_enter_message(), handle_updates(), iax2_codec_pref_index(), inform(), invalid_record_test(), launch_ha_netscript(), ldap_loadentry(), lintocodec2_frameout(), lintogsm_frameout(), lintoilbc_frameout(), lintolpc10_frameout(), lintospeex_frameout(), listfilter(), localized_config_load(), localized_config_load_with_comments(), localsub(), mallocconcat(), malloccopy(), match_filter(), mgcpsock_read(), mwi_thread(), my_connect_db(), MYSQL_exec(), nominal_sync_run(), nominal_test(), odbc_datastore_free(), off_nominal_async_callback(), off_nominal_sync_run(), off_nominal_test(), ogg_speex_open(), ogg_vorbis_open(), op_func(), P3(), parsefilearg(), pgsql_log(), process_my_load_module(), radius_log(), read_credentials(), read_mf_digits(), read_packet(), read_sf_digits(), realtime_ldap_base_ap(), realtime_multi_mysql(), realtime_multi_pgsql(), realtime_mysql(), realtime_pgsql(), receivefax_exec(), require_pgsql(), rtp_address_is_ice_blacklisted(), say(), sdp_crypto_alloc(), sendfax_exec(), sip_report_security_event(), sip_resolve_callback(), sorcery_memory_cache_complete_name(), sorcery_memory_cache_complete_object_name(), speech_grammar(), speech_read(), speech_score(), speech_text(), store_pgsql(), str2tech(), stun_address_is_blacklisted(), subscription_statistics_complete_name(), t30_phase_e_handler(), test_dtmf_amplitude_sweep(), test_dtmf_twist_sweep(), test_execute(), test_results(), test_tone_amplitude_sweep(), test_tone_freq_sweep(), testtime_write(), tmcomp(), topic_statistics_complete_name(), tzload(), update2_pgsql(), update_pgsql(), wait_exec(), and whitefilter_cmp_fn().

◆ schema

char* schema
static

Definition at line 72 of file cel_pgsql.c.

Referenced by load_config(), my_unload_module(), and process_my_load_module().

◆ table

char* table
static

Definition at line 71 of file cel_pgsql.c.

Referenced by my_unload_module(), pgsql_log(), and process_my_load_module().

◆ usegmtime

int usegmtime = 0
static

Definition at line 77 of file cel_pgsql.c.

Referenced by pgsql_log(), and process_my_load_module().