Source: ../../rtrmgr/op_commands.hh


 
LOGO
 Annotated List  Files  Globals  Hierarchy  Index  Top
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-

// Copyright (c) 2001-2005 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.

// $XORP: xorp/rtrmgr/op_commands.hh,v 1.24 2005/03/25 02:54:37 pavlin Exp $

#ifndef __RTRMGR_OP_COMMAND_HH__
#define __RTRMGR_OP_COMMAND_HH__


#include <list>
#include <set>

#include "libxorp/asyncio.hh"

#include "cli.hh"
#include "rtrmgr_error.hh"


class ConfigTree;
class OpCommand;
class TemplateTree;
class SlaveModuleManager;

class OpInstance {
public:
    OpInstance(EventLoop&			eventloop,
	       const string&			executable_filename,
	       const string&			command_arguments,
	       RouterCLI::OpModePrintCallback	print_cb,
	       RouterCLI::OpModeDoneCallback	done_cb,
	       OpCommand*			op_command);
    OpInstance(const OpInstance& orig);
    ~OpInstance();

    void append_data(AsyncFileOperator::Event event, const uint8_t* buffer,
		     size_t buffer_bytes, size_t offset);
    void done(bool success);
    bool operator<(const OpInstance& them) const;

    /**
     * Terminate this command
     */
    void terminate();

private:
    static const size_t OP_BUF_SIZE = 8192;

    string		_executable_filename;
    string		_command_arguments;
    OpCommand*		_op_command;
    AsyncFileReader*	_stdout_file_reader;
    AsyncFileReader*	_stderr_file_reader;
    FILE*		_stdout_stream;
    FILE*		_stderr_stream;
    uint8_t		_stdout_buffer[OP_BUF_SIZE];
    uint8_t		_stderr_buffer[OP_BUF_SIZE];
    pid_t		_pid;
    bool		_is_error;
    string		_error_msg;
    size_t		_last_offset;
    RouterCLI::OpModePrintCallback _print_callback;
    RouterCLI::OpModeDoneCallback _done_callback;
};

class OpCommand {
public:
    OpCommand(const list<string>& command_parts);

    const list<string>& command_parts() const { return _command_parts; }
    const string& command_name() const { return _command_name; }
    const string& help_string() const { return _help_string; }
    const string& module() const { return _module; }
    const string& command_action() const { return _command_action; }
    void set_help_string(const string& v) { _help_string = v; }
    void set_module(const string& v) { _module = v; }
    void set_command_action(const string& v) { _command_action = v; }
    void set_command_action_filename(const string& v) { _command_action_filename = v; }
    void set_command_action_arguments(const list<string>& v) { _command_action_arguments = v; }
    void set_command_executable_filename(const string& v) { _command_executable_filename = v; }
    bool is_executable() const { return (! _command_action.empty()); }

    void add_opt_param(const string& opt_param, const string& opt_param_help);
    bool has_opt_param(const string& opt_param) const;
    string str() const;
    static string command_parts2command_name(const list<string>& command_parts);
    /**
     * Select a positional argument.
     *
     * @param arguments the list with the arguments.
     * @param position the positional argument (e.g., "$0" specifies all
     * arguments, "$1" is the first argument, "$2" the second argument, etc.)
     * @param error_msg the error message (if error).
     * @return if @ref position is valid, then the string with the selected
     * argument, or an empty string if an error.
     */
    static string select_positional_argument(const list<string>& arguments,
					     const string& position,
					     string& error_msg);
    /**
     * Execute an operational mode command.
     *
     * @param eventloop the event loop.
     * @param command_line command to execute and arguments
     * @param print_cb callback to be invoked with output from command.
     * @param done_cb callback to invoke when the command terminates.
     *
     * @return a pointer to the command instance on success.
     */
    OpInstance* execute(EventLoop& eventloop,
			const list<string>& command_line,
			RouterCLI::OpModePrintCallback print_cb,
			RouterCLI::OpModeDoneCallback done_cb);

    bool command_match(const list<string>& path_parts,
		       SlaveConfigTree* sct, bool exact_match) const;
    void get_matches(size_t wordnum, SlaveConfigTree* sct,
		     map<string, string>& return_matches,
		     bool& is_executable,
		     bool& can_pipe) const;
    void remove_instance(OpInstance* instance);

private:
    list<string>	_command_parts;
    string		_command_name;
    string		_help_string;
    string		_module;
    string		_command_action;
    string		_command_action_filename;
    list<string>	_command_action_arguments;
    string		_command_executable_filename;
    map<string, string>	_opt_params;	// Optional parameters and the CLI help
    set<OpInstance*>	_instances;
};

class OpCommandList {
public:
    OpCommandList(const string& config_template_dir, const TemplateTree* tt,
		  SlaveModuleManager& mmgr)
	throw (InitError);
    ~OpCommandList();

    void set_slave_config_tree(SlaveConfigTree* sct) { _slave_config_tree = sct; }
    bool check_variable_name(const string& variable_name) const;
    OpCommand* find_op_command(const list<string>& command_parts);
    OpCommand* add_op_command(const OpCommand& op_command);
    bool command_match(const list<string>& command_parts,
		       bool exact_match) const;
    OpInstance *execute(EventLoop& eventloop,
			const list<string>& command_parts,
			RouterCLI::OpModePrintCallback print_cb,
			RouterCLI::OpModeDoneCallback done_cb) const;
    map<string, string> top_level_commands() const;
    map<string, string> childlist(const string& path,
				  bool& is_executable,
				  bool& can_pipe) const;
    bool find_executable_filename(const string& command_filename,
				  string& executable_filename) const;

private:
    list<OpCommand*>	_op_commands;

    // Below here is temporary storage for use in parsing
    list<string>	_path_segments;
    OpCommand*		_current_command;
    const TemplateTree*	_template_tree;
    SlaveConfigTree*	_slave_config_tree;
    SlaveModuleManager& _mmgr;
};

#endif // __RTRMGR_OP_COMMAND_HH__

Generated by: pavlin on possum.icir.org on Wed Apr 13 21:53:23 2005, using kdoc $.