From 639c835bc2730a4fbffd915f5b2028a68375ee7a Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Wed, 28 Jul 2010 14:30:32 -0700 Subject: add new cstore library --- src/cli_shell_api.cpp | 316 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 src/cli_shell_api.cpp (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp new file mode 100644 index 0000000..0962c80 --- /dev/null +++ b/src/cli_shell_api.cpp @@ -0,0 +1,316 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +} + +#include + +static int op_idx = -1; +static const char *op_name[] = { + "getSessionEnv", + "getEditEnv", + "getEditUpEnv", + "getEditResetEnv", + "editLevelAtRoot", + "getCompletionEnv", + "getEditLevelStr", + "markSessionUnsaved", + "unmarkSessionUnsaved", + "sessionUnsaved", + "sessionChanged", + "teardownSession", + "setupSession", + "inSession", + NULL +}; +static const int op_exact_args[] = { + 1, + -1, + 0, + 0, + 0, + -1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -1 +}; +static const char *op_exact_error[] = { + "Must specify session ID", + NULL, + "No argument expected", + "No argument expected", + "No argument expected", + NULL, + "No argument expected", + "No argument expected", + "No argument expected", + "No argument expected", + "No argument expected", + "No argument expected", + "No argument expected", + "No argument expected", + NULL +}; +static const int op_min_args[] = { + -1, + 1, + -1, + -1, + -1, + 2, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 +}; +static const char *op_min_error[] = { + NULL, + "Must specify config path to edit", + NULL, + NULL, + NULL, + "Must specify command and at least one component", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; +#define OP_exact_args op_exact_args[op_idx] +#define OP_min_args op_min_args[op_idx] +#define OP_exact_error op_exact_error[op_idx] +#define OP_min_error op_min_error[op_idx] + +static void +doGetSessionEnv(const vector& args) +{ + string env; + UnionfsCstore cstore(args[0], env); + printf("%s", env.c_str()); +} + +static void +doGetEditEnv(const vector& args) +{ + UnionfsCstore cstore(true); + string env; + if (!cstore.getEditEnv(args, env)) { + exit(-1); + } + printf("%s", env.c_str()); +} + +static void +doGetEditUpEnv(const vector& args) +{ + UnionfsCstore cstore(true); + string env; + if (!cstore.getEditUpEnv(env)) { + exit(-1); + } + printf("%s", env.c_str()); +} + +static void +doGetEditResetEnv(const vector& args) +{ + UnionfsCstore cstore(true); + string env; + if (!cstore.getEditResetEnv(env)) { + exit(-1); + } + printf("%s", env.c_str()); +} + +static void +doEditLevelAtRoot(const vector& args) +{ + UnionfsCstore cstore(true); + exit(cstore.editLevelAtRoot() ? 0 : 1); +} + +static void +doGetCompletionEnv(const vector& args) +{ + UnionfsCstore cstore(true); + string env; + if (!cstore.getCompletionEnv(args, env)) { + exit(-1); + } + printf("%s", env.c_str()); +} + +static void +doGetEditLevelStr(const vector& args) +{ + UnionfsCstore cstore(true); + vector lvec; + cstore.getEditLevel(lvec); + string level; + for (unsigned int i = 0; i < lvec.size(); i++) { + if (level.length() > 0) { + level += " "; + } + level += lvec[i]; + } + printf("%s", level.c_str()); +} + +static void +doMarkSessionUnsaved(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.markSessionUnsaved()) { + exit(-1); + } +} + +static void +doUnmarkSessionUnsaved(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.unmarkSessionUnsaved()) { + exit(-1); + } +} + +static void +doSessionUnsaved(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.sessionUnsaved()) { + exit(-1); + } +} + +static void +doSessionChanged(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.sessionChanged()) { + exit(-1); + } +} + +static void +doTeardownSession(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.teardownSession()) { + exit(-1); + } +} + +static void +doSetupSession(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.setupSession()) { + exit(-1); + } +} + +static void +doInSession(const vector& args) +{ + UnionfsCstore cstore(true); + if (!cstore.inSession()) { + exit(-1); + } +} + +typedef void (*OpFuncT)(const vector& args); +OpFuncT OpFunc[] = { + &doGetSessionEnv, + &doGetEditEnv, + &doGetEditUpEnv, + &doGetEditResetEnv, + &doEditLevelAtRoot, + &doGetCompletionEnv, + &doGetEditLevelStr, + &doMarkSessionUnsaved, + &doUnmarkSessionUnsaved, + &doSessionUnsaved, + &doSessionChanged, + &doTeardownSession, + &doSetupSession, + &doInSession, + NULL +}; + +int +main(int argc, char **argv) +{ + int i = 0; + if (argc < 2) { + printf("Must specify operation\n"); + exit(-1); + } + while (op_name[i]) { + if (strcmp(argv[1], op_name[i]) == 0) { + op_idx = i; + break; + } + ++i; + } + if (op_idx == -1) { + printf("Invalid operation\n"); + exit(-1); + } + if (OP_exact_args >= 0 && (argc - 2) != OP_exact_args) { + printf("%s\n", OP_exact_error); + exit(-1); + } + if (OP_min_args >= 0 && (argc - 2) < OP_min_args) { + printf("%s\n", OP_min_error); + exit(-1); + } + + vector args; + for (int i = 2; i < argc; i++) { + args.push_back(argv[i]); + } + + // call the op function + OpFunc[op_idx](args); + exit(0); +} + -- cgit v1.2.3 From a56723cbb6424e1d49289efceeb9c251eed324bb Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Wed, 28 Jul 2010 19:08:43 -0700 Subject: add cstore-specific header file --- Makefile.am | 4 +- src/cli_bin.cpp | 5 +- src/cli_cstore.h | 147 ++++++++++++++++++++++++++++++++++ src/cli_new.c | 20 ++--- src/cli_shell_api.cpp | 5 +- src/cli_val.h | 110 +------------------------ src/cstore/cstore-c.cpp | 11 +-- src/cstore/cstore-c.h | 7 +- src/cstore/cstore-varref.cpp | 8 +- src/cstore/cstore-varref.hpp | 2 +- src/cstore/cstore.cpp | 37 ++++----- src/cstore/cstore.hpp | 8 +- src/cstore/unionfs/cstore-unionfs.cpp | 19 +++-- src/cstore/unionfs/cstore-unionfs.hpp | 13 ++- 14 files changed, 210 insertions(+), 186 deletions(-) create mode 100644 src/cli_cstore.h (limited to 'src/cli_shell_api.cpp') diff --git a/Makefile.am b/Makefile.am index b38f0fd..7c93743 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,9 +37,7 @@ LDADD = src/libvyatta-cfg.la LDADD += /usr/lib/libglib-2.0.la vincludedir = $(includedir)/vyatta-cfg -vinclude_HEADERS = src/cli_val.h -vinclude_HEADERS += src/cli_val_engine.h -vinclude_HEADERS += src/cli_path_utils.h +vinclude_HEADERS = src/cli_cstore.h vcincdir = $(vincludedir)/cstore vcinc_HEADERS = src/cstore/cstore-c.h diff --git a/src/cli_bin.cpp b/src/cli_bin.cpp index 420d19c..25a86ce 100644 --- a/src/cli_bin.cpp +++ b/src/cli_bin.cpp @@ -20,10 +20,7 @@ #include #include -extern "C" { -#include -} - +#include #include static int op_idx = -1; diff --git a/src/cli_cstore.h b/src/cli_cstore.h new file mode 100644 index 0000000..c03bddf --- /dev/null +++ b/src/cli_cstore.h @@ -0,0 +1,147 @@ +/* + * 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 . + */ + +#ifndef _CLI_VAL_CSTORE_H_ +#define _CLI_VAL_CSTORE_H_ +#ifdef __cplusplus +extern "C" { +#endif + +/* this header file contains all definitions/declarations in the original + * CLI implementation that are needed by the cstore library. + */ + +/* types */ +typedef int boolean; + +typedef enum { + ERROR_TYPE, + INT_TYPE, + IPV4_TYPE, + IPV4NET_TYPE, + IPV6_TYPE, + IPV6NET_TYPE, + MACADDR_TYPE, + DOMAIN_TYPE, /*end of addr types */ + TEXT_TYPE, + BOOL_TYPE, + PRIORITY_TYPE +} vtw_type_e; + +typedef struct { + vtw_type_e val_type; + char *val; + int cnt; /* >0 means multivalue */ + char **vals; /* We might union with val */ + vtw_type_e *val_types; /* used with vals and multitypes */ + boolean free_me; +} valstruct; + +typedef enum { + LIST_OP, /* right is next, left is list elem */ + HELP_OP, /* right is help string, left is elem */ + EXEC_OP, /* left command string, right help string */ + PATTERN_OP, /* left to var, right to pattern */ + OR_OP, + AND_OP, + NOT_OP, + COND_OP, /* aux field specifies cond type (GT, GE, etc.)*/ + VAL_OP, /* for strings used in other nodes */ + VAR_OP, /* string points to var */ + B_QUOTE_OP, /* string points to operand to be executed */ + ASSIGN_OP /* left to var, right to exp */ +} vtw_oper_e; + +typedef struct vtw_node{ + vtw_oper_e vtw_node_oper; + struct vtw_node *vtw_node_left; + struct vtw_node *vtw_node_right; + char *vtw_node_string; + int vtw_node_aux; + vtw_type_e vtw_node_type; + valstruct vtw_node_val; /* we'll union it later */ +} vtw_node; + +typedef struct { + vtw_node *vtw_list_head; + vtw_node *vtw_list_tail; +} vtw_list; + +typedef enum { + delete_act, + create_act, + activate_act, + update_act, + syntax_act, + commit_act, + begin_act, + end_act, + top_act +} vtw_act_type; + +typedef struct { + vtw_type_e def_type; + vtw_type_e def_type2; + char *def_type_help; + char *def_node_help; + char *def_default; + unsigned int def_priority; + char *def_priority_ext; + char *def_enumeration; + char *def_comp_help; + char *def_allowed; + char *def_val_help; + unsigned int def_tag; + unsigned int def_multi; + boolean tag; + boolean multi; + vtw_list actions[top_act]; + int is_value; /* this is used by the config store to indicate whether + * the last path component is a "value". */ +} vtw_def; + +/* extern variables */ +extern void *var_ref_handle; +extern FILE *out_stream; + +/* note that some functions may be used outside the actual CLI operations, + * so output may not have been initialized. nop in such cases. + */ +#define OUTPUT_USER(fmt, args...) do \ + { \ + if (out_stream) { \ + fprintf(out_stream, fmt , ##args); \ + } \ + } while (0); + +/* functions */ +const valstruct *get_syntax_self_in_valstruct(vtw_node *vnode); +int get_shell_command_output(const char *cmd, char *buf, + unsigned int buf_size); +int parse_def(vtw_def *defp, const char *path, boolean type_only); +boolean validate_value(vtw_def *def, char *value); +const char *type_to_name(vtw_type_e type); +int initialize_output(const char *op); +void bye(const char *msg, ...) __attribute__((format(printf, 1, 2), noreturn)); + +/* functions from cli_objects */ +char *get_at_string(void); + +#ifdef __cplusplus +} +#endif +#endif /* _CLI_VAL_CSTORE_H_ */ + diff --git a/src/cli_new.c b/src/cli_new.c index 9cc9777..a047f36 100644 --- a/src/cli_new.c +++ b/src/cli_new.c @@ -1471,18 +1471,19 @@ static int eval_va(valstruct *res, vtw_node *node) * cstore implementation. * handle is set => we are in cstore operation. */ - clind_val cv; - if (!cstore_get_var_ref(var_ref_handle, pathp, &cv, + vtw_type_e vtype; + char *vptr = NULL; + if (!cstore_get_var_ref(var_ref_handle, pathp, &vtype, &vptr, is_in_delete_action())) { status = -1; } else { /* success */ status = 0; - if(cv.value) { - res->val_type = cv.val_type; + if(vptr) { + res->val_type = vtype; res->val_types = NULL; res->free_me = TRUE; - res->val = cv.value; + res->val = vptr; } } } else { @@ -1648,10 +1649,11 @@ static int expand_string(char *stringp) * cstore implementation. * handle is set => we are in cstore operation. */ - clind_val cv; - if (cstore_get_var_ref(var_ref_handle, scanp, &cv, - is_in_delete_action())) { - cp=cv.value; + vtw_type_e vtype; + char *vptr = NULL; + if (cstore_get_var_ref(var_ref_handle, scanp, &vtype, &vptr, + is_in_delete_action()) && vptr) { + cp = vptr; } } else { /* legacy usage */ diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index 0962c80..22a5cad 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -22,10 +22,7 @@ #include #include -extern "C" { -#include -} - +#include #include static int op_idx = -1; diff --git a/src/cli_val.h b/src/cli_val.h index 41e4461..536d964 100644 --- a/src/cli_val.h +++ b/src/cli_val.h @@ -2,9 +2,10 @@ #define CLI_DEF_H #include +#include + #define BITWISE 0 /* no partial commit */ -#define boolean int #ifndef FALSE #define FALSE 0 #endif @@ -21,19 +22,6 @@ typedef enum { create_mode, update_mode }vtw_cmode; -typedef enum { - ERROR_TYPE, - INT_TYPE, - IPV4_TYPE, - IPV4NET_TYPE, - IPV6_TYPE, - IPV6NET_TYPE, - MACADDR_TYPE, - DOMAIN_TYPE, /*end of addr types */ - TEXT_TYPE, - BOOL_TYPE, - PRIORITY_TYPE -}vtw_type_e; typedef enum { EQ_COND = 1, @@ -47,83 +35,11 @@ typedef enum { }vtw_cond_e; /* IN_COND is like EQ for singular compare, but OR for multivalue right operand */ -typedef enum { - LIST_OP, /* right is next, left is list elem */ - HELP_OP, /* right is help string, left is elem */ - EXEC_OP, /* left command string, right help string */ - PATTERN_OP, /* left to var, right to pattern */ - OR_OP, - AND_OP, - NOT_OP, - COND_OP, /* aux field specifies cond type (GT, GE, etc.)*/ - VAL_OP, /* for strings used in other nodes */ - VAR_OP, /* string points to var */ - B_QUOTE_OP, /* string points to operand to be executed */ - ASSIGN_OP /* left to var, right to exp */ -}vtw_oper_e; - -typedef struct { - vtw_type_e val_type; - char *val; - int cnt; /* >0 means multivalue */ - char **vals; /* We might union with val */ - vtw_type_e *val_types; /* used with vals and multitypes */ - boolean free_me; -}valstruct; - -typedef struct vtw_node{ - vtw_oper_e vtw_node_oper; - struct vtw_node *vtw_node_left; - struct vtw_node *vtw_node_right; - char *vtw_node_string; - int vtw_node_aux; - vtw_type_e vtw_node_type; - valstruct vtw_node_val; /* we'll union it later */ -}vtw_node; - -typedef struct { - vtw_node *vtw_list_head; - vtw_node *vtw_list_tail; -}vtw_list; - typedef struct { int t_lev; int m_lev; }vtw_mark; -typedef enum { - delete_act, - create_act, - activate_act, - update_act, - syntax_act, - commit_act, - begin_act, - end_act, - top_act -}vtw_act_type; - -typedef struct { - vtw_type_e def_type; - vtw_type_e def_type2; - char *def_type_help; - char *def_node_help; - char *def_default; - unsigned int def_priority; - char *def_priority_ext; - char *def_enumeration; - char *def_comp_help; - char *def_allowed; - char *def_val_help; - unsigned int def_tag; - unsigned int def_multi; - boolean tag; - boolean multi; - vtw_list actions[top_act]; - int is_value; /* this is used by the config store to indicate whether - * the last path component is a "value". */ -}vtw_def; - typedef struct { const char *f_segp; int f_seglen; @@ -162,10 +78,6 @@ extern vtw_node *make_str_node(char *str); extern vtw_node *make_var_node(char *str); extern vtw_node *make_str_node0(char *str, vtw_oper_e op); extern void append(vtw_list *l, vtw_node *n, int aux); -const valstruct *get_syntax_self_in_valstruct(vtw_node *vnode); -int get_shell_command_output(const char *cmd, char *buf, - unsigned int buf_size); -extern int parse_def(vtw_def *defp, const char *path, boolean type_only); extern int yy_cli_val_lex(void); extern void cli_val_start(char *s); @@ -178,7 +90,6 @@ extern void free_def(vtw_def *defp); extern void free_sorted(vtw_sorted *sortp); extern vtw_path m_path, t_path; -extern void *var_ref_handle; /************************************************* GLOBAL FUNCTIONS @@ -193,14 +104,10 @@ extern boolean val_cmp(const valstruct *left, const valstruct *right, vtw_cond_e cond); extern void out_of_memory(void) __attribute__((noreturn)); extern void subtract_values(char **lhs, const char *rhs); -extern boolean validate_value(vtw_def *def, - char *value); extern void internal_error(int line, const char *file) __attribute__((noreturn)); extern void done(void); extern void del_value(vtw_def *defp, char *cp); -extern void bye(const char *msg, ...) - __attribute__((format(printf, 1, 2), noreturn)); extern void print_msg(const char *msg, ...) __attribute__((format(printf, 1, 2))); extern void switch_path(first_seg *seg); @@ -209,7 +116,6 @@ extern void free_val(valstruct *val); extern void touch(void); extern int mkdir_p(const char *path); -extern const char *type_to_name(vtw_type_e type); extern boolean execute_list(vtw_node *cur, vtw_def *def, const char **outbuf); extern void touch_dir(const char *dp); extern void touch_file(const char *name); @@ -237,20 +143,8 @@ extern int get_config_lock(void); #define LOGFILE_STDERR "/tmp/cfg-stderr.log" extern int out_fd; -extern FILE *out_stream; extern FILE *err_stream; -extern int initialize_output(const char *op); -/* note that some functions may be used outside the actual CLI operations, - * so output may not have been initialized. nop in such cases. - */ -#define OUTPUT_USER(fmt, args...) do \ - { \ - if (out_stream) { \ - fprintf(out_stream, fmt , ##args); \ - } \ - } while (0); - /* debug hooks? */ #define my_malloc(size, name) malloc(size) #define my_realloc(ptr, size, name) realloc(ptr, size) diff --git a/src/cstore/cstore-c.cpp b/src/cstore/cstore-c.cpp index 3215707..0e25b3c 100644 --- a/src/cstore/cstore-c.cpp +++ b/src/cstore/cstore-c.cpp @@ -18,8 +18,8 @@ #include #include -#include "cstore-c.h" -#include "cstore/unionfs/cstore-unionfs.hpp" +#include +#include void * cstore_init(void) @@ -80,12 +80,13 @@ cstore_cfg_path_exists(void *handle, const char *path_comps[], int num_comps) } int -cstore_get_var_ref(void *handle, const char *ref_str, clind_val *cval, - int from_active) +cstore_get_var_ref(void *handle, const char *ref_str, vtw_type_e *type, + char **val, int from_active) { if (handle) { Cstore *cs = (Cstore *) handle; - return (cs->getVarRef(ref_str, *cval, from_active) ? 1 : 0); + *val = cs->getVarRef(ref_str, *type, from_active); + return (*val ? 1 : 0); } return 0; } diff --git a/src/cstore/cstore-c.h b/src/cstore/cstore-c.h index e664f95..c2c5fa0 100644 --- a/src/cstore/cstore-c.h +++ b/src/cstore/cstore-c.h @@ -20,8 +20,7 @@ extern "C" { #endif -#include -#include +#include void *cstore_init(void); void cstore_free(void *handle); @@ -39,8 +38,8 @@ int cstore_cfg_path_deactivated(void *handle, const char *path_comps[], * during cstore operations since they operate on "current" paths constructed * by the operations. */ -int cstore_get_var_ref(void *handle, const char *ref_str, clind_val *cval, - int from_active); +int cstore_get_var_ref(void *handle, const char *ref_str, vtw_type_e *type, + char **val, int from_active); int cstore_set_var_ref(void *handle, const char *ref_str, const char *value, int to_active); diff --git a/src/cstore/cstore-varref.cpp b/src/cstore/cstore-varref.cpp index 6d71307..46950fa 100644 --- a/src/cstore/cstore-varref.cpp +++ b/src/cstore/cstore-varref.cpp @@ -19,12 +19,8 @@ #include #include -#include "cstore-varref.hpp" - -extern "C" { -#include "cli_val.h" -#include "cli_objects.h" -} +#include +#include using namespace std; diff --git a/src/cstore/cstore-varref.hpp b/src/cstore/cstore-varref.hpp index 1fc1d52..7ab523f 100644 --- a/src/cstore/cstore-varref.hpp +++ b/src/cstore/cstore-varref.hpp @@ -20,7 +20,7 @@ #include #include -#include "cstore.hpp" +#include using namespace std; diff --git a/src/cstore/cstore.cpp b/src/cstore/cstore.cpp index 31c896a..e97ea2c 100644 --- a/src/cstore/cstore.cpp +++ b/src/cstore/cstore.cpp @@ -25,12 +25,9 @@ #include #include -extern "C" { -#include "cli_val.h" -} - -#include "cstore.hpp" -#include "cstore-varref.hpp" +#include +#include +#include ////// constants @@ -57,8 +54,9 @@ const string Cstore::C_ENV_SHAPI_COMP_HELP = "_cli_shell_api_comp_help"; const string Cstore::C_ENV_SHAPI_HELP_ITEMS = "_cli_shell_api_hitems"; const string Cstore::C_ENV_SHAPI_HELP_STRS = "_cli_shell_api_hstrs"; -//// dirs +//// dirs/files const string Cstore::C_ENUM_SCRIPT_DIR = "/opt/vyatta/share/enumeration"; +const string Cstore::C_LOGFILE_STDOUT = "/tmp/cfg-stdout.log"; ////// constructors/destructors /* this constructor just returns the generic environment string, @@ -1691,25 +1689,24 @@ Cstore::cfgPathGetEffectiveValues(const vector& path_comps, /* get the value string that corresponds to specified variable ref string. * ref_str: var ref string (e.g., "./cost/@"). - * cval: (output) contains the resulting string. + * type: (output) the node type. * from_active: if true, value string should come from "active config". * otherwise from "working config". - * return true if successful. otherwise return false. + * return a pointer to the value string if successful (caller must free). + * otherwise return NULL. */ -bool -Cstore::getVarRef(const string& ref_str, clind_val& cval, bool from_active) +char * +Cstore::getVarRef(const string& ref_str, vtw_type_e& type, bool from_active) { - bool ret = true; + char *ret = NULL; SAVE_PATHS; VarRef vref(this, ref_str, from_active); string val; - vtw_type_e type; - if (!vref.getValue(val, type)) { - ret = false; - } else { - cval.val_type = type; + vtw_type_e t; + if (vref.getValue(val, t)) { + type = t; // follow original implementation. caller is supposed to free this. - cval.value = strdup(val.c_str()); + ret = strdup(val.c_str()); } RESTORE_PATHS; return ret; @@ -1855,8 +1852,8 @@ Cstore::output_internal(const char *fmt, ...) int fdout = -1; FILE *fout = NULL; do { - // XXX for now use the constant from cli_val.h - if ((fdout = open(LOGFILE_STDOUT, O_WRONLY | O_CREAT, 0660)) == -1) { + if ((fdout = open(C_LOGFILE_STDOUT.c_str(), + O_WRONLY | O_CREAT, 0660)) == -1) { break; } if (lseek(fdout, 0, SEEK_END) == ((off_t) -1)) { diff --git a/src/cstore/cstore.hpp b/src/cstore/cstore.hpp index f6a4215..1d4ffe2 100644 --- a/src/cstore/cstore.hpp +++ b/src/cstore/cstore.hpp @@ -20,10 +20,7 @@ #include #include -extern "C" { -#include -#include -} +#include #define exit_internal(fmt, args...) do \ { \ @@ -65,6 +62,7 @@ public: static const string C_ENV_SHAPI_HELP_STRS; static const string C_ENUM_SCRIPT_DIR; + static const string C_LOGFILE_STDOUT; static const size_t MAX_CMD_OUTPUT_SIZE = 4096; @@ -245,7 +243,7 @@ public: * 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); + char *getVarRef(const string& ref_str, vtw_type_e& type, bool from_active); bool setVarRef(const string& ref_str, const string& value, bool to_active); protected: diff --git a/src/cstore/unionfs/cstore-unionfs.cpp b/src/cstore/unionfs/cstore-unionfs.cpp index 977a597..6e6e5de 100644 --- a/src/cstore/unionfs/cstore-unionfs.cpp +++ b/src/cstore/unionfs/cstore-unionfs.cpp @@ -24,12 +24,8 @@ #include #include -extern "C" { -#include "cli_val.h" -#include "cli_objects.h" -} - -#include "cstore-unionfs.hpp" +#include +#include ////// constants @@ -61,6 +57,9 @@ const string UnionfsCstore::C_MARKER_CHANGED = ".modified"; const string UnionfsCstore::C_MARKER_UNSAVED = ".unsaved"; const string UnionfsCstore::C_COMMITTED_MARKER_FILE = "/tmp/.changes"; const string UnionfsCstore::C_COMMENT_FILE = ".comment"; +const string UnionfsCstore::C_TAG_NAME = "node.tag"; +const string UnionfsCstore::C_VAL_NAME = "node.val"; +const string UnionfsCstore::C_DEF_NAME = "node.def"; ////// static @@ -414,9 +413,9 @@ UnionfsCstore::tmpl_node_exists() bool UnionfsCstore::tmpl_parse(vtw_def& def) { - push_tmpl_path(DEF_NAME); + push_tmpl_path(C_DEF_NAME); bool ret = (b_fs::exists(tmpl_path) && b_fs::is_regular(tmpl_path) - && parse_def(&def, tmpl_path.file_string().c_str(), FALSE) == 0); + && parse_def(&def, tmpl_path.file_string().c_str(), 0) == 0); pop_tmpl_path(); return ret; } @@ -490,8 +489,8 @@ UnionfsCstore::get_all_child_node_names_impl(vector& cnodes, * node.val * def */ - if (b_fs::exists(p / VAL_NAME) && b_fs::is_regular(p / VAL_NAME)) { - cnodes.push_back(VAL_NAME); + if (b_fs::exists(p / C_VAL_NAME) && b_fs::is_regular(p / C_VAL_NAME)) { + cnodes.push_back(C_VAL_NAME); } if (b_fs::exists(p / C_MARKER_DEF_VALUE) && b_fs::is_regular(p / C_MARKER_DEF_VALUE)) { diff --git a/src/cstore/unionfs/cstore-unionfs.hpp b/src/cstore/unionfs/cstore-unionfs.hpp index 357e307..dd44d9a 100644 --- a/src/cstore/unionfs/cstore-unionfs.hpp +++ b/src/cstore/unionfs/cstore-unionfs.hpp @@ -26,13 +26,9 @@ #include +#include #include -extern "C" { -#include -#include -} - namespace b_fs = boost::filesystem; class UnionfsCstore : public Cstore { @@ -71,6 +67,9 @@ private: static const string C_MARKER_UNSAVED; static const string C_COMMITTED_MARKER_FILE; static const string C_COMMENT_FILE; + static const string C_TAG_NAME; + static const string C_VAL_NAME; + static const string C_DEF_NAME; static const size_t MAX_FILE_READ_SIZE = 8192; @@ -93,7 +92,7 @@ private: push_path(tmpl_path, new_comp); }; void push_tmpl_path_tag() { - push_tmpl_path(TAG_NAME); + push_tmpl_path(C_TAG_NAME); }; string pop_tmpl_path() { return pop_path(tmpl_path); @@ -102,7 +101,7 @@ private: push_path(mutable_cfg_path, new_comp); }; void push_cfg_path_val() { - push_cfg_path(VAL_NAME); + push_cfg_path(C_VAL_NAME); }; string pop_cfg_path() { return pop_path(mutable_cfg_path); -- cgit v1.2.3 From bd41d33a5a140465188c95c404e12aa00f838aef Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Tue, 10 Aug 2010 15:55:34 -0700 Subject: add functions to shell API --- Makefile.am | 1 - scripts/vyatta-exists | 14 -------------- src/cli_shell_api.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 15 deletions(-) delete mode 100755 scripts/vyatta-exists (limited to 'src/cli_shell_api.cpp') diff --git a/Makefile.am b/Makefile.am index 7c93743..a424d2f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,7 +78,6 @@ sbin_SCRIPTS += scripts/vyatta-cfg-notify sbin_SCRIPTS += scripts/vyatta-irqaffin sbin_SCRIPTS += scripts/vyatta-auto-irqaffin.pl sbin_SCRIPTS += scripts/vyatta-check-typeless-node.pl -sbin_SCRIPTS += scripts/vyatta-exists sbin_SCRIPTS += scripts/vyatta-strip-migration-comments.pl share_perl5_DATA = lib/Vyatta/Config.pm diff --git a/scripts/vyatta-exists b/scripts/vyatta-exists deleted file mode 100755 index ef2dea3..0000000 --- a/scripts/vyatta-exists +++ /dev/null @@ -1,14 +0,0 @@ -#! /bin/bash - -# Test if given node exists in Vyatta config hierarchy -# -# if vyatta-exists interfaces wireless - -if [ -z "$VYATTA_TEMP_CONFIG_DIR" ]; then - echo "$0: not in configuration mode" 1>&2; - exit 1; -fi -IFS=/ -node=$* -IFS= -exec test -d $VYATTA_TEMP_CONFIG_DIR/$node diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index 22a5cad..d863025 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -41,6 +41,8 @@ static const char *op_name[] = { "teardownSession", "setupSession", "inSession", + "exists", + "existsActive", NULL }; static const int op_exact_args[] = { @@ -58,6 +60,8 @@ static const int op_exact_args[] = { 0, 0, 0, + -1, + -1, -1 }; static const char *op_exact_error[] = { @@ -75,6 +79,8 @@ static const char *op_exact_error[] = { "No argument expected", "No argument expected", "No argument expected", + NULL, + NULL, NULL }; static const int op_min_args[] = { @@ -92,6 +98,8 @@ static const int op_min_args[] = { -1, -1, -1, + 1, + 1, -1 }; static const char *op_min_error[] = { @@ -109,6 +117,8 @@ static const char *op_min_error[] = { NULL, NULL, NULL, + "Must specify config path", + "Must specify config path", NULL }; #define OP_exact_args op_exact_args[op_idx] @@ -254,6 +264,20 @@ doInSession(const vector& args) } } +static void +doExists(const vector& args) +{ + UnionfsCstore cstore(true); + exit(cstore.cfgPathExists(args, false) ? 0 : 1); +} + +static void +doExistsActive(const vector& args) +{ + UnionfsCstore cstore(true); + exit(cstore.cfgPathExists(args, true) ? 0 : 1); +} + typedef void (*OpFuncT)(const vector& args); OpFuncT OpFunc[] = { &doGetSessionEnv, @@ -270,6 +294,8 @@ OpFuncT OpFunc[] = { &doTeardownSession, &doSetupSession, &doInSession, + &doExists, + &doExistsActive, NULL }; -- cgit v1.2.3 From 85072854b503971d5bbed2549304197a384e3988 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Tue, 10 Aug 2010 16:53:05 -0700 Subject: simplify extension of shell API --- src/cli_shell_api.cpp | 207 +++++++++++++++++++++----------------------------- 1 file changed, 85 insertions(+), 122 deletions(-) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index d863025..c0d70ca 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -25,106 +25,16 @@ #include #include -static int op_idx = -1; -static const char *op_name[] = { - "getSessionEnv", - "getEditEnv", - "getEditUpEnv", - "getEditResetEnv", - "editLevelAtRoot", - "getCompletionEnv", - "getEditLevelStr", - "markSessionUnsaved", - "unmarkSessionUnsaved", - "sessionUnsaved", - "sessionChanged", - "teardownSession", - "setupSession", - "inSession", - "exists", - "existsActive", - NULL -}; -static const int op_exact_args[] = { - 1, - -1, - 0, - 0, - 0, - -1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - -1, - -1, - -1 -}; -static const char *op_exact_error[] = { - "Must specify session ID", - NULL, - "No argument expected", - "No argument expected", - "No argument expected", - NULL, - "No argument expected", - "No argument expected", - "No argument expected", - "No argument expected", - "No argument expected", - "No argument expected", - "No argument expected", - "No argument expected", - NULL, - NULL, - NULL -}; -static const int op_min_args[] = { - -1, - 1, - -1, - -1, - -1, - 2, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - 1, - 1, - -1 -}; -static const char *op_min_error[] = { - NULL, - "Must specify config path to edit", - NULL, - NULL, - NULL, - "Must specify command and at least one component", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Must specify config path", - "Must specify config path", - NULL -}; -#define OP_exact_args op_exact_args[op_idx] -#define OP_min_args op_min_args[op_idx] -#define OP_exact_error op_exact_error[op_idx] -#define OP_min_error op_min_error[op_idx] +typedef void (*OpFuncT)(const vector& args); + +typedef struct { + const char *op_name; + const int op_exact_args; + const char *op_exact_error; + const int op_min_args; + const char *op_min_error; + OpFuncT op_func; +} OpT; static void doGetSessionEnv(const vector& args) @@ -278,26 +188,79 @@ doExistsActive(const vector& args) exit(cstore.cfgPathExists(args, true) ? 0 : 1); } -typedef void (*OpFuncT)(const vector& args); -OpFuncT OpFunc[] = { - &doGetSessionEnv, - &doGetEditEnv, - &doGetEditUpEnv, - &doGetEditResetEnv, - &doEditLevelAtRoot, - &doGetCompletionEnv, - &doGetEditLevelStr, - &doMarkSessionUnsaved, - &doUnmarkSessionUnsaved, - &doSessionUnsaved, - &doSessionChanged, - &doTeardownSession, - &doSetupSession, - &doInSession, - &doExists, - &doExistsActive, - NULL +static int op_idx = -1; +static OpT ops[] = { + {"getSessionEnv", + 1, "Must specify session ID", -1, NULL, + &doGetSessionEnv}, + + {"getEditEnv", + -1, NULL, 1, "Must specify config path", + &doGetEditEnv}, + + {"getEditUpEnv", + 0, "No argument expected", -1, NULL, + &doGetEditUpEnv}, + + {"getEditResetEnv", + 0, "No argument expected", -1, NULL, + &doGetEditResetEnv}, + + {"editLevelAtRoot", + 0, "No argument expected", -1, NULL, + &doEditLevelAtRoot}, + + {"getCompletionEnv", + -1, NULL, 2, "Must specify command and at least one component", + &doGetCompletionEnv}, + + {"getEditLevelStr", + 0, "No argument expected", -1, NULL, + &doGetEditLevelStr}, + + {"markSessionUnsaved", + 0, "No argument expected", -1, NULL, + &doMarkSessionUnsaved}, + + {"unmarkSessionUnsaved", + 0, "No argument expected", -1, NULL, + &doUnmarkSessionUnsaved}, + + {"sessionUnsaved", + 0, "No argument expected", -1, NULL, + &doSessionUnsaved}, + + {"sessionChanged", + 0, "No argument expected", -1, NULL, + &doSessionChanged}, + + {"teardownSession", + 0, "No argument expected", -1, NULL, + &doTeardownSession}, + + {"setupSession", + 0, "No argument expected", -1, NULL, + &doSetupSession}, + + {"inSession", + 0, "No argument expected", -1, NULL, + &doInSession}, + + {"exists", + -1, NULL, 1, "Must specify config path", + &doExists}, + + {"existsActive", + -1, NULL, 1, "Must specify config path", + &doExistsActive}, + + {NULL, -1, NULL, -1, NULL, NULL} }; +#define OP_exact_args ops[op_idx].op_exact_args +#define OP_min_args ops[op_idx].op_min_args +#define OP_exact_error ops[op_idx].op_exact_error +#define OP_min_error ops[op_idx].op_min_error +#define OP_func ops[op_idx].op_func int main(int argc, char **argv) @@ -307,8 +270,8 @@ main(int argc, char **argv) printf("Must specify operation\n"); exit(-1); } - while (op_name[i]) { - if (strcmp(argv[1], op_name[i]) == 0) { + while (ops[i].op_name) { + if (strcmp(argv[1], ops[i].op_name) == 0) { op_idx = i; break; } @@ -333,7 +296,7 @@ main(int argc, char **argv) } // call the op function - OpFunc[op_idx](args); + OP_func(args); exit(0); } -- cgit v1.2.3 From ed02dd2278c30bafe2fdc5bdca1e219786c56b3e Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Tue, 10 Aug 2010 19:15:55 -0700 Subject: further simplify shell API extension and add more functions. --- src/cli_shell_api.cpp | 154 ++++++++++++++++++++++---------------------------- 1 file changed, 68 insertions(+), 86 deletions(-) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index c0d70ca..f5e7681 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -25,6 +25,14 @@ #include #include +static void +print_vec(const vector& vec, const char *sep, const char *quote) +{ + for (unsigned int i = 0; i < vec.size(); i++) { + printf("%s%s%s%s", ((i > 0) ? sep : ""), quote, vec[i].c_str(), quote); + } +} + typedef void (*OpFuncT)(const vector& args); typedef struct { @@ -37,7 +45,7 @@ typedef struct { } OpT; static void -doGetSessionEnv(const vector& args) +getSessionEnv(const vector& args) { string env; UnionfsCstore cstore(args[0], env); @@ -45,7 +53,7 @@ doGetSessionEnv(const vector& args) } static void -doGetEditEnv(const vector& args) +getEditEnv(const vector& args) { UnionfsCstore cstore(true); string env; @@ -56,7 +64,7 @@ doGetEditEnv(const vector& args) } static void -doGetEditUpEnv(const vector& args) +getEditUpEnv(const vector& args) { UnionfsCstore cstore(true); string env; @@ -67,7 +75,7 @@ doGetEditUpEnv(const vector& args) } static void -doGetEditResetEnv(const vector& args) +getEditResetEnv(const vector& args) { UnionfsCstore cstore(true); string env; @@ -78,14 +86,14 @@ doGetEditResetEnv(const vector& args) } static void -doEditLevelAtRoot(const vector& args) +editLevelAtRoot(const vector& args) { UnionfsCstore cstore(true); exit(cstore.editLevelAtRoot() ? 0 : 1); } static void -doGetCompletionEnv(const vector& args) +getCompletionEnv(const vector& args) { UnionfsCstore cstore(true); string env; @@ -96,23 +104,16 @@ doGetCompletionEnv(const vector& args) } static void -doGetEditLevelStr(const vector& args) +getEditLevelStr(const vector& args) { UnionfsCstore cstore(true); vector lvec; cstore.getEditLevel(lvec); - string level; - for (unsigned int i = 0; i < lvec.size(); i++) { - if (level.length() > 0) { - level += " "; - } - level += lvec[i]; - } - printf("%s", level.c_str()); + print_vec(lvec, " ", ""); } static void -doMarkSessionUnsaved(const vector& args) +markSessionUnsaved(const vector& args) { UnionfsCstore cstore(true); if (!cstore.markSessionUnsaved()) { @@ -121,7 +122,7 @@ doMarkSessionUnsaved(const vector& args) } static void -doUnmarkSessionUnsaved(const vector& args) +unmarkSessionUnsaved(const vector& args) { UnionfsCstore cstore(true); if (!cstore.unmarkSessionUnsaved()) { @@ -130,7 +131,7 @@ doUnmarkSessionUnsaved(const vector& args) } static void -doSessionUnsaved(const vector& args) +sessionUnsaved(const vector& args) { UnionfsCstore cstore(true); if (!cstore.sessionUnsaved()) { @@ -139,7 +140,7 @@ doSessionUnsaved(const vector& args) } static void -doSessionChanged(const vector& args) +sessionChanged(const vector& args) { UnionfsCstore cstore(true); if (!cstore.sessionChanged()) { @@ -148,7 +149,7 @@ doSessionChanged(const vector& args) } static void -doTeardownSession(const vector& args) +teardownSession(const vector& args) { UnionfsCstore cstore(true); if (!cstore.teardownSession()) { @@ -157,7 +158,7 @@ doTeardownSession(const vector& args) } static void -doSetupSession(const vector& args) +setupSession(const vector& args) { UnionfsCstore cstore(true); if (!cstore.setupSession()) { @@ -166,7 +167,7 @@ doSetupSession(const vector& args) } static void -doInSession(const vector& args) +inSession(const vector& args) { UnionfsCstore cstore(true); if (!cstore.inSession()) { @@ -175,84 +176,65 @@ doInSession(const vector& args) } static void -doExists(const vector& args) +exists(const vector& args) { UnionfsCstore cstore(true); exit(cstore.cfgPathExists(args, false) ? 0 : 1); } static void -doExistsActive(const vector& args) +existsActive(const vector& args) { UnionfsCstore cstore(true); exit(cstore.cfgPathExists(args, true) ? 0 : 1); } -static int op_idx = -1; -static OpT ops[] = { - {"getSessionEnv", - 1, "Must specify session ID", -1, NULL, - &doGetSessionEnv}, - - {"getEditEnv", - -1, NULL, 1, "Must specify config path", - &doGetEditEnv}, - - {"getEditUpEnv", - 0, "No argument expected", -1, NULL, - &doGetEditUpEnv}, - - {"getEditResetEnv", - 0, "No argument expected", -1, NULL, - &doGetEditResetEnv}, - - {"editLevelAtRoot", - 0, "No argument expected", -1, NULL, - &doEditLevelAtRoot}, - - {"getCompletionEnv", - -1, NULL, 2, "Must specify command and at least one component", - &doGetCompletionEnv}, - - {"getEditLevelStr", - 0, "No argument expected", -1, NULL, - &doGetEditLevelStr}, - - {"markSessionUnsaved", - 0, "No argument expected", -1, NULL, - &doMarkSessionUnsaved}, - - {"unmarkSessionUnsaved", - 0, "No argument expected", -1, NULL, - &doUnmarkSessionUnsaved}, - - {"sessionUnsaved", - 0, "No argument expected", -1, NULL, - &doSessionUnsaved}, - - {"sessionChanged", - 0, "No argument expected", -1, NULL, - &doSessionChanged}, - - {"teardownSession", - 0, "No argument expected", -1, NULL, - &doTeardownSession}, - - {"setupSession", - 0, "No argument expected", -1, NULL, - &doSetupSession}, +static void +listNodes(const vector& args) +{ + UnionfsCstore cstore(true); + vector cnodes; + cstore.cfgPathGetChildNodes(args, cnodes, false); + print_vec(cnodes, " ", "'"); +} - {"inSession", - 0, "No argument expected", -1, NULL, - &doInSession}, +static void +listActiveNodes(const vector& args) +{ + UnionfsCstore cstore(true); + vector cnodes; + cstore.cfgPathGetChildNodes(args, cnodes, true); + print_vec(cnodes, " ", "'"); +} - {"exists", - -1, NULL, 1, "Must specify config path", - &doExists}, +#define OP(name, exact, exact_err, min, min_err) \ + { #name, exact, exact_err, min, min_err, &name } - {"existsActive", - -1, NULL, 1, "Must specify config path", - &doExistsActive}, +static int op_idx = -1; +static OpT ops[] = { + OP(getSessionEnv, 1, "Must specify session ID", -1, NULL), + OP(getEditEnv, -1, NULL, 1, "Must specify config path"), + OP(getEditUpEnv, 0, "No argument expected", -1, NULL), + OP(getEditResetEnv, 0, "No argument expected", -1, NULL), + OP(editLevelAtRoot, 0, "No argument expected", -1, NULL), + OP(getCompletionEnv, -1, NULL, + 2, "Must specify command and at least one component"), + OP(getEditLevelStr, 0, "No argument expected", -1, NULL), + + OP(markSessionUnsaved, 0, "No argument expected", -1, NULL), + OP(unmarkSessionUnsaved, 0, "No argument expected", -1, NULL), + OP(sessionUnsaved, 0, "No argument expected", -1, NULL), + OP(sessionChanged, 0, "No argument expected", -1, NULL), + + OP(teardownSession, 0, "No argument expected", -1, NULL), + OP(setupSession, 0, "No argument expected", -1, NULL), + OP(inSession, 0, "No argument expected", -1, NULL), + + OP(exists, -1, NULL, 1, "Must specify config path"), + OP(existsActive, -1, NULL, 1, "Must specify config path"), + + OP(listNodes, -1, NULL, -1, NULL), + OP(listActiveNodes, -1, NULL, -1, NULL), {NULL, -1, NULL, -1, NULL, NULL} }; -- cgit v1.2.3 From d1b7813a2a82118936738a3a1721959cd0150e64 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Wed, 11 Aug 2010 13:57:05 -0700 Subject: add functions to shell API --- src/cli_shell_api.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index f5e7681..44dcc3c 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -207,6 +207,50 @@ listActiveNodes(const vector& args) print_vec(cnodes, " ", "'"); } +static void +returnValue(const vector& args) +{ + UnionfsCstore cstore(true); + string val; + if (!cstore.cfgPathGetValue(args, val, false)) { + exit(1); + } + printf("%s", val.c_str()); +} + +static void +returnActiveValue(const vector& args) +{ + UnionfsCstore cstore(true); + string val; + if (!cstore.cfgPathGetValue(args, val, true)) { + exit(1); + } + printf("%s", val.c_str()); +} + +static void +returnValues(const vector& args) +{ + UnionfsCstore cstore(true); + vector vvec; + if (!cstore.cfgPathGetValues(args, vvec, false)) { + exit(1); + } + print_vec(vvec, " ", "'"); +} + +static void +returnActiveValues(const vector& args) +{ + UnionfsCstore cstore(true); + vector vvec; + if (!cstore.cfgPathGetValues(args, vvec, true)) { + exit(1); + } + print_vec(vvec, " ", "'"); +} + #define OP(name, exact, exact_err, min, min_err) \ { #name, exact, exact_err, min, min_err, &name } @@ -232,9 +276,12 @@ static OpT ops[] = { OP(exists, -1, NULL, 1, "Must specify config path"), OP(existsActive, -1, NULL, 1, "Must specify config path"), - OP(listNodes, -1, NULL, -1, NULL), OP(listActiveNodes, -1, NULL, -1, NULL), + OP(returnValue, -1, NULL, 1, "Must specify config path"), + OP(returnActiveValue, -1, NULL, 1, "Must specify config path"), + OP(returnValues, -1, NULL, 1, "Must specify config path"), + OP(returnActiveValues, -1, NULL, 1, "Must specify config path"), {NULL, -1, NULL, -1, NULL, NULL} }; @@ -249,7 +296,7 @@ main(int argc, char **argv) { int i = 0; if (argc < 2) { - printf("Must specify operation\n"); + fprintf(stderr, "Must specify operation\n"); exit(-1); } while (ops[i].op_name) { @@ -260,15 +307,15 @@ main(int argc, char **argv) ++i; } if (op_idx == -1) { - printf("Invalid operation\n"); + fprintf(stderr, "Invalid operation\n"); exit(-1); } if (OP_exact_args >= 0 && (argc - 2) != OP_exact_args) { - printf("%s\n", OP_exact_error); + fprintf(stderr, "%s\n", OP_exact_error); exit(-1); } if (OP_min_args >= 0 && (argc - 2) < OP_min_args) { - printf("%s\n", OP_min_error); + fprintf(stderr, "%s\n", OP_min_error); exit(-1); } -- cgit v1.2.3 From 8524a3bcbf493296365ede2cb4aa8ac38856bd77 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Wed, 11 Aug 2010 17:00:20 -0700 Subject: add comments to document shell API usage --- src/cli_shell_api.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index 44dcc3c..eb0fd1a 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -25,6 +25,21 @@ #include #include +/* This program provides an API for shell scripts (e.g., snippets in + * templates, standalone scripts, etc.) to access the CLI cstore library. + * It is installed in "/opt/vyatta/sbin", but a symlink "/bin/cli-shell-api" + * is installed by the package so that it can be invoked simply as + * "cli-shell-api" (as long as "/bin" is in "PATH"). + * + * The API functions communicate with the caller using a combination of + * output and exit status. For example, a "boolean" function "returns true" + * by exiting with status 0, and non-zero exit status means false. The + * functions are documented below when necessary. + */ + +/* util function: prints a vector with the specified "separator" and "quote" + * characters. + */ static void print_vec(const vector& vec, const char *sep, const char *quote) { @@ -44,6 +59,7 @@ typedef struct { OpFuncT op_func; } OpT; +/* outputs an environment string to be "eval"ed */ static void getSessionEnv(const vector& args) { @@ -52,6 +68,7 @@ getSessionEnv(const vector& args) printf("%s", env.c_str()); } +/* outputs an environment string to be "eval"ed */ static void getEditEnv(const vector& args) { @@ -63,6 +80,7 @@ getEditEnv(const vector& args) printf("%s", env.c_str()); } +/* outputs an environment string to be "eval"ed */ static void getEditUpEnv(const vector& args) { @@ -74,6 +92,7 @@ getEditUpEnv(const vector& args) printf("%s", env.c_str()); } +/* outputs an environment string to be "eval"ed */ static void getEditResetEnv(const vector& args) { @@ -92,6 +111,7 @@ editLevelAtRoot(const vector& args) exit(cstore.editLevelAtRoot() ? 0 : 1); } +/* outputs an environment string to be "eval"ed */ static void getCompletionEnv(const vector& args) { @@ -103,6 +123,7 @@ getCompletionEnv(const vector& args) printf("%s", env.c_str()); } +/* outputs a string */ static void getEditLevelStr(const vector& args) { @@ -189,6 +210,16 @@ existsActive(const vector& args) exit(cstore.cfgPathExists(args, true) ? 0 : 1); } +/* outputs a string representing multiple nodes. this string MUST be + * "eval"ed into an array of nodes. e.g., + * + * values=$(cli-shell-api listNodes interfaces) + * eval "nodes=($values)" + * + * or a single step: + * + * eval "nodes=($(cli-shell-api listNodes interfaces))" + */ static void listNodes(const vector& args) { @@ -198,6 +229,9 @@ listNodes(const vector& args) print_vec(cnodes, " ", "'"); } +/* outputs a string representing multiple nodes. this string MUST be + * "eval"ed into an array of nodes. see listNodes above. + */ static void listActiveNodes(const vector& args) { @@ -207,6 +241,7 @@ listActiveNodes(const vector& args) print_vec(cnodes, " ", "'"); } +/* outputs a string */ static void returnValue(const vector& args) { @@ -218,6 +253,7 @@ returnValue(const vector& args) printf("%s", val.c_str()); } +/* outputs a string */ static void returnActiveValue(const vector& args) { @@ -229,6 +265,24 @@ returnActiveValue(const vector& args) printf("%s", val.c_str()); } +/* outputs a string representing multiple values. this string MUST be + * "eval"ed into an array of values. see listNodes above. + * + * note that success/failure can be checked using the two-step invocation + * above. e.g., + * + * if valstr=$(cli-shell-api returnValues system ntp-server); then + * # got the values + * eval "values=($valstr)" + * ... + * else + * # failed + * ... + * fi + * + * in most cases, the one-step invocation should be sufficient since a + * failure would result in an empty array after the eval. + */ static void returnValues(const vector& args) { @@ -240,6 +294,9 @@ returnValues(const vector& args) print_vec(vvec, " ", "'"); } +/* outputs a string representing multiple values. this string MUST be + * "eval"ed into an array of values. see returnValues above. + */ static void returnActiveValues(const vector& args) { -- cgit v1.2.3 From beb3e08460695b9b97eaf57630347c032a51f244 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Wed, 11 Aug 2010 17:56:28 -0700 Subject: document equivalent perl API functions for shell API. --- src/cli_shell_api.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index eb0fd1a..7f0a4d1 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -196,6 +196,7 @@ inSession(const vector& args) } } +/* same as exists() in Perl API */ static void exists(const vector& args) { @@ -203,6 +204,7 @@ exists(const vector& args) exit(cstore.cfgPathExists(args, false) ? 0 : 1); } +/* same as existsOrig() in Perl API */ static void existsActive(const vector& args) { @@ -210,7 +212,9 @@ existsActive(const vector& args) exit(cstore.cfgPathExists(args, true) ? 0 : 1); } -/* outputs a string representing multiple nodes. this string MUST be +/* same as listNodes() in Perl API. + * + * outputs a string representing multiple nodes. this string MUST be * "eval"ed into an array of nodes. e.g., * * values=$(cli-shell-api listNodes interfaces) @@ -229,7 +233,9 @@ listNodes(const vector& args) print_vec(cnodes, " ", "'"); } -/* outputs a string representing multiple nodes. this string MUST be +/* same as listOrigNodes() in Perl API. + * + * outputs a string representing multiple nodes. this string MUST be * "eval"ed into an array of nodes. see listNodes above. */ static void @@ -241,7 +247,7 @@ listActiveNodes(const vector& args) print_vec(cnodes, " ", "'"); } -/* outputs a string */ +/* same as returnValue() in Perl API. outputs a string. */ static void returnValue(const vector& args) { @@ -253,7 +259,7 @@ returnValue(const vector& args) printf("%s", val.c_str()); } -/* outputs a string */ +/* same as returnOrigValue() in Perl API. outputs a string. */ static void returnActiveValue(const vector& args) { @@ -265,7 +271,9 @@ returnActiveValue(const vector& args) printf("%s", val.c_str()); } -/* outputs a string representing multiple values. this string MUST be +/* same as returnValues() in Perl API. + * + * outputs a string representing multiple values. this string MUST be * "eval"ed into an array of values. see listNodes above. * * note that success/failure can be checked using the two-step invocation @@ -294,7 +302,9 @@ returnValues(const vector& args) print_vec(vvec, " ", "'"); } -/* outputs a string representing multiple values. this string MUST be +/* same as returnOrigValues() in Perl API. + * + * outputs a string representing multiple values. this string MUST be * "eval"ed into an array of values. see returnValues above. */ static void -- cgit v1.2.3 From ced5e57f16b055249be5012bf13bb90c8811eb2a Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Thu, 12 Aug 2010 12:03:54 -0700 Subject: add more functions to shell API --- src/cli_shell_api.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/cstore/cstore.hpp | 8 +++++--- 2 files changed, 62 insertions(+), 3 deletions(-) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index 7f0a4d1..f0ac34f 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -212,6 +212,14 @@ existsActive(const vector& args) exit(cstore.cfgPathExists(args, true) ? 0 : 1); } +/* same as isEffective() in Perl API */ +static void +existsEffective(const vector& args) +{ + UnionfsCstore cstore(true); + exit(cstore.cfgPathEffective(args) ? 0 : 1); +} + /* same as listNodes() in Perl API. * * outputs a string representing multiple nodes. this string MUST be @@ -247,6 +255,20 @@ listActiveNodes(const vector& args) print_vec(cnodes, " ", "'"); } +/* same as listEffectiveNodes() in Perl API. + * + * outputs a string representing multiple nodes. this string MUST be + * "eval"ed into an array of nodes. see listNodes above. + */ +static void +listEffectiveNodes(const vector& args) +{ + UnionfsCstore cstore(true); + vector cnodes; + cstore.cfgPathGetEffectiveChildNodes(args, cnodes); + print_vec(cnodes, " ", "'"); +} + /* same as returnValue() in Perl API. outputs a string. */ static void returnValue(const vector& args) @@ -271,6 +293,18 @@ returnActiveValue(const vector& args) printf("%s", val.c_str()); } +/* same as returnEffectiveValue() in Perl API. outputs a string. */ +static void +returnEffectiveValue(const vector& args) +{ + UnionfsCstore cstore(true); + string val; + if (!cstore.cfgPathGetEffectiveValue(args, val)) { + exit(1); + } + printf("%s", val.c_str()); +} + /* same as returnValues() in Perl API. * * outputs a string representing multiple values. this string MUST be @@ -318,6 +352,22 @@ returnActiveValues(const vector& args) print_vec(vvec, " ", "'"); } +/* same as returnEffectiveValues() in Perl API. + * + * outputs a string representing multiple values. this string MUST be + * "eval"ed into an array of values. see returnValues above. + */ +static void +returnEffectiveValues(const vector& args) +{ + UnionfsCstore cstore(true); + vector vvec; + if (!cstore.cfgPathGetEffectiveValues(args, vvec)) { + exit(1); + } + print_vec(vvec, " ", "'"); +} + #define OP(name, exact, exact_err, min, min_err) \ { #name, exact, exact_err, min, min_err, &name } @@ -343,12 +393,19 @@ static OpT ops[] = { OP(exists, -1, NULL, 1, "Must specify config path"), OP(existsActive, -1, NULL, 1, "Must specify config path"), + OP(existsEffective, -1, NULL, 1, "Must specify config path"), + OP(listNodes, -1, NULL, -1, NULL), OP(listActiveNodes, -1, NULL, -1, NULL), + OP(listEffectiveNodes, -1, NULL, 1, "Must specify config path"), + OP(returnValue, -1, NULL, 1, "Must specify config path"), OP(returnActiveValue, -1, NULL, 1, "Must specify config path"), + OP(returnEffectiveValue, -1, NULL, 1, "Must specify config path"), + OP(returnValues, -1, NULL, 1, "Must specify config path"), OP(returnActiveValues, -1, NULL, 1, "Must specify config path"), + OP(returnEffectiveValues, -1, NULL, 1, "Must specify config path"), {NULL, -1, NULL, -1, NULL, NULL} }; diff --git a/src/cstore/cstore.hpp b/src/cstore/cstore.hpp index 34193c2..caf845b 100644 --- a/src/cstore/cstore.hpp +++ b/src/cstore/cstore.hpp @@ -174,6 +174,7 @@ public: bool active_cfg = false); bool cfgPathDefault(const vector& path_comps, bool active_cfg = false); + /* observers for working AND active configs (at the same time). * MUST ONLY be used during config session. */ @@ -184,9 +185,10 @@ public: vector& cnodes); void cfgPathGetChildNodesStatus(const vector& path_comps, map& cmap); - /* observers for "effective config" (a combination of working config, - * active config, and commit processing state) only. - * MUST ONLY be used during config session. + + /* observers for "effective config". can be used both during a config + * session and outside a config session. more detailed information + * can be found in the source file. */ bool cfgPathEffective(const vector& path_comps); void cfgPathGetEffectiveChildNodes(const vector& path_comps, -- cgit v1.2.3 From 95c385ceffe94eb7216dbb09eb7bb107ae1cf67b Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Thu, 12 Aug 2010 17:47:05 -0700 Subject: add more functions to shell API --- src/cli_shell_api.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/cli_shell_api.cpp') diff --git a/src/cli_shell_api.cpp b/src/cli_shell_api.cpp index f0ac34f..1a4f469 100644 --- a/src/cli_shell_api.cpp +++ b/src/cli_shell_api.cpp @@ -368,6 +368,26 @@ returnEffectiveValues(const vector& args) print_vec(vvec, " ", "'"); } +/* checks if specified path is a valid "template path" *without* checking + * the validity of any "tag values" along the path. + */ +static void +validateTmplPath(const vector& args) +{ + UnionfsCstore cstore(true); + exit(cstore.validateTmplPath(args, false) ? 0 : 1); +} + +/* checks if specified path is a valid "template path", *including* the + * validity of any "tag values" along the path. + */ +static void +validateTmplValPath(const vector& args) +{ + UnionfsCstore cstore(true); + exit(cstore.validateTmplPath(args, true) ? 0 : 1); +} + #define OP(name, exact, exact_err, min, min_err) \ { #name, exact, exact_err, min, min_err, &name } @@ -407,6 +427,9 @@ static OpT ops[] = { OP(returnActiveValues, -1, NULL, 1, "Must specify config path"), OP(returnEffectiveValues, -1, NULL, 1, "Must specify config path"), + OP(validateTmplPath, -1, NULL, 1, "Must specify config path"), + OP(validateTmplValPath, -1, NULL, 1, "Must specify config path"), + {NULL, -1, NULL, -1, NULL, NULL} }; #define OP_exact_args ops[op_idx].op_exact_args -- cgit v1.2.3