diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/asterisk.c | 656 | ||||
-rw-r--r-- | main/astobj2.c | 80 | ||||
-rw-r--r-- | main/cdr.c | 72 | ||||
-rw-r--r-- | main/channel.c | 119 | ||||
-rw-r--r-- | main/cli.c | 266 | ||||
-rw-r--r-- | main/db.c | 235 | ||||
-rw-r--r-- | main/file.c | 35 | ||||
-rw-r--r-- | main/image.c | 32 | ||||
-rw-r--r-- | main/threadstorage.c | 79 | ||||
-rw-r--r-- | main/translate.c | 49 | ||||
-rw-r--r-- | main/udptl.c | 99 |
11 files changed, 977 insertions, 745 deletions
diff --git a/main/asterisk.c b/main/asterisk.c index 59b97e59e..6e9ccb7d4 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -305,10 +305,6 @@ struct thread_list_t { static AST_RWLIST_HEAD_STATIC(thread_list, thread_list_t); -static const char show_threads_help[] = -"Usage: core show threads\n" -" List threads currently active in the system.\n"; - void ast_register_thread(char *name) { struct thread_list_t *new = ast_calloc(1, sizeof(*new)); @@ -342,105 +338,130 @@ void ast_unregister_thread(void *id) } /*! \brief Give an overview of core settings */ -static int handle_show_settings(int fd, int argc, char *argv[]) +static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char buf[BUFSIZ]; struct ast_tm tm; - ast_cli(fd, "\nPBX Core settings\n"); - ast_cli(fd, "-----------------\n"); - ast_cli(fd, " Version: %s\n", "" ASTERISK_VERSION "" ); + switch (cmd) { + case CLI_INIT: + e->command = "core show settings"; + e->usage = "Usage: core show settings\n" + " Show core misc settings"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + ast_cli(a->fd, "\nPBX Core settings\n"); + ast_cli(a->fd, "-----------------\n"); + ast_cli(a->fd, " Version: %s\n", "" ASTERISK_VERSION "" ); if (option_maxcalls) - ast_cli(fd, " Max. calls: %d (Current %d)\n", option_maxcalls, ast_active_channels()); + ast_cli(a->fd, " Max. calls: %d (Current %d)\n", option_maxcalls, ast_active_channels()); else - ast_cli(fd, " Max. calls: Not set\n"); + ast_cli(a->fd, " Max. calls: Not set\n"); if (option_maxfiles) - ast_cli(fd, " Max. open file handles: %d\n", option_maxfiles); + ast_cli(a->fd, " Max. open file handles: %d\n", option_maxfiles); else - ast_cli(fd, " Max. open file handles: Not set\n"); - ast_cli(fd, " Verbosity: %d\n", option_verbose); - ast_cli(fd, " Debug level: %d\n", option_debug); - ast_cli(fd, " Max load avg: %lf\n", option_maxload); + ast_cli(a->fd, " Max. open file handles: Not set\n"); + ast_cli(a->fd, " Verbosity: %d\n", option_verbose); + ast_cli(a->fd, " Debug level: %d\n", option_debug); + ast_cli(a->fd, " Max load avg: %lf\n", option_maxload); #if defined(HAVE_SYSINFO) - ast_cli(fd, " Min Free Memory: %ld MB\n", option_minmemfree); + ast_cli(a->fd, " Min Free Memory: %ld MB\n", option_minmemfree); #endif if (ast_localtime(&ast_startuptime, &tm, NULL)) { ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm); - ast_cli(fd, " Startup time: %s\n", buf); + ast_cli(a->fd, " Startup time: %s\n", buf); } if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) { ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm); - ast_cli(fd, " Last reload time: %s\n", buf); - } - ast_cli(fd, " System: %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date); - ast_cli(fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME); - ast_cli(fd, " Default language: %s\n", defaultlanguage); - ast_cli(fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled"); - ast_cli(fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP); - ast_cli(fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled"); - ast_cli(fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled"); - ast_cli(fd, " Internal timing: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); - ast_cli(fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); - - ast_cli(fd, "\n* Subsystems\n"); - ast_cli(fd, " -------------\n"); - ast_cli(fd, " Manager (AMI): %s\n", check_manager_enabled() ? "Enabled" : "Disabled"); - ast_cli(fd, " Web Manager (AMI/HTTP): %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled"); - ast_cli(fd, " Call data records: %s\n", check_cdr_enabled() ? "Enabled" : "Disabled"); - ast_cli(fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Last reload time: %s\n", buf); + } + ast_cli(a->fd, " System: %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date); + ast_cli(a->fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME); + ast_cli(a->fd, " Default language: %s\n", defaultlanguage); + ast_cli(a->fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled"); + ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP); + ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Internal timing: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); + + ast_cli(a->fd, "\n* Subsystems\n"); + ast_cli(a->fd, " -------------\n"); + ast_cli(a->fd, " Manager (AMI): %s\n", check_manager_enabled() ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Web Manager (AMI/HTTP): %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Call data records: %s\n", check_cdr_enabled() ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled"); /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues */ - ast_cli(fd, "\n* Directories\n"); - ast_cli(fd, " -------------\n"); - ast_cli(fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE); - ast_cli(fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR); - ast_cli(fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR); - ast_cli(fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR); - ast_cli(fd, " Log directory: %s\n", ast_config_AST_LOG_DIR); - ast_cli(fd, "\n\n"); - return 0; + ast_cli(a->fd, "\n* Directories\n"); + ast_cli(a->fd, " -------------\n"); + ast_cli(a->fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE); + ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR); + ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR); + ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR); + ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR); + ast_cli(a->fd, "\n\n"); + return CLI_SUCCESS; } -static int handle_show_threads(int fd, int argc, char *argv[]) +static char *handle_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int count = 0; struct thread_list_t *cur; + switch (cmd) { + case CLI_INIT: + e->command = "core show threads"; + e->usage = + "Usage: core show threads\n" + " List threads currently active in the system.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } AST_RWLIST_RDLOCK(&thread_list); AST_RWLIST_TRAVERSE(&thread_list, cur, list) { - ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name); + ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name); count++; } AST_RWLIST_UNLOCK(&thread_list); - ast_cli(fd, "%d threads listed.\n", count); - return 0; + ast_cli(a->fd, "%d threads listed.\n", count); + return CLI_SUCCESS; } #if defined(HAVE_SYSINFO) -static const char show_sysinfo_help[] = -"Usage: core show sysinfo\n" -" List current system information.\n"; - /*! \brief Give an overview of system statistics */ -static int handle_show_sysinfo(int fd, int argc, char *argv[]) +static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct sysinfo sys_info; - - if (sysinfo(&sys_info)) { - ast_cli(fd, "FAILED to retrieve system information\n\n"); - return 0; + switch (cmd) { + case CLI_INIT: + e->command = "core show sysinfo"; + e->usage = + "Usage: core show sysinfo\n" + " List current system information.\n"; + return NULL; + case CLI_GENERATE: + return NULL; } - ast_cli(fd, "\nSystem Statistics\n"); - ast_cli(fd, "-----------------\n"); - ast_cli(fd, " System Uptime: %ld hours\n", sys_info.uptime/3600); - ast_cli(fd, " Total RAM: %ld KiB\n", (sys_info.totalram / sys_info.mem_unit)/1024); - ast_cli(fd, " Free RAM: %ld KiB\n", (sys_info.freeram / sys_info.mem_unit)/1024); - ast_cli(fd, " Buffer RAM: %ld KiB\n", (sys_info.bufferram / sys_info.mem_unit)/1024); - ast_cli(fd, " Total Swap Space: %ld KiB\n", (sys_info.totalswap / sys_info.mem_unit)/1024); - ast_cli(fd, " Free Swap Space: %ld KiB\n\n", (sys_info.freeswap / sys_info.mem_unit)/1024); - ast_cli(fd, " Number of Processes: %d \n\n", sys_info.procs); - return 0; + if (sysinfo(&sys_info)) { + ast_cli(a->fd, "FAILED to retrieve system information\n\n"); + return CLI_FAILURE; + } + ast_cli(a->fd, "\nSystem Statistics\n"); + ast_cli(a->fd, "-----------------\n"); + ast_cli(a->fd, " System Uptime: %ld hours\n", sys_info.uptime/3600); + ast_cli(a->fd, " Total RAM: %ld KiB\n", (sys_info.totalram / sys_info.mem_unit)/1024); + ast_cli(a->fd, " Free RAM: %ld KiB\n", (sys_info.freeram / sys_info.mem_unit)/1024); + ast_cli(a->fd, " Buffer RAM: %ld KiB\n", (sys_info.bufferram / sys_info.mem_unit)/1024); + ast_cli(a->fd, " Total Swap Space: %ld KiB\n", (sys_info.totalswap / sys_info.mem_unit)/1024); + ast_cli(a->fd, " Free Swap Space: %ld KiB\n\n", (sys_info.freeswap / sys_info.mem_unit)/1024); + ast_cli(a->fd, " Number of Processes: %d \n\n", sys_info.procs); + return CLI_SUCCESS; } #endif @@ -541,59 +562,84 @@ int64_t ast_mark(int i, int startstop) return prof_data->e[i].mark; } -static int handle_show_profile(int fd, int argc, char *argv[]) +#define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \ + max = prof_data->entries;\ + if (a->argc > 3) { /* specific entries */ \ + if (isdigit(a->argv[3][0])) { \ + min = atoi(a->argv[3]); \ + if (a->argc == 5 && strcmp(a->argv[4], "-")) \ + max = atoi(a->argv[4]); \ + } else \ + search = a->argv[3]; \ + } \ + if (max > prof_data->entries) \ + max = prof_data->entries; + +static char *handle_show_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int i, min, max; char *search = NULL; + switch (cmd) { + case CLI_INIT: + e->command = "core show profile"; + e->usage = "Usage: core show profile\n" + " show profile information"; + return NULL; + case CLI_GENERATE: + return NULL; + } if (prof_data == NULL) return 0; - min = 0; - max = prof_data->entries; - if (argc > 3) { /* specific entries */ - if (isdigit(argv[3][0])) { - min = atoi(argv[3]); - if (argc == 5 && strcmp(argv[4], "-")) - max = atoi(argv[4]); - } else - search = argv[3]; - } - if (max > prof_data->entries) - max = prof_data->entries; - if (!strcmp(argv[1], "clear")) { - for (i= min; i < max; i++) { - if (!search || strstr(prof_data->e[i].name, search)) { - prof_data->e[i].value = 0; - prof_data->e[i].events = 0; - } - } - return 0; - } - ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n", + DEFINE_PROFILE_MIN_MAX_VALUES; + ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n", prof_data->entries, prof_data->max_size); - ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", + ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", "Value", "Average", "Name"); for (i = min; i < max; i++) { struct profile_entry *e = &prof_data->e[i]; if (!search || strstr(prof_data->e[i].name, search)) - ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", + ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", i, (long)e->scale, (long)e->events, (long long)e->value, (long long)(e->events ? e->value / e->events : e->value), e->name); } - return 0; + return CLI_SUCCESS; } -static const char show_version_files_help[] = -"Usage: core show file version [like <pattern>]\n" -" Lists the revision numbers of the files used to build this copy of Asterisk.\n" -" Optional regular expression pattern is used to filter the file list.\n"; +static char *handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +{ + int i, min, max; + char *search = NULL; + switch (cmd) { + case CLI_INIT: + e->command = "core clear profile"; + e->usage = "Usage: core clear profile\n" + " clear profile information"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (prof_data == NULL) + return 0; + + DEFINE_PROFILE_MIN_MAX_VALUES; + for (i= min; i < max; i++) { + if (!search || strstr(prof_data->e[i].name, search)) { + prof_data->e[i].value = 0; + prof_data->e[i].events = 0; + } + } + return CLI_SUCCESS; +} +#undef DEFINE_PROFILE_MIN_MAX_VALUES /*! \brief CLI command to list module versions */ -static int handle_show_version_files(int fd, int argc, char *argv[]) +static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT "%-25.25s %-40.40s\n" struct file_version *iterator; @@ -601,15 +647,42 @@ static int handle_show_version_files(int fd, int argc, char *argv[]) int havepattern = 0; int havename = 0; int count_files = 0; + char *ret = NULL; + int matchlen, which = 0; + struct file_version *find; + + switch (cmd) { + case CLI_INIT: + e->command = "core show file version [like]"; + e->usage = + "Usage: core show file version [like <pattern>]\n" + " Lists the revision numbers of the files used to build this copy of Asterisk.\n" + " Optional regular expression pattern is used to filter the file list.\n"; + return NULL; + case CLI_GENERATE: + matchlen = strlen(a->word); + if (a->pos != 3) + return NULL; + AST_RWLIST_RDLOCK(&file_versions); + AST_RWLIST_TRAVERSE(&file_versions, find, list) { + if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) { + ret = ast_strdup(find->file); + break; + } + } + AST_RWLIST_UNLOCK(&file_versions); + return ret; + } - switch (argc) { + + switch (a->argc) { case 6: - if (!strcasecmp(argv[4], "like")) { - if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + if (!strcasecmp(a->argv[4], "like")) { + if (regcomp(®exbuf, a->argv[5], REG_EXTENDED | REG_NOSUB)) + return CLI_SHOWUSAGE; havepattern = 1; } else - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; break; case 5: havename = 1; @@ -617,57 +690,36 @@ static int handle_show_version_files(int fd, int argc, char *argv[]) case 4: break; default: - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } - ast_cli(fd, FORMAT, "File", "Revision"); - ast_cli(fd, FORMAT, "----", "--------"); + ast_cli(a->fd, FORMAT, "File", "Revision"); + ast_cli(a->fd, FORMAT, "----", "--------"); AST_RWLIST_RDLOCK(&file_versions); AST_RWLIST_TRAVERSE(&file_versions, iterator, list) { - if (havename && strcasecmp(iterator->file, argv[4])) + if (havename && strcasecmp(iterator->file, a->argv[4])) continue; if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) continue; - ast_cli(fd, FORMAT, iterator->file, iterator->version); + ast_cli(a->fd, FORMAT, iterator->file, iterator->version); count_files++; if (havename) break; } AST_RWLIST_UNLOCK(&file_versions); if (!havename) { - ast_cli(fd, "%d files listed.\n", count_files); + ast_cli(a->fd, "%d files listed.\n", count_files); } if (havepattern) regfree(®exbuf); - return RESULT_SUCCESS; + return CLI_SUCCESS; #undef FORMAT } -static char *complete_show_version_files(const char *line, const char *word, int pos, int state) -{ - struct file_version *find; - int which = 0; - char *ret = NULL; - int matchlen = strlen(word); - - if (pos != 3) - return NULL; - - AST_RWLIST_RDLOCK(&file_versions); - AST_RWLIST_TRAVERSE(&file_versions, find, list) { - if (!strncasecmp(word, find->file, matchlen) && ++which > state) { - ret = ast_strdup(find->file); - break; - } - } - AST_RWLIST_UNLOCK(&file_versions); - - return ret; -} #endif /* ! LOW_MEMORY */ int ast_register_atexit(void (*func)(void)) @@ -1409,62 +1461,25 @@ static int remoteconsolehandler(char *s) return ret; } -static const char abort_halt_help[] = -"Usage: abort shutdown\n" -" Causes Asterisk to abort an executing shutdown or restart, and resume normal\n" -" call operations.\n"; - -static const char shutdown_now_help[] = -"Usage: stop now\n" -" Shuts down a running Asterisk immediately, hanging up all active calls .\n"; - -static const char shutdown_gracefully_help[] = -"Usage: stop gracefully\n" -" Causes Asterisk to not accept new calls, and exit when all\n" -" active calls have terminated normally.\n"; - -static const char shutdown_when_convenient_help[] = -"Usage: stop when convenient\n" -" Causes Asterisk to perform a shutdown when all active calls have ended.\n"; - -static const char restart_now_help[] = -"Usage: restart now\n" -" Causes Asterisk to hangup all calls and exec() itself performing a cold\n" -" restart.\n"; - -static const char restart_gracefully_help[] = -"Usage: restart gracefully\n" -" Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n" -" restart when all active calls have ended.\n"; - -static const char restart_when_convenient_help[] = -"Usage: restart when convenient\n" -" Causes Asterisk to perform a cold restart when all active calls have ended.\n"; - -static const char bang_help[] = -"Usage: !<command>\n" -" Executes a given shell command\n"; - -static const char show_warranty_help[] = -"Usage: core show warranty\n" -" Shows the warranty (if any) for this copy of Asterisk.\n"; - -static const char show_license_help[] = -"Usage: core show license\n" -" Shows the license(s) for this copy of Asterisk.\n"; - -static const char version_help[] = -"Usage: core show version\n" -" Shows Asterisk version information.\n"; - -static int handle_version(int fd, int argc, char *argv[]) +static char *handle_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 3) - return RESULT_SHOWUSAGE; - ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", + switch (cmd) { + case CLI_INIT: + e->command = "core show version"; + e->usage = + "Usage: core show version\n" + " Shows Asterisk version information.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", ASTERISK_VERSION, ast_build_user, ast_build_hostname, ast_build_machine, ast_build_os, ast_build_date); - return RESULT_SUCCESS; + return CLI_SUCCESS; } #if 0 @@ -1477,68 +1492,160 @@ static int handle_quit(int fd, int argc, char *argv[]) } #endif -static int handle_shutdown_now(int fd, int argc, char *argv[]) +static char *handle_stop_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "stop now"; + e->usage = + "Usage: stop now\n" + " Shuts down a running Asterisk immediately, hanging up all active calls .\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_shutdown_gracefully(int fd, int argc, char *argv[]) +static char *handle_stop_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "stop gracefully"; + e->usage = + "Usage: stop gracefully\n" + " Causes Asterisk to not accept new calls, and exit when all\n" + " active calls have terminated normally.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_shutdown_when_convenient(int fd, int argc, char *argv[]) +static char *handle_stop_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 3) - return RESULT_SHOWUSAGE; - ast_cli(fd, "Waiting for inactivity to perform halt\n"); + switch (cmd) { + case CLI_INIT: + e->command = "stop when convenient"; + e->usage = + "Usage: stop when convenient\n" + " Causes Asterisk to perform a shutdown when all active calls have ended.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + ast_cli(a->fd, "Waiting for inactivity to perform halt\n"); quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_restart_now(int fd, int argc, char *argv[]) +static char *handle_restart_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "restart now"; + e->usage = + "Usage: restart now\n" + " Causes Asterisk to hangup all calls and exec() itself performing a cold\n" + " restart.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_restart_gracefully(int fd, int argc, char *argv[]) +static char *handle_restart_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "restart gracefully"; + e->usage = + "Usage: restart gracefully\n" + " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n" + " restart when all active calls have ended.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_restart_when_convenient(int fd, int argc, char *argv[]) +static char *handle_restart_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 3) - return RESULT_SHOWUSAGE; - ast_cli(fd, "Waiting for inactivity to perform restart\n"); + switch (cmd) { + case CLI_INIT: + e->command = "restart when convenient"; + e->usage = + "Usage: restart when convenient\n" + " Causes Asterisk to perform a cold restart when all active calls have ended.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + ast_cli(a->fd, "Waiting for inactivity to perform restart\n"); quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_abort_halt(int fd, int argc, char *argv[]) +static char *handle_abort_shutdown(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "abort shutdown"; + e->usage = + "Usage: abort shutdown\n" + " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n" + " call operations.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; ast_cancel_shutdown(); shuttingdown = 0; - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_bang(int fd, int argc, char *argv[]) +static char *handle_bang(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - return RESULT_SUCCESS; + switch (cmd) { + case CLI_INIT: + e->command = "!"; + e->usage = + "Usage: !<command>\n" + " Executes a given shell command\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + return CLI_SUCCESS; } static const char warranty_lines[] = { "\n" @@ -1565,11 +1672,22 @@ static const char warranty_lines[] = { "POSSIBILITY OF SUCH DAMAGES.\n" }; -static int show_warranty(int fd, int argc, char *argv[]) +static char *show_warranty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - ast_cli(fd, warranty_lines); + switch (cmd) { + case CLI_INIT: + e->command = "core show warranty"; + e->usage = + "Usage: core show warranty\n" + " Shows the warranty (if any) for this copy of Asterisk.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - return RESULT_SUCCESS; + ast_cli(a->fd, warranty_lines); + + return CLI_SUCCESS; } static const char license_lines[] = { @@ -1591,11 +1709,22 @@ static const char license_lines[] = { "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" }; -static int show_license(int fd, int argc, char *argv[]) +static char *show_license(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - ast_cli(fd, license_lines); + switch (cmd) { + case CLI_INIT: + e->command = "core show license"; + e->usage = + "Usage: core show license\n" + " Shows the license(s) for this copy of Asterisk.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - return RESULT_SUCCESS; + ast_cli(a->fd, license_lines); + + return CLI_SUCCESS; } #define ASTERISK_PROMPT "*CLI> " @@ -1603,75 +1732,26 @@ static int show_license(int fd, int argc, char *argv[]) #define ASTERISK_PROMPT2 "%s*CLI> " static struct ast_cli_entry cli_asterisk[] = { - { { "abort", "halt", NULL }, - handle_abort_halt, "Cancel a running halt", - abort_halt_help }, - - { { "stop", "now", NULL }, - handle_shutdown_now, "Shut down Asterisk immediately", - shutdown_now_help }, - - { { "stop", "gracefully", NULL }, - handle_shutdown_gracefully, "Gracefully shut down Asterisk", - shutdown_gracefully_help }, - - { { "stop", "when", "convenient", NULL }, - handle_shutdown_when_convenient, "Shut down Asterisk at empty call volume", - shutdown_when_convenient_help }, - - { { "restart", "now", NULL }, - handle_restart_now, "Restart Asterisk immediately", restart_now_help }, - - { { "restart", "gracefully", NULL }, - handle_restart_gracefully, "Restart Asterisk gracefully", - restart_gracefully_help }, - - { { "restart", "when", "convenient", NULL }, - handle_restart_when_convenient, "Restart Asterisk at empty call volume", - restart_when_convenient_help }, - - { { "core", "show", "warranty", NULL }, - show_warranty, "Show the warranty (if any) for this copy of Asterisk", - show_warranty_help }, - - { { "core", "show", "license", NULL }, - show_license, "Show the license(s) for this copy of Asterisk", - show_license_help }, - - { { "core", "show", "version", NULL }, - handle_version, "Display version info", - version_help }, - - { { "!", NULL }, - handle_bang, "Execute a shell command", - bang_help }, - + NEW_CLI(handle_abort_shutdown, "Cancel a running shutdown"), + NEW_CLI(handle_stop_now, "Shut down Asterisk immediately"), + NEW_CLI(handle_stop_gracefully, "Gracefully shut down Asterisk"), + NEW_CLI(handle_stop_when_convenient, "Shut down Asterisk at empty call volume"), + NEW_CLI(handle_restart_now, "Restart Asterisk immediately"), + NEW_CLI(handle_restart_gracefully, "Restart Asterisk gracefully"), + NEW_CLI(handle_restart_when_convenient, "Restart Asterisk at empty call volume"), + NEW_CLI(show_warranty, "Show the warranty (if any) for this copy of Asterisk"), + NEW_CLI(show_license, "Show the license(s) for this copy of Asterisk"), + NEW_CLI(handle_version, "Display version info"), + NEW_CLI(handle_bang, "Execute a shell command"), #if !defined(LOW_MEMORY) - { { "core", "show", "file", "version", NULL }, - handle_show_version_files, "List versions of files used to build Asterisk", - show_version_files_help, complete_show_version_files }, - - { { "core", "show", "threads", NULL }, - handle_show_threads, "Show running threads", - show_threads_help }, - + NEW_CLI(handle_show_version_files, "List versions of files used to build Asterisk"), + NEW_CLI(handle_show_threads, "Show running threads"), #if defined(HAVE_SYSINFO) - { { "core", "show", "sysinfo", NULL }, - handle_show_sysinfo, "Show System Information", - show_sysinfo_help }, + NEW_CLI(handle_show_sysinfo, "Show System Information"), #endif - - { { "core", "show", "profile", NULL }, - handle_show_profile, "Display profiling info", - NULL }, - - { { "core", "show", "settings", NULL }, - handle_show_settings, "Show some core settings", - NULL }, - - { { "core", "clear", "profile", NULL }, - handle_show_profile, "Clear profiling info", - NULL }, + NEW_CLI(handle_show_profile, "Display profiling info"), + NEW_CLI(handle_show_settings, "Show some core settings"), + NEW_CLI(handle_clear_profile, "Clear profiling info"), #endif /* ! LOW_MEMORY */ }; diff --git a/main/astobj2.c b/main/astobj2.c index f7fde9a29..7e1bdb021 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -607,40 +607,65 @@ static int print_cb(void *obj, void *arg, int flag) /* * Print stats */ -static int handle_astobj2_stats(int fd, int argc, char *argv[]) +static char *handle_astobj2_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - ast_cli(fd, "Objects : %d\n", ao2.total_objects); - ast_cli(fd, "Containers : %d\n", ao2.total_containers); - ast_cli(fd, "Memory : %d\n", ao2.total_mem); - ast_cli(fd, "Locked : %d\n", ao2.total_locked); - ast_cli(fd, "Refs : %d\n", ao2.total_refs); - return 0; + switch (cmd) { + case CLI_INIT: + e->command = "astobj2 stats"; + e->usage = "Usage: astobj2 stats\n" + " Show astobj2 stats\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + ast_cli(a->fd, "Objects : %d\n", ao2.total_objects); + ast_cli(a->fd, "Containers : %d\n", ao2.total_containers); + ast_cli(a->fd, "Memory : %d\n", ao2.total_mem); + ast_cli(a->fd, "Locked : %d\n", ao2.total_locked); + ast_cli(a->fd, "Refs : %d\n", ao2.total_refs); + return CLI_SUCCESS; } /* * This is testing code for astobj */ -static int handle_astobj2_test(int fd, int argc, char *argv[]) +static char *handle_astobj2_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ao2_container *c1; int i, lim; char *obj; static int prof_id = -1; + struct ast_cli_args fake_args = { a->fd, 0, NULL }; + + switch (cmd) { + case CLI_INIT: + e->command = "astobj2 test"; + e->usage = "Usage: astobj2 test <num>\n" + " Runs astobj2 test. Creates 'num' objects,\n" + " and test iterators, callbacks and may be other stuff\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) { + return CLI_SHOWUSAGE; + } if (prof_id == -1) prof_id = ast_add_profile("ao2_alloc", 0); - ast_cli(fd, "argc %d argv %s %s %s\n", argc, argv[0], argv[1], argv[2]); - lim = atoi(argv[2]); - ast_cli(fd, "called astobj_test\n"); + ast_cli(a->fd, "argc %d argv %s %s %s\n", a->argc, a->argv[0], a->argv[1], a->argv[2]); + lim = atoi(a->argv[2]); + ast_cli(a->fd, "called astobj_test\n"); - handle_astobj2_stats(fd, 0, NULL); + handle_astobj2_stats(e, CLI_HANDLER, &fake_args); /* * allocate a container with no default callback, and no hash function. * No hash means everything goes in the same bucket. */ c1 = ao2_container_alloc(100, NULL /* no callback */, NULL /* no hash */); - ast_cli(fd, "container allocated as %p\n", c1); + ast_cli(a->fd, "container allocated as %p\n", c1); /* * fill the container with objects. @@ -651,48 +676,47 @@ static int handle_astobj2_test(int fd, int argc, char *argv[]) ast_mark(prof_id, 1 /* start */); obj = ao2_alloc(80, NULL); ast_mark(prof_id, 0 /* stop */); - ast_cli(fd, "object %d allocated as %p\n", i, obj); + ast_cli(a->fd, "object %d allocated as %p\n", i, obj); sprintf(obj, "-- this is obj %d --", i); ao2_link(c1, obj); } - ast_cli(fd, "testing callbacks\n"); - ao2_callback(c1, 0, print_cb, &fd); + ast_cli(a->fd, "testing callbacks\n"); + ao2_callback(c1, 0, print_cb, &a->fd); - ast_cli(fd, "testing iterators, remove every second object\n"); + ast_cli(a->fd, "testing iterators, remove every second object\n"); { struct ao2_iterator ai; int x = 0; ai = ao2_iterator_init(c1, 0); while ( (obj = ao2_iterator_next(&ai)) ) { - ast_cli(fd, "iterator on <%s>\n", obj); + ast_cli(a->fd, "iterator on <%s>\n", obj); if (x++ & 1) ao2_unlink(c1, obj); ao2_ref(obj, -1); } - ast_cli(fd, "testing iterators again\n"); + ast_cli(a->fd, "testing iterators again\n"); ai = ao2_iterator_init(c1, 0); while ( (obj = ao2_iterator_next(&ai)) ) { - ast_cli(fd, "iterator on <%s>\n", obj); + ast_cli(a->fd, "iterator on <%s>\n", obj); ao2_ref(obj, -1); } } - ast_cli(fd, "testing callbacks again\n"); - ao2_callback(c1, 0, print_cb, &fd); + ast_cli(a->fd, "testing callbacks again\n"); + ao2_callback(c1, 0, print_cb, &a->fd); ast_verbose("now you should see an error message:\n"); ao2_ref(&i, -1); /* i is not a valid object so we print an error here */ - ast_cli(fd, "destroy container\n"); + ast_cli(a->fd, "destroy container\n"); ao2_ref(c1, -1); /* destroy container */ - handle_astobj2_stats(fd, 0, NULL); - return 0; + handle_astobj2_stats(e, CLI_HANDLER, &fake_args); + return CLI_SUCCESS; } static struct ast_cli_entry cli_astobj2[] = { - { { "astobj2", "stats", NULL }, - handle_astobj2_stats, "Print astobj2 statistics", }, - { { "astobj2", "test", NULL } , handle_astobj2_test, "Test astobj2", }, + NEW_CLI(handle_astobj2_stats, "Print astobj2 statistics"), + NEW_CLI(handle_astobj2_test, "Test astobj2"), }; #endif /* AO2_DEBUG */ diff --git a/main/cdr.c b/main/cdr.c index 12d1e37fd..3c28b1cbd 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -1225,64 +1225,74 @@ static void *do_cdr(void *data) return NULL; } -static int handle_cli_status(int fd, int argc, char *argv[]) +static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_cdr_beitem *beitem=NULL; int cnt=0; long nextbatchtime=0; - if (argc > 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "cdr status"; + e->usage = + "Usage: cdr status\n" + " Displays the Call Detail Record engine system status.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - ast_cli(fd, "CDR logging: %s\n", enabled ? "enabled" : "disabled"); - ast_cli(fd, "CDR mode: %s\n", batchmode ? "batch" : "simple"); + if (a->argc > 2) + return CLI_SHOWUSAGE; + + ast_cli(a->fd, "CDR logging: %s\n", enabled ? "enabled" : "disabled"); + ast_cli(a->fd, "CDR mode: %s\n", batchmode ? "batch" : "simple"); if (enabled) { if (batchmode) { if (batch) cnt = batch->size; if (cdr_sched > -1) nextbatchtime = ast_sched_when(sched, cdr_sched); - ast_cli(fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled"); - ast_cli(fd, "CDR batch threading model: %s\n", batchscheduleronly ? "scheduler only" : "scheduler plus separate threads"); - ast_cli(fd, "CDR current batch size: %d record%s\n", cnt, ESS(cnt)); - ast_cli(fd, "CDR maximum batch size: %d record%s\n", batchsize, ESS(batchsize)); - ast_cli(fd, "CDR maximum batch time: %d second%s\n", batchtime, ESS(batchtime)); - ast_cli(fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, ESS(nextbatchtime)); + ast_cli(a->fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled"); + ast_cli(a->fd, "CDR batch threading model: %s\n", batchscheduleronly ? "scheduler only" : "scheduler plus separate threads"); + ast_cli(a->fd, "CDR current batch size: %d record%s\n", cnt, ESS(cnt)); + ast_cli(a->fd, "CDR maximum batch size: %d record%s\n", batchsize, ESS(batchsize)); + ast_cli(a->fd, "CDR maximum batch time: %d second%s\n", batchtime, ESS(batchtime)); + ast_cli(a->fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, ESS(nextbatchtime)); } AST_RWLIST_RDLOCK(&be_list); AST_RWLIST_TRAVERSE(&be_list, beitem, list) { - ast_cli(fd, "CDR registered backend: %s\n", beitem->name); + ast_cli(a->fd, "CDR registered backend: %s\n", beitem->name); } AST_RWLIST_UNLOCK(&be_list); } - return 0; + return CLI_SUCCESS; } -static int handle_cli_submit(int fd, int argc, char *argv[]) +static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc > 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "cdr submit"; + e->usage = + "Usage: cdr submit\n" + " Posts all pending batched CDR data to the configured CDR backend engine modules.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc > 2) + return CLI_SHOWUSAGE; submit_unscheduled_batch(); - ast_cli(fd, "Submitted CDRs to backend engines for processing. This may take a while.\n"); + ast_cli(a->fd, "Submitted CDRs to backend engines for processing. This may take a while.\n"); - return 0; + return CLI_SUCCESS; } -static struct ast_cli_entry cli_submit = { - { "cdr", "submit", NULL }, - handle_cli_submit, "Posts all pending batched CDR data", - "Usage: cdr submit\n" - " Posts all pending batched CDR data to the configured CDR backend engine modules.\n" -}; - -static struct ast_cli_entry cli_status = { - { "cdr", "status", NULL }, - handle_cli_status, "Display the CDR status", - "Usage: cdr status\n" - " Displays the Call Detail Record engine system status.\n" -}; +static struct ast_cli_entry cli_submit = NEW_CLI(handle_cli_submit, "Posts all pending batched CDR data"); +static struct ast_cli_entry cli_status = NEW_CLI(handle_cli_status, "Display the CDR status"); static int do_reload(int reload) { diff --git a/main/channel.c b/main/channel.c index 9cdf0521d..9e209714c 100644 --- a/main/channel.c +++ b/main/channel.c @@ -188,60 +188,106 @@ struct ast_variable *ast_channeltype_list(void) } /*! \brief Show channel types - CLI command */ -static int show_channeltypes(int fd, int argc, char *argv[]) +static char *handle_cli_core_show_channeltypes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" struct chanlist *cl; int count_chan = 0; - ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); - ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); + switch (cmd) { + case CLI_INIT: + e->command = "core show channeltypes"; + e->usage = + "Usage: core show channeltypes\n" + " Lists available channel types registered in your\n" + " Asterisk server.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + + ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); + ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); if (AST_RWLIST_RDLOCK(&channels)) { ast_log(LOG_WARNING, "Unable to lock channel list\n"); - return -1; + return CLI_FAILURE; } AST_LIST_TRAVERSE(&backends, cl, list) { - ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description, + ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description, (cl->tech->devicestate) ? "yes" : "no", (cl->tech->indicate) ? "yes" : "no", (cl->tech->transfer) ? "yes" : "no"); count_chan++; } AST_RWLIST_UNLOCK(&channels); - ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan); - return RESULT_SUCCESS; + ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan); + return CLI_SUCCESS; #undef FORMAT +} + +static char *complete_channeltypes(struct ast_cli_args *a) +{ + struct chanlist *cl; + int which = 0; + int wordlen; + char *ret = NULL; + + if (a->pos != 3) + return NULL; + wordlen = strlen(a->word); + + AST_LIST_TRAVERSE(&backends, cl, list) { + if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) { + ret = ast_strdup(cl->tech->type); + break; + } + } + + return ret; } /*! \brief Show details about a channel driver - CLI command */ -static int show_channeltype(int fd, int argc, char *argv[]) +static char *handle_cli_core_show_channeltype(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct chanlist *cl = NULL; - if (argc != 4) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "core show channeltype"; + e->usage = + "Usage: core show channeltype <name>\n" + " Show details about the specified channel type, <name>.\n"; + return NULL; + case CLI_GENERATE: + return complete_channeltypes(a); + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; if (AST_RWLIST_RDLOCK(&channels)) { ast_log(LOG_WARNING, "Unable to lock channel list\n"); - return RESULT_FAILURE; + return CLI_FAILURE; } AST_LIST_TRAVERSE(&backends, cl, list) { - if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) { + if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type))) break; - } } if (!cl) { - ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]); + ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]); AST_RWLIST_UNLOCK(&channels); - return RESULT_FAILURE; + return CLI_FAILURE; } - ast_cli(fd, + ast_cli(a->fd, "-- Info about channel driver: %s --\n" " Device State: %s\n" " Indication: %s\n" @@ -266,47 +312,12 @@ static int show_channeltype(int fd, int argc, char *argv[]) ); AST_RWLIST_UNLOCK(&channels); - return RESULT_SUCCESS; -} - -static char *complete_channeltypes(const char *line, const char *word, int pos, int state) -{ - struct chanlist *cl; - int which = 0; - int wordlen; - char *ret = NULL; - - if (pos != 3) - return NULL; - - wordlen = strlen(word); - - AST_LIST_TRAVERSE(&backends, cl, list) { - if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) { - ret = ast_strdup(cl->tech->type); - break; - } - } - - return ret; + return CLI_SUCCESS; } -static const char show_channeltypes_usage[] = -"Usage: core show channeltypes\n" -" Lists available channel types registered in your Asterisk server.\n"; - -static const char show_channeltype_usage[] = -"Usage: core show channeltype <name>\n" -" Show details about the specified channel type, <name>.\n"; - static struct ast_cli_entry cli_channel[] = { - { { "core", "show", "channeltypes", NULL }, - show_channeltypes, "List available channel types", - show_channeltypes_usage }, - - { { "core", "show", "channeltype", NULL }, - show_channeltype, "Give more details on that channel type", - show_channeltype_usage, complete_channeltypes }, + NEW_CLI(handle_cli_core_show_channeltypes, "List available channel types"), + NEW_CLI(handle_cli_core_show_channeltype, "Give more details on that channel type") }; /*! \brief Checks to see if a channel is needing hang up */ diff --git a/main/cli.c b/main/cli.c index 7e7514aba..da4c25fe3 100644 --- a/main/cli.c +++ b/main/cli.c @@ -123,22 +123,6 @@ unsigned int ast_verbose_get_by_file(const char *file) static AST_RWLIST_HEAD_STATIC(helpers, ast_cli_entry); -static const char logger_mute_help[] = -"Usage: logger mute\n" -" Disables logging output to the current console, making it possible to\n" -" gather information without being disturbed by scrolling lines.\n"; - -static const char softhangup_help[] = -"Usage: soft hangup <channel>\n" -" Request that a channel be hung up. The hangup takes effect\n" -" the next time the driver reads or writes from the channel\n"; - -static const char group_show_channels_help[] = -"Usage: group show channels [pattern]\n" -" Lists all currently active channels with channel group(s) specified.\n" -" Optional regular expression pattern is matched to group names for each\n" -" channel.\n"; - static char *complete_fn(const char *word, int state) { char *c; @@ -373,12 +357,24 @@ done: return CLI_SUCCESS; } -static int handle_logger_mute(int fd, int argc, char *argv[]) +static char *handle_logger_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; - ast_console_toggle_mute(fd); - return RESULT_SUCCESS; + switch (cmd) { + case CLI_INIT: + e->command = "logger mute"; + e->usage = + "Usage: logger mute\n" + " Disables logging output to the current console, making it possible to\n" + " gather information without being disturbed by scrolling lines.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; + ast_console_toggle_mute(a->fd); + return CLI_SUCCESS; } static char *handle_unload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) @@ -690,56 +686,61 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar #undef VERBOSE_FORMAT_STRING2 } -static const char showchan_help[] = -"Usage: core show channel <channel>\n" -" Shows lots of information about the specified channel.\n"; - -static const char commandcomplete_help[] = -"Usage: _command complete \"<line>\" text state\n" -" This function is used internally to help with command completion and should.\n" -" never be called by the user directly.\n"; - -static const char commandnummatches_help[] = -"Usage: _command nummatches \"<line>\" text \n" -" This function is used internally to help with command completion and should.\n" -" never be called by the user directly.\n"; - -static const char commandmatchesarray_help[] = -"Usage: _command matchesarray \"<line>\" text \n" -" This function is used internally to help with command completion and should.\n" -" never be called by the user directly.\n"; - -static int handle_softhangup(int fd, int argc, char *argv[]) +static char *handle_softhangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_channel *c=NULL; - if (argc != 3) - return RESULT_SHOWUSAGE; - c = ast_get_channel_by_name_locked(argv[2]); + + switch (cmd) { + case CLI_INIT: + e->command = "soft hangup"; + e->usage = + "Usage: soft hangup <channel>\n" + " Request that a channel be hung up. The hangup takes effect\n" + " the next time the driver reads or writes from the channel\n"; + return NULL; + case CLI_GENERATE: + return ast_complete_channels(a->line, a->word, a->pos, a->n, 2); + } + if (a->argc != 3) + return CLI_SHOWUSAGE; + c = ast_get_channel_by_name_locked(a->argv[2]); if (c) { - ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name); + ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name); ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); ast_channel_unlock(c); } else - ast_cli(fd, "%s is not a known channel\n", argv[2]); - return RESULT_SUCCESS; + ast_cli(a->fd, "%s is not a known channel\n", a->argv[2]); + return CLI_SUCCESS; } static char *__ast_cli_generator(const char *text, const char *word, int state, int lock); -static int handle_commandmatchesarray(int fd, int argc, char *argv[]) +static char *handle_commandmatchesarray(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *buf, *obuf; int buflen = 2048; int len = 0; char **matches; int x, matchlen; + + switch (cmd) { + case CLI_INIT: + e->command = "_command matchesarray"; + e->usage = + "Usage: _command matchesarray \"<line>\" text \n" + " This function is used internally to help with command completion and should.\n" + " never be called by the user directly.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - if (argc != 4) - return RESULT_SHOWUSAGE; + if (a->argc != 4) + return CLI_SHOWUSAGE; if (!(buf = ast_malloc(buflen))) - return RESULT_FAILURE; + return CLI_FAILURE; buf[len] = '\0'; - matches = ast_cli_completion_matches(argv[2], argv[3]); + matches = ast_cli_completion_matches(a->argv[2], a->argv[3]); if (matches) { for (x=0; matches[x]; x++) { matchlen = strlen(matches[x]) + 1; @@ -759,43 +760,65 @@ static int handle_commandmatchesarray(int fd, int argc, char *argv[]) } if (buf) { - ast_cli(fd, "%s%s",buf, AST_CLI_COMPLETE_EOF); + ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF); ast_free(buf); } else - ast_cli(fd, "NULL\n"); + ast_cli(a->fd, "NULL\n"); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_commandnummatches(int fd, int argc, char *argv[]) +static char *handle_commandnummatches(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int matches = 0; - if (argc != 4) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "_command nummatches"; + e->usage = + "Usage: _command nummatches \"<line>\" text \n" + " This function is used internally to help with command completion and should.\n" + " never be called by the user directly.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; - matches = ast_cli_generatornummatches(argv[2], argv[3]); + matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]); - ast_cli(fd, "%d", matches); + ast_cli(a->fd, "%d", matches); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_commandcomplete(int fd, int argc, char *argv[]) +static char *handle_commandcomplete(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *buf; - - if (argc != 5) - return RESULT_SHOWUSAGE; - buf = __ast_cli_generator(argv[2], argv[3], atoi(argv[4]), 0); + switch (cmd) { + case CLI_INIT: + e->command = "_command complete"; + e->usage = + "Usage: _command complete \"<line>\" text state\n" + " This function is used internally to help with command completion and should.\n" + " never be called by the user directly.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc != 5) + return CLI_SHOWUSAGE; + buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0); if (buf) { - ast_cli(fd, buf); + ast_cli(a->fd, buf); ast_free(buf); } else - ast_cli(fd, "NULL\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "NULL\n"); + return CLI_SUCCESS; } static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) @@ -891,7 +914,7 @@ static char *handle_nodebugchan_deprecated(struct ast_cli_entry *e, int cmd, str return res; } -static int handle_showchan(int fd, int argc, char *argv[]) +static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_channel *c=NULL; struct timeval now; @@ -900,14 +923,25 @@ static int handle_showchan(int fd, int argc, char *argv[]) char nf[256], wf[256], rf[256]; long elapsed_seconds=0; int hour=0, min=0, sec=0; + + switch (cmd) { + case CLI_INIT: + e->command = "core show channel"; + e->usage = + "Usage: core show channel <channel>\n" + " Shows lots of information about the specified channel.\n"; + return NULL; + case CLI_GENERATE: + return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); + } - if (argc != 4) - return RESULT_SHOWUSAGE; + if (a->argc != 4) + return CLI_SHOWUSAGE; now = ast_tvnow(); - c = ast_get_channel_by_name_locked(argv[3]); + c = ast_get_channel_by_name_locked(a->argv[3]); if (!c) { - ast_cli(fd, "%s is not a known channel\n", argv[3]); - return RESULT_SUCCESS; + ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); + return CLI_SUCCESS; } if (c->cdr) { elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; @@ -917,7 +951,7 @@ static int handle_showchan(int fd, int argc, char *argv[]) snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec); } else strcpy(cdrtime, "N/A"); - ast_cli(fd, + ast_cli(a->fd, " -- General --\n" " Name: %s\n" " Type: %s\n" @@ -970,12 +1004,12 @@ static int handle_showchan(int fd, int argc, char *argv[]) (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)")); if (pbx_builtin_serialize_variables(c, &out)) - ast_cli(fd," Variables:\n%s\n", out->str); + ast_cli(a->fd," Variables:\n%s\n", out->str); if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1)) - ast_cli(fd," CDR Variables:\n%s\n", out->str); + ast_cli(a->fd," CDR Variables:\n%s\n", out->str); ast_channel_unlock(c); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /* @@ -1015,17 +1049,7 @@ char *ast_complete_channels(const char *line, const char *word, int pos, int sta return ret == ¬found ? NULL : ret; } -static char *complete_ch_3(const char *line, const char *word, int pos, int state) -{ - return ast_complete_channels(line, word, pos, state, 2); -} - -static char *complete_ch_4(const char *line, const char *word, int pos, int state) -{ - return ast_complete_channels(line, word, pos, state, 3); -} - -static int group_show_channels(int fd, int argc, char *argv[]) +static char *group_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT_STRING "%-25s %-20s %-20s\n" @@ -1034,23 +1058,36 @@ static int group_show_channels(int fd, int argc, char *argv[]) regex_t regexbuf; int havepattern = 0; - if (argc < 3 || argc > 4) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "group show channels"; + e->usage = + "Usage: group show channels [pattern]\n" + " Lists all currently active channels with channel group(s) specified.\n" + " Optional regular expression pattern is matched to group names for each\n" + " channel.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc < 3 || a->argc > 4) + return CLI_SHOWUSAGE; - if (argc == 4) { - if (regcomp(®exbuf, argv[3], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + if (a->argc == 4) { + if (regcomp(®exbuf, a->argv[3], REG_EXTENDED | REG_NOSUB)) + return CLI_SHOWUSAGE; havepattern = 1; } - ast_cli(fd, FORMAT_STRING, "Channel", "Group", "Category"); + ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category"); ast_app_group_list_rdlock(); gi = ast_app_group_list_head(); while (gi) { if (!havepattern || !regexec(®exbuf, gi->group, 0, NULL, 0)) { - ast_cli(fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category)); + ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category)); numchans++; } gi = AST_LIST_NEXT(gi, list); @@ -1061,8 +1098,8 @@ static int group_show_channels(int fd, int argc, char *argv[]) if (havepattern) regfree(®exbuf); - ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans)); - return RESULT_SUCCESS; + ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans)); + return CLI_SUCCESS; #undef FORMAT_STRING } @@ -1072,18 +1109,9 @@ static int group_show_channels(int fd, int argc, char *argv[]) */ static struct ast_cli_entry builtins[] = { /* Keep alphabetized, with longer matches first (example: abcd before abc) */ - { { "_command", "complete", NULL }, - handle_commandcomplete, "Command complete", - commandcomplete_help }, - - { { "_command", "nummatches", NULL }, - handle_commandnummatches, "Returns number of command matches", - commandnummatches_help }, - - { { "_command", "matchesarray", NULL }, - handle_commandmatchesarray, "Returns command matches array", - commandmatchesarray_help }, - + NEW_CLI(handle_commandcomplete, "Command complete"), + NEW_CLI(handle_commandnummatches, "Returns number of command matches"), + NEW_CLI(handle_commandmatchesarray, "Returns command matches array"), { { NULL }, NULL, NULL, NULL } }; @@ -1100,24 +1128,18 @@ static struct ast_cli_entry cli_cli[] = { NEW_CLI(handle_chanlist, "Display information on channels"), - { { "core", "show", "channel", NULL }, - handle_showchan, "Display information on a specific channel", - showchan_help, complete_ch_4 }, + NEW_CLI(handle_showchan, "Display information on a specific channel"), NEW_CLI(handle_core_set_debug_channel, "Enable/disable debugging on a channel", .deprecate_cmd = &cli_debug_channel_deprecated), NEW_CLI(handle_verbose, "Set level of debug/verbose chattiness"), - { { "group", "show", "channels", NULL }, - group_show_channels, "Display active channels with group(s)", - group_show_channels_help }, + NEW_CLI(group_show_channels, "Display active channels with group(s)"), NEW_CLI(handle_help, "Display help list, or specific help on a command"), - { { "logger", "mute", NULL }, - handle_logger_mute, "Toggle logging output to a console", - logger_mute_help }, + NEW_CLI(handle_logger_mute, "Toggle logging output to a console"), NEW_CLI(handle_modlist, "List modules and info"), @@ -1129,9 +1151,7 @@ static struct ast_cli_entry cli_cli[] = { NEW_CLI(handle_showuptime, "Show uptime information"), - { { "soft", "hangup", NULL }, - handle_softhangup, "Request a hangup on a given channel", - softhangup_help, complete_ch_3 }, + NEW_CLI(handle_softhangup, "Request a hangup on a given channel"), }; /*! @@ -240,68 +240,120 @@ int ast_db_del(const char *family, const char *keys) return res; } -static int database_put(int fd, int argc, char *argv[]) +static char *handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int res; - if (argc != 5) - return RESULT_SHOWUSAGE; - res = ast_db_put(argv[2], argv[3], argv[4]); + + switch (cmd) { + case CLI_INIT: + e->command = "database put"; + e->usage = + "Usage: database put <family> <key> <value>\n" + " Adds or updates an entry in the Asterisk database for\n" + " a given family, key, and value.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 5) + return CLI_SHOWUSAGE; + res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]); if (res) { - ast_cli(fd, "Failed to update entry\n"); + ast_cli(a->fd, "Failed to update entry\n"); } else { - ast_cli(fd, "Updated database successfully\n"); + ast_cli(a->fd, "Updated database successfully\n"); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int database_get(int fd, int argc, char *argv[]) +static char *handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int res; char tmp[256]; - if (argc != 4) - return RESULT_SHOWUSAGE; - res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); + + switch (cmd) { + case CLI_INIT: + e->command = "database get"; + e->usage = + "Usage: database get <family> <key>\n" + " Retrieves an entry in the Asterisk database for a given\n" + " family and key.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; + res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp)); if (res) { - ast_cli(fd, "Database entry not found.\n"); + ast_cli(a->fd, "Database entry not found.\n"); } else { - ast_cli(fd, "Value: %s\n", tmp); + ast_cli(a->fd, "Value: %s\n", tmp); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int database_del(int fd, int argc, char *argv[]) +static char *handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int res; - if (argc != 4) - return RESULT_SHOWUSAGE; - res = ast_db_del(argv[2], argv[3]); + + switch (cmd) { + case CLI_INIT: + e->command = "database del"; + e->usage = + "Usage: database del <family> <key>\n" + " Deletes an entry in the Asterisk database for a given\n" + " family and key.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; + res = ast_db_del(a->argv[2], a->argv[3]); if (res) { - ast_cli(fd, "Database entry does not exist.\n"); + ast_cli(a->fd, "Database entry does not exist.\n"); } else { - ast_cli(fd, "Database entry removed.\n"); + ast_cli(a->fd, "Database entry removed.\n"); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int database_deltree(int fd, int argc, char *argv[]) +static char *handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int res; - if ((argc < 3) || (argc > 4)) - return RESULT_SHOWUSAGE; - if (argc == 4) { - res = ast_db_deltree(argv[2], argv[3]); + + switch (cmd) { + case CLI_INIT: + e->command = "database deltree"; + e->usage = + "Usage: database deltree <family> [keytree]\n" + " Deletes a family or specific keytree within a family\n" + " in the Asterisk database.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if ((a->argc < 3) || (a->argc > 4)) + return CLI_SHOWUSAGE; + if (a->argc == 4) { + res = ast_db_deltree(a->argv[2], a->argv[3]); } else { - res = ast_db_deltree(argv[2], NULL); + res = ast_db_deltree(a->argv[2], NULL); } if (res < 0) { - ast_cli(fd, "Database entries do not exist.\n"); + ast_cli(a->fd, "Database entries do not exist.\n"); } else { - ast_cli(fd, "%d database entries removed.\n",res); + ast_cli(a->fd, "%d database entries removed.\n",res); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int database_show(int fd, int argc, char *argv[]) +static char *handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char prefix[256]; DBT key, data; @@ -310,23 +362,35 @@ static int database_show(int fd, int argc, char *argv[]) int pass; int counter = 0; - if (argc == 4) { + switch (cmd) { + case CLI_INIT: + e->command = "database show"; + e->usage = + "Usage: database show [family [keytree]]\n" + " Shows Asterisk database contents, optionally restricted\n" + " to a given family, or family and keytree.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc == 4) { /* Family and key tree */ - snprintf(prefix, sizeof(prefix), "/%s/%s", argv[2], argv[3]); - } else if (argc == 3) { + snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]); + } else if (a->argc == 3) { /* Family only */ - snprintf(prefix, sizeof(prefix), "/%s", argv[2]); - } else if (argc == 2) { + snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]); + } else if (a->argc == 2) { /* Neither */ prefix[0] = '\0'; } else { - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } ast_mutex_lock(&dblock); if (dbinit()) { ast_mutex_unlock(&dblock); - ast_cli(fd, "Database unavailable\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "Database unavailable\n"); + return CLI_SUCCESS; } memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); @@ -345,16 +409,16 @@ static int database_show(int fd, int argc, char *argv[]) values = "<bad value>"; } if (keymatch(keys, prefix)) { - ast_cli(fd, "%-50s: %-25s\n", keys, values); + ast_cli(a->fd, "%-50s: %-25s\n", keys, values); counter++; } } ast_mutex_unlock(&dblock); - ast_cli(fd, "%d results found.\n", counter); - return RESULT_SUCCESS; + ast_cli(a->fd, "%d results found.\n", counter); + return CLI_SUCCESS; } -static int database_showkey(int fd, int argc, char *argv[]) +static char *handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char suffix[256]; DBT key, data; @@ -363,17 +427,28 @@ static int database_showkey(int fd, int argc, char *argv[]) int pass; int counter = 0; - if (argc == 3) { + switch (cmd) { + case CLI_INIT: + e->command = "database show"; + e->usage = + "Usage: database showkey <keytree>\n" + " Shows Asterisk database contents, restricted to a given key.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc == 3) { /* Key only */ - snprintf(suffix, sizeof(suffix), "/%s", argv[2]); + snprintf(suffix, sizeof(suffix), "/%s", a->argv[2]); } else { - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } ast_mutex_lock(&dblock); if (dbinit()) { ast_mutex_unlock(&dblock); - ast_cli(fd, "Database unavailable\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "Database unavailable\n"); + return CLI_SUCCESS; } memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); @@ -392,13 +467,13 @@ static int database_showkey(int fd, int argc, char *argv[]) values = "<bad value>"; } if (subkeymatch(keys, suffix)) { - ast_cli(fd, "%-50s: %-25s\n", keys, values); + ast_cli(a->fd, "%-50s: %-25s\n", keys, values); counter++; } } ast_mutex_unlock(&dblock); - ast_cli(fd, "%d results found.\n", counter); - return RESULT_SUCCESS; + ast_cli(a->fd, "%d results found.\n", counter); + return CLI_SUCCESS; } struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree) @@ -473,59 +548,13 @@ void ast_db_freetree(struct ast_db_entry *dbe) } } -static const char database_show_usage[] = -"Usage: database show [family [keytree]]\n" -" Shows Asterisk database contents, optionally restricted\n" -"to a given family, or family and keytree.\n"; - -static const char database_showkey_usage[] = -"Usage: database showkey <keytree>\n" -" Shows Asterisk database contents, restricted to a given key.\n"; - -static const char database_put_usage[] = -"Usage: database put <family> <key> <value>\n" -" Adds or updates an entry in the Asterisk database for\n" -"a given family, key, and value.\n"; - -static const char database_get_usage[] = -"Usage: database get <family> <key>\n" -" Retrieves an entry in the Asterisk database for a given\n" -"family and key.\n"; - -static const char database_del_usage[] = -"Usage: database del <family> <key>\n" -" Deletes an entry in the Asterisk database for a given\n" -"family and key.\n"; - -static const char database_deltree_usage[] = -"Usage: database deltree <family> [keytree]\n" -" Deletes a family or specific keytree within a family\n" -"in the Asterisk database.\n"; - struct ast_cli_entry cli_database[] = { - { { "database", "show", NULL }, - database_show, "Shows database contents", - database_show_usage }, - - { { "database", "showkey", NULL }, - database_showkey, "Shows database contents", - database_showkey_usage }, - - { { "database", "get", NULL }, - database_get, "Gets database value", - database_get_usage }, - - { { "database", "put", NULL }, - database_put, "Adds/updates database value", - database_put_usage }, - - { { "database", "del", NULL }, - database_del, "Removes database key/value", - database_del_usage }, - - { { "database", "deltree", NULL }, - database_deltree, "Removes database keytree/values", - database_deltree_usage }, + NEW_CLI(handle_cli_database_show, "Shows database contents"), + NEW_CLI(handle_cli_database_showkey, "Shows database contents"), + NEW_CLI(handle_cli_database_get, "Gets database value"), + NEW_CLI(handle_cli_database_put, "Adds/updates database value"), + NEW_CLI(handle_cli_database_del, "Removes database key/value"), + NEW_CLI(handle_cli_database_deltree, "Removes database keytree/values") }; static int manager_dbput(struct mansession *s, const struct message *m) diff --git a/main/file.c b/main/file.c index 19f50bf81..93763c872 100644 --- a/main/file.c +++ b/main/file.c @@ -1202,37 +1202,44 @@ int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char * return res; } -static int show_file_formats(int fd, int argc, char *argv[]) +static char *handle_cli_core_show_file_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT "%-10s %-10s %-20s\n" #define FORMAT2 "%-10s %-10s %-20s\n" struct ast_format *f; int count_fmt = 0; - if (argc != 4) - return RESULT_SHOWUSAGE; - ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); + switch (cmd) { + case CLI_INIT: + e->command = "core show file formats"; + e->usage = + "Usage: core show file formats\n" + " Displays currently registered file formats (if any).\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; + + ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions"); + ast_cli(a->fd, FORMAT, "------", "----", "----------"); AST_RWLIST_RDLOCK(&formats); AST_RWLIST_TRAVERSE(&formats, f, list) { - ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); + ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); count_fmt++; } AST_RWLIST_UNLOCK(&formats); - ast_cli(fd, "%d file formats registered.\n", count_fmt); - return RESULT_SUCCESS; + ast_cli(a->fd, "%d file formats registered.\n", count_fmt); + return CLI_SUCCESS; #undef FORMAT #undef FORMAT2 } -static const char show_file_formats_usage[] = -"Usage: core show file formats\n" -" Displays currently registered file formats (if any)\n"; - struct ast_cli_entry cli_file[] = { - { { "core", "show", "file", "formats" }, - show_file_formats, "Displays file formats", - show_file_formats_usage }, + NEW_CLI(handle_cli_core_show_file_formats, "Displays file formats") }; int ast_file_init(void) diff --git a/main/image.c b/main/image.c index 718d463a9..0530ec5a4 100644 --- a/main/image.c +++ b/main/image.c @@ -179,27 +179,39 @@ int ast_send_image(struct ast_channel *chan, char *filename) return res; } -static int show_image_formats(int fd, int argc, char *argv[]) +static char *handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT "%10s %10s %50s %10s\n" #define FORMAT2 "%10s %10s %50s %10s\n" struct ast_imager *i; - if (argc != 4) - return RESULT_SHOWUSAGE; - ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format"); + int count_fmt = 0; + + switch (cmd) { + case CLI_INIT: + e->command = "core show image formats"; + e->usage = + "Usage: core show image formats\n" + " Displays currently registered image formats (if any).\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc != 4) + return CLI_SHOWUSAGE; + ast_cli(a->fd, FORMAT, "Name", "Extensions", "Description", "Format"); + ast_cli(a->fd, FORMAT, "----", "----------", "-----------", "------"); AST_RWLIST_RDLOCK(&imagers); AST_RWLIST_TRAVERSE(&imagers, i, list) { - ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format)); + ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format)); + count_fmt++; } AST_RWLIST_UNLOCK(&imagers); - return RESULT_SUCCESS; + ast_cli(a->fd, "\n%d image format%s registered.\n", count_fmt, count_fmt == 1 ? "" : "s"); + return CLI_SUCCESS; } struct ast_cli_entry cli_image[] = { - { { "core", "show", "image", "formats" }, - show_image_formats, "Displays image formats", - "Usage: core show image formats\n" - " displays currently registered image formats (if any)\n" }, + NEW_CLI(handle_core_show_image_formats, "Displays image formats") }; int ast_image_init(void) diff --git a/main/threadstorage.c b/main/threadstorage.c index 26f3e1c19..de3e9e0df 100644 --- a/main/threadstorage.c +++ b/main/threadstorage.c @@ -104,15 +104,30 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len AST_RWLIST_UNLOCK(&tls_objects); } -static int handle_show_allocations(int fd, int argc, char *argv[]) +static char *handle_cli_threadstorage_show_allocations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *fn = NULL; size_t len = 0; unsigned int count = 0; struct tls_object *to; - if (argc > 3) - fn = argv[3]; + switch (cmd) { + case CLI_INIT: + e->command = "threadstorage show allocations"; + e->usage = + "Usage: threadstorage show allocations [<file>]\n" + " Dumps a list of all thread-specific memory allocations,\n" + " optionally limited to those from a specific file\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc > 4) + return CLI_SHOWUSAGE; + + if (a->argc > 3) + fn = a->argv[3]; AST_RWLIST_RDLOCK(&tls_objects); @@ -120,7 +135,7 @@ static int handle_show_allocations(int fd, int argc, char *argv[]) if (fn && strcasecmp(to->file, fn)) continue; - ast_cli(fd, "%10d bytes allocated in %20s at line %5d of %25s (thread %p)\n", + ast_cli(a->fd, "%10d bytes allocated in %20s at line %5d of %25s (thread %p)\n", (int) to->size, to->function, to->line, to->file, (void *) to->thread); len += to->size; count++; @@ -128,12 +143,12 @@ static int handle_show_allocations(int fd, int argc, char *argv[]) AST_RWLIST_UNLOCK(&tls_objects); - ast_cli(fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : ""); + ast_cli(a->fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : ""); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_show_summary(int fd, int argc, char *argv[]) +static char *handle_cli_threadstorage_show_summary(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *fn = NULL; size_t len = 0; @@ -145,10 +160,26 @@ static int handle_show_summary(int fd, int argc, char *argv[]) unsigned int count; AST_LIST_ENTRY(file) entry; } *file; + + switch (cmd) { + case CLI_INIT: + e->command = "threadstorage show summary"; + e->usage = + "Usage: threadstorage show summary [<file>]\n" + " Summarizes thread-specific memory allocations by file, or optionally\n" + " by function, if a file is specified\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc > 4) + return CLI_SHOWUSAGE; + AST_LIST_HEAD_NOLOCK_STATIC(file_summary, file); - if (argc > 3) - fn = argv[3]; + if (a->argc > 3) + fn = a->argv[3]; AST_RWLIST_RDLOCK(&tls_objects); @@ -178,38 +209,22 @@ static int handle_show_summary(int fd, int argc, char *argv[]) len += file->len; count += file->count; if (fn) { - ast_cli(fd, "%10d bytes in %d allocation%ss in function %s\n", + ast_cli(a->fd, "%10d bytes in %d allocation%ss in function %s\n", (int) file->len, file->count, file->count > 1 ? "s" : "", file->name); } else { - ast_cli(fd, "%10d bytes in %d allocation%s in file %s\n", + ast_cli(a->fd, "%10d bytes in %d allocation%s in file %s\n", (int) file->len, file->count, file->count > 1 ? "s" : "", file->name); } } - ast_cli(fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : ""); - - return RESULT_SUCCESS; + ast_cli(a->fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : ""); + + return CLI_SUCCESS; } static struct ast_cli_entry cli[] = { - { - .cmda = { "threadstorage", "show", "allocations", NULL }, - .handler = handle_show_allocations, - .summary = "Display outstanding thread local storage allocations", - .usage = - "Usage: threadstorage show allocations [<file>]\n" - " Dumps a list of all thread-specific memory allocations,\n" - "optionally limited to those from a specific file\n", - }, - { - .cmda = { "threadstorage", "show", "summary", NULL }, - .handler = handle_show_summary, - .summary = "Summarize outstanding memory allocations", - .usage = - "Usage: threadstorage show summary [<file>]\n" - " Summarizes thread-specific memory allocations by file, or optionally\n" - "by function, if a file is specified\n", - }, + NEW_CLI(handle_cli_threadstorage_show_allocations, "Display outstanding thread local storage allocations"), + NEW_CLI(handle_cli_threadstorage_show_summary, "Summarize outstanding memory allocations") }; void threadstorage_init(void) diff --git a/main/translate.c b/main/translate.c index b22a3386d..88811ddc8 100644 --- a/main/translate.c +++ b/main/translate.c @@ -491,28 +491,42 @@ static void rebuild_matrix(int samples) } } -static int show_translation(int fd, int argc, char *argv[]) +static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define SHOW_TRANS 13 int x, y, z; int curlen = 0, longest = 0; - if (argc > 5) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "core show translation [recalc]"; + e->usage = + "Usage: core show translation [recalc] [<recalc seconds>]\n" + " Displays known codec translators and the cost associated\n" + " with each conversion. If the argument 'recalc' is supplied along\n" + " with optional number of seconds to test a new test will be performed\n" + " as the chart is being displayed.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc > 5) + return CLI_SHOWUSAGE; - if (argv[3] && !strcasecmp(argv[3], "recalc")) { - z = argv[4] ? atoi(argv[4]) : 1; + if (a->argv[3] && !strcasecmp(a->argv[3], "recalc")) { + z = a->argv[4] ? atoi(a->argv[4]) : 1; if (z <= 0) { - ast_cli(fd, " C'mon let's be serious here... defaulting to 1.\n"); + ast_cli(a->fd, " Recalc must be greater than 0. Defaulting to 1.\n"); z = 1; } if (z > MAX_RECALC) { - ast_cli(fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC); + ast_cli(a->fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC); z = MAX_RECALC; } - ast_cli(fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z); + ast_cli(a->fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z); AST_RWLIST_WRLOCK(&translators); rebuild_matrix(z); AST_RWLIST_UNLOCK(&translators); @@ -520,8 +534,8 @@ static int show_translation(int fd, int argc, char *argv[]) AST_RWLIST_RDLOCK(&translators); - ast_cli(fd, " Translation times between formats (in microseconds) for one second of data\n"); - ast_cli(fd, " Source Format (Rows) Destination Format (Columns)\n\n"); + ast_cli(a->fd, " Translation times between formats (in microseconds) for one second of data\n"); + ast_cli(a->fd, " Source Format (Rows) Destination Format (Columns)\n\n"); /* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */ for (x = 0; x < SHOW_TRANS; x++) { curlen = strlen(ast_getformatname(1 << (x + 1))); @@ -554,23 +568,14 @@ static int show_translation(int fd, int argc, char *argv[]) } } ast_str_append(&out, -1, "\n"); - ast_cli(fd, out->str); + ast_cli(a->fd, out->str); } AST_RWLIST_UNLOCK(&translators); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static const char show_trans_usage[] = -"Usage: core show translation [recalc] [<recalc seconds>]\n" -" Displays known codec translators and the cost associated\n" -"with each conversion. If the argument 'recalc' is supplied along\n" -"with optional number of seconds to test a new test will be performed\n" -"as the chart is being displayed.\n"; - static struct ast_cli_entry cli_translate[] = { - { { "core", "show", "translation", NULL }, - show_translation, "Display translation matrix", - show_trans_usage, NULL, NULL }, + NEW_CLI(handle_cli_core_show_translation, "Display translation matrix") }; /*! \brief register codec translator */ diff --git a/main/udptl.c b/main/udptl.c index d3c6163e7..a140cc4fe 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -1107,7 +1107,7 @@ int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, return -1; } -static int udptl_do_debug_ip(int fd, int argc, char *argv[]) +static char *handle_cli_udptl_debug_ip(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct hostent *hp; struct ast_hostent ahp; @@ -1115,10 +1115,22 @@ static int udptl_do_debug_ip(int fd, int argc, char *argv[]) char *p; char *arg; + switch (cmd) { + case CLI_INIT: + e->command = "udptl debug ip"; + e->usage = + "Usage: udptl debug [ip host[:port]]\n" + " Enable dumping of all UDPTL packets to and from host.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + port = 0; - if (argc != 4) - return RESULT_SHOWUSAGE; - arg = argv[3]; + + if (a->argc != 4) + return CLI_SHOWUSAGE; + arg = a->argv[3]; p = strstr(arg, ":"); if (p) { *p = '\0'; @@ -1127,60 +1139,67 @@ static int udptl_do_debug_ip(int fd, int argc, char *argv[]) } hp = ast_gethostbyname(arg, &ahp); if (hp == NULL) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; udptldebugaddr.sin_family = AF_INET; memcpy(&udptldebugaddr.sin_addr, hp->h_addr, sizeof(udptldebugaddr.sin_addr)); udptldebugaddr.sin_port = htons(port); if (port == 0) - ast_cli(fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr)); + ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr)); else - ast_cli(fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port); + ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port); udptldebug = 1; - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int udptl_do_debug(int fd, int argc, char *argv[]) +static char *handle_cli_udptl_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) { - if (argc != 4) - return RESULT_SHOWUSAGE; - return udptl_do_debug_ip(fd, argc, argv); + switch (cmd) { + case CLI_INIT: + e->command = "udptl debug"; + e->usage = + "Usage: udptl debug\n" + " Enable dumping of all UDPTL packets.\n"; + return NULL; + case CLI_GENERATE: + return NULL; } + + if (a->argc != 2) + return CLI_SHOWUSAGE; + udptldebug = 1; - memset(&udptldebugaddr,0,sizeof(udptldebugaddr)); - ast_cli(fd, "UDPTL Debugging Enabled\n"); - return RESULT_SUCCESS; -} + memset(&udptldebugaddr, 0, sizeof(udptldebugaddr)); -static int udptl_nodebug(int fd, int argc, char *argv[]) -{ - if (argc != 3) - return RESULT_SHOWUSAGE; - udptldebug = 0; - ast_cli(fd,"UDPTL Debugging Disabled\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "UDPTL Debugging Enabled\n"); + return CLI_SUCCESS; } -static const char debug_usage[] = - "Usage: udptl debug [ip host[:port]]\n" - " Enable dumping of all UDPTL packets to and from host.\n"; +static char *handle_cli_udptl_debug_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +{ + switch (cmd) { + case CLI_INIT: + e->command = "udptl debug off"; + e->usage = + "Usage: udptl debug off\n" + " Disable dumping of all UDPTL packets.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } -static const char nodebug_usage[] = - "Usage: udptl debug off\n" - " Disable all UDPTL debugging\n"; + if (a->argc != 3) + return CLI_SHOWUSAGE; -static struct ast_cli_entry cli_udptl[] = { - { { "udptl", "debug", NULL }, - udptl_do_debug, "Enable UDPTL debugging", - debug_usage }, + udptldebug = 0; - { { "udptl", "debug", "ip", NULL }, - udptl_do_debug, "Enable UDPTL debugging on IP", - debug_usage }, + ast_cli(a->fd, "UDPTL Debugging Disabled\n"); + return CLI_SUCCESS; +} - { { "udptl", "debug", "off", NULL }, - udptl_nodebug, "Disable UDPTL debugging", - nodebug_usage }, +static struct ast_cli_entry cli_udptl[] = { + NEW_CLI(handle_cli_udptl_debug, "Enable UDPTL debugging"), + NEW_CLI(handle_cli_udptl_debug_ip, "Enable UDPTL debugging on IP"), + NEW_CLI(handle_cli_udptl_debug_off, "Disable UDPTL debugging") }; static void __ast_udptl_reload(int reload) |