diff options
author | Tom Grennan <tgrennan@io.vyatta.com> | 2007-12-13 18:36:43 -0800 |
---|---|---|
committer | Tom Grennan <tgrennan@io.vyatta.com> | 2007-12-13 18:36:43 -0800 |
commit | 8d6bac43ac6604b3c2a0ac9315a2e5c168299a5a (patch) | |
tree | 4764a95a26a97186c638b8c37ce5335d7df85b8e | |
parent | 9a781e1b6dbdba52ea430499d48730b6b311dd5c (diff) | |
parent | fddadb2df7980fe86deabb0bfa27189d52479a0e (diff) | |
download | vyatta-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-cfg | 32 | ||||
-rw-r--r-- | etc/default/vyatta-cfg | 21 | ||||
-rw-r--r-- | scripts/VyattaConfigDOMTree.pm | 2 | ||||
-rwxr-xr-x | scripts/vyatta-cfg-notify | 4 | ||||
-rw-r--r-- | src/cli_new.c | 142 | ||||
-rw-r--r-- | src/cli_objects.c | 2 | ||||
-rw-r--r-- | src/cli_val.h | 1 | ||||
-rw-r--r-- | src/commit.c | 24 | ||||
-rw-r--r-- | templates/interfaces/ethernet/node.tag/address/node.def | 2 |
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 $(../@)" |