diff --git a/build/modules.conf.in b/build/modules.conf.in index 3193d05365..762f357e22 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -7,6 +7,7 @@ applications/mod_enum applications/mod_fifo applications/mod_voicemail applications/mod_limit +applications/mod_expr #applications/mod_ivrtest #applications/mod_soundtouch #applications/mod_rss diff --git a/conf/modules.conf.xml b/conf/modules.conf.xml index 0b87c59b8c..3e5b5e6233 100644 --- a/conf/modules.conf.xml +++ b/conf/modules.conf.xml @@ -36,6 +36,7 @@ + diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index e1e4201435..edbfc905a9 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -298,7 +298,10 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in); */ SWITCH_DECLARE(unsigned int) switch_separate_string(char *buf, char delim, char **array, int arraylen); +SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str); +SWITCH_DECLARE(char *) switch_strip_spaces(const char *str); SWITCH_DECLARE(const char *) switch_stristr(const char *str, const char *instr); +SWITCH_DECLARE(switch_bool_t) switch_is_lan_addr(const char *ip); /*! \brief Escape a string by prefixing a list of characters with an escape character diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index adfb0d4ebb..955a376b22 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -40,6 +40,138 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load); SWITCH_MODULE_DEFINITION(mod_commands, mod_commands_load, NULL, NULL); + +typedef enum { + O_NONE, + O_EQ, + O_NE, + O_GT, + O_GE, + O_LT, + O_LE +} o_t; + +SWITCH_STANDARD_API(qq_function) +{ + int argc; + char *mydata = NULL, *argv[3]; + char *expr; + char *a, *b; + float a_f = 0.0, b_f = 0.0; + o_t o = O_NONE; + int is_true = 0; + char *p; + + if (!cmd) { + goto error; + } + + mydata = strdup(cmd); + assert(mydata); + + if ((p = strchr(mydata, '?'))) { + *p = ':'; + } else { + goto error; + } + + argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc != 3) { + goto error; + } + + a = argv[0]; + + if ((expr = strchr(a, '!'))) { + *expr++ = '\0'; + if (*expr == '=') { + o = O_NE; + } + } else if ((expr = strchr(a, '>'))) { + if (*(expr+1) == '=') { + *expr++ = '\0'; + o = O_GE; + } else { + o = O_GT; + } + } else if ((expr = strchr(a, '<'))) { + if (*(expr+1) == '=') { + *expr++ = '\0'; + o = O_LE; + } else { + o = O_LT; + } + } else if ((expr = strchr(a, '='))) { + *expr++ = '\0'; + if (*expr == '=') { + o = O_EQ; + } + } + + + if (o) { + char *s_a = NULL, *s_b = NULL; + int a_is_num, b_is_num; + *expr++ = '\0'; + b = expr; + s_a = switch_strip_spaces(a); + s_b = switch_strip_spaces(b); + a_is_num = switch_is_number(s_a); + b_is_num = switch_is_number(s_b); + + a_f = a_is_num ? atof(s_a) : (float) strlen(s_a); + b_f = b_is_num ? atof(s_b) : (float) strlen(s_b); + + switch (o) { + case O_EQ: + if (!a_is_num && !b_is_num) { + is_true = !strcmp(s_a, s_b); + } else { + is_true = a_f == b_f; + } + break; + case O_NE: + is_true = a_f != b_f; + break; + case O_GT: + is_true = a_f > b_f; + break; + case O_GE: + is_true = a_f >= b_f; + break; + case O_LT: + is_true = a_f < b_f; + break; + case O_LE: + is_true = a_f <= b_f; + break; + default: + break; + } + switch_safe_free(s_a); + switch_safe_free(s_b); + stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]); + goto ok; + } + + error: + stream->write_function(stream, "!err!"); + ok: + + switch_safe_free(mydata); + return SWITCH_STATUS_SUCCESS; + + +} + + +SWITCH_STANDARD_API(lan_addr_function) +{ + stream->write_function(stream, "%s", switch_is_lan_addr(cmd) ? "yes" : "no"); + return SWITCH_STATUS_SUCCESS; +} + SWITCH_STANDARD_API(status_function) { uint8_t html = 0; @@ -1502,6 +1634,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "sched_api", "Schedule an api command", sched_api_function, "[+]