Doxygen documentation update from oej (issue #5505)
[asterisk/asterisk.git] / apps / app_db.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  * Copyright (C) 2003, Jefferson Noxon
6  *
7  * Mark Spencer <markster@digium.com>
8  * Jefferson Noxon <jeff@debian.org>
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20
21 /*! \file
22  *
23  * \brief Database access functions
24  *
25  */
26
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/types.h>
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include "asterisk/options.h"
37 #include "asterisk/file.h"
38 #include "asterisk/logger.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/module.h"
42 #include "asterisk/astdb.h"
43 #include "asterisk/lock.h"
44
45 static char *tdesc = "Database access functions for Asterisk extension logic";
46
47 static char *g_descrip =
48         "  DBget(varname=family/key): Retrieves a value from the Asterisk\n"
49         "database and stores it in the given variable.  Always returns 0.  If the\n"
50         "requested key is not found, jumps to priority n+101 if available.\n";
51
52 static char *p_descrip =
53         "  DBput(family/key=value): Stores the given value in the Asterisk\n"
54         "database.  Always returns 0.\n";
55
56 static char *d_descrip =
57         "  DBdel(family/key): Deletes a key from the Asterisk database.  Always\n"
58         "returns 0.\n";
59
60 static char *dt_descrip =
61         "  DBdeltree(family[/keytree]): Deletes a family or keytree from the Asterisk\n"
62         "database.  Always returns 0.\n";
63
64 static char *g_app = "DBget";
65 static char *p_app = "DBput";
66 static char *d_app = "DBdel";
67 static char *dt_app = "DBdeltree";
68
69 static char *g_synopsis = "Retrieve a value from the database";
70 static char *p_synopsis = "Store a value in the database";
71 static char *d_synopsis = "Delete a key from the database";
72 static char *dt_synopsis = "Delete a family or keytree from the database";
73
74 STANDARD_LOCAL_USER;
75
76 LOCAL_USER_DECL;
77
78 static int deltree_exec(struct ast_channel *chan, void *data)
79 {
80         char *argv, *family, *keytree;
81         struct localuser *u;
82
83         LOCAL_USER_ADD(u);
84
85         argv = ast_strdupa(data);
86         if (!argv) {
87                 ast_log(LOG_ERROR, "Memory allocation failed\n");
88                 LOCAL_USER_REMOVE(u);
89                 return 0;
90         }
91
92         if (strchr(argv, '/')) {
93                 family = strsep(&argv, "/");
94                 keytree = strsep(&argv, "\0");
95                         if (!family || !keytree) {
96                                 ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
97                                 LOCAL_USER_REMOVE(u);
98                                 return 0;
99                         }
100                 if (!strlen(keytree))
101                         keytree = 0;
102         } else {
103                 family = argv;
104                 keytree = 0;
105         }
106
107         if (option_verbose > 2) {
108                 if (keytree)
109                         ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: family=%s, keytree=%s\n", family, keytree);
110                 else
111                         ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: family=%s\n", family);
112         }
113
114         if (ast_db_deltree(family, keytree)) {
115                 if (option_verbose > 2)
116                         ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: Error deleting key from database.\n");
117         }
118
119         LOCAL_USER_REMOVE(u);
120
121         return 0;
122 }
123
124 static int del_exec(struct ast_channel *chan, void *data)
125 {
126         char *argv, *family, *key;
127         struct localuser *u;
128
129         LOCAL_USER_ADD(u);
130
131         argv = ast_strdupa(data);
132         if (!argv) {
133                 ast_log (LOG_ERROR, "Memory allocation failed\n");
134                 LOCAL_USER_REMOVE(u);
135                 return 0;
136         }
137
138         if (strchr(argv, '/')) {
139                 family = strsep(&argv, "/");
140                 key = strsep(&argv, "\0");
141                 if (!family || !key) {
142                         ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
143                         LOCAL_USER_REMOVE(u);
144                         return 0;
145                 }
146                 if (option_verbose > 2)
147                         ast_verbose(VERBOSE_PREFIX_3 "DBdel: family=%s, key=%s\n", family, key);
148                 if (ast_db_del(family, key)) {
149                         if (option_verbose > 2)
150                                 ast_verbose(VERBOSE_PREFIX_3 "DBdel: Error deleting key from database.\n");
151                 }
152         } else {
153                 ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
154         }
155
156         LOCAL_USER_REMOVE(u);
157         
158         return 0;
159 }
160
161 static int put_exec(struct ast_channel *chan, void *data)
162 {
163         char *argv, *value, *family, *key;
164         static int dep_warning = 0;
165         struct localuser *u;
166
167         LOCAL_USER_ADD(u);
168
169         if (!dep_warning) {
170                 ast_log(LOG_WARNING, "This application has been deprecated, please use the ${DB(family/key)} function instead.\n");
171                 dep_warning = 1;
172         }
173         
174         argv = ast_strdupa(data);
175         if (!argv) {
176                 ast_log(LOG_ERROR, "Memory allocation failed\n");
177                 LOCAL_USER_REMOVE(u);
178                 return 0;
179         }
180
181         if (strchr(argv, '/') && strchr(argv, '=')) {
182                 family = strsep(&argv, "/");
183                 key = strsep(&argv, "=");
184                 value = strsep(&argv, "\0");
185                 if (!value || !family || !key) {
186                         ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
187                         LOCAL_USER_REMOVE(u);
188                         return 0;
189                 }
190                 if (option_verbose > 2)
191                         ast_verbose(VERBOSE_PREFIX_3 "DBput: family=%s, key=%s, value=%s\n", family, key, value);
192                 if (ast_db_put(family, key, value)) {
193                         if (option_verbose > 2)
194                                 ast_verbose(VERBOSE_PREFIX_3 "DBput: Error writing value to database.\n");
195                 }
196
197         } else  {
198                 ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
199         }
200
201         LOCAL_USER_REMOVE(u);
202
203         return 0;
204 }
205
206 static int get_exec(struct ast_channel *chan, void *data)
207 {
208         char *argv, *varname, *family, *key;
209         char dbresult[256];
210         static int dep_warning = 0;
211         struct localuser *u;
212
213         LOCAL_USER_ADD(u);
214
215         if (!dep_warning) {
216                 ast_log(LOG_WARNING, "This application has been deprecated, please use the ${DB(family/key)} function instead.\n");
217                 dep_warning = 1;
218         }
219         
220         argv = ast_strdupa(data);
221         if (!argv) {
222                 ast_log(LOG_ERROR, "Memory allocation failed\n");
223                 LOCAL_USER_REMOVE(u);
224                 return 0;
225         }
226
227         if (strchr(argv, '=') && strchr(argv, '/')) {
228                 varname = strsep(&argv, "=");
229                 family = strsep(&argv, "/");
230                 key = strsep(&argv, "\0");
231                 if (!varname || !family || !key) {
232                         ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
233                         LOCAL_USER_REMOVE(u);
234                         return 0;
235                 }
236                 if (option_verbose > 2)
237                         ast_verbose(VERBOSE_PREFIX_3 "DBget: varname=%s, family=%s, key=%s\n", varname, family, key);
238                 if (!ast_db_get(family, key, dbresult, sizeof (dbresult) - 1)) {
239                         pbx_builtin_setvar_helper(chan, varname, dbresult);
240                         if (option_verbose > 2)
241                                 ast_verbose(VERBOSE_PREFIX_3 "DBget: set variable %s to %s\n", varname, dbresult);
242                 } else {
243                         if (option_verbose > 2)
244                         ast_verbose(VERBOSE_PREFIX_3 "DBget: Value not found in database.\n");
245                         /* Send the call to n+101 priority, where n is the current priority */
246                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
247                 }
248         } else {
249                 ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
250         }
251
252         LOCAL_USER_REMOVE(u);
253
254         return 0;
255 }
256
257 int unload_module(void)
258 {
259         int retval;
260
261         retval = ast_unregister_application(dt_app);
262         retval |= ast_unregister_application(d_app);
263         retval |= ast_unregister_application(p_app);
264         retval |= ast_unregister_application(g_app);
265
266         STANDARD_HANGUP_LOCALUSERS;
267
268         return retval;
269 }
270
271 int load_module(void)
272 {
273         int retval;
274
275         retval = ast_register_application(g_app, get_exec, g_synopsis, g_descrip);
276         retval |= ast_register_application(p_app, put_exec, p_synopsis, p_descrip);
277         retval |= ast_register_application(d_app, del_exec, d_synopsis, d_descrip);
278         retval |= ast_register_application(dt_app, deltree_exec, dt_synopsis, dt_descrip);
279         
280         return retval;
281 }
282
283 char *description(void)
284 {
285         return tdesc;
286 }
287
288 int usecount(void)
289 {
290         int res;
291         STANDARD_USECOUNT(res);
292         return res;
293 }
294
295 char *key()
296 {
297         return ASTERISK_GPL_KEY;
298 }