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