Asterisk - The Open Source Telephony Project  GIT-master-a24979a
main/db.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief ASTdb Management
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \note DB3 is licensed under Sleepycat Public License and is thus incompatible
26  * with GPL. To avoid having to make another exception (and complicate
27  * licensing even further) we elect to use DB1 which is BSD licensed
28  */
29 
30 /*** MODULEINFO
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 #include "asterisk/_private.h"
37 #include "asterisk/paths.h" /* use ast_config_AST_DB */
38 #include <sys/time.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <signal.h>
43 #include <dirent.h>
44 #include <sqlite3.h>
45 
46 #include "asterisk/channel.h"
47 #include "asterisk/file.h"
48 #include "asterisk/app.h"
49 #include "asterisk/dsp.h"
50 #include "asterisk/astdb.h"
51 #include "asterisk/cli.h"
52 #include "asterisk/utils.h"
53 #include "asterisk/manager.h"
54 
55 /*** DOCUMENTATION
56  <manager name="DBGet" language="en_US">
57  <synopsis>
58  Get DB Entry.
59  </synopsis>
60  <syntax>
61  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
62  <parameter name="Family" required="true" />
63  <parameter name="Key" required="true" />
64  </syntax>
65  <description>
66  </description>
67  </manager>
68  <manager name="DBPut" language="en_US">
69  <synopsis>
70  Put DB entry.
71  </synopsis>
72  <syntax>
73  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
74  <parameter name="Family" required="true" />
75  <parameter name="Key" required="true" />
76  <parameter name="Val" />
77  </syntax>
78  <description>
79  </description>
80  </manager>
81  <manager name="DBDel" language="en_US">
82  <synopsis>
83  Delete DB entry.
84  </synopsis>
85  <syntax>
86  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
87  <parameter name="Family" required="true" />
88  <parameter name="Key" required="true" />
89  </syntax>
90  <description>
91  </description>
92  </manager>
93  <manager name="DBDelTree" language="en_US">
94  <synopsis>
95  Delete DB Tree.
96  </synopsis>
97  <syntax>
98  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
99  <parameter name="Family" required="true" />
100  <parameter name="Key" />
101  </syntax>
102  <description>
103  </description>
104  </manager>
105  ***/
106 
107 #define MAX_DB_FIELD 256
110 static sqlite3 *astdb;
111 static pthread_t syncthread;
112 static int doexit;
113 static int dosync;
114 
115 static void db_sync(void);
116 
117 #define DEFINE_SQL_STATEMENT(stmt,sql) static sqlite3_stmt *stmt; \
118  const char stmt##_sql[] = sql;
119 
120 DEFINE_SQL_STATEMENT(put_stmt, "INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)")
121 DEFINE_SQL_STATEMENT(get_stmt, "SELECT value FROM astdb WHERE key=?")
122 DEFINE_SQL_STATEMENT(del_stmt, "DELETE FROM astdb WHERE key=?")
123 DEFINE_SQL_STATEMENT(deltree_stmt, "DELETE FROM astdb WHERE key || '/' LIKE ? || '/' || '%'")
124 DEFINE_SQL_STATEMENT(deltree_all_stmt, "DELETE FROM astdb")
125 DEFINE_SQL_STATEMENT(gettree_stmt, "SELECT key, value FROM astdb WHERE key || '/' LIKE ? || '/' || '%' ORDER BY key")
126 DEFINE_SQL_STATEMENT(gettree_all_stmt, "SELECT key, value FROM astdb ORDER BY key")
127 DEFINE_SQL_STATEMENT(showkey_stmt, "SELECT key, value FROM astdb WHERE key LIKE '%' || '/' || ? ORDER BY key")
128 DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))")
129 
130 /* This query begs an explanation:
131  *
132  * First, the parameter binding syntax used here is slightly different than the other
133  * queries in that we use a numbered parameter so that we can bind once and get the same
134  * value substituted multiple times within the executed query.
135  *
136  * Second, the key comparison is being used to find all keys that are lexicographically
137  * greater than the provided key, but less than the provided key with a high (but
138  * invalid) Unicode codepoint appended to it. This will give us all keys in the database
139  * that have 'key' as a prefix and performs much better than the equivalent "LIKE key ||
140  * '%'" operation.
141  */
142 DEFINE_SQL_STATEMENT(gettree_prefix_stmt, "SELECT key, value FROM astdb WHERE key > ?1 AND key <= ?1 || X'ffff'")
143 
144 static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
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 }
156 
157 /*! \internal
158  * \brief Clean up the prepared SQLite3 statement
159  * \note dblock should already be locked prior to calling this method
160  */
161 static int clean_stmt(sqlite3_stmt **stmt, const char *sql)
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 }
171 
172 /*! \internal
173  * \brief Clean up all prepared SQLite3 statements
174  * \note dblock should already be locked prior to calling this method
175  */
176 static void clean_statements(void)
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 }
189 
190 static int init_statements(void)
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 }
204 
205 static int convert_bdb_to_sqlite3(void)
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 }
218 
219 static int db_create_astdb(void)
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 }
238 
239 static int db_open(void)
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 }
281 
282 static int db_init(void)
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 }
294 
295 /* We purposely don't lock around the sqlite3 call because the transaction
296  * calls will be called with the database lock held. For any other use, make
297  * sure to take the dblock yourself. */
298 static int db_execute_sql(const char *sql, int (*callback)(void *, int, char **, char **), void *arg)
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 }
311 
312 static int ast_db_begin_transaction(void)
313 {
314  return db_execute_sql("BEGIN TRANSACTION", NULL, NULL);
315 }
316 
318 {
319  return db_execute_sql("COMMIT", NULL, NULL);
320 }
321 
323 {
324  return db_execute_sql("ROLLBACK", NULL, NULL);
325 }
326 
327 int ast_db_put(const char *family, const char *key, const char *value)
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 }
358 
359 /*!
360  * \internal
361  * \brief Get key value specified by family/key.
362  *
363  * Gets the value associated with the specified \a family and \a key, and
364  * stores it, either into the fixed sized buffer specified by \a buffer
365  * and \a bufferlen, or as a heap allocated string if \a bufferlen is -1.
366  *
367  * \note If \a bufferlen is -1, \a buffer points to heap allocated memory
368  * and must be freed by calling ast_free().
369  *
370  * \retval -1 An error occurred
371  * \retval 0 Success
372  */
373 static int db_get_common(const char *family, const char *key, char **buffer, int bufferlen)
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 }
411 
412 int ast_db_get(const char *family, const char *key, char *value, int valuelen)
413 {
414  ast_assert(value != NULL);
415 
416  /* Make sure we initialize */
417  value[0] = 0;
418 
419  return db_get_common(family, key, &value, valuelen);
420 }
421 
422 int ast_db_get_allocated(const char *family, const char *key, char **out)
423 {
424  *out = NULL;
425 
426  return db_get_common(family, key, out, -1);
427 }
428 
429 int ast_db_del(const char *family, const char *key)
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 }
456 
457 int ast_db_deltree(const char *family, const char *keytree)
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 }
491 
492 static struct ast_db_entry *db_gettree_common(sqlite3_stmt *stmt)
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 }
530 
531 struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
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 }
570 
571 struct ast_db_entry *ast_db_gettree_by_prefix(const char *family, const char *key_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 }
597 
598 void ast_db_freetree(struct ast_db_entry *dbe)
599 {
600  struct ast_db_entry *last;
601  while (dbe) {
602  last = dbe;
603  dbe = dbe->next;
604  ast_free(last);
605  }
606 }
607 
608 static char *handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 }
634 
635 static char *handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 }
662 
663 static char *handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 }
689 
690 static char *handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 }
724 
725 static char *handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 }
788 
789 static char *handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 }
833 
834 static int display_results(void *arg, int columns, char **values, char **colnames)
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 }
846 
847 static char *handle_cli_database_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 
866  db_execute_sql(a->argv[2], display_results, a);
867  db_sync(); /* Go ahead and sync the db in case they write */
869 
870  return CLI_SUCCESS;
871 }
872 
873 static struct ast_cli_entry cli_database[] = {
874  AST_CLI_DEFINE(handle_cli_database_show, "Shows database contents"),
875  AST_CLI_DEFINE(handle_cli_database_showkey, "Shows database contents"),
876  AST_CLI_DEFINE(handle_cli_database_get, "Gets database value"),
877  AST_CLI_DEFINE(handle_cli_database_put, "Adds/updates database value"),
878  AST_CLI_DEFINE(handle_cli_database_del, "Removes database key/value"),
879  AST_CLI_DEFINE(handle_cli_database_deltree, "Removes database keytree/values"),
880  AST_CLI_DEFINE(handle_cli_database_query, "Run a user-specified query on the astdb"),
881 };
882 
883 static int manager_dbput(struct mansession *s, const struct message *m)
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 }
907 
908 static int manager_dbget(struct mansession *s, const struct message *m)
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 }
949 
950 static int manager_dbdel(struct mansession *s, const struct message *m)
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 }
974 
975 static int manager_dbdeltree(struct mansession *s, const struct message *m)
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 }
1002 
1003 /*!
1004  * \internal
1005  * \brief Signal the astdb sync thread to do its thing.
1006  *
1007  * \note dblock is assumed to be held when calling this function.
1008  */
1009 static void db_sync(void)
1010 {
1011  dosync = 1;
1013 }
1014 
1015 /*!
1016  * \internal
1017  * \brief astdb sync thread
1018  *
1019  * This thread is in charge of syncing astdb to disk after a change.
1020  * By pushing it off to this thread to take care of, this I/O bound operation
1021  * will not block other threads from performing other critical processing.
1022  * If changes happen rapidly, this thread will also ensure that the sync
1023  * operations are rate limited.
1024  */
1025 static void *db_sync_thread(void *data)
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 }
1053 
1054 /*!
1055  * \internal
1056  * \brief Clean up resources on Asterisk shutdown
1057  */
1058 static void astdb_atexit(void)
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 }
1081 
1082 int astdb_init(void)
1083 {
1085 
1086  if (db_init()) {
1087  return -1;
1088  }
1089 
1091  return -1;
1092  }
1093 
1100  return 0;
1101 }
Prototypes for public functions only of internal interest,.
struct sla_ringing_trunk * last
Definition: app_meetme.c:1094
#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.
Definition: clicompat.c:13
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
static char * columns
static PGresult * result
Definition: cel_pgsql.c:84
General Asterisk PBX channel definitions.
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
Convenient Signal Processing routines.
Generic File Format Support. Should be included by clients of the file handling routines....
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.
Definition: manager.c:3208
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3166
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:3244
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3198
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3252
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3087
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:2827
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7268
static char prefix[MAX_PREFIX]
Definition: http.c:144
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.
Definition: extconf.c:829
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_NOTICE
#define LOG_WARNING
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_mutex_unlock(a)
Definition: lock.h:188
pthread_cond_t ast_cond_t
Definition: lock.h:176
#define ast_mutex_lock(a)
Definition: lock.h:187
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:518
#define ast_cond_signal(cond)
Definition: lock.h:201
static int manager_dbdel(struct mansession *s, const struct message *m)
Definition: main/db.c:950
static char * handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:608
static void db_sync(void)
Definition: main/db.c:1009
static int doexit
Definition: main/db.c:112
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327
static void clean_statements(void)
Definition: main/db.c:176
static int manager_dbdeltree(struct mansession *s, const struct message *m)
Definition: main/db.c:975
static struct ast_cli_entry cli_database[]
Definition: main/db.c:873
static struct ast_db_entry * db_gettree_common(sqlite3_stmt *stmt)
Definition: main/db.c:492
void ast_db_freetree(struct ast_db_entry *dbe)
Free structure created by ast_db_gettree()
Definition: main/db.c:598
static int manager_dbget(struct mansession *s, const struct message *m)
Definition: main/db.c:908
static int db_init(void)
Definition: main/db.c:282
int astdb_init(void)
Definition: main/db.c:1082
static sqlite3 * astdb
Definition: main/db.c:110
static int convert_bdb_to_sqlite3(void)
Definition: main/db.c:205
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.
Definition: main/db.c:422
static int manager_dbput(struct mansession *s, const struct message *m)
Definition: main/db.c:883
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
Definition: main/db.c:298
static int display_results(void *arg, int columns, char **values, char **colnames)
Definition: main/db.c:834
static char * handle_cli_database_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:847
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
static int ast_db_begin_transaction(void)
Definition: main/db.c:312
static int db_create_astdb(void)
Definition: main/db.c:219
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
static int ast_db_commit_transaction(void)
Definition: main/db.c:317
static int db_open(void)
Definition: main/db.c:239
static ast_mutex_t dblock
Definition: main/db.c:108
#define DEFINE_SQL_STATEMENT(stmt, sql)
Definition: main/db.c:117
static ast_cond_t dbcond
Definition: main/db.c:109
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.
Definition: main/db.c:571
static char * handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:663
static int dosync
Definition: main/db.c:113
static char * handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:690
static void * db_sync_thread(void *data)
Definition: main/db.c:1025
static pthread_t syncthread
Definition: main/db.c:111
static void astdb_atexit(void)
Definition: main/db.c:1058
static char * handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:789
static int init_statements(void)
Definition: main/db.c:190
static int db_get_common(const char *family, const char *key, char **buffer, int bufferlen)
Definition: main/db.c:373
static int clean_stmt(sqlite3_stmt **stmt, const char *sql)
Definition: main/db.c:161
static char * handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:725
static int ast_db_rollback_transaction(void)
Definition: main/db.c:322
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
Definition: main/db.c:457
static char * handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/db.c:635
#define MAX_DB_FIELD
Definition: main/db.c:107
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
Definition: main/db.c:531
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define EVENT_FLAG_REPORTING
Definition: manager.h:84
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_SBIN_DIR
Definition: options.c:163
const char * ast_config_AST_DB
Definition: options.c:165
static char dbname[MAX_DB_OPTION_SIZE]
#define NULL
Definition: resample.c:96
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
Definition: astdb.h:31
struct ast_db_entry * next
Definition: astdb.h:32
char * key
Definition: astdb.h:33
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:1632
Definition: ast_expr2.c:325
int value
Definition: syslog.c:37
@ KEY
Definition: test_db.c:41
static struct test_val a
FILE * out
Definition: utils/frame.c:33
Utility functions.
#define ast_assert(a)
Definition: utils.h:734
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:587
#define ARRAY_LEN(a)
Definition: utils.h:661