Use older functions out of deference to older distros
[asterisk/asterisk.git] / main / db.c
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 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/_private.h"
35 #include "asterisk/paths.h"     /* use ast_config_AST_DB */
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <unistd.h>
40 #include <signal.h>
41 #include <dirent.h>
42 #include <sqlite3.h>
43
44 #include "asterisk/channel.h"
45 #include "asterisk/file.h"
46 #include "asterisk/app.h"
47 #include "asterisk/dsp.h"
48 #include "asterisk/astdb.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/utils.h"
51 #include "asterisk/manager.h"
52
53 /*** DOCUMENTATION
54         <manager name="DBGet" language="en_US">
55                 <synopsis>
56                         Get DB Entry.
57                 </synopsis>
58                 <syntax>
59                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
60                         <parameter name="Family" required="true" />
61                         <parameter name="Key" required="true" />
62                 </syntax>
63                 <description>
64                 </description>
65         </manager>
66         <manager name="DBPut" language="en_US">
67                 <synopsis>
68                         Put DB entry.
69                 </synopsis>
70                 <syntax>
71                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
72                         <parameter name="Family" required="true" />
73                         <parameter name="Key" required="true" />
74                         <parameter name="Val" />
75                 </syntax>
76                 <description>
77                 </description>
78         </manager>
79         <manager name="DBDel" language="en_US">
80                 <synopsis>
81                         Delete DB entry.
82                 </synopsis>
83                 <syntax>
84                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
85                         <parameter name="Family" required="true" />
86                         <parameter name="Key" required="true" />
87                 </syntax>
88                 <description>
89                 </description>
90         </manager>
91         <manager name="DBDelTree" language="en_US">
92                 <synopsis>
93                         Delete DB Tree.
94                 </synopsis>
95                 <syntax>
96                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
97                         <parameter name="Family" required="true" />
98                         <parameter name="Key" />
99                 </syntax>
100                 <description>
101                 </description>
102         </manager>
103  ***/
104
105 #define MAX_DB_FIELD 256
106 AST_MUTEX_DEFINE_STATIC(dblock);
107 static ast_cond_t dbcond;
108 static sqlite3 *astdb;
109 static pthread_t syncthread;
110 static int doexit;
111
112 static void db_sync(void);
113
114 #define DEFINE_SQL_STATEMENT(stmt,sql) static sqlite3_stmt *stmt; \
115         const char stmt##_sql[] = sql;
116
117 DEFINE_SQL_STATEMENT(put_stmt, "INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)")
118 DEFINE_SQL_STATEMENT(get_stmt, "SELECT value FROM astdb WHERE key=?")
119 DEFINE_SQL_STATEMENT(del_stmt, "DELETE FROM astdb WHERE key=?")
120 DEFINE_SQL_STATEMENT(deltree_stmt, "DELETE FROM astdb WHERE key LIKE ? || '/' || '%'")
121 DEFINE_SQL_STATEMENT(deltree_all_stmt, "DELETE FROM astdb")
122 DEFINE_SQL_STATEMENT(gettree_stmt, "SELECT key, value FROM astdb WHERE key LIKE ? || '/' || '%'")
123 DEFINE_SQL_STATEMENT(gettree_all_stmt, "SELECT key, value FROM astdb")
124 DEFINE_SQL_STATEMENT(showkey_stmt, "SELECT key, value FROM astdb WHERE key LIKE '%' || '/' || ?")
125 DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))")
126
127 static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
128 {
129         ast_mutex_lock(&dblock);
130         if (sqlite3_prepare(astdb, sql, len, stmt, NULL) != SQLITE_OK) {
131                 ast_log(LOG_WARNING, "Couldn't prepare statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
132                 ast_mutex_unlock(&dblock);
133                 return -1;
134         }
135         ast_mutex_unlock(&dblock);
136
137         return 0;
138 }
139
140 static int init_statements(void)
141 {
142         /* Don't initialize create_astdb_statment here as the astdb table needs to exist
143          * brefore these statments can be initialized */
144         return init_stmt(&get_stmt, get_stmt_sql, sizeof(get_stmt_sql))
145         || init_stmt(&del_stmt, del_stmt_sql, sizeof(del_stmt_sql))
146         || init_stmt(&deltree_stmt, deltree_stmt_sql, sizeof(deltree_stmt_sql))
147         || init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
148         || init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
149         || init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
150         || init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
151         || init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
152 }
153
154 static int convert_bdb_to_sqlite3(void)
155 {
156         char *cmd;
157         int res;
158
159         ast_asprintf(&cmd, "astdb2sqlite3 '%s'\n", ast_config_AST_DB);
160         res = ast_safe_system(cmd);
161         ast_free(cmd);
162
163         return res;
164 }
165
166 static int db_create_astdb(void)
167 {
168         int res = 0;
169
170         if (!create_astdb_stmt) {
171                 init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
172         }
173
174         ast_mutex_lock(&dblock);
175         if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
176                 ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
177                 res = -1;
178         }
179         sqlite3_reset(create_astdb_stmt);
180         db_sync();
181         ast_mutex_unlock(&dblock);
182
183         return res;
184 }
185
186 static int db_open(void)
187 {
188         char *dbname;
189         struct stat dont_care;
190
191         if (!(dbname = alloca(strlen(ast_config_AST_DB) + sizeof(".sqlite3")))) {
192                 return -1;
193         }
194         strcpy(dbname, ast_config_AST_DB);
195         strcat(dbname, ".sqlite3");
196
197         if (stat(dbname, &dont_care) && !stat(ast_config_AST_DB, &dont_care)) {
198                 if (convert_bdb_to_sqlite3()) {
199                         ast_log(LOG_ERROR, "*** Database conversion failed!\n");
200                         ast_log(LOG_ERROR, "*** Asterisk now uses SQLite3 for its internal\n");
201                         ast_log(LOG_ERROR, "*** database. Conversion from the old astdb\n");
202                         ast_log(LOG_ERROR, "*** failed. Most likely the astdb2sqlite3 utility\n");
203                         ast_log(LOG_ERROR, "*** was not selected for build. To convert the\n");
204                         ast_log(LOG_ERROR, "*** old astdb, please delete '%s'\n", dbname);
205                         ast_log(LOG_ERROR, "*** and re-run 'make menuselect' and select astdb2sqlite3\n");
206                         ast_log(LOG_ERROR, "*** in the Utilities section, then 'make && make install'.\n");
207                         sleep(5);
208                 } else {
209                         ast_log(LOG_NOTICE, "Database conversion succeeded!\n");
210                 }
211         }
212
213         ast_mutex_lock(&dblock);
214         if (sqlite3_open(dbname, &astdb) != SQLITE_OK) {
215                 ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", dbname, sqlite3_errmsg(astdb));
216                 sqlite3_close(astdb);
217                 ast_mutex_unlock(&dblock);
218                 return -1;
219         }
220         ast_mutex_unlock(&dblock);
221
222         return 0;
223 }
224
225 static int db_init(void)
226 {
227         if (astdb) {
228                 return 0;
229         }
230
231         if (db_open() || db_create_astdb() || init_statements()) {
232                 return -1;
233         }
234
235         return 0;
236 }
237
238 /* We purposely don't lock around the sqlite3 call because the transaction
239  * calls will be called with the database lock held. For any other use, make
240  * sure to take the dblock yourself. */
241 static int db_execute_sql(const char *sql, int (*callback)(void *, int, char **, char **), void *arg)
242 {
243         char *errmsg = NULL;
244         int res =0;
245
246         sqlite3_exec(astdb, sql, callback, arg, &errmsg);
247         if (errmsg) {
248                 ast_log(LOG_WARNING, "Error executing SQL: %s\n", errmsg);
249                 sqlite3_free(errmsg);
250                 res = -1;
251         }
252
253         return res;
254 }
255
256 static int ast_db_begin_transaction(void)
257 {
258         return db_execute_sql("BEGIN TRANSACTION", NULL, NULL);
259 }
260
261 static int ast_db_commit_transaction(void)
262 {
263         return db_execute_sql("COMMIT", NULL, NULL);
264 }
265
266 static int ast_db_rollback_transaction(void)
267 {
268         return db_execute_sql("ROLLBACK", NULL, NULL);
269 }
270
271 int ast_db_put(const char *family, const char *key, const char *value)
272 {
273         char fullkey[MAX_DB_FIELD];
274         size_t fullkey_len;
275         int res = 0;
276
277         if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
278                 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
279                 return -1;
280         }
281
282         fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
283
284         ast_mutex_lock(&dblock);
285         if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
286                 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
287                 res = -1;
288         } else if (sqlite3_bind_text(put_stmt, 2, value, -1, SQLITE_STATIC) != SQLITE_OK) {
289                 ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
290                 res = -1;
291         } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
292                 ast_log(LOG_WARNING, "Couldn't execute statment: %s\n", sqlite3_errmsg(astdb));
293                 res = -1;
294         }
295
296         sqlite3_reset(put_stmt);
297         db_sync();
298         ast_mutex_unlock(&dblock);
299
300         return res;
301 }
302
303 int ast_db_get(const char *family, const char *key, char *value, int valuelen)
304 {
305         const unsigned char *result;
306         char fullkey[MAX_DB_FIELD];
307         size_t fullkey_len;
308         int res = 0;
309
310         if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
311                 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
312                 return -1;
313         }
314
315         fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
316
317         ast_mutex_lock(&dblock);
318         if (sqlite3_bind_text(get_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
319                 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
320                 res = -1;
321         } else if (sqlite3_step(get_stmt) != SQLITE_ROW) {
322                 ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
323                 res = -1;
324         } else if (!(result = sqlite3_column_text(get_stmt, 0))) {
325                 ast_log(LOG_WARNING, "Couldn't get value\n");
326                 res = -1;
327         } else {
328                 strncpy(value, (const char *) result, valuelen);
329         }
330         sqlite3_reset(get_stmt);
331         ast_mutex_unlock(&dblock);
332
333         return res;
334 }
335
336 int ast_db_del(const char *family, const char *key)
337 {
338         char fullkey[MAX_DB_FIELD];
339         size_t fullkey_len;
340         int res = 0;
341
342         if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
343                 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
344                 return -1;
345         }
346
347         fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
348
349         ast_mutex_lock(&dblock);
350         if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
351                 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
352                 res = -1;
353         } else if (sqlite3_step(del_stmt) != SQLITE_DONE) {
354                 ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
355                 res = -1;
356         }
357         sqlite3_reset(del_stmt);
358         db_sync();
359         ast_mutex_unlock(&dblock);
360
361         return res;
362 }
363
364 int ast_db_deltree(const char *family, const char *subfamily)
365 {
366         sqlite3_stmt *stmt = deltree_stmt;
367         char prefix[MAX_DB_FIELD];
368         int res = 0;
369
370         if (!ast_strlen_zero(family)) {
371                 if (!ast_strlen_zero(subfamily)) {
372                         /* Family and key tree */
373                         snprintf(prefix, sizeof(prefix), "/%s/%s", family, subfamily);
374                 } else {
375                         /* Family only */
376                         snprintf(prefix, sizeof(prefix), "/%s", family);
377                 }
378         } else {
379                 prefix[0] = '\0';
380                 stmt = deltree_all_stmt;
381         }
382
383         ast_mutex_lock(&dblock);
384         if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
385                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
386                 res = -1;
387         } else if (sqlite3_step(stmt) != SQLITE_DONE) {
388                 ast_log(LOG_WARNING, "Couldn't execute stmt: %s\n", sqlite3_errmsg(astdb));
389                 res = -1;
390         }
391         res = sqlite3_changes(astdb);
392         sqlite3_reset(stmt);
393         db_sync();
394         ast_mutex_unlock(&dblock);
395
396         return res;
397 }
398
399 struct ast_db_entry *ast_db_gettree(const char *family, const char *subfamily)
400 {
401         char prefix[MAX_DB_FIELD];
402         sqlite3_stmt *stmt = gettree_stmt;
403         struct ast_db_entry *cur, *last = NULL, *ret = NULL;
404
405         if (!ast_strlen_zero(family)) {
406                 if (!ast_strlen_zero(subfamily)) {
407                         /* Family and key tree */
408                         snprintf(prefix, sizeof(prefix), "/%s/%s", family, subfamily);
409                 } else {
410                         /* Family only */
411                         snprintf(prefix, sizeof(prefix), "/%s", family);
412                 }
413         } else {
414                 prefix[0] = '\0';
415                 stmt = gettree_all_stmt;
416         }
417
418         ast_mutex_lock(&dblock);
419         if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
420                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
421                 sqlite3_reset(stmt);
422                 ast_mutex_unlock(&dblock);
423                 return NULL;
424         }
425
426         while (sqlite3_step(stmt) == SQLITE_ROW) {
427                 const char *key_s, *value_s;
428                 if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
429                         break;
430                 }
431                 if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
432                         break;
433                 }
434                 if (!(cur = ast_malloc(sizeof(*cur) + strlen(key_s) + strlen(value_s) + 2))) {
435                         break;
436                 }
437                 cur->next = NULL;
438                 cur->key = cur->data + strlen(value_s) + 1;
439                 strcpy(cur->data, value_s);
440                 strcpy(cur->key, key_s);
441                 if (last) {
442                         last->next = cur;
443                 } else {
444                         ret = cur;
445                 }
446                 last = cur;
447         }
448         sqlite3_reset(stmt);
449         ast_mutex_unlock(&dblock);
450
451         return ret;
452 }
453
454 void ast_db_freetree(struct ast_db_entry *dbe)
455 {
456         struct ast_db_entry *last;
457         while (dbe) {
458                 last = dbe;
459                 dbe = dbe->next;
460                 ast_free(last);
461         }
462 }
463
464 static char *handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
465 {
466         int res;
467
468         switch (cmd) {
469         case CLI_INIT:
470                 e->command = "database put";
471                 e->usage =
472                         "Usage: database put <family> <key> <value>\n"
473                         "       Adds or updates an entry in the Asterisk database for\n"
474                         "       a given family, key, and value.\n";
475                 return NULL;
476         case CLI_GENERATE:
477                 return NULL;
478         }
479
480         if (a->argc != 5)
481                 return CLI_SHOWUSAGE;
482         res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
483         if (res)  {
484                 ast_cli(a->fd, "Failed to update entry\n");
485         } else {
486                 ast_cli(a->fd, "Updated database successfully\n");
487         }
488         return CLI_SUCCESS;
489 }
490
491 static char *handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
492 {
493         int res;
494         char tmp[MAX_DB_FIELD];
495
496         switch (cmd) {
497         case CLI_INIT:
498                 e->command = "database get";
499                 e->usage =
500                         "Usage: database get <family> <key>\n"
501                         "       Retrieves an entry in the Asterisk database for a given\n"
502                         "       family and key.\n";
503                 return NULL;
504         case CLI_GENERATE:
505                 return NULL;
506         }
507
508         if (a->argc != 4)
509                 return CLI_SHOWUSAGE;
510         res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
511         if (res) {
512                 ast_cli(a->fd, "Database entry not found.\n");
513         } else {
514                 ast_cli(a->fd, "Value: %s\n", tmp);
515         }
516         return CLI_SUCCESS;
517 }
518
519 static char *handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
520 {
521         int res;
522
523         switch (cmd) {
524         case CLI_INIT:
525                 e->command = "database del";
526                 e->usage =
527                         "Usage: database del <family> <key>\n"
528                         "       Deletes an entry in the Asterisk database for a given\n"
529                         "       family and key.\n";
530                 return NULL;
531         case CLI_GENERATE:
532                 return NULL;
533         }
534
535         if (a->argc != 4)
536                 return CLI_SHOWUSAGE;
537         res = ast_db_del(a->argv[2], a->argv[3]);
538         if (res) {
539                 ast_cli(a->fd, "Database entry does not exist.\n");
540         } else {
541                 ast_cli(a->fd, "Database entry removed.\n");
542         }
543         return CLI_SUCCESS;
544 }
545
546 static char *handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
547 {
548         int res;
549
550         switch (cmd) {
551         case CLI_INIT:
552                 e->command = "database deltree";
553                 e->usage =
554                         "Usage: database deltree <family> [subfamily]\n"
555                         "       Deletes a family or specific subfamily within a family\n"
556                         "       in the Asterisk database.\n";
557                 return NULL;
558         case CLI_GENERATE:
559                 return NULL;
560         }
561
562         if ((a->argc < 3) || (a->argc > 4))
563                 return CLI_SHOWUSAGE;
564         if (a->argc == 4) {
565                 res = ast_db_deltree(a->argv[2], a->argv[3]);
566         } else {
567                 res = ast_db_deltree(a->argv[2], NULL);
568         }
569         if (res < 0) {
570                 ast_cli(a->fd, "Database entries do not exist.\n");
571         } else {
572                 ast_cli(a->fd, "%d database entries removed.\n",res);
573         }
574         return CLI_SUCCESS;
575 }
576
577 static char *handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
578 {
579         char prefix[MAX_DB_FIELD];
580         int counter = 0;
581         sqlite3_stmt *stmt = gettree_stmt;
582
583         switch (cmd) {
584         case CLI_INIT:
585                 e->command = "database show";
586                 e->usage =
587                         "Usage: database show [family [subfamily]]\n"
588                         "       Shows Asterisk database contents, optionally restricted\n"
589                         "       to a given family, or family and subfamily.\n";
590                 return NULL;
591         case CLI_GENERATE:
592                 return NULL;
593         }
594
595         if (a->argc == 4) {
596                 /* Family and key tree */
597                 snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
598         } else if (a->argc == 3) {
599                 /* Family only */
600                 snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
601         } else if (a->argc == 2) {
602                 /* Neither */
603                 prefix[0] = '\0';
604                 stmt = gettree_all_stmt;
605
606         } else {
607                 return CLI_SHOWUSAGE;
608         }
609
610         ast_mutex_lock(&dblock);
611         if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
612                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
613                 sqlite3_reset(stmt);
614                 ast_mutex_unlock(&dblock);
615                 return NULL;
616         }
617
618         while (sqlite3_step(stmt) == SQLITE_ROW) {
619                 const char *key_s, *value_s;
620                 if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
621                         ast_log(LOG_WARNING, "Skipping invalid key!\n");
622                         continue;
623                 }
624                 if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
625                         ast_log(LOG_WARNING, "Skipping invalid value!\n");
626                         continue;
627                 }
628                 ++counter;
629                 ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
630         }
631
632         sqlite3_reset(stmt);
633         ast_mutex_unlock(&dblock);
634
635         ast_cli(a->fd, "%d results found.\n", counter);
636         return CLI_SUCCESS;
637 }
638
639 static char *handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
640 {
641         int counter = 0;
642
643         switch (cmd) {
644         case CLI_INIT:
645                 e->command = "database showkey";
646                 e->usage =
647                         "Usage: database showkey <subfamily>\n"
648                         "       Shows Asterisk database contents, restricted to a given key.\n";
649                 return NULL;
650         case CLI_GENERATE:
651                 return NULL;
652         }
653
654         if (a->argc != 3) {
655                 return CLI_SHOWUSAGE;
656         }
657
658         ast_mutex_lock(&dblock);
659         if (!ast_strlen_zero(a->argv[2]) && (sqlite3_bind_text(showkey_stmt, 1, a->argv[2], -1, SQLITE_STATIC) != SQLITE_OK)) {
660                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", a->argv[2], sqlite3_errmsg(astdb));
661                 sqlite3_reset(showkey_stmt);
662                 ast_mutex_unlock(&dblock);
663                 return NULL;
664         }
665
666         while (sqlite3_step(showkey_stmt) == SQLITE_ROW) {
667                 const char *key_s, *value_s;
668                 if (!(key_s = (const char *) sqlite3_column_text(showkey_stmt, 0))) {
669                         break;
670                 }
671                 if (!(value_s = (const char *) sqlite3_column_text(showkey_stmt, 1))) {
672                         break;
673                 }
674                 ++counter;
675                 ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
676         }
677         sqlite3_reset(showkey_stmt);
678         ast_mutex_unlock(&dblock);
679
680         ast_cli(a->fd, "%d results found.\n", counter);
681         return CLI_SUCCESS;
682 }
683
684 static int display_results(void *arg, int columns, char **values, char **colnames)
685 {
686         struct ast_cli_args *a = arg;
687         size_t x;
688
689         for (x = 0; x < columns; x++) {
690                 ast_cli(a->fd, "%-5s: %-50s\n", colnames[x], values[x]);
691         }
692         ast_cli(a->fd, "\n");
693
694         return 0;
695 }
696
697 static char *handle_cli_database_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
698 {
699
700         switch (cmd) {
701         case CLI_INIT:
702                 e->command = "database query";
703                 e->usage =
704                         "Usage: database query \"<SQL Statement>\"\n"
705                         "       Run a user-specified SQL query on the database. Be careful.\n";
706                 return NULL;
707         case CLI_GENERATE:
708                 return NULL;
709         }
710
711         if (a->argc != 3) {
712                 return CLI_SHOWUSAGE;
713         }
714
715         ast_mutex_lock(&dblock);
716         db_execute_sql(a->argv[2], display_results, a);
717         db_sync(); /* Go ahead and sync the db in case they write */
718         ast_mutex_unlock(&dblock);
719
720         return CLI_SUCCESS;
721 }
722
723 static struct ast_cli_entry cli_database[] = {
724         AST_CLI_DEFINE(handle_cli_database_show,    "Shows database contents"),
725         AST_CLI_DEFINE(handle_cli_database_showkey, "Shows database contents"),
726         AST_CLI_DEFINE(handle_cli_database_get,     "Gets database value"),
727         AST_CLI_DEFINE(handle_cli_database_put,     "Adds/updates database value"),
728         AST_CLI_DEFINE(handle_cli_database_del,     "Removes database key/value"),
729         AST_CLI_DEFINE(handle_cli_database_deltree, "Removes database subfamily/values"),
730         AST_CLI_DEFINE(handle_cli_database_query,   "Run a user-specified query on the astdb"),
731 };
732
733 static int manager_dbput(struct mansession *s, const struct message *m)
734 {
735         const char *family = astman_get_header(m, "Family");
736         const char *key = astman_get_header(m, "Key");
737         const char *val = astman_get_header(m, "Val");
738         int res;
739
740         if (ast_strlen_zero(family)) {
741                 astman_send_error(s, m, "No family specified");
742                 return 0;
743         }
744         if (ast_strlen_zero(key)) {
745                 astman_send_error(s, m, "No key specified");
746                 return 0;
747         }
748
749         res = ast_db_put(family, key, S_OR(val, ""));
750         if (res) {
751                 astman_send_error(s, m, "Failed to update entry");
752         } else {
753                 astman_send_ack(s, m, "Updated database successfully");
754         }
755         return 0;
756 }
757
758 static int manager_dbget(struct mansession *s, const struct message *m)
759 {
760         const char *id = astman_get_header(m,"ActionID");
761         char idText[256] = "";
762         const char *family = astman_get_header(m, "Family");
763         const char *key = astman_get_header(m, "Key");
764         char tmp[MAX_DB_FIELD];
765         int res;
766
767         if (ast_strlen_zero(family)) {
768                 astman_send_error(s, m, "No family specified.");
769                 return 0;
770         }
771         if (ast_strlen_zero(key)) {
772                 astman_send_error(s, m, "No key specified.");
773                 return 0;
774         }
775
776         if (!ast_strlen_zero(id))
777                 snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
778
779         res = ast_db_get(family, key, tmp, sizeof(tmp));
780         if (res) {
781                 astman_send_error(s, m, "Database entry not found");
782         } else {
783                 astman_send_ack(s, m, "Result will follow");
784                 astman_append(s, "Event: DBGetResponse\r\n"
785                                 "Family: %s\r\n"
786                                 "Key: %s\r\n"
787                                 "Val: %s\r\n"
788                                 "%s"
789                                 "\r\n",
790                                 family, key, tmp, idText);
791                 astman_append(s, "Event: DBGetComplete\r\n"
792                                 "%s"
793                                 "\r\n",
794                                 idText);
795         }
796         return 0;
797 }
798
799 static int manager_dbdel(struct mansession *s, const struct message *m)
800 {
801         const char *family = astman_get_header(m, "Family");
802         const char *key = astman_get_header(m, "Key");
803         int res;
804
805         if (ast_strlen_zero(family)) {
806                 astman_send_error(s, m, "No family specified.");
807                 return 0;
808         }
809
810         if (ast_strlen_zero(key)) {
811                 astman_send_error(s, m, "No key specified.");
812                 return 0;
813         }
814
815         res = ast_db_del(family, key);
816         if (res)
817                 astman_send_error(s, m, "Database entry not found");
818         else
819                 astman_send_ack(s, m, "Key deleted successfully");
820
821         return 0;
822 }
823
824 static int manager_dbdeltree(struct mansession *s, const struct message *m)
825 {
826         const char *family = astman_get_header(m, "Family");
827         const char *key = astman_get_header(m, "Key");
828         int res;
829
830         if (ast_strlen_zero(family)) {
831                 astman_send_error(s, m, "No family specified.");
832                 return 0;
833         }
834
835         if (!ast_strlen_zero(key))
836                 res = ast_db_deltree(family, key);
837         else
838                 res = ast_db_deltree(family, NULL);
839
840         if (res < 0)
841                 astman_send_error(s, m, "Database entry not found");
842         else
843                 astman_send_ack(s, m, "Key tree deleted successfully");
844
845         return 0;
846 }
847
848 /*!
849  * \internal
850  * \brief Signal the astdb sync thread to do its thing.
851  *
852  * \note dblock is assumed to be held when calling this function.
853  */
854 static void db_sync(void)
855 {
856         ast_cond_signal(&dbcond);
857 }
858
859 /*!
860  * \internal
861  * \brief astdb sync thread
862  *
863  * This thread is in charge of syncing astdb to disk after a change.
864  * By pushing it off to this thread to take care of, this I/O bound operation
865  * will not block other threads from performing other critical processing.
866  * If changes happen rapidly, this thread will also ensure that the sync
867  * operations are rate limited.
868  */
869 static void *db_sync_thread(void *data)
870 {
871         ast_mutex_lock(&dblock);
872         ast_db_begin_transaction();
873         for (;;) {
874                 /* We're ok with spurious wakeups, so we don't worry about a predicate */
875                 ast_cond_wait(&dbcond, &dblock);
876                 if (ast_db_commit_transaction()) {
877                         ast_db_rollback_transaction();
878                 }
879                 if (doexit) {
880                         ast_mutex_unlock(&dblock);
881                         break;
882                 }
883                 ast_db_begin_transaction();
884                 ast_mutex_unlock(&dblock);
885                 sleep(1);
886                 ast_mutex_lock(&dblock);
887         }
888
889         return NULL;
890 }
891
892 static void astdb_atexit(void)
893 {
894         doexit = 1;
895         db_sync();
896         pthread_join(syncthread, NULL);
897         ast_mutex_lock(&dblock);
898         sqlite3_close(astdb);
899         ast_mutex_unlock(&dblock);
900 }
901
902 int astdb_init(void)
903 {
904         if (db_init()) {
905                 return -1;
906         }
907
908         ast_cond_init(&dbcond, NULL);
909         if (ast_pthread_create_background(&syncthread, NULL, db_sync_thread, NULL)) {
910                 return -1;
911         }
912
913         ast_register_atexit(astdb_atexit);
914         ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database));
915         ast_manager_register_xml("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget);
916         ast_manager_register_xml("DBPut", EVENT_FLAG_SYSTEM, manager_dbput);
917         ast_manager_register_xml("DBDel", EVENT_FLAG_SYSTEM, manager_dbdel);
918         ast_manager_register_xml("DBDelTree", EVENT_FLAG_SYSTEM, manager_dbdeltree);
919         return 0;
920 }