summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2011-01-20 10:28:06 -0800
committerAn-Cheng Huang <ancheng@vyatta.com>2011-01-20 10:28:06 -0800
commit9cb5eb04bf0700bef1c061261ffbd6dc893eb7e8 (patch)
tree38a18b559793d00e6ffa43ab0ba8f91b96b8a61d
parent2239b0ff1aa4c9075012021731ed9e2890446911 (diff)
downloadvyatta-cfg-9cb5eb04bf0700bef1c061261ffbd6dc893eb7e8.tar.gz
vyatta-cfg-9cb5eb04bf0700bef1c061261ffbd6dc893eb7e8.zip
export config output algorithms through shell API
-rw-r--r--src/cli_shell_api.cpp45
-rw-r--r--src/cnode/cnode-algorithm.cpp59
-rw-r--r--src/cnode/cnode-algorithm.hpp8
-rw-r--r--src/cparse/cparse.hpp1
-rw-r--r--src/cparse/cparse.ypp10
5 files changed, 122 insertions, 1 deletions
diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp
index 6546480..a61046c 100644
--- a/src/cli_shell_api.cpp
+++ b/src/cli_shell_api.cpp
@@ -57,6 +57,9 @@ int op_show_show_defaults = 0;
int op_show_hide_secrets = 0;
int op_show_working_only = 0;
int op_show_context_diff = 0;
+int op_show_commands = 0;
+char *op_show_cfg1 = NULL;
+char *op_show_cfg2 = NULL;
typedef void (*OpFuncT)(Cstore& cstore, const vector<string>& args);
@@ -400,6 +403,28 @@ showCfg(Cstore& cstore, const vector<string>& args)
}
static void
+showConfig(Cstore& cstore, const vector<string>& args)
+{
+ string cfg1 = cnode::ACTIVE_CFG;
+ string cfg2 = cnode::WORKING_CFG;
+
+ if (op_show_active_only) {
+ cfg2 = cnode::ACTIVE_CFG;
+ } else if (op_show_working_only) {
+ cfg1 = cnode::WORKING_CFG;
+ } else if (op_show_cfg1 && op_show_cfg2) {
+ cfg1 = op_show_cfg1;
+ cfg2 = op_show_cfg2;
+ } else {
+ // default
+ }
+
+ cnode::showConfig(cfg1, cfg2, args, op_show_show_defaults,
+ op_show_hide_secrets, op_show_context_diff,
+ op_show_commands);
+}
+
+static void
loadFile(Cstore& cstore, const vector<string>& args)
{
if (!cstore.loadFile(args[0].c_str())) {
@@ -451,6 +476,7 @@ static OpT ops[] = {
OP(validateTmplValPath, -1, NULL, 1, "Must specify config path", false),
OP(showCfg, -1, NULL, -1, NULL, true),
+ OP(showConfig, -1, NULL, -1, NULL, true),
OP(loadFile, 1, "Must specify config file", -1, NULL, false),
{NULL, -1, NULL, -1, NULL, NULL, false}
@@ -462,12 +488,20 @@ static OpT ops[] = {
#define OP_use_edit ops[op_idx].op_use_edit
#define OP_func ops[op_idx].op_func
+enum {
+ SHOW_CFG1 = 1,
+ SHOW_CFG2
+};
+
struct option options[] = {
{"show-active-only", no_argument, &op_show_active_only, 1},
{"show-show-defaults", no_argument, &op_show_show_defaults, 1},
{"show-hide-secrets", no_argument, &op_show_hide_secrets, 1},
{"show-working-only", no_argument, &op_show_working_only, 1},
{"show-context-diff", no_argument, &op_show_context_diff, 1},
+ {"show-commands", no_argument, &op_show_commands, 1},
+ {"show-cfg1", required_argument, NULL, SHOW_CFG1},
+ {"show-cfg2", required_argument, NULL, SHOW_CFG2},
{NULL, 0, NULL, 0}
};
@@ -477,7 +511,16 @@ main(int argc, char **argv)
// handle options first
int c = 0;
while ((c = getopt_long(argc, argv, "", options, NULL)) != -1) {
- // nothing for now
+ switch (c) {
+ case SHOW_CFG1:
+ op_show_cfg1 = strdup(optarg);
+ break;
+ case SHOW_CFG2:
+ op_show_cfg2 = strdup(optarg);
+ break;
+ default:
+ break;
+ }
}
int nargs = argc - optind - 1;
char *oname = argv[optind];
diff --git a/src/cnode/cnode-algorithm.cpp b/src/cnode/cnode-algorithm.cpp
index 844b145..3722d13 100644
--- a/src/cnode/cnode-algorithm.cpp
+++ b/src/cnode/cnode-algorithm.cpp
@@ -17,9 +17,11 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <tr1/memory>
#include <cstore/cstore.hpp>
#include <cnode/cnode.hpp>
+#include <cparse/cparse.hpp>
#include <cnode/cnode-algorithm.hpp>
using namespace std;
@@ -33,6 +35,8 @@ static const string PFX_DIFF_UPD = ">"; // changed
static const string PFX_DIFF_NONE = " ";
static const string PFX_DIFF_NULL = "";
+const string cnode::ACTIVE_CFG = "@ACTIVE";
+const string cnode::WORKING_CFG = "@WORKING";
////// static (internal) functions
static void
@@ -893,3 +897,58 @@ cnode::get_cmds(const CfgNode& cfg, vector<vector<string> >& set_list,
_get_cmds_diff(&cfg, &cfg, cur_path, del_list, set_list, com_list);
}
+void
+cnode::showConfig(const string& cfg1, const string& cfg2,
+ const vector<string>& path, bool show_def, bool hide_secret,
+ bool context_diff, bool show_cmds)
+{
+ tr1::shared_ptr<CfgNode> aroot, wroot, croot1, croot2;
+ tr1::shared_ptr<Cstore> cstore;
+ vector<string> rpath(path);
+ vector<string> cur_path;
+
+ if ((cfg1 == ACTIVE_CFG || cfg1 == WORKING_CFG)
+ && (cfg2 == ACTIVE_CFG || cfg2 == WORKING_CFG)) {
+ // active/working config only => use edit level and path
+ cstore.reset(Cstore::createCstore(true));
+ cstore->getEditLevel(cur_path);
+ } else {
+ // at least one config file => don't use edit level and path
+ cstore.reset(Cstore::createCstore(false));
+ rpath.clear();
+ }
+ if (cfg1 == ACTIVE_CFG || cfg2 == ACTIVE_CFG) {
+ aroot.reset(new CfgNode(*cstore, rpath, true, true));
+ }
+ if (cfg1 == WORKING_CFG || cfg2 == WORKING_CFG) {
+ // note: if there is no config session, this will abort
+ wroot.reset(new CfgNode(*cstore, rpath, false, true));
+ }
+
+ if (cfg1 == ACTIVE_CFG) {
+ croot1 = aroot;
+ } else if (cfg1 == WORKING_CFG) {
+ croot1 = wroot;
+ } else {
+ croot1.reset(cparse::parse_file(cfg1.c_str(), *cstore));
+ }
+ if (cfg2 == ACTIVE_CFG) {
+ croot2 = aroot;
+ } else if (cfg2 == WORKING_CFG) {
+ croot2 = wroot;
+ } else {
+ croot2.reset(cparse::parse_file(cfg2.c_str(), *cstore));
+ }
+ if (!croot1.get() || !croot2.get()) {
+ printf("Cannot parse specified config file(s)\n");
+ return;
+ }
+
+ if (show_cmds) {
+ show_cmds_diff(*croot1, *croot2);
+ } else {
+ show_cfg_diff(*croot1, *croot2, cur_path, show_def, hide_secret,
+ context_diff);
+ }
+}
+
diff --git a/src/cnode/cnode-algorithm.hpp b/src/cnode/cnode-algorithm.hpp
index 4b1ec2f..c473d6a 100644
--- a/src/cnode/cnode-algorithm.hpp
+++ b/src/cnode/cnode-algorithm.hpp
@@ -38,6 +38,14 @@ void get_cmds_diff(const CfgNode& cfg1, const CfgNode& cfg2,
void get_cmds(const CfgNode& cfg, vector<vector<string> >& set_list,
vector<vector<string> >& com_list);
+extern const string ACTIVE_CFG;
+extern const string WORKING_CFG;
+
+void showConfig(const string& cfg1, const string& cfg2,
+ const vector<string>& path, bool show_def = false,
+ bool hide_secret = false, bool context_diff = false,
+ bool show_cmds = false);
+
} // namespace cnode
#endif /* _CNODE_ALGORITHM_HPP_ */
diff --git a/src/cparse/cparse.hpp b/src/cparse/cparse.hpp
index 5751d64..d359deb 100644
--- a/src/cparse/cparse.hpp
+++ b/src/cparse/cparse.hpp
@@ -23,6 +23,7 @@
namespace cparse {
cnode::CfgNode *parse_file(FILE *fin, Cstore& cs);
+cnode::CfgNode *parse_file(const char *fname, Cstore& cs);
} // namespace cparse
diff --git a/src/cparse/cparse.ypp b/src/cparse/cparse.ypp
index b1958e9..aeecaf3 100644
--- a/src/cparse/cparse.ypp
+++ b/src/cparse/cparse.ypp
@@ -215,3 +215,13 @@ cparse::parse_file(FILE *fin, Cstore& cs)
return cur_parent;
}
+CfgNode *
+cparse::parse_file(const char *fname, Cstore& cs)
+{
+ FILE *fin = fopen(fname, "r");
+ if (!fin) {
+ return NULL;
+ }
+ return parse_file(fin, cs);
+}
+