// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2007 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
#ident "$XORP: xorp/cli/cli_node_internal_commands.cc,v 1.17 2007/02/16 22:45:29 pavlin Exp $"
//
// CLI internal commands.
//
#include "cli_module.h"
#include "libxorp/xorp.h"
#include "libxorp/xlog.h"
#include "libxorp/debug.h"
#include "libxorp/ipvx.hh"
#include "cli_node.hh"
#include "cli_client.hh"
#include "cli_command.hh"
//
// Exported variables
//
//
// Local constants definitions
//
//
// Local structures/classes, typedefs and macros
//
//
// Local variables
//
//
// Local functions prototypes
//
/**
* CliNode::add_internal_cli_commands:
* @error_msg: The error message (if error).
*
* Add the internal default CLI commands from the top.
* XXX: used by the CLI itself for internal processing of a command.
* TODO: for consistency, even the internal commands should use XRLs instead.
*
* Return value: %XORP_OK on success, otherwise %XORP_ERROR.
**/
int
CliNode::add_internal_cli_commands(string& error_msg)
{
CliCommand *c0;
c0 = cli_command_root();
if (c0 == NULL) {
error_msg = c_format("Cannot find root CLI command");
return (XORP_ERROR);
}
if (c0->add_command("show", "Display information", true, error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("show log",
"Display information about log files and users",
true,
callback(this, &CliNode::cli_show_log),
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("show log user",
"Display information about users",
true,
callback(this, &CliNode::cli_show_log_user),
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set", "Set variable", true, error_msg) == NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log", "Set log-related state", true, error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log output",
"Set output destination for log messages",
true,
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log output cli",
"Set output CLI terminal for log messages",
true,
callback(this, &CliNode::cli_set_log_output_cli),
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log output file",
"Set output file for log messages",
true,
callback(this, &CliNode::cli_set_log_output_file),
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log output remove",
"Remove output destination for log messages",
true,
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log output remove cli",
"Remove output CLI terminal for log messages",
true,
callback(this, &CliNode::cli_set_log_output_remove_cli),
error_msg)
== NULL) {
return (XORP_ERROR);
}
if (c0->add_command("set log output remove file",
"Remove output file for log messages",
true,
callback(this, &CliNode::cli_set_log_output_remove_file),
error_msg)
== NULL) {
return (XORP_ERROR);
}
return (XORP_OK);
}
//
// CLI COMMAND: "show log [filename]"
//
// Display information about log files
// TODO: probably should change the command name to "show log file" ??
int
CliNode::cli_show_log(const string& , // server_name
const string& cli_term_name,
uint32_t , // cli_session_id
const vector<string>& , // command_global_name
const vector<string>& argv)
{
CliClient *cli_client = find_cli_by_term_name(cli_term_name);
if (cli_client == NULL)
return (XORP_ERROR);
for (size_t i = 0; i < argv.size(); i++) {
// Show log information about optional files
cli_client->cli_print(c_format("Showing information about file '%s'\n",
argv[i].c_str()));
}
return (XORP_OK);
}
//
// CLI COMMAND: "show log user [username]"
//
// Display information about users
// TODO: add the missing info at the end to make it 'who'-like
int
CliNode::cli_show_log_user(const string& , // server_name
const string& cli_term_name,
uint32_t , // cli_session_id
const vector<string>& , // command_global_name
const vector<string>&argv)
{
CliClient *cli_client = find_cli_by_term_name(cli_term_name);
if (cli_client == NULL)
return (XORP_ERROR);
string user_name; // The optional user name to return info for
bool user_name_found = false;
if (argv.size()) {
user_name = argv[0];
cli_client->cli_print(c_format("Showing information about user '%s'\n",
user_name.c_str()));
} else {
user_name_found = true;
}
list<CliClient *>::iterator iter;
for (iter = client_list().begin(); iter != client_list().end(); ++iter) {
CliClient *tmp_cli_client = *iter;
if (user_name.size()
&& (user_name != tmp_cli_client->cli_session_user_name())) {
continue;
}
user_name_found = true;
// Get the start time
TimeVal start_time_tv = tmp_cli_client->cli_session_start_time();
string start_time;
{
char buf[sizeof("999999999/99/99 99/99/99.999999999 ")];
size_t maxlen = sizeof(buf);
time_t time_clock = start_time_tv.sec();
struct tm *local_time = localtime(&time_clock);
if (strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", local_time)
== 0) {
snprintf(buf, maxlen / sizeof(buf[0]), "strftime ERROR");
}
start_time = buf;
}
cli_client->cli_print(
c_format("%-16s%-16s%-16s%-16s\n",
tmp_cli_client->cli_session_user_name().c_str(),
tmp_cli_client->cli_session_term_name().c_str(),
cstring(tmp_cli_client->cli_session_from_address()),
start_time.c_str())
);
}
if (user_name.size() && (! user_name_found)) {
cli_client->cli_print(
c_format("No such user '%s'\n", user_name.c_str())
);
}
#if 0
list<CliClient *>::iterator iter;
for (iter = client_list().begin();
iter != client_list().end(); ++iter) {
CliClient *tmp_cli_client = *iter;
cli_client->cli_print(
c_format("%-16s%-16s%-16s%-16s - %-16s (%s)\n",
tmp_cli_client->cli_session_user_name().c_str(),
tmp_cli_client->cli_session_term_name().c_str(),
cstring(tmp_cli_client->cli_session_from_address()),
tmp_cli_client->cli_session_start_time().c_str(),
tmp_cli_client->cli_session_stop_time().c_str(),
tmp_cli_client->cli_session_duration_time().c_str())
);
}
#endif
return (XORP_OK);
}
//
// CLI COMMAND: "set log output cli <cli_term_name> | 'all' "
//
// Add CLI terminal to the set of output destinations of log messages
// TODO: this is a home-brew own command
// TODO: this command should set state in the appropriate protocols and
// start getting the logs from each of them (through XRLs) instead
// of applying it only to the local process logs.
int
CliNode::cli_set_log_output_cli(const string& , // server_name
const string& cli_term_name,
uint32_t , // cli_session_id
const vector<string>& , // command_global_name
const vector<string>& argv)
{
CliClient *cli_client = find_cli_by_term_name(cli_term_name);
if (cli_client == NULL)
return (XORP_ERROR);
CliClient *tmp_cli_client;
string term_name;
uint32_t cli_n = 0;
if (argv.empty()) {
cli_client->cli_print("ERROR: missing CLI terminal name\n");
return (XORP_ERROR);
}
term_name = argv[0];
if (term_name == "all") {
list<CliClient *>::iterator iter;
for (iter = client_list().begin();
iter != client_list().end();
++iter) {
tmp_cli_client = *iter;
if (! tmp_cli_client->is_log_output()) {
if (tmp_cli_client->set_log_output(true) == XORP_OK) {
cli_n++;
} else {
cli_client->cli_print(
c_format("ERROR: cannot add CLI terminal "
"'%s' as log output\n",
tmp_cli_client->cli_session_term_name().c_str()));
}
}
}
} else {
tmp_cli_client = find_cli_by_term_name(term_name);
if (tmp_cli_client == NULL) {
cli_client->cli_print(
c_format("ERROR: cannot find CLI terminal '%s'\n",
term_name.c_str()));
return (XORP_ERROR);
}
if (! tmp_cli_client->is_log_output()) {
if (tmp_cli_client->set_log_output(true) == XORP_OK) {
cli_n++;
} else {
cli_client->cli_print(
c_format("ERROR: cannot add CLI terminal "
"'%s' as log output\n",
tmp_cli_client->cli_session_term_name().c_str())
);
return (XORP_ERROR);
}
}
}
cli_client->cli_print(c_format("Added %u CLI terminal(s)\n",
XORP_UINT_CAST(cli_n)));
return (XORP_OK);
}
//
// CLI COMMAND: "set log output cli remove <cli_term_name> | 'all' "
//
// Remove CLI terminal from the set of output destinations of log messages
// TODO: this is a home-brew own command
// TODO: merge this function with "set log output cli"
int
CliNode::cli_set_log_output_remove_cli(const string& , // server_name
const string& cli_term_name,
uint32_t , // cli_session_id
const vector<string>& , // command_global_name
const vector<string>& argv)
{
CliClient *cli_client = find_cli_by_term_name(cli_term_name);
if (cli_client == NULL)
return (XORP_ERROR);
CliClient *tmp_cli_client;
string term_name;
uint32_t cli_n = 0;
if (argv.empty()) {
cli_client->cli_print("ERROR: missing CLI terminal name\n");
return (XORP_ERROR);
}
term_name = argv[0];
if (term_name == "all") {
list<CliClient *>::iterator iter;
for (iter = client_list().begin();
iter != client_list().end();
++iter) {
tmp_cli_client = *iter;
if (tmp_cli_client->is_log_output()) {
if (tmp_cli_client->set_log_output(false) == XORP_OK) {
cli_n++;
} else {
cli_client->cli_print(
c_format("ERROR: cannot remove CLI terminal "
"'%s' as log output\n",
tmp_cli_client->cli_session_term_name().c_str()));
}
}
}
} else {
tmp_cli_client = find_cli_by_term_name(term_name);
if (tmp_cli_client == NULL) {
cli_client->cli_print(
c_format("ERROR: cannot find CLI terminal '%s'\n",
term_name.c_str()));
return (XORP_ERROR);
}
if (tmp_cli_client->is_log_output()) {
if (tmp_cli_client->set_log_output(false) == XORP_OK) {
cli_n++;
} else {
cli_client->cli_print(
c_format("ERROR: cannot remove CLI terminal "
"'%s' from log output\n",
tmp_cli_client->cli_session_term_name().c_str()));
return (XORP_ERROR);
}
}
}
cli_client->cli_print(c_format("Removed %u CLI terminal(s)\n",
XORP_UINT_CAST(cli_n)));
return (XORP_OK);
}
//
// CLI COMMAND: "set log output file <filename>"
//
// Add a file to the set of output destinations of log messages
// TODO: this is a home-brew own command
// TODO: this command should set state in the appropriate protocols and
// start getting the logs from each of them (through XRLs) instead
// of applying it only to the local process logs.
int
CliNode::cli_set_log_output_file(const string& , // server_name
const string& cli_term_name,
uint32_t , // cli_session_id
const vector<string>& , // command_global_name
const vector<string>& argv)
{
CliClient *cli_client = find_cli_by_term_name(cli_term_name);
if (cli_client == NULL)
return (XORP_ERROR);
string file_name;
if (argv.empty()) {
cli_client->cli_print("ERROR: missing file name\n");
return (XORP_ERROR);
}
file_name = argv[0];
cli_client->cli_print("TODO: function not implemented yet\n");
return (XORP_OK);
}
//
// CLI COMMAND: "set log output remove file <filename>"
//
// Remove a file from the set of output destinations of log messages
// TODO: this is a home-brew own command
int
CliNode::cli_set_log_output_remove_file(const string& , // server_name
const string& cli_term_name,
uint32_t , // cli_session_id
const vector<string>& , // command_global_name
const vector<string>& argv)
{
CliClient *cli_client = find_cli_by_term_name(cli_term_name);
if (cli_client == NULL)
return (XORP_ERROR);
string file_name;
if (argv.empty()) {
cli_client->cli_print("ERROR: missing file name\n");
return (XORP_ERROR);
}
file_name = argv[0];
cli_client->cli_print("TODO: function not implemented yet\n");
return (XORP_OK);
}
syntax highlighted by Code2HTML, v. 0.9.1