119#define MAX_DB_FIELD 256
129#define DEFINE_SQL_STATEMENT(stmt,sql) static sqlite3_stmt *stmt; \
130 const char stmt##_sql[] = sql;
157static
int init_stmt(sqlite3_stmt **stmt, const
char *sql,
size_t len)
160 if (sqlite3_prepare(
astdb, sql,
len, stmt,
NULL) != SQLITE_OK) {
176 if (sqlite3_finalize(*stmt) != SQLITE_OK) {
195 clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
197 clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
198 clean_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql);
201 clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
208 return init_stmt(&get_stmt, get_stmt_sql,
sizeof(get_stmt_sql))
209 ||
init_stmt(&exists_stmt, exists_stmt_sql,
sizeof(exists_stmt_sql))
210 ||
init_stmt(&del_stmt, del_stmt_sql,
sizeof(del_stmt_sql))
211 ||
init_stmt(&deltree_stmt, deltree_stmt_sql,
sizeof(deltree_stmt_sql))
212 ||
init_stmt(&deltree_all_stmt, deltree_all_stmt_sql,
sizeof(deltree_all_stmt_sql))
213 ||
init_stmt(&gettree_stmt, gettree_stmt_sql,
sizeof(gettree_stmt_sql))
214 ||
init_stmt(&gettree_all_stmt, gettree_all_stmt_sql,
sizeof(gettree_all_stmt_sql))
215 ||
init_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql,
sizeof(gettree_prefix_stmt_sql))
216 ||
init_stmt(&showkey_stmt, showkey_stmt_sql,
sizeof(showkey_stmt_sql))
217 ||
init_stmt(&put_stmt, put_stmt_sql,
sizeof(put_stmt_sql));
238 if (!create_astdb_stmt) {
239 init_stmt(&create_astdb_stmt, create_astdb_stmt_sql,
sizeof(create_astdb_stmt_sql));
243 if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
247 sqlite3_reset(create_astdb_stmt);
257 struct stat dont_care;
263 strcat(
dbname,
".sqlite3");
273 ast_log(
LOG_ERROR,
"*** and re-run 'make menuselect' and select astdb2sqlite3\n");
274 ast_log(
LOG_ERROR,
"*** in the Utilities section, then 'make && make install'.\n");
275 ast_log(
LOG_ERROR,
"*** It is also imperative that the user under which\n");
276 ast_log(
LOG_ERROR,
"*** Asterisk runs have write permission to the directory\n");
287 sqlite3_close(
astdb);
313static int db_execute_sql(
const char *sql,
int (*callback)(
void *,
int,
char **,
char **),
void *arg)
318 if (sqlite3_exec(
astdb, sql, callback, arg, &errmsg) != SQLITE_OK) {
320 sqlite3_free(errmsg);
348 if (strlen(family) + strlen(key) + 2 >
sizeof(fullkey) - 1) {
349 ast_log(
LOG_WARNING,
"Family and key length must be less than %zu bytes\n",
sizeof(fullkey) - 3);
353 fullkey_len = snprintf(fullkey,
sizeof(fullkey),
"/%s/%s", family, key);
356 if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
359 }
else if (sqlite3_bind_text(put_stmt, 2,
value, -1, SQLITE_STATIC) != SQLITE_OK) {
362 }
else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
367 sqlite3_reset(put_stmt);
388static int db_get_common(
const char *family,
const char *key,
char **buffer,
int bufferlen)
390 const unsigned char *
result;
395 if (strlen(family) + strlen(key) + 2 >
sizeof(fullkey) - 1) {
396 ast_log(
LOG_WARNING,
"Family and key length must be less than %zu bytes\n",
sizeof(fullkey) - 3);
400 fullkey_len = snprintf(fullkey,
sizeof(fullkey),
"/%s/%s", family, key);
403 if (sqlite3_bind_text(get_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
406 }
else if (sqlite3_step(get_stmt) != SQLITE_ROW) {
407 ast_debug(1,
"Unable to find key '%s' in family '%s'\n", key, family);
409 }
else if (!(
result = sqlite3_column_text(get_stmt, 0))) {
415 if (bufferlen == -1) {
421 sqlite3_reset(get_stmt);
451 fullkey_len = snprintf(fullkey,
sizeof(fullkey),
"/%s/%s", family, key);
452 if (fullkey_len >=
sizeof(fullkey)) {
453 ast_log(
LOG_WARNING,
"Family and key length must be less than %zu bytes\n",
sizeof(fullkey) - 3);
458 res = sqlite3_bind_text(exists_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC);
459 if (res != SQLITE_OK) {
462 }
else if (sqlite3_step(exists_stmt) != SQLITE_ROW) {
464 }
else if (!(
result = sqlite3_column_int(exists_stmt, 0))) {
469 sqlite3_reset(exists_stmt);
482 if (strlen(family) + strlen(key) + 2 >
sizeof(fullkey) - 1) {
483 ast_log(
LOG_WARNING,
"Family and key length must be less than %zu bytes\n",
sizeof(fullkey) - 3);
487 fullkey_len = snprintf(fullkey,
sizeof(fullkey),
"/%s/%s", family, key);
490 if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
493 }
else if (sqlite3_step(del_stmt) != SQLITE_DONE) {
494 ast_debug(1,
"Unable to find key '%s' in family '%s'\n", key, family);
497 sqlite3_reset(del_stmt);
511 if (strlen(family) + strlen(key) + 2 >
sizeof(fullkey) - 1) {
512 ast_log(
LOG_WARNING,
"Family and key length must be less than %zu bytes\n",
sizeof(fullkey) - 3);
516 fullkey_len = snprintf(fullkey,
sizeof(fullkey),
"/%s/%s", family, key);
522 }
else if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
525 }
else if ((mres = sqlite3_step(del_stmt) != SQLITE_DONE)) {
529 sqlite3_reset(del_stmt);
538 sqlite3_stmt *stmt = deltree_stmt;
545 snprintf(
prefix,
sizeof(
prefix),
"/%s/%s", family, keytree);
552 stmt = deltree_all_stmt;
559 }
else if (sqlite3_step(stmt) != SQLITE_DONE) {
563 res = sqlite3_changes(
astdb);
575 while (sqlite3_step(stmt) == SQLITE_ROW) {
577 size_t key_len, value_len;
579 key = (
const char *) sqlite3_column_text(stmt, 0);
580 value = (
const char *) sqlite3_column_text(stmt, 1);
586 key_len = strlen(
key);
587 value_len = strlen(
value);
589 cur =
ast_malloc(
sizeof(*cur) + key_len + value_len + 2);
595 cur->key = cur->data + value_len + 1;
596 memcpy(cur->data,
value, value_len + 1);
597 memcpy(cur->key,
key, key_len + 1);
613 sqlite3_stmt *stmt = gettree_stmt;
620 res = snprintf(
prefix,
sizeof(
prefix),
"/%s/%s", family, keytree);
626 if (res >=
sizeof(
prefix)) {
632 stmt = gettree_all_stmt;
636 if (res && (sqlite3_bind_text(stmt, 1,
prefix, res, SQLITE_STATIC) != SQLITE_OK)) {
656 res = snprintf(
prefix,
sizeof(
prefix),
"/%s/%s", family, key_prefix);
657 if (res >=
sizeof(
prefix)) {
663 if (sqlite3_bind_text(gettree_prefix_stmt, 1,
prefix, res, SQLITE_STATIC) != SQLITE_OK) {
665 sqlite3_reset(gettree_prefix_stmt);
671 sqlite3_reset(gettree_prefix_stmt);
695 "Usage: database put <family> <key> <value>\n"
696 " Adds or updates an entry in the Asterisk database for\n"
697 " a given family, key, and value.\n";
707 ast_cli(
a->fd,
"Failed to update entry\n");
709 ast_cli(
a->fd,
"Updated database successfully\n");
723 "Usage: database get <family> <key>\n"
724 " Retrieves an entry in the Asterisk database for a given\n"
725 " family and key.\n";
735 ast_cli(
a->fd,
"Database entry not found.\n");
750 "Usage: database del <family> <key>\n"
751 " Deletes an entry in the Asterisk database for a given\n"
752 " family and key.\n";
762 ast_cli(
a->fd,
"Database entry could not be removed.\n");
764 ast_cli(
a->fd,
"Database entry removed.\n");
775 e->
command =
"database deltree";
777 "Usage: database deltree <family> [keytree]\n"
778 " OR: database deltree <family>[/keytree]\n"
779 " Deletes a family or specific keytree within a family\n"
780 " in the Asterisk database. The two arguments may be\n"
781 " separated by either a space or a slash.\n";
787 if ((
a->argc < 3) || (
a->argc > 4))
794 if (num_deleted < 0) {
795 ast_cli(
a->fd,
"Database unavailable.\n");
796 }
else if (num_deleted == 0) {
797 ast_cli(
a->fd,
"Database entries do not exist.\n");
799 ast_cli(
a->fd,
"%d database entries removed.\n",num_deleted);
808 sqlite3_stmt *stmt = gettree_stmt;
814 "Usage: database show [family [keytree]]\n"
815 " OR: database show [family[/keytree]]\n"
816 " Shows Asterisk database contents, optionally restricted\n"
817 " to a given family, or family and keytree. The two arguments\n"
818 " may be separated either by a space or by a slash.\n";
826 snprintf(
prefix,
sizeof(
prefix),
"/%s/%s",
a->argv[2],
a->argv[3]);
827 }
else if (
a->argc == 3) {
830 }
else if (
a->argc == 2) {
833 stmt = gettree_all_stmt;
847 while (sqlite3_step(stmt) == SQLITE_ROW) {
848 const char *key_s, *value_s;
849 if (!(key_s = (
const char *) sqlite3_column_text(stmt, 0))) {
853 if (!(value_s = (
const char *) sqlite3_column_text(stmt, 1))) {
858 ast_cli(
a->fd,
"%-50s: %-25s\n", key_s, value_s);
864 ast_cli(
a->fd,
"%d results found.\n", counter);
874 e->
command =
"database showkey";
876 "Usage: database showkey <keytree>\n"
877 " Shows Asterisk database contents, restricted to a given key.\n";
888 if (!
ast_strlen_zero(
a->argv[2]) && (sqlite3_bind_text(showkey_stmt, 1,
a->argv[2], -1, SQLITE_STATIC) != SQLITE_OK)) {
890 sqlite3_reset(showkey_stmt);
895 while (sqlite3_step(showkey_stmt) == SQLITE_ROW) {
896 const char *key_s, *value_s;
897 if (!(key_s = (
const char *) sqlite3_column_text(showkey_stmt, 0))) {
900 if (!(value_s = (
const char *) sqlite3_column_text(showkey_stmt, 1))) {
904 ast_cli(
a->fd,
"%-50s: %-25s\n", key_s, value_s);
906 sqlite3_reset(showkey_stmt);
909 ast_cli(
a->fd,
"%d results found.\n", counter);
918 for (x = 0; x <
columns; x++) {
933 "Usage: database query \"<SQL Statement>\"\n"
934 " Run a user-specified SQL query on the database. Be careful.\n";
1007 snprintf(idText,
sizeof(idText) ,
"ActionID: %s\r\n",
id);
1021 family, key,
tmp, idText);
1036 sqlite3_stmt *stmt = gettree_stmt;
1041 snprintf(
prefix,
sizeof(
prefix),
"/%s/%s", family, key);
1048 stmt = gettree_all_stmt;
1053 snprintf(idText,
sizeof(idText) ,
"ActionID: %s\r\n",
id);
1059 sqlite3_reset(stmt);
1067 while (sqlite3_step(stmt) == SQLITE_ROW) {
1068 const char *key_s, *value_s;
1069 if (!(key_s = (
const char *) sqlite3_column_text(stmt, 0))) {
1073 if (!(value_s = (
const char *) sqlite3_column_text(stmt, 1))) {
1082 key_s, value_s, idText);
1086 sqlite3_reset(stmt);
1137 if (num_deleted < 0) {
1139 }
else if (num_deleted == 0) {
1222 if (sqlite3_close(
astdb) == SQLITE_OK) {
Prototypes for public functions only of internal interest,.
struct sla_ringing_trunk * last
#define EXISTS(a, b, c, d)
#define DELETE(a, b, c, d)
static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
Persistent data storage (akin to *doze registry)
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_malloc(len)
A wrapper for malloc()
General Asterisk PBX channel definitions.
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Convenient Signal Processing routines.
Generic File Format Support. Should be included by clients of the file handling routines....
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
void astman_append(struct mansession *s, const char *fmt,...)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
static char prefix[MAX_PREFIX]
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_cond_wait(cond, mutex)
#define ast_cond_init(cond, attr)
#define ast_mutex_unlock(a)
pthread_cond_t ast_cond_t
#define ast_mutex_lock(a)
#define AST_MUTEX_DEFINE_STATIC(mutex)
#define ast_cond_signal(cond)
static char * handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int manager_dbdel(struct mansession *s, const struct message *m)
static void db_sync(void)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
static void clean_statements(void)
static char * handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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.
static int manager_db_tree_get(struct mansession *s, const struct message *m)
int ast_db_del2(const char *family, const char *key)
Same as ast_db_del, but with more stringent error checking.
static int manager_dbdeltree(struct mansession *s, const struct message *m)
static struct ast_cli_entry cli_database[]
void ast_db_freetree(struct ast_db_entry *dbe)
Free structure created by ast_db_gettree()
static struct ast_db_entry * db_gettree_common(sqlite3_stmt *stmt)
static int manager_dbget(struct mansession *s, const struct message *m)
static char * handle_cli_database_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int convert_bdb_to_sqlite3(void)
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.
static int manager_dbput(struct mansession *s, const struct message *m)
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
static int display_results(void *arg, int columns, char **values, char **colnames)
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
static int ast_db_begin_transaction(void)
static int db_create_astdb(void)
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
static int ast_db_commit_transaction(void)
static ast_mutex_t dblock
#define DEFINE_SQL_STATEMENT(stmt, sql)
static void * db_sync_thread(void *data)
static char * handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
static pthread_t syncthread
static char * handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void astdb_atexit(void)
static int init_statements(void)
static char * handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int db_get_common(const char *family, const char *key, char **buffer, int bufferlen)
static int clean_stmt(sqlite3_stmt **stmt, const char *sql)
static int ast_db_rollback_transaction(void)
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
static char * handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_db_exists(const char *family, const char *key)
Check if family/key exitsts.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define EVENT_FLAG_REPORTING
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
#define EVENT_FLAG_SYSTEM
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_SBIN_DIR
const char * ast_config_AST_DB
static char dbname[MAX_DB_OPTION_SIZE]
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
descriptor for a cli entry.
struct ast_db_entry * next
In case you didn't read that giant block of text above the mansession_session struct,...
#define ast_pthread_create_background(a, b, c, d)