summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Grennan <tgrennan@io.vyatta.com>2007-12-13 18:36:43 -0800
committerTom Grennan <tgrennan@io.vyatta.com>2007-12-13 18:36:43 -0800
commit8d6bac43ac6604b3c2a0ac9315a2e5c168299a5a (patch)
tree4764a95a26a97186c638b8c37ce5335d7df85b8e
parent9a781e1b6dbdba52ea430499d48730b6b311dd5c (diff)
parentfddadb2df7980fe86deabb0bfa27189d52479a0e (diff)
downloadvyatta-cfg-8d6bac43ac6604b3c2a0ac9315a2e5c168299a5a.tar.gz
vyatta-cfg-8d6bac43ac6604b3c2a0ac9315a2e5c168299a5a.zip
Merge branch 'master' of http://phuket.vyatta.com/vyatta-cfg
-rw-r--r--etc/bash_completion.d/20vyatta-cfg32
-rw-r--r--etc/default/vyatta-cfg21
-rw-r--r--scripts/VyattaConfigDOMTree.pm2
-rwxr-xr-xscripts/vyatta-cfg-notify4
-rw-r--r--src/cli_new.c142
-rw-r--r--src/cli_objects.c2
-rw-r--r--src/cli_val.h1
-rw-r--r--src/commit.c24
-rw-r--r--templates/interfaces/ethernet/node.tag/address/node.def2
9 files changed, 187 insertions, 43 deletions
diff --git a/etc/bash_completion.d/20vyatta-cfg b/etc/bash_completion.d/20vyatta-cfg
index ecf414d..bc9088f 100644
--- a/etc/bash_completion.d/20vyatta-cfg
+++ b/etc/bash_completion.d/20vyatta-cfg
@@ -647,6 +647,17 @@ ENDCOMMENT
vyatta_help_text="\\nNo help text available"
}
+generate_pipe_help ()
+{
+ local -a hcomps=( "${_vyatta_pipe_completions[@]}" \
+ "${_vyatta_pipe_noncompletions[@]}" )
+ local -a hstrs=()
+ for comp in "${hcomps[@]}"; do
+ hstrs+=("$(_vyatta_pipe_help "$comp")")
+ done
+ generate_help_text hcomps hstrs
+}
+
vyatta_config_complete ()
{
local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; )
@@ -660,6 +671,14 @@ vyatta_config_complete ()
vyatta_do_help=0
fi
+ # handle pipe
+ if _vyatta_pipe_completion "${COMP_WORDS[@]}"; then
+ generate_pipe_help
+ vyatta_completions=( "${_vyatta_pipe_completions[@]}" )
+ vyatta_do_complete
+ return
+ fi
+
if (( ${#COMP_WORDS[@]} < 2 )); then
declare -a hitems=( "commit" \
"delete" \
@@ -707,19 +726,6 @@ vyatta_config_complete ()
(( num_comp -= 1 ))
fi
- # handle pipe
- if [ "${COMP_WORDS[$num_comp]}" == "|" ]; then
- declare -a hitems=( "more" \
- )
- declare -a hstrs=( \
- "Paginate the output" \
- )
- generate_help_text hitems hstrs
- vyatta_completions=( "${hitems[@]}" )
- vyatta_do_complete
- return
- fi
-
(( last_idx = num_comp - 1 ))
comp_words=( ${COMP_WORDS[@]:1:$num_comp} )
diff --git a/etc/default/vyatta-cfg b/etc/default/vyatta-cfg
index d369e0f..e560788 100644
--- a/etc/default/vyatta-cfg
+++ b/etc/default/vyatta-cfg
@@ -1,15 +1,18 @@
# Vyatta shell environment variables for config mode
# should be sourced from /etc/default/vyatta
-export VYATTA_ACTIVE_CONFIGURATION_DIR=${vyatta_configdir}/active
-export VYATTA_CHANGES_ONLY_DIR=${vyatta_configdir}/tmp/changes_only_$$
-export VYATTA_TEMP_CONFIG_DIR=${vyatta_configdir}/tmp/new_config_$$
-export VYATTA_CONFIG_TMP=${vyatta_configdir}/tmp/tmp_$$
-export VYATTA_CONFIG_TEMPLATE=$vyatta_cfg_templates
-export VYATTA_EDIT_LEVEL=/
-export VYATTA_TEMPLATE_LEVEL=/
-export VYATTA_TAG_NAME=node.tag
-export VYATTA_MOD_NAME=.modified
+{
+declare -x -r VYATTA_ACTIVE_CONFIGURATION_DIR=${vyatta_configdir}/active
+declare -x -r VYATTA_CHANGES_ONLY_DIR=${vyatta_configdir}/tmp/changes_only_$$
+declare -x -r VYATTA_TEMP_CONFIG_DIR=${vyatta_configdir}/tmp/new_config_$$
+declare -x -r VYATTA_CONFIG_TMP=${vyatta_configdir}/tmp/tmp_$$
+declare -x -r VYATTA_CONFIG_TEMPLATE=$vyatta_cfg_templates
+declare -x -r VYATTA_EDIT_LEVEL=/
+declare -x -r VYATTA_TEMPLATE_LEVEL=/
+declare -x -r VYATTA_TAG_NAME=node.tag
+declare -x -r VYATTA_MOD_NAME=.modified
+declare -x -r VYATTA_CFG_GROUP_NAME=vyattacfg
+} 2>/dev/null || :
# don't set level if already set
if [ -n "$VYATTA_USER_LEVEL_DIR" ]; then
diff --git a/scripts/VyattaConfigDOMTree.pm b/scripts/VyattaConfigDOMTree.pm
index d951202..86aabf8 100644
--- a/scripts/VyattaConfigDOMTree.pm
+++ b/scripts/VyattaConfigDOMTree.pm
@@ -307,7 +307,7 @@ sub getSubNodesNumber {
my @subs = $node->getSubNodes();
- if(defined @subs) {
+ if(@subs) {
$ret = $#subs + 1;
}
}
diff --git a/scripts/vyatta-cfg-notify b/scripts/vyatta-cfg-notify
index 82dc6a3..07a385d 100755
--- a/scripts/vyatta-cfg-notify
+++ b/scripts/vyatta-cfg-notify
@@ -1,11 +1,13 @@
#!/bin/bash
+[ -r /etc/default/vyatta ] && source /etc/default/vyatta
+
declare cur_tty=$(ps -o tty= |head -n1)
declare cur_uid=($(ps -o ruser= n |head -n1))
declare cur_user=$(grep "[^:]\+:[^:]*:${cur_uid[0]}:" /etc/passwd \
| cut -d ':' -f 1)
declare -a ulist=( $(ps -a -o args,tty,ruser n \
- | grep '^newgrp quaggavty' | cut -c 29-) )
+ | grep "^newgrp $VYATTA_CFG_GROUP_NAME" | cut -c 29-) )
for (( i = 0; i < ${#ulist[@]}; i += 2 )); do
utty=${ulist[i]}
diff --git a/src/cli_new.c b/src/cli_new.c
index bbdde10..3f64489 100644
--- a/src/cli_new.c
+++ b/src/cli_new.c
@@ -56,8 +56,13 @@ static int cond_format_lens[DOMAIN_TYPE] =
6 /* MACADDR_TYPE */
};
+struct __slist_t;
+
+typedef struct __slist_t {
+ struct __slist_t *next;
+} slist_t;
+
static int cli_val_len;
-static char *cli_val_alloc;
static char *cli_val_ptr;
static char *exe_string;
@@ -82,6 +87,8 @@ static void free_reuse_list(void);
void free_path(vtw_path *path);
static void free_string(char *str);
static vtw_node * get_node(void);
+void subtract_values(char **lhs, const char *rhs);
+
static void scan_ipv6(char *val, unsigned int *parts);
@@ -233,19 +240,44 @@ release_config_lock()
int
get_config_lock()
{
- int fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660);
- if (fd == -1) {
- return -1;
- }
- if (close(fd) == -1) {
- release_config_lock();
- return -1;
- }
- if (atexit(release_config_lock) != 0) {
+ int fd = -1;
+ FILE *lfile = NULL;
+ int ret = -1;
+
+ do {
+ /* create lock file */
+ fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660);
+ if (fd == -1) {
+ break;
+ }
+
+ /* write pid into lock file */
+ if ((lfile = fdopen(fd, "w")) == NULL) {
+ break;
+ }
+ if (fprintf(lfile, "%u", getpid()) < 0) {
+ break;
+ }
+ /* fclose also closes fd */
+ if (fclose(lfile) != 0) {
+ break;
+ }
+ /* clean up on exit */
+ if (atexit(release_config_lock) != 0) {
+ break;
+ }
+ ret = 0;
+ } while (0);
+
+ if (ret == -1) {
+ if (lfile) {
+ fclose(lfile);
+ } else if (fd != -1) {
+ close(fd);
+ }
release_config_lock();
- return -1;
}
- return 0;
+ return ret;
}
void internal_error(int line, char *file)
@@ -1515,7 +1547,6 @@ int get_value(char **valpp, vtw_path *pathp)
readcnt = fread(valp, 1, statbuf.st_size, in);
if (readcnt != statbuf.st_size) {
my_free(valp);
- cli_val_alloc = 0;
err = "Error reading value file in [%s]\n";
goto bad_path;
}
@@ -1781,6 +1812,91 @@ boolean validate_value(vtw_def *def, char *cp)
return ret;
}
+typedef struct __value_list {
+ slist_t link;
+ const char *value;
+} value_list;
+
+static void delete_list(slist_t *head)
+{
+ while (head != NULL) {
+ slist_t *elem = head;
+ head = head->next;
+ my_free(elem);
+ }
+}
+
+void subtract_values(char **lhs, const char *rhs)
+{
+ size_t length = 0;
+ const char *line = NULL;
+ char *rhs_copy = NULL, *res = NULL;
+ slist_t *head = NULL, *ptr = NULL;
+ slist_t *new_head = NULL, *new_ptr = NULL;
+
+ if (lhs == NULL || *lhs == NULL || **lhs == '\0' || rhs == NULL || *rhs == '\0')
+ return;
+
+ rhs_copy = my_malloc(strlen(rhs), "subtract_values rhs_copy");
+ strcpy(rhs_copy, rhs);
+
+ head = ptr = my_malloc(sizeof(slist_t), "subtract_values list1");
+ memset(head, 0, sizeof(slist_t));
+
+ line = strtok(rhs_copy, "\n\r");
+ while (line != NULL && *line != '\0') {
+ value_list *elem = NULL;
+
+ elem = (value_list *) my_malloc(sizeof(value_list), "subtract_values elem1");
+ memset(elem, 0, sizeof(value_list));
+ elem->value = line;
+ ptr->next = (slist_t *) elem;
+ ptr = ptr->next;
+ line = strtok(NULL, "\n\r");
+ }
+
+ new_head = new_ptr = my_malloc(sizeof(slist_t), "subtract_values list2");
+ memset(new_head, 0, sizeof(slist_t));
+
+ line = strtok(*lhs, "\n\r");
+ while (line != NULL && *line != '\0') {
+ value_list *elem = NULL;
+
+ ptr = head;
+ while (ptr->next != NULL) {
+ elem = (value_list *) ptr->next;
+ if (strncmp(line, elem->value, strlen(line)) == 0)
+ break;
+ ptr = ptr->next;
+ }
+ if (ptr->next == NULL) {
+ elem = (value_list *) my_malloc(sizeof(value_list), "subtract_values elem2");
+ memset(elem, 0, sizeof(value_list));
+ elem->value = line;
+ new_ptr->next = elem;
+ new_ptr = new_ptr->next;
+ length += strlen(line) + 1;
+ }
+ line = strtok(NULL, "\n\r");
+ }
+
+ new_ptr = new_head->next;
+ res = (char *) my_malloc(length + 1, "subtract_values result");
+ *res = '\0';
+ while (new_ptr != NULL) {
+ strcat(res, ((value_list *) new_ptr)->value);
+ strcat(res, "\n");
+ new_ptr = new_ptr->next;
+ }
+
+ delete_list(head);
+ delete_list(new_head);
+ if (rhs_copy != NULL)
+ my_free(rhs_copy);
+ my_free(*lhs);
+
+ *lhs = res;
+}
int cli_val_read(char *buf, int max_size)
{
diff --git a/src/cli_objects.c b/src/cli_objects.c
index 9bb36f0..8f0f6fe 100644
--- a/src/cli_objects.c
+++ b/src/cli_objects.c
@@ -334,7 +334,7 @@ void init_paths(boolean for_commit)
init_path(&m_path, startp);
switch_path(get_f_seg_c_ptr());
m_path.print_offset = max_len;
- }else
+ } else
init_path(&m_path, mdirp);
init_path(&t_path, tdirp);
diff --git a/src/cli_val.h b/src/cli_val.h
index 7383263..edbda41 100644
--- a/src/cli_val.h
+++ b/src/cli_val.h
@@ -171,6 +171,7 @@ extern void dump_tree(vtw_node *node, int lev);
extern void dump_def(vtw_def *defp);
extern boolean val_cmp(valstruct *left, valstruct *right, vtw_cond_e cond);
extern void out_of_memory(void);
+extern void subtract_values(char **lhs, const char *rhs);
extern boolean validate_value(vtw_def *def,
char *value);
extern void internal_error(int line, char *file);
diff --git a/src/commit.c b/src/commit.c
index d0d2517..b2e1c8a 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -91,7 +91,7 @@ static boolean validate_dir_for_commit()
def_present = TRUE;
memset(&def, 0, sizeof(def));
#ifdef DEBUG1
- printf("Parsing definition\n");
+ printf("Parsing definition %s\n", t_path.path);
#endif
if ((status = parse_def(&def, t_path.path,
@@ -102,7 +102,7 @@ static boolean validate_dir_for_commit()
}
#ifdef DEBUG1
else
- printf("No definition\n");
+ printf("No definition %s\n", t_path.path);
#endif
pop_path(&t_path); /* for PUSH 1 */
@@ -156,11 +156,27 @@ static boolean validate_dir_for_commit()
/* read it */
cp = NULL;
status = get_value(&cp, &m_path);
- if (status == VTWERR_OK){
+ if (status == VTWERR_OK) {
#ifdef DEBUG1
printf("Validating value |%s|\n"
"for path %s\n", cp, m_path.path);
#endif
+
+ // multivalue has to be diff-ed with the pre-existing value.
+ // only the difference should be ran through the validation.
+ // Bug #2509
+ if (def.multi) {
+ char *old_value = NULL;
+ switch_path(APATH); // temporarily switching to the active config path
+ status = get_value(&old_value, &m_path);
+ if (status == VTWERR_OK) {
+ subtract_values(&cp, old_value);
+ }
+ switch_path(CPATH);
+ if (old_value)
+ my_free(old_value);
+ }
+
status = validate_value(&def, cp);
ret = ret && status;
}
@@ -232,7 +248,7 @@ static boolean validate_dir_for_commit()
}
if (def_present && def.tag)
- pop_path(&t_path); /* for PUSH 3a */
+ pop_path(&t_path); /* for PUSH 2a */
if (def_present)
free_def(&def);
#ifdef DEBUG
diff --git a/templates/interfaces/ethernet/node.tag/address/node.def b/templates/interfaces/ethernet/node.tag/address/node.def
index 9447c99..6cef105 100644
--- a/templates/interfaces/ethernet/node.tag/address/node.def
+++ b/templates/interfaces/ethernet/node.tag/address/node.def
@@ -2,5 +2,5 @@ multi:
type: txt
help: "Set IPv4 address and prefix for this interface"
syntax: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $(@) --dev $(../@)"
-create: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $(@) --dev $(../@)"; "Error setting address $(@) on dev $(../@)"
+update: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $(@) --dev $(../@)"; "Error setting address $(@) on dev $(../@)"
delete: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $(@) --dev $(../@)"; "Error deleting address $(@) on dev $(../@)"