Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
main/db.c File Reference

ASTdb Management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <sqlite3.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
Include dependency graph for main/db.c:

Go to the source code of this file.

Macros

#define DEFINE_SQL_STATEMENT(stmt, sql)
 
#define MAX_DB_FIELD   256
 

Functions

static int ast_db_begin_transaction (void)
 
static int ast_db_commit_transaction (void)
 
int ast_db_del (const char *family, const char *key)
 Delete entry in astdb. More...
 
int ast_db_deltree (const char *family, const char *keytree)
 Delete one or more entries in astdb. More...
 
void ast_db_freetree (struct ast_db_entry *dbe)
 Free structure created by ast_db_gettree() More...
 
int ast_db_get (const char *family, const char *key, char *value, int valuelen)
 Get key value specified by family/key. More...
 
int ast_db_get_allocated (const char *family, const char *key, char **out)
 Get key value specified by family/key as a heap allocated string. More...
 
struct ast_db_entryast_db_gettree (const char *family, const char *keytree)
 Get a list of values within the astdb tree. More...
 
struct ast_db_entryast_db_gettree_by_prefix (const char *family, const char *key_prefix)
 Get a list of values with the given key prefix. More...
 
int ast_db_put (const char *family, const char *key, const char *value)
 Store value addressed by family/key. More...
 
static int ast_db_rollback_transaction (void)
 
static void astdb_atexit (void)
 
int astdb_init (void)
 
static void clean_statements (void)
 
static int clean_stmt (sqlite3_stmt **stmt, const char *sql)
 
static int convert_bdb_to_sqlite3 (void)
 
static int db_create_astdb (void)
 
