app_voicemail/IMAP: check mailstream not NULL in leave_voicemail
[asterisk/asterisk.git] / res / res_realtime.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Anthony Minessale <anthmct@yahoo.com>
7  * Mark Spencer <markster@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \brief RealTime CLI
23  *
24  * \author Anthony Minessale <anthmct@yahoo.com>
25  * \author Mark Spencer <markster@digium.com>
26  *
27  * \ingroup applications
28  */
29
30 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 #include "asterisk/file.h"
37 #include "asterisk/channel.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/config.h"
40 #include "asterisk/module.h"
41 #include "asterisk/lock.h"
42 #include "asterisk/cli.h"
43
44
45 static char *cli_realtime_load(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
46 {
47 #define CRL_HEADER_FORMAT "%30s  %-30s\n"
48         struct ast_variable *var = NULL, *orig_var = NULL;
49
50         switch (cmd) {
51         case CLI_INIT:
52                 e->command = "realtime load";
53                 e->usage =
54                         "Usage: realtime load <family> <colmatch> <value>\n"
55                         "       Prints out a list of variables using the RealTime driver.\n"
56                         "       You must supply a family name, a column to match on, and a value to match to.\n";
57                 return NULL;
58         case CLI_GENERATE:
59                 return NULL;
60         }
61
62
63         if (a->argc < 5)
64                 return CLI_SHOWUSAGE;
65
66         var = ast_load_realtime_all(a->argv[2], a->argv[3], a->argv[4], SENTINEL);
67
68         if (var) {
69                 ast_cli(a->fd, CRL_HEADER_FORMAT, "Column Name", "Column Value");
70                 ast_cli(a->fd, CRL_HEADER_FORMAT, "--------------------", "--------------------");
71                 orig_var = var;
72                 while (var) {
73                         ast_cli(a->fd, CRL_HEADER_FORMAT, var->name, var->value);
74                         var = var->next;
75                 }
76         } else {
77                 ast_cli(a->fd, "No rows found matching search criteria.\n");
78         }
79         ast_variables_destroy(orig_var);
80         return CLI_SUCCESS;
81 }
82
83 static char *cli_realtime_update(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
84 {
85         int res = 0;
86
87         switch (cmd) {
88         case CLI_INIT:
89                 e->command = "realtime update";
90                 e->usage =
91                         "Usage: realtime update <family> <colmatch> <valuematch> <colupdate> <newvalue>\n"
92                         "       Update a single variable using the RealTime driver.\n"
93                         "       You must supply a family name, a column to update on, a new value, column to match, and value to match.\n"
94                         "       Ex: realtime update sippeers name bobsphone port 4343\n"
95                         "       will execute SQL as UPDATE sippeers SET port = 4343 WHERE name = bobsphone\n";
96                 return NULL;
97         case CLI_GENERATE:
98                 return NULL;
99         }
100
101         if (a->argc < 7)
102                 return CLI_SHOWUSAGE;
103
104         res = ast_update_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], SENTINEL);
105
106         if (res < 0) {
107                 ast_cli(a->fd, "Failed to update. Check the debug log for possible SQL related entries.\n");
108                 return CLI_FAILURE;
109         }
110
111         ast_cli(a->fd, "Updated %d RealTime record%s.\n", res, ESS(res));
112
113         return CLI_SUCCESS;
114 }
115
116 static char *cli_realtime_update2(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
117 {
118         int res = -1;
119
120         switch (cmd) {
121         case CLI_INIT:
122                 e->command = "realtime update2";
123                 e->usage =
124                         "Usage: realtime update2 <family> <colmatch> <valuematch> [... <colmatch5> <valuematch5>] NULL <colupdate> <newvalue>\n"
125                         "   Update a single variable, requiring one or more fields to match using the\n"
126                         "   RealTime driver.  You must supply a family name, a column to update, a new\n"
127                         "   value, and at least one column and value to match.\n"
128                         "   Ex: realtime update sippeers name bobsphone ipaddr 127.0.0.1 NULL port 4343\n"
129                         "   will execute SQL as\n"
130                         "   UPDATE sippeers SET port='4343' WHERE name='bobsphone' and ipaddr='127.0.0.1'\n";
131                 return NULL;
132         case CLI_GENERATE:
133                 return NULL;
134         }
135
136         if (a->argc < 7)
137                 return CLI_SHOWUSAGE;
138
139         if (a->argc == 7) {
140                 res = ast_update2_realtime(a->argv[2], a->argv[3], a->argv[4], SENTINEL, a->argv[5], a->argv[6], SENTINEL);
141         } else if (a->argc == 9) {
142                 res = ast_update2_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], SENTINEL, a->argv[7], a->argv[8], SENTINEL);
143         } else if (a->argc == 11) {
144                 res = ast_update2_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], SENTINEL, a->argv[9], a->argv[10], SENTINEL);
145         } else if (a->argc == 13) {
146                 res = ast_update2_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], a->argv[9], a->argv[10], SENTINEL, a->argv[11], a->argv[12], SENTINEL);
147         } else if (a->argc == 15) {
148                 res = ast_update2_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], a->argv[9], a->argv[10], a->argv[11], a->argv[12], SENTINEL, a->argv[13], a->argv[14], SENTINEL);
149         } else {
150                 return CLI_SHOWUSAGE;
151         }
152
153         if (res < 0) {
154                 ast_cli(a->fd, "Failed to update. Check the debug log for possible SQL related entries.\n");
155                 return CLI_FAILURE;
156         }
157
158         ast_cli(a->fd, "Updated %d RealTime record%s.\n", res, ESS(res));
159
160         return CLI_SUCCESS;
161 }
162
163 static char *cli_realtime_store(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
164 {
165         int res = -1;
166
167         switch (cmd) {
168         case CLI_INIT:
169                 e->command = "realtime store";
170                 e->usage =
171                         "Usage: realtime store <family> <colname1> <value1> [<colname2> <value2> [... <colname5> <value5>]]\n"
172                         "       Create a stored row using the RealTime driver.\n"
173                         "       You must supply a family name and name/value pairs (up to 5).  If\n"
174                         "       you need to store more than 5 key/value pairs, start with the first\n"
175                         "       five, then use 'realtime update' or 'realtime update2' to add\n"
176                         "       additional columns.\n";
177                 return NULL;
178         case CLI_GENERATE:
179                 return NULL;
180         }
181
182         if (a->argc < 5) {
183                 return CLI_SHOWUSAGE;
184         } else if (a->argc == 5) {
185                 res = ast_store_realtime(a->argv[2], a->argv[3], a->argv[4], SENTINEL);
186         } else if (a->argc == 7) {
187                 res = ast_store_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], SENTINEL);
188         } else if (a->argc == 9) {
189                 res = ast_store_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], SENTINEL);
190         } else if (a->argc == 11) {
191                 res = ast_store_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], a->argv[9], a->argv[10], SENTINEL);
192         } else if (a->argc == 13) {
193                 res = ast_store_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], a->argv[9], a->argv[10], a->argv[11], a->argv[12], SENTINEL);
194         } else {
195                 return CLI_SHOWUSAGE;
196         }
197
198         if (res < 0) {
199                 ast_cli(a->fd, "Failed to store record. Check the debug log for possible SQL related entries.\n");
200                 return CLI_FAILURE;
201         }
202
203         ast_cli(a->fd, "Stored RealTime record.\n");
204
205         return CLI_SUCCESS;
206 }
207
208 static char *cli_realtime_destroy(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
209 {
210         int res = -1;
211
212         switch (cmd) {
213         case CLI_INIT:
214                 e->command = "realtime destroy";
215                 e->usage =
216                         "Usage: realtime destroy <family> <colmatch1> <valuematch1> [<colmatch2> <valuematch2> [... <colmatch5> <valuematch5>]]\n"
217                         "       Remove a stored row using the RealTime driver.\n"
218                         "       You must supply a family name and name/value pairs (up to 5).\n";
219                 return NULL;
220         case CLI_GENERATE:
221                 return NULL;
222         }
223
224         if (a->argc < 5) {
225                 return CLI_SHOWUSAGE;
226         } else if (a->argc == 5) {
227                 res = ast_destroy_realtime(a->argv[2], a->argv[3], a->argv[4], SENTINEL);
228         } else if (a->argc == 7) {
229                 res = ast_destroy_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], SENTINEL);
230         } else if (a->argc == 9) {
231                 res = ast_destroy_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], SENTINEL);
232         } else if (a->argc == 11) {
233                 res = ast_destroy_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], a->argv[9], a->argv[10], SENTINEL);
234         } else if (a->argc == 13) {
235                 res = ast_destroy_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], a->argv[7], a->argv[8], a->argv[9], a->argv[10], a->argv[11], a->argv[12], SENTINEL);
236         } else {
237                 return CLI_SHOWUSAGE;
238         }
239
240         if (res < 0) {
241                 ast_cli(a->fd, "Failed to remove record. Check the debug log for possible SQL related entries.\n");
242                 return CLI_FAILURE;
243         }
244
245         ast_cli(a->fd, "Removed %d RealTime record%s.\n", res, ESS(res));
246
247         return CLI_SUCCESS;
248 }
249
250 static struct ast_cli_entry cli_realtime[] = {
251         AST_CLI_DEFINE(cli_realtime_load, "Used to print out RealTime variables."),
252         AST_CLI_DEFINE(cli_realtime_update, "Used to update RealTime variables."),
253         AST_CLI_DEFINE(cli_realtime_update2, "Used to test the RealTime update2 method"),
254         AST_CLI_DEFINE(cli_realtime_store, "Store a new row into a RealTime database"),
255         AST_CLI_DEFINE(cli_realtime_destroy, "Delete a row from a RealTime database"),
256 };
257
258 static int unload_module(void)
259 {
260         ast_cli_unregister_multiple(cli_realtime, ARRAY_LEN(cli_realtime));
261         return 0;
262 }
263
264 static int load_module(void)
265 {
266         ast_cli_register_multiple(cli_realtime, ARRAY_LEN(cli_realtime));
267         return AST_MODULE_LOAD_SUCCESS;
268 }
269
270 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Realtime Data Lookup/Rewrite");