res_realtime.c 9.3 KB

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