Skip to content
Snippets Groups Projects
cli.c 25.9 KiB
Newer Older
Mark Spencer's avatar
Mark Spencer committed
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * Standard Command Line Interface
 * 
 * Copyright (C) 1999, Mark Spencer
 *
 * Mark Spencer <markster@linux-support.net>
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <unistd.h>
#include <stdlib.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/cli.h>
#include <asterisk/module.h>
#include <asterisk/channel.h>
Mark Spencer's avatar
Mark Spencer committed
#include <asterisk/channel_pvt.h>
#include <asterisk/utils.h>
Mark Spencer's avatar
Mark Spencer committed
#include <sys/signal.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
/* For rl_filename_completion */
Mark Spencer's avatar
Mark Spencer committed
#include "editline/readline/readline.h"
Mark Spencer's avatar
Mark Spencer committed
/* For module directory */
#include "asterisk.h"
Mark Spencer's avatar
Mark Spencer committed
#include "build.h"
Mark Spencer's avatar
Mark Spencer committed
#include "astconf.h"
Mark Spencer's avatar
Mark Spencer committed

#define VERSION_INFO "Asterisk " ASTERISK_VERSION " built by " BUILD_USER "@" BUILD_HOSTNAME \
	" on a " BUILD_MACHINE " running " BUILD_OS
	
Mark Spencer's avatar
Mark Spencer committed
void ast_cli(int fd, char *fmt, ...)
{
Mark Spencer's avatar
Mark Spencer committed
	va_list ap;
	va_start(ap, fmt);
	vasprintf(&stuff, fmt, ap);
Mark Spencer's avatar
Mark Spencer committed
	va_end(ap);
	write(fd, stuff, strlen(stuff));
	free(stuff);
ast_mutex_t clilock = AST_MUTEX_INITIALIZER;
Mark Spencer's avatar
Mark Spencer committed


struct ast_cli_entry *helpers = NULL;

static char load_help[] = 
"Usage: load <module name>\n"
"       Loads the specified module into Asterisk.\n";

static char unload_help[] = 
"Usage: unload [-f|-h] <module name>\n"
"       Unloads the specified module from Asterisk.  The -f\n"
"       option causes the module to be unloaded even if it is\n"
"       in use (may cause a crash) and the -h module causes the\n"
"       module to be unloaded even if the module says it cannot, \n"
"       which almost always will cause a crash.\n";

static char help_help[] =
"Usage: help [topic]\n"
"       When called with a topic as an argument, displays usage\n"
"       information on the given command.  If called without a\n"
"       topic, it provides a list of commands.\n";

static char chanlist_help[] = 
"Usage: show channels\n"
"       Lists currently defined channels and some information about\n"
"       them.\n";

Mark Spencer's avatar
Mark Spencer committed
static char reload_help[] = 
"Usage: reload\n"
"       Reloads configuration files for all modules which support\n"
"       reloading.\n";

static char set_verbose_help[] = 
"Usage: set verbose <level>\n"
"       Sets level of verbose messages to be displayed.  0 means\n"
"       no messages should be displayed.\n";

static 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";

Mark Spencer's avatar
Mark Spencer committed
static int handle_load(int fd, int argc, char *argv[])
{
	if (argc != 2)
		return RESULT_SHOWUSAGE;
	if (ast_load_resource(argv[1])) {
		ast_cli(fd, "Unable to load module %s\n", argv[1]);
		return RESULT_FAILURE;
	}
	return RESULT_SUCCESS;
}

Mark Spencer's avatar
Mark Spencer committed
static int handle_reload(int fd, int argc, char *argv[])
{
	if (argc != 1)
		return RESULT_SHOWUSAGE;
	ast_module_reload();
	return RESULT_SUCCESS;
}

static int handle_set_verbose(int fd, int argc, char *argv[])
{
	int val;
	/* Has a hidden 'at least' argument */
	if ((argc != 3) && (argc != 4))
		return RESULT_SHOWUSAGE;
	if ((argc == 4) && strcasecmp(argv[2], "atleast"))
		return RESULT_SHOWUSAGE;
	if (argc == 3)
		option_verbose = atoi(argv[2]);
	else {
		val = atoi(argv[3]);
		if (val > option_verbose)
			option_verbose = val;
	}
	return RESULT_SUCCESS;
}

Mark Spencer's avatar
Mark Spencer committed
static int handle_unload(int fd, int argc, char *argv[])
{
	int x;
	int force=AST_FORCE_SOFT;
	if (argc < 2)
		return RESULT_SHOWUSAGE;
	for (x=1;x<argc;x++) {
		if (argv[x][0] == '-') {
			switch(argv[x][1]) {
			case 'f':
				force = AST_FORCE_FIRM;
				break;
			case 'h':
				force = AST_FORCE_HARD;
				break;
			default:
				return RESULT_SHOWUSAGE;
			}
		} else if (x !=  argc - 1) 
			return RESULT_SHOWUSAGE;
		else if (ast_unload_resource(argv[x], force)) {
			ast_cli(fd, "Unable to unload resource %s\n", argv[x]);
			return RESULT_FAILURE;
		}
	}
	return RESULT_SUCCESS;
}

#define MODLIST_FORMAT  "%-25s %-40.40s %-10d\n"
#define MODLIST_FORMAT2 "%-25s %-40.40s %-10s\n"
static ast_mutex_t climodentrylock = AST_MUTEX_INITIALIZER;
Mark Spencer's avatar
Mark Spencer committed
static int climodentryfd = -1;

static int modlist_modentry(char *module, char *description, int usecnt)
{
	ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt);
	return 0;
}

static char modlist_help[] =
"Usage: show modules\n"
"       Shows Asterisk modules currently in use, and usage "
"statistics.\n";

Mark Spencer's avatar
Mark Spencer committed
static char version_help[] =
"Usage: show version\n"
"       Shows Asterisk version information.\n ";

Mark Spencer's avatar
Mark Spencer committed
static char *format_uptimestr(time_t timeval)
{
	int years = 0, weeks = 0, days = 0, hours = 0, mins = 0, secs = 0;
	char timestr[256];
	int pos = 0;
#define SECOND (1)
#define MIN (SECOND*60)
#define HOUR (MIN*60)
#define DAY (HOUR*24)
#define WEEK (DAY*7)
#define YEAR (DAY*365)

	if (timeval < 0)
		return NULL;
Mark Spencer's avatar
Mark Spencer committed
	if (timeval > YEAR) {
		years = (timeval / YEAR);
		timeval -= (years * YEAR);
		if (years > 1)
			pos += sprintf(timestr + pos, "%d years, ", years);
		else
			pos += sprintf(timestr + pos, "1 year, ");
	}
	if (timeval > WEEK) {
Loading
Loading full blame...