update MANY more files with proper copyright/license info (thanks Ian!)
[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 /*
22  *
23  * 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         int arglen;
81         char *argv, *family, *keytree;
82
83         arglen = strlen(data);
84         argv = alloca(arglen + 1);
85         if (!argv) {    /* Why would this fail? */
86                 ast_log(LOG_DEBUG, "Memory allocation failed\n");
87                 return 0;
88         }
89         memcpy(argv, data, arglen + 1);
90
91         if (strchr(argv, '/')) {
92                 family = strsep(&argv, "/");
93                 keytree = strsep(&argv, "\0");
94                         if (!family || !keytree) {
95                                 ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
96                                 return 0;
97                         }
98                 if (!strlen(keytree))
99                         keytree = 0;
100         } else {
101                 family = argv;
102                 keytree = 0;
103         }
104
105         if (option_verbose > 2) {
106                 if (keytree)
107                         ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: family=%s, keytree=%s\n", family, keytree);
108                 else
109                         ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: family=%s\n", family);
110         }
111
112         if (ast_db_deltree(family, keytree)) {
113                 if (option_verbose > 2)
114                         ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: Error deleting key from database.\n");
115         }
116
117         return 0;
118 }
119
120 static int del_exec(struct ast_channel *chan, void *data)
121 {
122         int arglen;
123         char *argv, *family, *key;
124
125         arglen = strlen(data);
126         argv = alloca(arglen + 1);
127         if (!argv) {    /* Why would this fail? */
128                 ast_log (LOG_DEBUG, "Memory allocation failed\n");
129                 return 0;
130         }
131         memcpy(argv, data, arglen + 1);
132
133         if (strchr(argv, '/')) {
134                 family = strsep(&argv, "/");
135                 key = strsep(&argv, "\0");
136                 if (!family || !key) {
137                         ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
138                         return 0;
139                 }
140                 if (option_verbose > 2)
141                         ast_verbose(VERBOSE_PREFIX_3 "DBdel: family=%s, key=%s\n", family, key);
142                 if (ast_db_del(family, key)) {
143                         if (option_verbose > 2)
144                                 ast_verbose(VERBOSE_PREFIX_3 "DBdel: Error deleting key from database.\n");
145                 }
146         } else {
147                 ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
148         }
149         return 0;
150 }
151
152 static int put_exec(struct ast_channel *chan, void *data)
153 {
154         int arglen;
155         char *argv, *value, *family, *key;
156         static int dep_warning = 0;
157
158         if (!dep_warning) {
159                 ast_log(LOG_WARNING, "This application has been deprecated, please use the ${DB(family/key)} function instead.\n");
160                 dep_warning = 1;
161         }
162         
163         arglen = strlen(data);
164         argv = alloca(arglen + 1);
165         if (!argv) {    /* Why would this fail? */
166                 ast_log(LOG_DEBUG, "Memory allocation failed\n");
167                 return 0;
168         }
169         memcpy(argv, data, arglen + 1);
170
171         if (strchr(argv, '/') && strchr(argv, '=')) {
172                 family = strsep(&argv, "/");
173                 key = strsep(&argv, "=");
174                 value = strsep(&argv, "\0");
175                 if (!value || !family || !key) {
176                         ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
177                         return 0;
178                 }
179                 if (option_verbose > 2)
180                         ast_verbose(VERBOSE_PREFIX_3 "DBput: family=%s, key=%s, value=%s\n", family, key, value);
181                 if (ast_db_put(family, key, value)) {
182                         if (option_verbose > 2)
183                                 ast_verbose(VERBOSE_PREFIX_3 "DBput: Error writing value to database.\n");
184                 }
185
186         } else  {
187                 ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
188         }
189         return 0;
190 }
191
192 static int get_exec(struct ast_channel *chan, void *data)
193 {
194         int arglen;
195         char *argv, *varname, *family, *key;
196         char dbresult[256];
197         static int dep_warning = 0;
198
199         if (!dep_warning) {
200                 ast_log(LOG_WARNING, "This application has been deprecated, please use the ${DB(family/key)} function instead.\n");
201                 dep_warning = 1;
202         }
203         
204         arglen = strlen(data);
205         argv = alloca(arglen + 1);
206         if (!argv) {    /* Why would this fail? */
207                 ast_log(LOG_DEBUG, "Memory allocation failed\n");
208                 return 0;
209         }
210         memcpy(argv, data, arglen + 1);
211
212         if (strchr(argv, '=') && strchr(argv, '/')) {
213                 varname = strsep(&argv, "=");
214                 family = strsep(&argv, "/");
215                 key = strsep(&argv, "\0");
216                 if (!varname || !family || !key) {
217                         ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
218                         return 0;
219                 }
220                 if (option_verbose > 2)
221                         ast_verbose(VERBOSE_PREFIX_3 "DBget: varname=%s, family=%s, key=%s\n", varname, family, key);
222                 if (!ast_db_get(family, key, dbresult, sizeof (dbresult) - 1)) {
223                         pbx_builtin_setvar_helper(chan, varname, dbresult);
224                         if (option_verbose > 2)
225                                 ast_verbose(VERBOSE_PREFIX_3 "DBget: set variable %s to %s\n", varname, dbresult);
226                 } else {
227                         if (option_verbose > 2)
228                         ast_verbose(VERBOSE_PREFIX_3 "DBget: Value not found in database.\n");
229                         /* Send the call to n+101 priority, where n is the current priority */
230                         if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num))
231                                 chan->priority += 100;
232                 }
233
234         } else {
235                 ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
236         }
237         return 0;
238 }
239
240 int unload_module(void)
241 {
242         int retval;
243
244         STANDARD_HANGUP_LOCALUSERS;
245         retval = ast_unregister_application(dt_app);
246         retval |= ast_unregister_application(d_app);
247         retval |= ast_unregister_application(p_app);
248         retval |= ast_unregister_application(g_app);
249
250         return retval;
251 }
252
253 int load_module(void)
254 {
255         int retval;
256
257         retval = ast_register_application(g_app, get_exec, g_synopsis, g_descrip);
258         if (!retval)
259                 retval = ast_register_application(p_app, put_exec, p_synopsis, p_descrip);
260         if (!retval)
261                 retval = ast_register_application(d_app, del_exec, d_synopsis, d_descrip);
262         if (!retval)
263                 retval = ast_register_application(dt_app, deltree_exec, dt_synopsis, dt_descrip);
264         return retval;
265 }
266
267 char *description(void)
268 {
269         return tdesc;
270 }
271
272 int usecount(void)
273 {
274         int res;
275         STANDARD_USECOUNT(res);
276         return res;
277 }
278
279 char *key()
280 {
281         return ASTERISK_GPL_KEY;
282 }