static int db_execute_sql (const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
 
static int db_get_common (const char *family, const char *key, char **buffer, int bufferlen)
 
static struct ast_db_entrydb_gettree_common (sqlite3_stmt *stmt)
 
static int db_init (void)
 
static int db_open (void)
 
static void db_sync (void)
 
static void * db_sync_thread (void *data)
 
 DEFINE_SQL_STATEMENT (put_stmt, "INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)")
 
static int display_results (void *arg, int columns, char **values, char **colnames)
 
static char * handle_cli_database_del (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_deltree (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_get (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_put (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_query (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_showkey (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int init_statements (void)
 
static int manager_dbdel (struct mansession *s, const struct message *m)
 
static int manager_dbdeltree (struct mansession *s, const struct message *m)
 
static int manager_dbget (struct mansession *s, const struct message *m)
 
static int manager_dbput (struct mansession *s, const struct message *m)
 

Variables

static sqlite3 * astdb
 
static struct ast_cli_entry cli_database []
 
static ast_cond_t dbcond
 
static ast_mutex_t dblock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static int doexit
 
static int dosync
 
static pthread_t syncthread
 

Detailed Description

ASTdb Management.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
DB3 is licensed under Sleepycat Public License and is thus incompatible with GPL. To avoid having to make another exception (and complicate licensing even further) we elect to use DB1 which is BSD licensed

Definition in file main/db.c.

Macro Definition Documentation

◆ DEFINE_SQL_STATEMENT

#define DEFINE_SQL_STATEMENT (   stmt,
  sql 
)
Value:
static sqlite3_stmt *stmt; \
const char stmt##_sql[] = sql;

Definition at line 117 of file main/db.c.

◆ MAX_DB_FIELD

#define MAX_DB_FIELD   256

Function Documentation

◆ ast_db_begin_transaction()

static int ast_db_begin_transaction ( void  )
static

Definition at line 312 of file main/db.c.

References db_execute_sql(), and NULL.

Referenced by db_sync_thread().

313 {
314  return db_execute_sql("BEGIN TRANSACTION", NULL, NULL);
315 }
#define NULL
Definition: resample.c:96
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
Definition: main/db.c:298

◆ ast_db_commit_transaction()

static int ast_db_commit_transaction ( void  )
static

Definition at line 317 of file main/db.c.

References db_execute_sql(), and NULL.

Referenced by db_sync_thread().

318 {
319  return db_execute_sql("COMMIT", NULL, NULL);
320 }
#define NULL
Definition: resample.c:96
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
Definition: main/db.c:298

◆ ast_db_del()

int ast_db_del ( const char *  family,
const char *  key 
)

Delete entry in astdb.

Definition at line 429 of file main/db.c.

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, LOG_WARNING, and MAX_DB_FIELD.

Referenced by __expire_registry(), ast_privacy_set(), AST_TEST_DEFINE(), auth_exec(), cache_lookup_internal(), dahdi_cc_callback(), destroy_all_channels(), destroy_association(), dialgroup_refreshdb(), do_register_expire(), dump_queue_members(), function_db_delete(), handle_cli_database_del(), handle_dbdel(), manager_dbdel(), media_cache_item_del_from_astdb(), media_cache_remove_from_astdb(), mkintf(), presence_change_common(), process_clearcache(), reload_queue_members(), remove_public_key_from_astdb(), sorcery_astdb_delete(), stasis_app_device_state_delete(), and update_registry().

430 {
431  char fullkey[MAX_DB_FIELD];
432  size_t fullkey_len;
433  int res = 0;
434 
435  if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
436  ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
437  return -1;
438  }
439 
440  fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
441 
443  if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
444  ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
445  res = -1;
446  } else if (sqlite3_step(del_stmt) != SQLITE_DONE) {
447  ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
448  res = -1;
449  }
450  sqlite3_reset(del_stmt);
451  db_sync();
453 
454  return res;
455 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define MAX_DB_FIELD
Definition: main/db.c:107
static sqlite3 * astdb
Definition: main/db.c:110
static void db_sync(void)
Definition: main/db.c:1009
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_db_deltree()

int ast_db_deltree ( const char *  family,
const char *  keytree 
)

Delete one or more entries in astdb.

If both parameters are NULL, the entire database will be purged. If only keytree is NULL, all entries within the family will be purged. It is an error for keytree to have a value when family is NULL.

Return values
-1An error occurred
>=0 Number of records deleted

Definition at line 457 of file main/db.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, astdb, db_sync(), dblock, LOG_WARNING, MAX_DB_FIELD, and prefix.

Referenced by ast_privacy_reset(), AST_TEST_DEFINE(), deinitialize_sorcery(), deltree_exec(), dundi_flush(), handle_cli_database_deltree(), handle_dbdeltree(), iax_provision_reload(), manager_dbdeltree(), media_cache_item_del_from_astdb(), media_cache_remove_from_astdb(), and remove_public_key_from_astdb().

458 {
459  sqlite3_stmt *stmt = deltree_stmt;
460  char prefix[MAX_DB_FIELD];
461  int res = 0;
462 
463  if (!ast_strlen_zero(family)) {
464  if (!ast_strlen_zero(keytree)) {
465  /* Family and key tree */
466  snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
467  } else {
468  /* Family only */
469  snprintf(prefix, sizeof(prefix), "/%s", family);
470  }
471  } else {
472  prefix[0] = '\0';
473  stmt = deltree_all_stmt;
474  }
475 
477  if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
478  ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
479  res = -1;
480  } else if (sqlite3_step(stmt) != SQLITE_DONE) {
481  ast_log(LOG_WARNING, "Couldn't execute stmt: %s\n", sqlite3_errmsg(astdb));
482  res = -1;
483  }
484  res = sqlite3_changes(astdb);
485  sqlite3_reset(stmt);
486  db_sync();
488 
489  return res;
490 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define MAX_DB_FIELD
Definition: main/db.c:107
static sqlite3 * astdb
Definition: main/db.c:110
static void db_sync(void)
Definition: main/db.c:1009
#define ast_mutex_unlock(a)
Definition: lock.h:188
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_db_freetree()

void ast_db_freetree ( struct ast_db_entry dbe)

◆ ast_db_get()

int ast_db_get ( const char *  family,
const char *  key,
char *  value,
int  valuelen 
)

◆ ast_db_get_allocated()

int ast_db_get_allocated ( const char *  family,
const char *  key,
char **  out 
)

Get key value specified by family/key as a heap allocated string.

Given a family and key, sets out to a pointer to a heap allocated string. In the event of an error, out will be set to NULL. The string must be freed by calling ast_free().

Return values
-1An error occurred
0Success

Definition at line 422 of file main/db.c.

References db_get_common(), and NULL.

Referenced by AST_TEST_DEFINE(), media_cache_item_del_from_astdb(), reload_queue_members(), and sorcery_astdb_retrieve_id().

423 {
424  *out = NULL;
425 
426  return db_get_common(family, key, out, -1);
427 }
static int db_get_common(const char *family, const char *key, char **buffer, int bufferlen)
Definition: main/db.c:373
#define NULL
Definition: resample.c:96
FILE * out
Definition: utils/frame.c:33
char * key
Definition: astdb.h:33

◆ ast_db_gettree()

struct ast_db_entry* ast_db_gettree ( const char *  family,
const char *  keytree 
)

Get a list of values within the astdb tree.

If family is specified, only those keys will be returned. If keytree is specified, subkeys are expected to exist (separated from the key with a slash). If subkeys do not exist and keytree is specified, the tree will consist of either a single entry or NULL will be returned.

Resulting tree should be freed by passing the return value to ast_db_freetree() when usage is concluded.

Definition at line 531 of file main/db.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, astdb, db_gettree_common(), dblock, LOG_WARNING, MAX_DB_FIELD, NULL, and prefix.

Referenced by AST_TEST_DEFINE(), dundi_show_cache(), dundi_show_hints(), function_db_keys(), handle_cli_devstate_list(), handle_cli_presencestate_list(), load_module(), media_cache_item_populate_from_astdb(), media_cache_populate_from_astdb(), populate_cache(), process_clearcache(), reload_queue_members(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_regex(), and stasis_app_device_states_to_json().

532 {
533  char prefix[MAX_DB_FIELD];
534  sqlite3_stmt *stmt = gettree_stmt;
535  size_t res = 0;
536  struct ast_db_entry *ret;
537 
538  if (!ast_strlen_zero(family)) {
539  if (!ast_strlen_zero(keytree)) {
540  /* Family and key tree */
541  res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
542  } else {
543  /* Family only */
544  res = snprintf(prefix, sizeof(prefix), "/%s", family);
545  }
546 
547  if (res >= sizeof(prefix)) {
548  ast_log(LOG_WARNING, "Requested prefix is too long: %s\n", keytree);
549  return NULL;
550  }
551  } else {
552  prefix[0] = '\0';
553  stmt = gettree_all_stmt;
554  }
555 
557  if (res && (sqlite3_bind_text(stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK)) {
558  ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
559  sqlite3_reset(stmt);
561  return NULL;
562  }
563 
564  ret = db_gettree_common(stmt);
565  sqlite3_reset(stmt);
567 
568  return ret;
569 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static struct ast_db_entry * db_gettree_common(sqlite3_stmt *stmt)
Definition: main/db.c:492
#define MAX_DB_FIELD
Definition: main/db.c:107
Definition: astdb.h:31
static sqlite3 * astdb
Definition: main/db.c:110
#define ast_mutex_unlock(a)
Definition: lock.h:188
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_db_gettree_by_prefix()

struct ast_db_entry* ast_db_gettree_by_prefix ( const char *  family,
const char *  key_prefix 
)

Get a list of values with the given key prefix.

Parameters
familyThe family to search under
key_prefixThe key prefix to search under
Return values
NULLAn error occurred

Definition at line 571 of file main/db.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_gettree_common(), dblock, LOG_WARNING, MAX_DB_FIELD, NULL, and prefix.

Referenced by sorcery_astdb_retrieve_prefix().

572 {
573  char prefix[MAX_DB_FIELD];
574  size_t res;
575  struct ast_db_entry *ret;
576 
577  res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, key_prefix);
578  if (res >= sizeof(prefix)) {
579  ast_log(LOG_WARNING, "Requested key prefix is too long: %s\n", key_prefix);
580  return NULL;
581  }
582 
584  if (sqlite3_bind_text(gettree_prefix_stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK) {
585  ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
586  sqlite3_reset(gettree_prefix_stmt);
588  return NULL;
589  }
590 
591  ret = db_gettree_common(gettree_prefix_stmt);
592  sqlite3_reset(gettree_prefix_stmt);
594 
595  return ret;
596 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_log
Definition: astobj2.c:42
static struct ast_db_entry * db_gettree_common(sqlite3_stmt *stmt)
Definition: main/db.c:492
#define MAX_DB_FIELD
Definition: main/db.c:107
Definition: astdb.h:31
static sqlite3 * astdb
Definition: main/db.c:110
#define ast_mutex_unlock(a)
Definition: lock.h:188
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_db_put()

int ast_db_put ( const char *  family,
const char *  key,
const char *  value 
)

Store value addressed by family/key.

Definition at line 327 of file main/db.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, LOG_WARNING, and MAX_DB_FIELD.

Referenced by __analog_ss_thread(), add_public_key_to_astdb(), ast_privacy_set(), AST_TEST_DEFINE(), asterisk_daemon(), cache_save(), cache_save_hint(), dahdi_cc_callback(), database_increment(), devstate_write(), dialgroup_refreshdb(), dump_queue_members(), function_db_write(), handle_cli_database_put(), handle_cli_devstate_change(), handle_cli_presencestate_change(), handle_command_response(), handle_dbput(), iax_provision_build(), manager_dbput(), media_cache_item_sync_to_astdb(), metadata_sync_to_astdb(), mgcp_ss(), parse_register_contact(), presence_write(), save_secret(), set_public_key_expiration(), sorcery_astdb_create(), stasis_app_device_state_update(), test_stir_shaken_add_fake_astdb_entry(), and update_registry().

328 {
329  char fullkey[MAX_DB_FIELD];
330  size_t fullkey_len;
331  int res = 0;
332 
333  if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
334  ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
335  return -1;
336  }
337 
338  fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
339 
341  if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
342  ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
343  res = -1;
344  } else if (sqlite3_bind_text(put_stmt, 2, value, -1, SQLITE_STATIC) != SQLITE_OK) {
345  ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
346  res = -1;
347  } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
348  ast_log(LOG_WARNING, "Couldn't execute statement: %s\n", sqlite3_errmsg(astdb));
349  res = -1;
350  }
351 
352  sqlite3_reset(put_stmt);
353  db_sync();
355 
356  return res;
357 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
int value
Definition: syslog.c:37
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_log
Definition: astobj2.c:42
#define MAX_DB_FIELD
Definition: main/db.c:107
static sqlite3 * astdb
Definition: main/db.c:110
static void db_sync(void)
Definition: main/db.c:1009
#define ast_mutex_unlock(a)
Definition: lock.h:188
char * key
Definition: astdb.h:33

◆ ast_db_rollback_transaction()

static int ast_db_rollback_transaction ( void  )
static

Definition at line 322 of file main/db.c.

References db_execute_sql(), and NULL.

Referenced by db_sync_thread().

323 {
324  return db_execute_sql("ROLLBACK", NULL, NULL);
325 }
#define NULL
Definition: resample.c:96
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
Definition: main/db.c:298

◆ astdb_atexit()

static void astdb_atexit ( void  )
static

Definition at line 1058 of file main/db.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, astdb, clean_statements(), db_sync(), dblock, doexit, NULL, and syncthread.

Referenced by astdb_init().

1059 {
1061  ast_manager_unregister("DBGet");
1062  ast_manager_unregister("DBPut");
1063  ast_manager_unregister("DBDel");
1064  ast_manager_unregister("DBDelTree");
1065 
1066  /* Set doexit to 1 to kill thread. db_sync must be called with
1067  * mutex held. */
1069  doexit = 1;
1070  db_sync();
1072 
1073  pthread_join(syncthread, NULL);
1075  clean_statements();
1076  if (sqlite3_close(astdb) == SQLITE_OK) {
1077  astdb = NULL;
1078  }
1080 }
static struct ast_cli_entry cli_database[]
Definition: main/db.c:873
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dblock
Definition: main/db.c:108
static pthread_t syncthread
Definition: main/db.c:111
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static void clean_statements(void)
Definition: main/db.c:176
static sqlite3 * astdb
Definition: main/db.c:110
static int doexit
Definition: main/db.c:112
static void db_sync(void)
Definition: main/db.c:1009
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ astdb_init()

int astdb_init ( void  )

Provided by db.c

Definition at line 1082 of file main/db.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_cond_init, ast_manager_register_xml_core, ast_pthread_create_background, ast_register_atexit(), astdb_atexit(), db_init(), db_sync_thread(), dbcond, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), NULL, and syncthread.

Referenced by asterisk_daemon().

1083 {
1085 
1086  if (db_init()) {
1087  return -1;
1088  }
1089 
1091  return -1;
1092  }
1093 
1100  return 0;
1101 }
static struct ast_cli_entry cli_database[]
Definition: main/db.c:873
static void astdb_atexit(void)
Definition: main/db.c:1058
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int manager_dbdel(struct mansession *s, const struct message *m)
Definition: main/db.c:950
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define NULL
Definition: resample.c:96
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
static pthread_t syncthread
Definition: main/db.c:111
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: clicompat.c:13
static int db_init(void)
Definition: main/db.c:282
static ast_cond_t dbcond
Definition: main/db.c:109
static void * db_sync_thread(void *data)
Definition: main/db.c:1025
static int manager_dbget(struct mansession *s, const struct message *m)
Definition: main/db.c:908
static int manager_dbput(struct mansession *s, const struct message *m)
Definition: main/db.c:883
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static int manager_dbdeltree(struct mansession *s, const struct message *m)
Definition: main/db.c:975

◆ clean_statements()

static void clean_statements ( void  )
static

Definition at line 176 of file main/db.c.

References clean_stmt().

Referenced by astdb_atexit().

177 {
178  clean_stmt(&get_stmt, get_stmt_sql);
179  clean_stmt(&del_stmt, del_stmt_sql);
180  clean_stmt(&deltree_stmt, deltree_stmt_sql);
181  clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
182  clean_stmt(&gettree_stmt, gettree_stmt_sql);
183  clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
184  clean_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql);
185  clean_stmt(&showkey_stmt, showkey_stmt_sql);
186  clean_stmt(&put_stmt, put_stmt_sql);
187  clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
188 }
static int clean_stmt(sqlite3_stmt **stmt, const char *sql)
Definition: main/db.c:161

◆ clean_stmt()

static int clean_stmt ( sqlite3_stmt **  stmt,
const char *  sql 
)
static

Definition at line 161 of file main/db.c.

References ast_log, astdb, LOG_WARNING, and NULL.

Referenced by clean_statements().

162 {
163  if (sqlite3_finalize(*stmt) != SQLITE_OK) {
164  ast_log(LOG_WARNING, "Couldn't finalize statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
165  *stmt = NULL;
166  return -1;
167  }
168  *stmt = NULL;
169  return 0;
170 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static sqlite3 * astdb
Definition: main/db.c:110

◆ convert_bdb_to_sqlite3()

static int convert_bdb_to_sqlite3 ( void  )
static

Definition at line 205 of file main/db.c.

References ast_asprintf, ast_config_AST_DB, ast_config_AST_SBIN_DIR, ast_free, and ast_safe_system().

Referenced by db_open().

206 {
207  char *cmd;
208  int res;
209 
210  res = ast_asprintf(&cmd, "%s/astdb2sqlite3 '%s'\n", ast_config_AST_SBIN_DIR, ast_config_AST_DB);
211  if (0 <= res) {
212  res = ast_safe_system(cmd);
213  ast_free(cmd);
214  }
215 
216  return res;
217 }
const char * ast_config_AST_DB
Definition: options.c:165
const char * ast_config_AST_SBIN_DIR
Definition: options.c:163
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
#define ast_free(a)
Definition: astmm.h:182

◆ db_create_astdb()

static int db_create_astdb ( void  )
static

Definition at line 219 of file main/db.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, init_stmt(), and LOG_WARNING.

Referenced by db_init().

220 {
221  int res = 0;
222 
223  if (!create_astdb_stmt) {
224  init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
225  }
226 
228  if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
229  ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
230  res = -1;
231  }
232  sqlite3_reset(create_astdb_stmt);
233  db_sync();
235 
236  return res;
237 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_log
Definition: astobj2.c:42
static sqlite3 * astdb
Definition: main/db.c:110
static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
static void db_sync(void)
Definition: main/db.c:1009
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ db_execute_sql()

static int db_execute_sql ( const char *  sql,
int(*)(void *, int, char **, char **)  callback,
void *  arg 
)
static

Definition at line 298 of file main/db.c.

References ast_log, astdb, LOG_WARNING, and NULL.

Referenced by ast_db_begin_transaction(), ast_db_commit_transaction(), ast_db_rollback_transaction(), and handle_cli_database_query().

299 {
300  char *errmsg = NULL;
301  int res =0;
302 
303  if (sqlite3_exec(astdb, sql, callback, arg, &errmsg) != SQLITE_OK) {
304  ast_log(LOG_WARNING, "Error executing SQL (%s): %s\n", sql, errmsg);
305  sqlite3_free(errmsg);
306  res = -1;
307  }
308 
309  return res;
310 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static sqlite3 * astdb
Definition: main/db.c:110

◆ db_get_common()

static int db_get_common ( const char *  family,
const char *  key,
char **  buffer,
int  bufferlen 
)
static

Definition at line 373 of file main/db.c.

References ast_copy_string(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strdup, astdb, dblock, LOG_WARNING, MAX_DB_FIELD, result, and value.

Referenced by ast_db_get(), and ast_db_get_allocated().

374 {
375  const unsigned char *result;
376  char fullkey[MAX_DB_FIELD];
377  size_t fullkey_len;
378  int res = 0;
379 
380  if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
381  ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
382  return -1;
383  }
384 
385  fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
386 
388  if (sqlite3_bind_text(get_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
389  ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
390  res = -1;
391  } else if (sqlite3_step(get_stmt) != SQLITE_ROW) {
392  ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
393  res = -1;
394  } else if (!(result = sqlite3_column_text(get_stmt, 0))) {
395  ast_log(LOG_WARNING, "Couldn't get value\n");
396  res = -1;
397  } else {
398  const char *value = (const char *) result;
399 
400  if (bufferlen == -1) {
401  *buffer = ast_strdup(value);
402  } else {
403  ast_copy_string(*buffer, value, bufferlen);
404  }
405  }
406  sqlite3_reset(get_stmt);
408 
409  return res;
410 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
int value
Definition: syslog.c:37
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define MAX_DB_FIELD
Definition: main/db.c:107
static sqlite3 * astdb
Definition: main/db.c:110
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static PGresult * result
Definition: cel_pgsql.c:88
#define ast_mutex_unlock(a)
Definition: lock.h:188
char * key
Definition: astdb.h:33

◆ db_gettree_common()

static struct ast_db_entry* db_gettree_common ( sqlite3_stmt *  stmt)
static

Definition at line 492 of file main/db.c.

References ast_malloc, ast_db_entry::key, NULL, and value.

Referenced by ast_db_gettree(), and ast_db_gettree_by_prefix().

493 {
494  struct ast_db_entry *head = NULL, *prev = NULL, *cur;
495 
496  while (sqlite3_step(stmt) == SQLITE_ROW) {
497  const char *key, *value;
498  size_t key_len, value_len;
499 
500  key = (const char *) sqlite3_column_text(stmt, 0);
501  value = (const char *) sqlite3_column_text(stmt, 1);
502 
503  if (!key || !value) {
504  break;
505  }
506 
507  key_len = strlen(key);
508  value_len = strlen(value);
509 
510  cur = ast_malloc(sizeof(*cur) + key_len + value_len + 2);
511  if (!cur) {
512  break;
513  }
514 
515  cur->next = NULL;
516  cur->key = cur->data + value_len + 1;
517  memcpy(cur->data, value, value_len + 1);
518  memcpy(cur->key, key, key_len + 1);
519 
520  if (prev) {
521  prev->next = cur;
522  } else {
523  head = cur;
524  }
525  prev = cur;
526  }
527 
528  return head;
529 }
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
Definition: astdb.h:31
char * key
Definition: astdb.h:33

◆ db_init()

static int db_init ( void  )
static

Definition at line 282 of file main/db.c.

References astdb, db_create_astdb(), db_open(), and init_statements().

Referenced by astdb_init().

283 {
284  if (astdb) {
285  return 0;
286  }
287 
288  if (db_open() || db_create_astdb() || init_statements()) {
289  return -1;
290  }
291 
292  return 0;
293 }
static int init_statements(void)
Definition: main/db.c:190
static sqlite3 * astdb
Definition: main/db.c:110
static int db_create_astdb(void)
Definition: main/db.c:219
static int db_open(void)
Definition: main/db.c:239

◆ db_open()

static int db_open ( void  )
static

Definition at line 239 of file main/db.c.

References ast_alloca, ast_config_AST_DB, ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, convert_bdb_to_sqlite3(), dblock, dbname, LOG_ERROR, LOG_NOTICE, and LOG_WARNING.

Referenced by db_init().

240 {
241  char *dbname;
242  struct stat dont_care;
243 
244  if (!(dbname = ast_alloca(strlen(ast_config_AST_DB) + sizeof(".sqlite3")))) {
245  return -1;
246  }
247  strcpy(dbname, ast_config_AST_DB);
248  strcat(dbname, ".sqlite3");
249 
250  if (stat(dbname, &dont_care) && !stat(ast_config_AST_DB, &dont_care)) {
251  if (convert_bdb_to_sqlite3()) {
252  ast_log(LOG_ERROR, "*** Database conversion failed!\n");
253  ast_log(LOG_ERROR, "*** Asterisk now uses SQLite3 for its internal\n");
254  ast_log(LOG_ERROR, "*** database. Conversion from the old astdb\n");
255  ast_log(LOG_ERROR, "*** failed. Most likely the astdb2sqlite3 utility\n");
256  ast_log(LOG_ERROR, "*** was not selected for build. To convert the\n");
257  ast_log(LOG_ERROR, "*** old astdb, please delete '%s'\n", dbname);
258  ast_log(LOG_ERROR, "*** and re-run 'make menuselect' and select astdb2sqlite3\n");
259  ast_log(LOG_ERROR, "*** in the Utilities section, then 'make && make install'.\n");
260  ast_log(LOG_ERROR, "*** It is also imperative that the user under which\n");
261  ast_log(LOG_ERROR, "*** Asterisk runs have write permission to the directory\n");
262  ast_log(LOG_ERROR, "*** where the database resides.\n");
263  sleep(5);
264  } else {
265  ast_log(LOG_NOTICE, "Database conversion succeeded!\n");
266  }
267  }
268 
270  if (sqlite3_open(dbname, &astdb) != SQLITE_OK) {
271  ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", dbname, sqlite3_errmsg(astdb));
272  sqlite3_close(astdb);
274  return -1;
275  }
276 
278 
279  return 0;
280 }
const char * ast_config_AST_DB
Definition: options.c:165
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
static ast_mutex_t dblock
Definition: main/db.c:108
#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
#define LOG_NOTICE
Definition: logger.h:263
static sqlite3 * astdb
Definition: main/db.c:110
static struct ast_str * dbname
Definition: cdr_mysql.c:77
static int convert_bdb_to_sqlite3(void)
Definition: main/db.c:205
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ db_sync()

static void db_sync ( void  )
static

Definition at line 1009 of file main/db.c.

References ast_cond_signal, dbcond, and dosync.

Referenced by ast_db_del(), ast_db_deltree(), ast_db_put(), astdb_atexit(), db_create_astdb(), and handle_cli_database_query().

1010 {
1011  dosync = 1;
1013 }
#define ast_cond_signal(cond)
Definition: lock.h:201
static ast_cond_t dbcond
Definition: main/db.c:109
static int dosync
Definition: main/db.c:113

◆ db_sync_thread()

static void* db_sync_thread ( void *  data)
static

Definition at line 1025 of file main/db.c.

References ast_cond_wait, ast_db_begin_transaction(), ast_db_commit_transaction(), ast_db_rollback_transaction(), ast_mutex_lock, ast_mutex_unlock, dbcond, dblock, doexit, dosync, and NULL.

Referenced by astdb_init().

1026 {
1029  for (;;) {
1030  /* If dosync is set, db_sync() was called during sleep(1),
1031  * and the pending transaction should be committed.
1032  * Otherwise, block until db_sync() is called.
1033  */
1034  while (!dosync) {
1036  }
1037  dosync = 0;
1038  if (ast_db_commit_transaction()) {
1040  }
1041  if (doexit) {
1043  break;
1044  }
1047  sleep(1);
1049  }
1050 
1051  return NULL;
1052 }
static int ast_db_commit_transaction(void)
Definition: main/db.c:317
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dblock
Definition: main/db.c:108
static ast_cond_t dbcond
Definition: main/db.c:109
static int dosync
Definition: main/db.c:113
static int doexit
Definition: main/db.c:112
static int ast_db_rollback_transaction(void)
Definition: main/db.c:322
static int ast_db_begin_transaction(void)
Definition: main/db.c:312
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ DEFINE_SQL_STATEMENT()

DEFINE_SQL_STATEMENT ( put_stmt  ,
"INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)"   
)

Definition at line 120 of file main/db.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, dblock, LOG_WARNING, and NULL.

145 {
147  if (sqlite3_prepare(astdb, sql, len, stmt, NULL) != SQLITE_OK) {
148  ast_log(LOG_WARNING, "Couldn't prepare statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
150  return -1;
151  }
153 
154  return 0;
155 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static sqlite3 * astdb
Definition: main/db.c:110
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ display_results()

static int display_results ( void *  arg,
int  columns,
char **  values,
char **  colnames 
)
static

Definition at line 834 of file main/db.c.

References a, ast_cli(), columns, and ast_cli_args::fd.

Referenced by handle_cli_database_query().

835 {
836  struct ast_cli_args *a = arg;
837  size_t x;
838 
839  for (x = 0; x < columns; x++) {
840  ast_cli(a->fd, "%-5s: %-50s\n", colnames[x], values[x]);
841  }
842  ast_cli(a->fd, "\n");
843 
844  return 0;
845 }
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
static struct columns columns
static struct test_val a

◆ handle_cli_database_del()

static char* handle_cli_database_del ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 663 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_del(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

664 {
665  int res;
666 
667  switch (cmd) {
668  case CLI_INIT:
669  e->command = "database del";
670  e->usage =
671  "Usage: database del <family> <key>\n"
672  " Deletes an entry in the Asterisk database for a given\n"
673  " family and key.\n";
674  return NULL;
675  case CLI_GENERATE:
676  return NULL;
677  }
678 
679  if (a->argc != 4)
680  return CLI_SHOWUSAGE;
681  res = ast_db_del(a->argv[2], a->argv[3]);
682  if (res) {
683  ast_cli(a->fd, "Database entry does not exist.\n");
684  } else {
685  ast_cli(a->fd, "Database entry removed.\n");
686  }
687  return CLI_SUCCESS;
688 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_database_deltree()

static char* handle_cli_database_deltree ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 690 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_deltree(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

691 {
692  int num_deleted;
693 
694  switch (cmd) {
695  case CLI_INIT:
696  e->command = "database deltree";
697  e->usage =
698  "Usage: database deltree <family> [keytree]\n"
699  " OR: database deltree <family>[/keytree]\n"
700  " Deletes a family or specific keytree within a family\n"
701  " in the Asterisk database. The two arguments may be\n"
702  " separated by either a space or a slash.\n";
703  return NULL;
704  case CLI_GENERATE:
705  return NULL;
706  }
707 
708  if ((a->argc < 3) || (a->argc > 4))
709  return CLI_SHOWUSAGE;
710  if (a->argc == 4) {
711  num_deleted = ast_db_deltree(a->argv[2], a->argv[3]);
712  } else {
713  num_deleted = ast_db_deltree(a->argv[2], NULL);
714  }
715  if (num_deleted < 0) {
716  ast_cli(a->fd, "Database unavailable.\n");
717  } else if (num_deleted == 0) {
718  ast_cli(a->fd, "Database entries do not exist.\n");
719  } else {
720  ast_cli(a->fd, "%d database entries removed.\n",num_deleted);
721  }
722  return CLI_SUCCESS;
723 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
Definition: main/db.c:457

◆ handle_cli_database_get()

static char* handle_cli_database_get ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 635 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_get(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_DB_FIELD, NULL, tmp(), and ast_cli_entry::usage.

636 {
637  int res;
638  char tmp[MAX_DB_FIELD];
639 
640  switch (cmd) {
641  case CLI_INIT:
642  e->command = "database get";
643  e->usage =
644  "Usage: database get <family> <key>\n"
645  " Retrieves an entry in the Asterisk database for a given\n"
646  " family and key.\n";
647  return NULL;
648  case CLI_GENERATE:
649  return NULL;
650  }
651 
652  if (a->argc != 4)
653  return CLI_SHOWUSAGE;
654  res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
655  if (res) {
656  ast_cli(a->fd, "Database entry not found.\n");
657  } else {
658  ast_cli(a->fd, "Value: %s\n", tmp);
659  }
660  return CLI_SUCCESS;
661 }
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:412
const int fd
Definition: cli.h:159
#define MAX_DB_FIELD
Definition: main/db.c:107
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_database_put()

static char* handle_cli_database_put ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 608 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_put(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

609 {
610  int res;
611 
612  switch (cmd) {
613  case CLI_INIT:
614  e->command = "database put";
615  e->usage =
616  "Usage: database put <family> <key> <value>\n"
617  " Adds or updates an entry in the Asterisk database for\n"
618  " a given family, key, and value.\n";
619  return NULL;
620  case CLI_GENERATE:
621  return NULL;
622  }
623 
624  if (a->argc != 5)
625  return CLI_SHOWUSAGE;
626  res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
627  if (res) {
628  ast_cli(a->fd, "Failed to update entry\n");
629  } else {
630  ast_cli(a->fd, "Updated database successfully\n");
631  }
632  return CLI_SUCCESS;
633 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327

◆ handle_cli_database_query()

static char* handle_cli_database_query ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 847 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, db_execute_sql(), db_sync(), dblock, display_results(), NULL, and ast_cli_entry::usage.

848 {
849 
850  switch (cmd) {
851  case CLI_INIT:
852  e->command = "database query";
853  e->usage =
854  "Usage: database query \"<SQL Statement>\"\n"
855  " Run a user-specified SQL query on the database. Be careful.\n";
856  return NULL;
857  case CLI_GENERATE:
858  return NULL;
859  }
860 
861  if (a->argc != 3) {
862  return CLI_SHOWUSAGE;
863  }
864 
867  db_sync(); /* Go ahead and sync the db in case they write */
869 
870  return CLI_SUCCESS;
871 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dblock
Definition: main/db.c:108
const char *const * argv
Definition: cli.h:161
static int display_results(void *arg, int columns, char **values, char **colnames)
Definition: main/db.c:834
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
Definition: main/db.c:298
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static void db_sync(void)
Definition: main/db.c:1009
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ handle_cli_database_show()

static char* handle_cli_database_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 725 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, astdb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dblock, ast_cli_args::fd, LOG_WARNING, MAX_DB_FIELD, NULL, prefix, and ast_cli_entry::usage.

726 {
727  char prefix[MAX_DB_FIELD];
728  int counter = 0;
729  sqlite3_stmt *stmt = gettree_stmt;
730 
731  switch (cmd) {
732  case CLI_INIT:
733  e->command = "database show";
734  e->usage =
735  "Usage: database show [family [keytree]]\n"
736  " OR: database show [family[/keytree]]\n"
737  " Shows Asterisk database contents, optionally restricted\n"
738  " to a given family, or family and keytree. The two arguments\n"
739  " may be separated either by a space or by a slash.\n";
740  return NULL;
741  case CLI_GENERATE:
742  return NULL;
743  }
744 
745  if (a->argc == 4) {
746  /* Family and key tree */
747  snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
748  } else if (a->argc == 3) {
749  /* Family only */
750  snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
751  } else if (a->argc == 2) {
752  /* Neither */
753  prefix[0] = '\0';
754  stmt = gettree_all_stmt;
755 
756  } else {
757  return CLI_SHOWUSAGE;
758  }
759 
761  if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
762  ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
763  sqlite3_reset(stmt);
765  return NULL;
766  }
767 
768  while (sqlite3_step(stmt) == SQLITE_ROW) {
769  const char *key_s, *value_s;
770  if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
771  ast_log(LOG_WARNING, "Skipping invalid key!\n");
772  continue;
773  }
774  if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
775  ast_log(LOG_WARNING, "Skipping invalid value!\n");
776  continue;
777  }
778  ++counter;
779  ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
780  }
781 
782  sqlite3_reset(stmt);
784 
785  ast_cli(a->fd, "%d results found.\n", counter);
786  return CLI_SUCCESS;
787 }
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const int fd
Definition: cli.h:159
#define MAX_DB_FIELD
Definition: main/db.c:107
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static sqlite3 * astdb
Definition: main/db.c:110
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ast_mutex_unlock(a)
Definition: lock.h:188
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ handle_cli_database_showkey()

static char* handle_cli_database_showkey ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 789 of file main/db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, astdb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dblock, ast_cli_args::fd, LOG_WARNING, NULL, and ast_cli_entry::usage.

790 {
791  int counter = 0;
792 
793  switch (cmd) {
794  case CLI_INIT:
795  e->command = "database showkey";
796  e->usage =
797  "Usage: database showkey <keytree>\n"
798  " Shows Asterisk database contents, restricted to a given key.\n";
799  return NULL;
800  case CLI_GENERATE:
801  return NULL;
802  }
803 
804  if (a->argc != 3) {
805  return CLI_SHOWUSAGE;
806  }
807 
809  if (!ast_strlen_zero(a->argv[2]) && (sqlite3_bind_text(showkey_stmt, 1, a->argv[2], -1, SQLITE_STATIC) != SQLITE_OK)) {
810  ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", a->argv[2], sqlite3_errmsg(astdb));
811  sqlite3_reset(showkey_stmt);
813  return NULL;
814  }
815 
816  while (sqlite3_step(showkey_stmt) == SQLITE_ROW) {
817  const char *key_s, *value_s;
818  if (!(key_s = (const char *) sqlite3_column_text(showkey_stmt, 0))) {
819  break;
820  }
821  if (!(value_s = (const char *) sqlite3_column_text(showkey_stmt, 1))) {
822  break;
823  }
824  ++counter;
825  ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
826  }
827  sqlite3_reset(showkey_stmt);
829 
830  ast_cli(a->fd, "%d results found.\n", counter);
831  return CLI_SUCCESS;
832 }
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static ast_mutex_t dblock
Definition: main/db.c:108
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static sqlite3 * astdb
Definition: main/db.c:110
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ init_statements()

static int init_statements ( void  )
static

Definition at line 190 of file main/db.c.

References init_stmt().

Referenced by db_init().

191 {
192  /* Don't initialize create_astdb_statement here as the astdb table needs to exist
193  * brefore these statements can be initialized */
194  return init_stmt(&get_stmt, get_stmt_sql, sizeof(get_stmt_sql))
195  || init_stmt(&del_stmt, del_stmt_sql, sizeof(del_stmt_sql))
196  || init_stmt(&deltree_stmt, deltree_stmt_sql, sizeof(deltree_stmt_sql))
197  || init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
198  || init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
199  || init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
200  || init_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql, sizeof(gettree_prefix_stmt_sql))
201  || init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
202  || init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
203 }
static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)

◆ manager_dbdel()

static int manager_dbdel ( struct mansession s,
const struct message m 
)
static

Definition at line 950 of file main/db.c.

References ast_db_del(), ast_strlen_zero, astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by astdb_init().

951 {
952  const char *family = astman_get_header(m, "Family");
953  const char *key = astman_get_header(m, "Key");
954  int res;
955 
956  if (ast_strlen_zero(family)) {
957  astman_send_error(s, m, "No family specified.");
958  return 0;
959  }
960 
961  if (ast_strlen_zero(key)) {
962  astman_send_error(s, m, "No key specified.");
963  return 0;
964  }
965 
966  res = ast_db_del(family, key);
967  if (res)
968  astman_send_error(s, m, "Database entry not found");
969  else
970  astman_send_ack(s, m, "Key deleted successfully");
971 
972  return 0;
973 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ manager_dbdeltree()

static int manager_dbdeltree ( struct mansession s,
const struct message m 
)
static

Definition at line 975 of file main/db.c.

References ast_db_deltree(), ast_strlen_zero, astman_get_header(), astman_send_ack(), astman_send_error(), and NULL.

Referenced by astdb_init().

976 {
977  const char *family = astman_get_header(m, "Family");
978  const char *key = astman_get_header(m, "Key");
979  int num_deleted;
980 
981  if (ast_strlen_zero(family)) {
982  astman_send_error(s, m, "No family specified.");
983  return 0;
984  }
985 
986  if (!ast_strlen_zero(key)) {
987  num_deleted = ast_db_deltree(family, key);
988  } else {
989  num_deleted = ast_db_deltree(family, NULL);
990  }
991 
992  if (num_deleted < 0) {
993  astman_send_error(s, m, "Database unavailable");
994  } else if (num_deleted == 0) {
995  astman_send_error(s, m, "Database entry not found");
996  } else {
997  astman_send_ack(s, m, "Key tree deleted successfully");
998  }
999 
1000  return 0;
1001 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
Definition: main/db.c:457

◆ manager_dbget()

static int manager_dbget ( struct mansession s,
const struct message m 
)
static

Definition at line 908 of file main/db.c.

References ast_db_get(), ast_strlen_zero, astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), MAX_DB_FIELD, and tmp().

Referenced by astdb_init().

909 {
910  const char *id = astman_get_header(m,"ActionID");
911  char idText[256];
912  const char *family = astman_get_header(m, "Family");
913  const char *key = astman_get_header(m, "Key");
914  char tmp[MAX_DB_FIELD];
915  int res;
916 
917  if (ast_strlen_zero(family)) {
918  astman_send_error(s, m, "No family specified.");
919  return 0;
920  }
921  if (ast_strlen_zero(key)) {
922  astman_send_error(s, m, "No key specified.");
923  return 0;
924  }
925 
926  idText[0] = '\0';
927  if (!ast_strlen_zero(id))
928  snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
929 
930  res = ast_db_get(family, key, tmp, sizeof(tmp));
931  if (res) {
932  astman_send_error(s, m, "Database entry not found");
933  } else {
934  astman_send_listack(s, m, "Result will follow", "start");
935 
936  astman_append(s, "Event: DBGetResponse\r\n"
937  "Family: %s\r\n"
938  "Key: %s\r\n"
939  "Val: %s\r\n"
940  "%s"
941  "\r\n",
942  family, key, tmp, idText);
943 
944  astman_send_list_complete_start(s, m, "DBGetComplete", 1);
946  }
947  return 0;
948 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3237
static int tmp()
Definition: bt_open.c:389
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:412
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#define MAX_DB_FIELD
Definition: main/db.c:107
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3201

◆ manager_dbput()

static int manager_dbput ( struct mansession s,
const struct message m 
)
static

Definition at line 883 of file main/db.c.

References ast_db_put(), ast_strlen_zero, astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.

Referenced by astdb_init().

884 {
885  const char *family = astman_get_header(m, "Family");
886  const char *key = astman_get_header(m, "Key");
887  const char *val = astman_get_header(m, "Val");
888  int res;
889 
890  if (ast_strlen_zero(family)) {
891  astman_send_error(s, m, "No family specified");
892  return 0;
893  }
894  if (ast_strlen_zero(key)) {
895  astman_send_error(s, m, "No key specified");
896  return 0;
897  }
898 
899  res = ast_db_put(family, key, S_OR(val, ""));
900  if (res) {
901  astman_send_error(s, m, "Failed to update entry");
902  } else {
903  astman_send_ack(s, m, "Updated database successfully");
904  }
905  return 0;
906 }
Definition: ast_expr2.c:325
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

Variable Documentation

◆ astdb

sqlite3* astdb
static

◆ cli_database

struct ast_cli_entry cli_database[]
static

Definition at line 873 of file main/db.c.

◆ dbcond

ast_cond_t dbcond
static

Definition at line 109 of file main/db.c.

Referenced by astdb_init(), db_sync(), and db_sync_thread().

◆ dblock

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

◆ doexit

int doexit
static

Definition at line 112 of file main/db.c.

Referenced by ast_monitor_change_fname(), astdb_atexit(), and db_sync_thread().

◆ dosync

int dosync
static

Definition at line 113 of file main/db.c.

Referenced by db_sync(), and db_sync_thread().

◆ syncthread

pthread_t syncthread
static

Definition at line 111 of file main/db.c.

Referenced by astdb_atexit(), and astdb_init().