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