summaryrefslogtreecommitdiff
path: root/src/cstore/cstore.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cstore/cstore.hpp')
-rw-r--r--src/cstore/cstore.hpp409
1 files changed, 409 insertions, 0 deletions
diff --git a/src/cstore/cstore.hpp b/src/cstore/cstore.hpp
new file mode 100644
index 0000000..f6a4215
--- /dev/null
+++ b/src/cstore/cstore.hpp
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2010 Vyatta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CSTORE_H_
+#define _CSTORE_H_
+#include <vector>
+#include <string>
+#include <map>
+
+extern "C" {
+#include <cli_val.h>
+#include <cli_val_engine.h>
+}
+
+#define exit_internal(fmt, args...) do \
+ { \
+ output_internal("[%s:%d] " fmt, __FILE__, __LINE__ , ##args); \
+ exit(-1); \
+ } while (0);
+
+/* macros for saving/restoring paths.
+ * note: this allows "nested" save/restore invocations but NOT recursive ones.
+ */
+#define SAVE_PATHS save_paths(&__func__)
+#define RESTORE_PATHS restore_paths(&__func__)
+
+using namespace std;
+
+class Cstore {
+public:
+ Cstore() {};
+ Cstore(string& env);
+ ~Cstore() {};
+
+ // constants
+ static const string C_NODE_STATUS_DELETED;
+ static const string C_NODE_STATUS_ADDED;
+ static const string C_NODE_STATUS_CHANGED;
+ static const string C_NODE_STATUS_STATIC;
+
+ static const string C_ENV_EDIT_LEVEL;
+ static const string C_ENV_TMPL_LEVEL;
+
+ static const string C_ENV_SHELL_PROMPT;
+ static const string C_ENV_SHELL_CWORDS;
+ static const string C_ENV_SHELL_CWORD_COUNT;
+
+ static const string C_ENV_SHAPI_COMP_VALS;
+ static const string C_ENV_SHAPI_LCOMP_VAL;
+ static const string C_ENV_SHAPI_COMP_HELP;
+ static const string C_ENV_SHAPI_HELP_ITEMS;
+ static const string C_ENV_SHAPI_HELP_STRS;
+
+ static const string C_ENUM_SCRIPT_DIR;
+
+ static const size_t MAX_CMD_OUTPUT_SIZE = 4096;
+
+ ////// the public cstore interface
+ //// functions implemented in this base class
+ // these operate on template path
+ bool validateTmplPath(const vector<string>& path_comps, bool validate_vals);
+ bool validateTmplPath(const vector<string>& path_comps, bool validate_vals,
+ vtw_def& def);
+ bool getParsedTmpl(const vector<string>& path_comps,
+ map<string, string>& tmap, bool allow_val = true);
+ void tmplGetChildNodes(const vector<string>& path_comps,
+ vector<string>& cnodes);
+
+ /******
+ * functions for actual CLI operations:
+ * set
+ * delete
+ * activate
+ * deactivate
+ * rename
+ * copy
+ * comment
+ * discard
+ * move (currently this is only available in cfg-cmd-wrapper)
+ * edit-related commands (invoked from shell functions)
+ * completion-related (for completion script)
+ * session-related (setup, teardown, etc.)
+ * load (XXX currently still implemented in perl)
+ *
+ * these operate on the "working config" and the session and MUST NOT
+ * be used by anything other than the listed operations.
+ */
+ // set
+ bool validateSetPath(const vector<string>& path_comps);
+ bool setCfgPath(const vector<string>& path_comps);
+ // delete
+ bool validateDeletePath(const vector<string>& path_comps, vtw_def& def);
+ bool deleteCfgPath(const vector<string>& path_comps, const vtw_def& def);
+ // activate (actually "unmark deactivated" since it is 2-state, not 3)
+ bool validateActivatePath(const vector<string>& path_comps);
+ bool unmarkCfgPathDeactivated(const vector<string>& path_comps);
+ // deactivate
+ bool validateDeactivatePath(const vector<string>& path_comps);
+ bool markCfgPathDeactivated(const vector<string>& path_comps);
+ // rename
+ bool validateRenameArgs(const vector<string>& args);
+ bool renameCfgPath(const vector<string>& args);
+ // copy
+ bool validateCopyArgs(const vector<string>& args);
+ bool copyCfgPath(const vector<string>& args);
+ // comment
+ bool validateCommentArgs(const vector<string>& args, vtw_def& def);
+ bool commentCfgPath(const vector<string>& args, const vtw_def& def);
+ // discard
+ bool discardChanges();
+ // move
+ bool validateMoveArgs(const vector<string>& args);
+ bool moveCfgPath(const vector<string>& args);
+ // edit-related
+ bool getEditEnv(const vector<string>& path_comps, string& env);
+ bool getEditUpEnv(string& env);
+ bool getEditResetEnv(string& env);
+ bool editLevelAtRoot() {
+ return edit_level_at_root();
+ };
+ // completion-related
+ bool getCompletionEnv(const vector<string>& comps, string& env);
+ void getEditLevel(vector<string>& comps) {
+ get_edit_level(comps);
+ };
+ // session-related
+ virtual bool markSessionUnsaved() = 0;
+ virtual bool unmarkSessionUnsaved() = 0;
+ virtual bool sessionUnsaved() = 0;
+ virtual bool sessionChanged() = 0;
+ virtual bool setupSession() = 0;
+ virtual bool teardownSession() = 0;
+ virtual bool inSession() = 0;
+ // common
+ bool markCfgPathChanged(const vector<string>& path_comps);
+ // XXX load
+ //bool unmarkCfgPathDeactivatedDescendants(const vector<string>& path_comps);
+
+ /******
+ * these functions are observers of the current "working config" or
+ * "active config" during a config session.
+ * MOST users of the cstore API should be using these functions (most
+ * likely during a commit operation).
+ *
+ * note that these MUST NOT worry about "deactivated" state.
+ * for these functions, deactivated nodes are equivalent to having been
+ * deleted. in other words, these functions are NOT "deactivate-aware".
+ *
+ * also, the functions that can be used to observe "active config" can
+ * be used outside a config session as well (only when observing active
+ * config, of course).
+ */
+ // observers for "working config" (by default) OR "active config"
+ bool cfgPathExists(const vector<string>& path_comps,
+ bool active_cfg = false);
+ void cfgPathGetChildNodes(const vector<string>& path_comps,
+ vector<string>& cnodes, bool active_cfg = false);
+ bool cfgPathGetValue(const vector<string>& path_comps, string& value,
+ bool active_cfg = false);
+ bool cfgPathGetValues(const vector<string>& path_comps,
+ vector<string>& values, bool active_cfg = false);
+ bool cfgPathGetComment(const vector<string>& path_comps, string& comment,
+ bool active_cfg = false);
+ /* observers for working AND active configs (at the same time).
+ * MUST ONLY be used during config session.
+ */
+ bool cfgPathDeleted(const vector<string>& path_comps);
+ bool cfgPathAdded(const vector<string>& path_comps);
+ bool cfgPathChanged(const vector<string>& path_comps);
+ void cfgPathGetDeletedChildNodes(const vector<string>& path_comps,
+ vector<string>& cnodes);
+ void cfgPathGetChildNodesStatus(const vector<string>& path_comps,
+ map<string, string>& cmap);
+ /* observers for "effective config" (a combination of working config,
+ * active config, and commit processing state) only.
+ * MUST ONLY be used during config session.
+ */
+ bool cfgPathEffective(const vector<string>& path_comps);
+ void cfgPathGetEffectiveChildNodes(const vector<string>& path_comps,
+ vector<string>& cnodes);
+ bool cfgPathGetEffectiveValue(const vector<string>& path_comps,
+ string& value);
+ bool cfgPathGetEffectiveValues(const vector<string>& path_comps,
+ vector<string>& values);
+
+ /******
+ * "deactivate-aware" observers of the current working or active config.
+ * these are the only functions that are allowed to see the "deactivate"
+ * state of config nodes.
+ *
+ * these functions MUST ONLY be used by operations that NEED to distinguish
+ * between deactivated nodes and deleted nodes. below is the list
+ * of operations that are allowed to use these functions:
+ * * configuration output (show, save, load)
+ *
+ * operations that are not on the above list MUST NOT use these
+ * "deactivate-aware" functions.
+ *
+ * note: the last argument "include_deactivated" for the DA functions
+ * is for implementation convenience and does not need to be
+ * passed in when calling them.
+ */
+ // working or active config
+ bool cfgPathDeactivated(const vector<string>& path_comps,
+ bool active_cfg = false);
+ bool cfgPathMarkedDeactivated(const vector<string>& path_comps,
+ bool active_cfg = false);
+ bool cfgPathExistsDA(const vector<string>& path_comps,
+ bool active_cfg = false,
+ bool include_deactivated = true);
+ void cfgPathGetChildNodesDA(const vector<string>& path_comps,
+ vector<string>& cnodes,
+ bool active_cfg = false,
+ bool include_deactivated = true);
+ bool cfgPathGetValueDA(const vector<string>& path_comps, string& value,
+ bool active_cfg = false,
+ bool include_deactivated = true);
+ bool cfgPathGetValuesDA(const vector<string>& path_comps,
+ vector<string>& values,
+ bool active_cfg = false,
+ bool include_deactivated = true);
+ // working AND active configs
+ void cfgPathGetDeletedChildNodesDA(const vector<string>& path_comps,
+ vector<string>& cnodes,
+ bool include_deactivated = true);
+ void cfgPathGetChildNodesStatusDA(const vector<string>& path_comps,
+ map<string, string>& cmap);
+
+
+ /* these are internal API functions and operate on current cfg and
+ * tmpl paths during cstore operations. they are only used to work around
+ * the limitations of the original CLI library implementation and MUST NOT
+ * be used by anyone other than the original CLI library.
+ */
+ bool getVarRef(const string& ref_str, clind_val& cval, bool from_active);
+ bool setVarRef(const string& ref_str, const string& value, bool to_active);
+
+protected:
+ ////// functions for subclasses
+ void output_user(const char *fmt, ...);
+ void output_internal(const char *fmt, ...);
+
+private:
+ ////// member class
+ // for variable reference
+ class VarRef;
+
+ ////// virtual
+ /* "path modifiers"
+ * note: only these functions are allowed to permanently change the paths.
+ * all other functions must "preserve" the paths (but can change paths
+ * "during" an invocation), i.e., the paths after invocation must be
+ * the same as before invocation.
+ */
+ // begin path modifiers
+ virtual void push_tmpl_path(const string& path_comp) = 0;
+ virtual void push_tmpl_path_tag() = 0;
+ virtual string pop_tmpl_path() = 0;
+ virtual void push_cfg_path(const string& path_comp) = 0;
+ virtual void push_cfg_path_val() = 0;
+ virtual string pop_cfg_path() = 0;
+ virtual void append_cfg_path(const vector<string>& path_comps) = 0;
+ virtual void reset_paths() = 0;
+ virtual void save_paths(const void *handle = NULL) = 0;
+ virtual void restore_paths(const void *handle = NULL) = 0;
+ virtual bool cfg_path_at_root() = 0;
+ virtual bool tmpl_path_at_root() = 0;
+ // end path modifiers
+
+ // these operate on current tmpl path
+ virtual bool tmpl_node_exists() = 0;
+ virtual bool tmpl_parse(vtw_def& def) = 0;
+
+ // these operate on current work path (or active with "active_cfg")
+ virtual bool remove_node() = 0;
+ virtual void get_all_child_node_names_impl(vector<string>& cnodes,
+ bool active_cfg = false) = 0;
+ virtual void get_all_tmpl_child_node_names(vector<string>& cnodes) = 0;
+ virtual bool write_value_vec(const vector<string>& vvec,
+ bool active_cfg = false) = 0;
+ virtual bool add_node() = 0;
+ virtual bool rename_child_node(const string& oname, const string& nname) = 0;
+ virtual bool copy_child_node(const string& oname, const string& nname) = 0;
+ virtual bool mark_display_default() = 0;
+ virtual bool unmark_display_default() = 0;
+ virtual bool mark_deactivated() = 0;
+ virtual bool unmark_deactivated() = 0;
+ virtual bool unmark_deactivated_descendants() = 0;
+ virtual bool mark_changed() = 0;
+ virtual bool remove_comment() = 0;
+ virtual bool set_comment(const string& comment) = 0;
+ virtual bool discard_changes(unsigned long long& num_removed) = 0;
+
+ // observers for current work path
+ virtual bool marked_changed() = 0;
+ virtual bool marked_display_default() = 0;
+
+ // observers for current work path or active path
+ virtual bool read_value_vec(vector<string>& vvec, bool active_cfg) = 0;
+ virtual bool cfg_node_exists(bool active_cfg) = 0;
+ virtual bool marked_deactivated(bool active_cfg) = 0;
+ virtual bool get_comment(string& comment, bool active_cfg) = 0;
+
+ // observers during commit operation
+ virtual bool marked_committed(const vtw_def& def, bool is_set) = 0;
+
+ // these operate on both current tmpl and work paths
+ virtual bool validate_val_impl(vtw_def *def, char *value) = 0;
+
+ // observers for "edit/tmpl levels" (for "edit"-related operations)
+ /* note that these should be handled in the base class since they
+ * should not be implementation-specific. however, current definitions
+ * of these "levels" environment vars require filesystem-specific
+ * "escapes", so handle them in derived class.
+ *
+ * revisit when the env vars are redefined.
+ *
+ * these operate on current "work" or "tmpl" path, i.e., cfg/tmpl path
+ * needs to be set up before calling these.
+ */
+ virtual string get_edit_level_path() = 0;
+ virtual string get_tmpl_level_path() = 0;
+ virtual void get_edit_level(vector<string>& path_comps) = 0;
+ virtual bool edit_level_at_root() = 0;
+
+ // these are for testing/debugging
+ virtual string cfg_path_to_str() = 0;
+ virtual string tmpl_path_to_str() = 0;
+
+ ////// implemented
+ // begin path modifiers (only these can change path permanently)
+ bool append_tmpl_path(const vector<string>& path_comps, bool& is_tag);
+ bool append_tmpl_path(const vector<string>& path_comps) {
+ bool dummy;
+ return append_tmpl_path(path_comps, dummy);
+ };
+ bool append_tmpl_path(const string& path_comp, bool& is_tag) {
+ return append_tmpl_path(vector<string>(1, path_comp), is_tag);
+ };
+ bool append_tmpl_path(const string& path_comp) {
+ bool dummy;
+ return append_tmpl_path(path_comp, dummy);
+ };
+ // end path modifiers
+
+ // these require full path
+ // (note: get_parsed_tmpl also uses current tmpl path)
+ bool get_parsed_tmpl(const vector<string>& path_comps, bool validate_vals,
+ vtw_def& def, string& error);
+ bool get_parsed_tmpl(const vector<string>& path_comps, bool validate_vals,
+ vtw_def& def) {
+ string dummy;
+ return get_parsed_tmpl(path_comps, validate_vals, def, dummy);
+ };
+ bool validate_act_deact(const vector<string>& path_comps, const string& op,
+ vtw_def& def);
+ bool validate_rename_copy(const vector<string>& args, const string& op);
+ bool conv_move_args_for_rename(const vector<string>& args,
+ vector<string>& edit_path_comps,
+ vector<string>& rn_args);
+ bool cfg_path_exists(const vector<string>& path_comps,
+ bool active_cfg, bool include_deactivated);
+
+ // these operate on current work path (or active with "active_cfg")
+ bool remove_tag();
+ bool remove_value_from_multi(const string& value);
+ bool write_value(const string& value, bool active_cfg = false) {
+ vector<string> vvec(1, value);
+ return write_value_vec(vvec, active_cfg);
+ };
+ bool add_tag(const vtw_def& def);
+ bool add_value_to_multi(const vtw_def& def, const string& value);
+ bool add_child_node(const string& name) {
+ push_cfg_path(name);
+ bool ret = add_node();
+ pop_cfg_path();
+ return ret;
+ };
+ void get_all_child_node_names(vector<string>& cnodes, bool active_cfg,
+ bool include_deactivated);
+
+ // observers for work path or active path
+ bool cfg_value_exists(const string& value, bool active_cfg);
+
+ // these operate on both current tmpl and work paths
+ bool validate_val(const vtw_def *def, const string& value);
+ bool create_default_children();
+ void get_edit_env(string& env);
+
+ // util functions
+ string get_shell_prompt(const string& level);
+ void shell_escape_squotes(string& str);
+};
+
+#endif /* _CSTORE_H_ */
+