diff options
-rwxr-xr-x | include/asterisk/utils.h | 3 | ||||
-rwxr-xr-x | pbx.c | 90 | ||||
-rwxr-xr-x | utils.c | 47 |
3 files changed, 125 insertions, 15 deletions
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index 93f99432a..bfbdd951c 100755 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -41,6 +41,7 @@ extern int ast_utils_init(void); #ifdef LINUX #define ast_pthread_create pthread_create +#define ast_strcasestr strcasestr #else /* Linux threads have a default 2MB stack size. */ #ifndef PTHREAD_ATTR_STACKSIZE @@ -49,4 +50,6 @@ extern int ast_utils_init(void); extern int ast_pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data); #endif /* LINUX */ +extern char *ast_strcasestr(const char *, const char *); + #endif @@ -2391,8 +2391,10 @@ static char show_application_help[] = " Describes a particular application.\n"; static char show_applications_help[] = -"Usage: show applications\n" -" List applications which are currently available.\n"; +"Usage: show applications [{like|describing} <text>]\n" +" List applications which are currently available.\n" +" If 'like', <text> will be a substring of the app name\n" +" If 'describing', <text> will be a substring of the description\n"; static char show_dialplan_help[] = "Usage: show dialplan [exten@][context]\n" @@ -2553,6 +2555,7 @@ static int handle_show_switches(int fd, int argc, char *argv[]) static int handle_show_applications(int fd, int argc, char *argv[]) { struct ast_app *a; + int like=0, describing=0; /* try to lock applications list ... */ if (ast_mutex_lock(&applock)) { @@ -2560,26 +2563,54 @@ static int handle_show_applications(int fd, int argc, char *argv[]) return -1; } - /* ... go to first application ... */ - a = apps; - /* ... have we got at least one application (first)? no? */ - if (!a) { - ast_cli(fd, "There is no registered applications\n"); + if (!apps) { + ast_cli(fd, "There are no registered applications\n"); ast_mutex_unlock(&applock); return -1; } - /* ... we have applications ... */ - ast_cli(fd, "\n -= Registered Asterisk Applications =-\n"); + /* show applications like <keyword> */ + if ((argc == 4) && (!strcmp(argv[2], "like"))) { + like = 1; + } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { + describing = 1; + } + + /* show applications describing <keyword1> [<keyword2>] [...] */ + if ((!like) && (!describing)) { + ast_cli(fd, " -= Registered Asterisk Applications =-\n"); + } else { + ast_cli(fd, " -= Matching Asterisk Applications =-\n"); + } /* ... go through all applications ... */ - while (a) { + for (a = apps; a; a = a->next) { /* ... show informations about applications ... */ - ast_cli(fd," %20s: %s\n", - a->name, - a->synopsis ? a->synopsis : "<Synopsis not available>"); - a = a->next; + int printapp=0; + + if (like) { + if (ast_strcasestr(a->name, argv[3])) { + printapp = 1; + } + } else if (describing) { + if (a->description) { + /* Match all words on command line */ + int i; + printapp = 1; + for (i=3;i<argc;i++) { + if (! ast_strcasestr(a->description, argv[i])) { + printapp = 0; + } + } + } + } else { + printapp = 1; + } + + if (printapp) { + ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); + } } /* ... unlock and return */ @@ -2588,6 +2619,35 @@ static int handle_show_applications(int fd, int argc, char *argv[]) return RESULT_SUCCESS; } +static char *complete_show_applications(char *line, char *word, int pos, int state) +{ + if (pos == 2) { + if (ast_strlen_zero(word)) { + switch (state) { + case 0: + return strdup("like"); + case 1: + return strdup("describing"); + default: + return NULL; + } + } else if (! strncasecmp(word, "like", strlen(word))) { + if (state == 0) { + return strdup("like"); + } else { + return NULL; + } + } else if (! strncasecmp(word, "describing", strlen(word))) { + if (state == 0) { + return strdup("describing"); + } else { + return NULL; + } + } + } + return NULL; +} + /* * 'show dialplan' CLI command implementation functions ... */ @@ -2824,7 +2884,7 @@ static int handle_show_dialplan(int fd, int argc, char *argv[]) static struct ast_cli_entry show_applications_cli = { { "show", "applications", NULL }, handle_show_applications, "Shows registered applications", - show_applications_help }; + show_applications_help, complete_show_applications }; static struct ast_cli_entry show_application_cli = { { "show", "application", NULL }, @@ -9,6 +9,9 @@ * the GNU General Public License */ +#ifdef Linux /* For strcasestr */ +#define __USE_GNU +#endif #include <ctype.h> #include <string.h> #include <unistd.h> @@ -20,6 +23,7 @@ #include <asterisk/lock.h> #include <asterisk/utils.h> #include <asterisk/logger.h> +#include <alloca.h> static char base64[64]; static char b2a[256]; @@ -363,3 +367,46 @@ int ast_pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_ro return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */ } #endif /* ! LINUX */ + +static char *upper(const char *orig, char *buf, int bufsize) +{ + int i; + memset(buf, 0, bufsize); + for (i=0; i<bufsize - 1; i++) { + buf[i] = toupper(orig[i]); + if (orig[i] == '\0') { + break; + } + } + return buf; +} + +/* Case-insensitive substring matching */ +#ifndef LINUX +char *ast_strcasestr(const char *haystack, const char *needle) +{ + char *u1, *u2; + int u1len = strlen(haystack), u2len = strlen(needle); + + u1 = alloca(u1len); + u2 = alloca(u2len); + if (u1 && u2) { + char *offset; + if (u2len > u1len) { + /* Needle bigger than haystack */ + return NULL; + } + offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len)); + if (offset) { + /* Return the offset into the original string */ + return ((char *)((unsigned int)haystack + (unsigned int)(offset - u1))); + } else { + return NULL; + } + } else { + ast_log(LOG_ERROR, "Out of memory\n"); + return NULL; + } +} +#endif + |