summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--debian/changelog62
-rwxr-xr-xetc/bash_completion.d/20vyatta-cfg22
-rwxr-xr-xlib/Vyatta/Config.pm23
-rwxr-xr-xlib/Vyatta/ConfigLoad.pm96
-rwxr-xr-xlib/Vyatta/ConfigOutput.pm26
-rwxr-xr-xscripts/enumeration/existing-interfaces4
-rw-r--r--scripts/update-priority.pl11
-rw-r--r--scripts/vyatta-activate-config.pl76
-rwxr-xr-xscripts/vyatta-cfg-cmd-wrapper4
-rw-r--r--scripts/vyatta-comment-config.pl76
-rwxr-xr-xscripts/vyatta-config-gen-sets.pl3
-rwxr-xr-xscripts/vyatta-config-loader.pl40
-rwxr-xr-xscripts/vyatta-load-config.pl44
-rw-r--r--src/cli_def.l4
-rw-r--r--src/cli_new.c88
-rw-r--r--src/cli_val.h4
-rw-r--r--src/common/unionfs.c4
-rw-r--r--src/delete.c4
-rw-r--r--src/set.c33
20 files changed, 500 insertions, 128 deletions
diff --git a/Makefile.am b/Makefile.am
index efe1a92..a1a8f8a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,6 +4,7 @@ initddir = /etc/init.d
defaultdir = /etc/default
etc_shell_leveldir = $(sysconfdir)/shell/level
dhcphookdir = /etc/dhcp3/dhclient-exit-hooks.d
+enumdir = $(datadir)/enumeration
AM_CFLAGS = -I src -Wall -I /usr/include/glib-2.0 -I /usr/lib/glib-2.0/include
AM_YFLAGS = -d --name-prefix=yy_`basename $* .y`_
@@ -54,6 +55,7 @@ sbin_SCRIPTS += scripts/vyatta-output-config.pl
sbin_SCRIPTS += scripts/vyatta-save-config.pl
sbin_SCRIPTS += scripts/vyatta-load-config.pl
sbin_SCRIPTS += scripts/vyatta-activate-config.pl
+sbin_SCRIPTS += scripts/vyatta-comment-config.pl
sbin_SCRIPTS += scripts/vyatta-cfg-notify
sbin_SCRIPTS += scripts/vyatta-irqaffin
sbin_SCRIPTS += scripts/vyatta-auto-irqaffin.pl
@@ -70,6 +72,8 @@ share_perl5_DATA += lib/Vyatta/ConfigLoad.pm
share_perl5_DATA += lib/Vyatta/Keepalived.pm
share_perl5_DATA += lib/Vyatta/Zone.pm
+enum_SCRIPTS = scripts/enumeration/existing-interfaces
+
default_DATA = etc/default/vyatta-cfg
cpiop = find . ! -regex '\(.*~\|.*\.bak\|.*\.swp\|.*\#.*\#\)' -print0 | \
diff --git a/debian/changelog b/debian/changelog
index 22f9812..4fcd160 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,65 @@
+vyatta-cfg (0.16.44) unstable; urgency=low
+
+ * fix for disable nodes loading (bug 5610). Additional checks added on
+ configuration of disable nodes. requires vyatta-config-migrate
+ package as well.
+
+ -- Michael Larson <slioch@slioch.vyatta.com> Fri, 21 May 2010 10:21:32 -0700
+
+vyatta-cfg (0.16.43) unstable; urgency=low
+
+ * fixed error message on multinode limit exceeded--refer to parent
+ node name, not value.
+ * fixed seg violation on commit due to extended multiple types support
+ in valstruct.
+
+ -- Michael Larson <slioch@slioch.vyatta.com> Thu, 20 May 2010 15:41:25 -0700
+
+vyatta-cfg (0.16.42) unstable; urgency=low
+
+ * fix for bug 5618. needed to extend valstruct to maintain multiple
+ types rather than using first type found in node.val file. also
+ simplified type check.
+
+ -- Michael Larson <slioch@slioch.vyatta.com> Thu, 20 May 2010 13:36:53 -0700
+
+vyatta-cfg (0.16.41) unstable; urgency=low
+
+ * trap for illegal characters in comment field being set by user and
+ provide feedback.
+ * modified tag limit == 1. Now when set this node will only allow a
+ single instance. todo update the parsing structure to support a
+ signed value to support embedded tag node
+
+ -- Michael Larson <slioch@slioch.vyatta.com> Wed, 19 May 2010 14:56:31 -0700
+
+vyatta-cfg (0.16.40) unstable; urgency=low
+
+ [ Arthur Xiong ]
+ * 1) skip comment and empty lines in priority file;
+
+ [ Michael Larson ]
+ * added additional warning message if the user tries to deactivate a
+ node that has already been deactivated.
+ * initial checkin of comment feature for cli.
+
+ [ An-Cheng Huang ]
+ * POC implementation of unified enumeration mechanism
+
+ -- An-Cheng Huang <ancheng@vyatta.com> Fri, 14 May 2010 17:41:16 -0700
+
+vyatta-cfg (0.16.39) unstable; urgency=low
+
+ * additional fix
+
+ -- An-Cheng Huang <ancheng@vyatta.com> Thu, 06 May 2010 17:32:40 -0700
+
+vyatta-cfg (0.16.38) unstable; urgency=low
+
+ * fix parsing error in node.def--seen with boolean default values.
+
+ -- Michael Larson <slioch@slioch.vyatta.com> Thu, 06 May 2010 16:04:45 -0700
+
vyatta-cfg (0.16.37) unstable; urgency=low
[ Arthur ]
diff --git a/etc/bash_completion.d/20vyatta-cfg b/etc/bash_completion.d/20vyatta-cfg
index e17fd36..03f0bb2 100755
--- a/etc/bash_completion.d/20vyatta-cfg
+++ b/etc/bash_completion.d/20vyatta-cfg
@@ -431,6 +431,17 @@ loadkey()
eval "${vyatta_sbindir}/vyatta-load-user-key.pl $@"
}
+comment()
+{
+ if [ "$#" -eq "0" ]; then
+ return 0
+ fi
+ args=("$@")
+ #now need to replace last element
+ args[${#args[*]}-1]="\"${args[${#args[*]}-1]i}\"";
+ eval "${vyatta_sbindir}/vyatta-comment-config.pl ${args[*]}"
+}
+
activate()
{
#create or remove activate file
@@ -632,6 +643,7 @@ vyatta_parse_tmpl ()
# $1: tmpl
vyatta_cfg_help=""
vyatta_cfg_type=""
+ vyatta_cfg_enum=''
vyatta_cfg_tag=0
vyatta_cfg_multi=0
vyatta_cfg_allowed=()
@@ -648,11 +660,18 @@ vyatta_parse_tmpl ()
s/^tag:.*/vyatta_cfg_tag=1/p
s/^multi:.*/vyatta_cfg_multi=1/p
s/^type:[ ]\+\([^ ;]\+\)\(;.*\)\?/vyatta_cfg_type=\1/p
+ s/^enumeration:[ ]\+\([^ ]\+\)/vyatta_cfg_enum=\1/p
' $1`
vyatta_cfg_help=$(vyatta_parse_tmpl_comp_fields $1 "help")
local acmd=$(vyatta_parse_tmpl_comp_fields $1 "allowed")
+ if [ -n "$vyatta_cfg_enum" ]; then
+ local enum_script="/opt/vyatta/share/enumeration/$vyatta_cfg_enum"
+ if [ -f "$enum_script" ] && [ -e "$enum_script" ]; then
+ acmd="$enum_script"
+ fi
+ fi
vyatta_cfg_comp_help=$(vyatta_parse_tmpl_comp_fields $1 "comp_help")
if (( ${#vyatta_cfg_allowed[@]} == 0 )); then
@@ -942,6 +961,7 @@ vyatta_config_complete ()
if (( ${#COMP_WORDS[@]} < 2 )); then
declare -a hitems=( "activate" \
+ "comment" \
"commit" \
"copy" \
"deactivate" \
@@ -959,6 +979,7 @@ vyatta_config_complete ()
"show" )
declare -a hstrs=( \
"Enable this portion of the configuration" \
+ "Add comment to this configuration element" \
"Commit the current set of changes" \
"Copy a configuration element" \
"Inactivate this portion of the configuration" \
@@ -1310,6 +1331,7 @@ complete -F vyatta_loadsave_complete save
complete -F vyatta_loadsave_complete load
complete -F vyatta_loadsave_complete merge
complete -F vyatta_loadkey_complete loadkey
+complete -F vyatta_config_complete comment
complete -F vyatta_config_complete activate
complete -F vyatta_config_complete deactivate
complete -F vyatta_config_complete copy
diff --git a/lib/Vyatta/Config.pm b/lib/Vyatta/Config.pm
index 82d835f..e4d74bb 100755
--- a/lib/Vyatta/Config.pm
+++ b/lib/Vyatta/Config.pm
@@ -329,6 +329,27 @@ sub returnValue {
return $tmp;
}
+## returnComment("node")
+# returns the value of "node" or undef if the node doesn't exist .
+# node is relative
+sub returnComment {
+ my ( $self, $node ) = @_;
+ my $tmp = undef;
+
+ $node =~ s/\//%2F/g;
+ $node =~ s/\s+/\//g;
+
+ return unless
+ open my $file, '<',
+ "$self->{_new_config_dir_base}/$node/.comment";
+
+ read $file, $tmp, 16384;
+ close $file;
+
+ $tmp =~ s/\n$//;
+ return $tmp;
+}
+
## returnOrigPlusComValue("node")
# returns the value of "node" or undef if the node doesn't exist .
# node is relative
@@ -808,6 +829,8 @@ sub parseTmplAll {
}
} elsif (/^help:\s+(\S.*)$/) {
$ret{help} = $1;
+ } elsif (/^enumeration:\s+(\S+)$/) {
+ $ret{enum} = $1;
}
}
close($tmpl);
diff --git a/lib/Vyatta/ConfigLoad.pm b/lib/Vyatta/ConfigLoad.pm
index 28e932e..183e598 100755
--- a/lib/Vyatta/ConfigLoad.pm
+++ b/lib/Vyatta/ConfigLoad.pm
@@ -30,6 +30,9 @@ use Vyatta::Config;
my @all_nodes = ();
my @all_naked_nodes = ();
+my @disable_list = ();
+
+
sub match_regex {
my ($pattern, $str) = @_;
$pattern =~ s/^(.*)$/\^$1\$/;
@@ -58,6 +61,8 @@ sub applySingleQuote {
return @return;
}
+my @comment_list = ();
+
sub enumerate_branch {
my $cur_node = shift;
my @cur_path = @_;
@@ -72,31 +77,42 @@ sub enumerate_branch {
}
my $terminal = 0;
if (!defined($cur_node->{'children'})) {
- $terminal = 1;
+ $terminal = 1;
} else {
- foreach (@{$cur_node->{'children'}}) {
- if (defined($_->{'name'})) {
- enumerate_branch($_, @cur_path);
- $terminal = 0;
+ my $comment;
+ foreach (@{$cur_node->{'children'}}) {
+ if (defined($_->{'comment'})) {
+ $comment = $_->{'comment'};
+ }
+
+ if (defined($_->{'name'})) {
+ if (defined $comment) {
+ push @comment_list, join(" ", (@cur_path, $_->{'name'}, "\"" . $comment . "\""));
+ $comment = undef;
+ }
+ else {
+ #need to check for existance of .comment file here.
+ push @comment_list, join(" ", (@cur_path, $_->{'name'}, "\"\""));
+ }
+ enumerate_branch($_, @cur_path);
+ $terminal = 0;
+ }
+
}
- }
}
+
+ if (defined($cur_node->{'disable'})) {
+ push @disable_list, join(" ",@cur_path);
+ }
+
if ($terminal) {
my $val = $cur_node->{'value'};
if (defined($val)) {
push @cur_path, $val;
}
- if (defined $cur_node->{'disable'}) {
- push @all_naked_nodes, [ '!', @cur_path ];
- my @qpath = applySingleQuote(@cur_path);
- unshift(@qpath,'!');
- push @all_nodes, [\@qpath, 0];
- }
- else {
- push @all_naked_nodes, [ @cur_path ];
- my @qpath = applySingleQuote(@cur_path);
- push @all_nodes, [\@qpath, 0];
- }
+ push @all_naked_nodes, [ @cur_path ];
+ my @qpath = applySingleQuote(@cur_path);
+ push @all_nodes, [\@qpath, 0];
}
}
@@ -111,6 +127,8 @@ sub getStartupConfigStatements {
if (!defined($load_cfg)) {
return ();
}
+
+ my $comments = shift;
my $xcp = new XorpConfigParser();
$xcp->parse($load_cfg);
@@ -120,7 +138,20 @@ sub getStartupConfigStatements {
}
enumerate_branch($root, ( ));
- return @all_nodes;
+ if (defined $comments && $comments eq 'true') {
+ #add comment commands to all nodes
+ foreach my $c (@comment_list) {
+ if ($c !~ /\"\"$/) {
+ my @pth = split(" ",'comment ' . $c);
+ push @all_nodes, [\@pth, 1];
+ }
+ }
+ }
+ my %conf = (
+ 'set' => \@all_nodes,
+ 'deactivate' => \@disable_list,
+ );
+ return %conf;
}
my %node_order = ();
@@ -221,7 +252,6 @@ sub getSortedMultiValues {
my $active_cfg = undef;
my $new_cfg_ref = undef;
-
my @delete_list = ();
# find specified node's values in active config that have been deleted from
@@ -278,7 +308,6 @@ sub findDeletedNodes {
}
my @set_list = ();
-my @disable_list = ();
# find specified node's values in active config that are set
# (added or changed).
@@ -326,9 +355,9 @@ sub findSetNodes {
my %active_hash = map { $_ => 1 } @active_nodes;
my $nref = $active_cfg->parseTmplAll(join ' ', @active_path);
if (defined($nref->{type}) and !defined($nref->{tag})) {
- # we are at a leaf node.
- findSetValues($new_ref, \@active_path);
- return;
+ # we are at a leaf node.
+ findSetValues($new_ref, \@active_path);
+ return;
}
foreach (sort keys %{$new_ref}) {
if (scalar(keys %{$new_ref->{$_}}) == 0) {
@@ -336,28 +365,16 @@ sub findSetNodes {
# check if we need to add this node.
if (!defined($active_hash{$_})) {
my @plist = applySingleQuote(@active_path, $_);
- if ($active_path[0] eq '!') {
- my @tmp = @plist[1..$#plist];
- push @disable_list, [\@tmp, 0];
- push @set_list, [\@tmp, 0];
- }
- else {
- push @set_list, [\@plist, 0];
- }
+ push @set_list, [\@plist, 0];
} else {
# node already present. do nothing.
}
next;
}
- if ($active_path[0] eq '!') {
- my @plist = applySingleQuote(@active_path, $_);
- my @tmp = @plist[1..$#plist];
- push @disable_list, [\@tmp, 0];
- }
+ # we recur regardless of whether it's in active. all changes will be
+ # handled when we reach leaf nodes (above).
findSetNodes($new_ref->{$_}, [ @active_path, $_ ]);
}
- # we recur regardless of whether it's in active. all changes will be
- # handled when we reach leaf nodes (above).
}
# compare the current active config with the specified hierarchy and return
@@ -368,7 +385,7 @@ sub getConfigDiff {
$active_cfg = new Vyatta::Config;
$new_cfg_ref = shift;
@set_list = ();
- @disable_list = ();
+# @disable_list = ();
@delete_list = ();
findDeletedNodes($new_cfg_ref, [ ]);
findSetNodes($new_cfg_ref, [ ]);
@@ -392,6 +409,7 @@ sub getConfigDiff {
'delete' => \@new_delete_list,
'set' => \@set_list,
'deactivate' => \@disable_list,
+ 'comment' => \@comment_list,
);
return %diff;
}
diff --git a/lib/Vyatta/ConfigOutput.pm b/lib/Vyatta/ConfigOutput.pm
index caa9356..99a0da8 100755
--- a/lib/Vyatta/ConfigOutput.pm
+++ b/lib/Vyatta/ConfigOutput.pm
@@ -82,6 +82,7 @@ sub displayValues {
my $HIDE_PASSWORD = '****************';
$config->setLevel(join ' ', @cur_path);
+
if ($is_multi) {
my @ovals = $config->returnOrigValues('');
my @nvals = $config->returnValues('');
@@ -201,6 +202,11 @@ sub displayDeletedOrigChildren {
if (!defined $is_tag) {
my $path = join(' ',( @cur_path, $child ));
+ my $comment = $config->returnComment($path);
+ if (defined $comment) {
+ print "$prefix /* $comment */\n";
+ }
+
my ($state, $n) = $config->getDeactivated($path);
if (defined $state) {
$dis = '! ';
@@ -211,6 +217,7 @@ sub displayDeletedOrigChildren {
}
$config->setLevel(join ' ', (@cur_path, $child));
+
my @cnames = sort $config->listOrigNodesNoDef();
if ($cnames[0] eq 'node.val') {
@@ -227,8 +234,14 @@ sub displayDeletedOrigChildren {
next;
}
- #need separate check here
my $path = join(' ',( @cur_path, $child, $cname ));
+
+ my $comment = $config->returnComment($path);
+ if (defined $comment) {
+ print "$prefix /* $comment */\n";
+ }
+
+ #need separate check here
my ($state, $n) = $config->getDeactivated($path);
if (defined $state) {
$dis = '! ';
@@ -288,6 +301,11 @@ sub displayChildren {
if (!defined($is_tag)) {
my $path = join(' ',( @cur_path, $child ));
+ my $comment = $config->returnComment($path);
+ if (defined $comment) {
+ print "$prefix /* $comment */\n";
+ }
+
my ($state, $n) = $config->getDeactivated($path);
if (defined $state) {
$dis = '! ';
@@ -325,6 +343,11 @@ sub displayChildren {
}
my $path = join(' ',( @cur_path, $child, $cname ));
+ my $comment = $config->returnComment($path);
+ if (defined $comment) {
+ print "$prefix /* $comment */\n";
+ }
+
my ($state, $n) = $config->getDeactivated($path);
if (defined $state) {
$dis = '! ';
@@ -388,6 +411,7 @@ sub outputNewConfig {
$config = new Vyatta::Config;
$config->setLevel(join ' ', @_);
my %rnodes = $config->listNodeStatus(undef,'true');
+
if (scalar(keys %rnodes) > 0) {
my @rn = keys %rnodes;
diff --git a/scripts/enumeration/existing-interfaces b/scripts/enumeration/existing-interfaces
new file mode 100755
index 0000000..1defc22
--- /dev/null
+++ b/scripts/enumeration/existing-interfaces
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+ls /sys/class/net 2>/dev/null
+
diff --git a/scripts/update-priority.pl b/scripts/update-priority.pl
index 84b4933..feb1e7f 100644
--- a/scripts/update-priority.pl
+++ b/scripts/update-priority.pl
@@ -38,7 +38,7 @@ my $prefix = $ARGV[1];
open my $pf, '<', $priority_file or die "$priority_file can't be opened";
while (<$pf>) {
chomp;
- next if /^#.*/;
+ next if /^#.*/ or /^$/;
die "Syntax Error \"$_\"" unless /^(\d+)\s+(\S+)(|\s+|\s+#.*)$/;
$priority = $1;
$path = $2;
@@ -55,11 +55,12 @@ while (<$pf>) {
open my $nf, '<', $node_def or die "$node_def can't be opened";
open my $nfn, '>', "$node_def.new" or die "$node_def.new can't be opened";
while (<$nf>) {
- print $nfn $_ if /^(tag|multi):/;
- print $nfn $priority_line;
- print $nfn $_ unless /^priority:\s(\d+)/ or /^(tag|multi):/;
- last if $. == 1;
+ last unless /^#.*/ or /^$/;
+ print $nfn $_;
}
+ print $nfn $_ if /^(tag|multi):/;
+ print $nfn $priority_line if $priority != 0;
+ print $nfn $_ unless /^priority:\s(\d+)/ or /^(tag|multi):/;
while (<$nf>) {
print $nfn $_ unless /^priority:\s(\d+)/;
}
diff --git a/scripts/vyatta-activate-config.pl b/scripts/vyatta-activate-config.pl
index 20f704d..3eca90f 100644
--- a/scripts/vyatta-activate-config.pl
+++ b/scripts/vyatta-activate-config.pl
@@ -27,15 +27,40 @@ use lib "/opt/vyatta/share/perl5";
sub wanted {
return unless ( $_ eq '.disable' );
- print("Cannot set nested deactivated nodes\n");
+ print("Cannot deactivate nested elements\n");
exit 1;
}
+sub check_parents {
+ my @p = @_;
+ my $l_dir = "$ENV{VYATTA_TEMP_CONFIG_DIR}/";
+ my $a_dir = "$ENV{VYATTA_ACTIVE_CONFIGURATION_DIR}/";
+ foreach my $sw (@p) {
+ $l_dir .= "/$sw";
+ $a_dir .= "/$sw";
+
+ if (-e "$l_dir/.disable") {
+ return 1;
+ }
+ if (-e "$a_dir/.disable") {
+ return 1;
+ }
+ }
+ return 0;
+}
+
sub usage() {
print "Usage: $0 <path>\n";
exit 0;
}
+my $action = $ARGV[0];
+
+if (!defined $ARGV[1] || $ARGV[1] eq '') {
+ print("Cannot activate/deactivate configuration root\n");
+ exit 1;
+}
+
#adjust for leaf node
my $i = 0;
my @path = @ARGV[1..$#ARGV];
@@ -53,7 +78,6 @@ if (! -e $full_path) {
my $leaf = "$ENV{VYATTA_TEMP_CONFIG_DIR}/$path/node.val";
if (-e $leaf) {
#prevent setting on leaf or multi, check for node.val
-# $full_path = "$ENV{VYATTA_TEMP_CONFIG_DIR}/$path";
printf("Cannot activate/deactivate end node\n");
exit 1;
}
@@ -63,45 +87,53 @@ if (! -e $full_path) {
}
}
+#######################################################
+#now check for nesting of the activate/deactivate nodes
+#######################################################
+if ($action eq 'deactivate') {
+ my $active_dir = "$ENV{VYATTA_ACTIVE_CONFIGURATION_DIR}/$path";
+ my $local_dir = $full_path;
+ if (-e $active_dir) { #checks active children
+ find( \&wanted, $active_dir );
+ }
+ if (-e $local_dir) { #checks locally commit children
+ find( \&wanted, $local_dir );
+ }
+ #final check that walks up tree and checks
+ if (check_parents(@path)) { #checks active and locally committed parents
+ print("Cannot deactivate nested elements\n");
+ exit 1;
+ }
+}
-if ($ARGV[0] eq 'activate') {
+#######################################################
+#now apply the magic
+#######################################################
+if ($action eq 'activate') {
$full_path .= "/.disable";
if (-e $full_path) {
`rm -f $full_path`;
}
else {
- printf("This element is not deactivated.\n");
+ printf("This element has not been deactivated\n");
exit 1;
}
}
-elsif ($ARGV[0] eq 'deactivate') {
+elsif ($action eq 'deactivate') {
#first let's check and ensure that there is not another child .disable node...
#also needs to be enforced when committing
my $active_dir = "$ENV{VYATTA_ACTIVE_CONFIGURATION_DIR}/$path";
my $local_dir = $full_path;
- if (-e $active_dir) {
- find( \&wanted, $active_dir );
- }
- if (-e $local_dir) {
- find( \&wanted, $local_dir );
+ if (-e "$active_dir/.disable" || -e "$local_dir/.disable") {
+ printf("This element has already been deactivated\n");
+ exit 1;
}
`touch $full_path/.disable`;
}
-elsif ($ARGV[0] eq 'complete') {
- #provide match...
- printf("complete\n");
-}
else {
- printf("incoming arg: " . $ARGV[0] . "\n");
+ printf("bad argument: " . $action . "\n");
usage();
}
-#if this is activate
-# make sure no activate subnodes
-# create .disable file in node
-#else
-# ensure .disable file exists
-# remove node
-
print "Done\n";
exit 0;
diff --git a/scripts/vyatta-cfg-cmd-wrapper b/scripts/vyatta-cfg-cmd-wrapper
index 3b2f040..4941e37 100755
--- a/scripts/vyatta-cfg-cmd-wrapper
+++ b/scripts/vyatta-cfg-cmd-wrapper
@@ -220,6 +220,10 @@ case "$1" in
/opt/vyatta/sbin/vyatta-activate-config.pl activate "${@:2}"
RET_STATUS=$?
;;
+ comment)
+ /opt/vyatta/sbin/vyatta-comment-config.pl "${@:2}"
+ RET_STATUS=$?
+ ;;
commit)
# debug file /tmp/bar should be deleted before release
/opt/vyatta/sbin/my_commit -a >> /tmp/bar
diff --git a/scripts/vyatta-comment-config.pl b/scripts/vyatta-comment-config.pl
new file mode 100644
index 0000000..ab3191e
--- /dev/null
+++ b/scripts/vyatta-comment-config.pl
@@ -0,0 +1,76 @@
+#!/usr/bin/perl
+
+# Author: Michael Larson <mike@vyatta.com>
+# Date: 2010
+# Description: Perl script for adding comments to portions of the configuration
+
+# **** License ****
+# 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.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2006, 2007, 2008, 2009, 2010 Vyatta, Inc.
+# All Rights Reserved.
+# **** End License ****
+
+use strict;
+use warnings;
+use File::Find;
+use lib "/opt/vyatta/share/perl5";
+
+
+sub usage() {
+ print "Usage: $0 <path>\n";
+ exit 0;
+}
+
+if ($#ARGV == 0) {
+ exit 0;
+}
+
+#adjust for leaf node
+my $i = 0;
+my @path = @ARGV[0..$#ARGV-1];
+foreach my $elem (@path) {
+ $elem =~ s/\//%2F/g;
+ $elem =~ s/\s+/\//g;
+ $path[$i++] = $elem;
+}
+my $path = join '/', @path;
+
+my $full_path = "$ENV{VYATTA_TEMP_CONFIG_DIR}/$path";
+
+if (! -e $full_path) {
+ $path = join '/', @path[0..$#path-1];
+ my $leaf = "$ENV{VYATTA_TEMP_CONFIG_DIR}/$path/node.val";
+ if (-e $leaf) {
+ $full_path = "$ENV{VYATTA_TEMP_CONFIG_DIR}/$path";
+ }
+ else {
+ `echo \"Path is not valid\n\"`;
+ exit 0;
+ }
+}
+
+#scan for illegal characters here: '/*', '*/'
+if ($ARGV[$#ARGV] =~ /\/\*|\*\//) {
+ print "illegal characters found in comment\n";
+ exit 1;
+}
+
+
+if ($ARGV[$#ARGV] eq '') {
+ `rm -f $full_path/.comment`;
+}
+else {
+ `echo \"$ARGV[$#ARGV]\" > $full_path/.comment`;
+}
+
+print "Done\n";
+exit 0;
diff --git a/scripts/vyatta-config-gen-sets.pl b/scripts/vyatta-config-gen-sets.pl
index e364dfa..7cf4feb 100755
--- a/scripts/vyatta-config-gen-sets.pl
+++ b/scripts/vyatta-config-gen-sets.pl
@@ -32,7 +32,8 @@ my $conf_file = '/opt/vyatta/etc/config/config.boot';
$conf_file = $ARGV[0] if defined $ARGV[0];
# get a list of all config statement in the startup config file
-my @all_nodes = Vyatta::ConfigLoad::getStartupConfigStatements($conf_file);
+my %cfg_hier = Vyatta::ConfigLoad::getStartupConfigStatements($conf_file);
+my @all_nodes = @{ $cfg_hier{'set'} };
if (scalar(@all_nodes) == 0) {
# no config statements
exit 1;
diff --git a/scripts/vyatta-config-loader.pl b/scripts/vyatta-config-loader.pl
index 7a3df2b..0aae55b 100755
--- a/scripts/vyatta-config-loader.pl
+++ b/scripts/vyatta-config-loader.pl
@@ -46,7 +46,9 @@ sub restore_fds {
}
# get a list of all config statement in the startup config file
-my @all_nodes = Vyatta::ConfigLoad::getStartupConfigStatements($ARGV[0]);
+my %cfg_hier = Vyatta::ConfigLoad::getStartupConfigStatements($ARGV[0],'true');
+my @all_nodes = @{ $cfg_hier{'set'} };
+my @deactivate_nodes = @{ $cfg_hier{'deactivate'} };
if (scalar(@all_nodes) == 0) {
# no config statements
restore_fds();
@@ -72,11 +74,30 @@ foreach (@all_nodes) {
my ($path_ref, $rank) = @$_;
my @pr = @$path_ref;
- if (@pr[0] eq '!') {
- @pr = @pr[1..$#pr];
- my $deactivate_cmd = "$CWRAPPER deactivate " . (join ' ', @pr) . " 1>/dev/null";
- system("$deactivate_cmd");
- #ignore these errors due to nesting warnings.
+ if (@pr[0] =~ /^comment$/) {
+ my $ct = 0;
+ my $rel_path;
+ foreach my $rp (@pr[1..$#pr]) {
+ $ct++;
+ my $tmp_path = $rel_path . "/" . $rp;
+ my $node_path = "/opt/vyatta/share/vyatta-cfg/templates/" . $tmp_path . "/node.def";
+ if ($rp eq '"') {
+ last;
+ }
+ elsif ($rp eq '""') {
+ last;
+ }
+ elsif (!-e $node_path) {
+ #pop this element
+ delete @pr[$ct];
+ last;
+ }
+ $rel_path = $tmp_path;
+ }
+
+ my $comment_cmd = "$CWRAPPER " . join(" ",@pr) ;
+ `$comment_cmd`;
+ next;
}
my $cmd = "$CWRAPPER set " . (join ' ', @pr);
@@ -90,6 +111,13 @@ foreach (@all_nodes) {
# continue after set failure (or should we abort?)
}
}
+
+# Now deactivate these nodes
+for (@deactivate_nodes) {
+ my $cmd = "$CWRAPPER deactivate " . $_ . " 1>/dev/null";
+ system("$cmd");
+}
+
$ret = system("$commit_cmd");
if ($ret >> 8) {
print OLDOUT "Commit failed at boot\n";
diff --git a/scripts/vyatta-load-config.pl b/scripts/vyatta-load-config.pl
index ab5a47e..296dc0d 100755
--- a/scripts/vyatta-load-config.pl
+++ b/scripts/vyatta-load-config.pl
@@ -191,6 +191,7 @@ if ( scalar( keys %cfg_hier ) == 0 ) {
my %cfg_diff = Vyatta::ConfigLoad::getConfigDiff( \%cfg_hier );
my @set_list = @{ $cfg_diff{'set'} };
my @deactivate_list = @{ $cfg_diff{'deactivate'} };
+my @comment_list = @{ $cfg_diff{'comment'} };
if ($merge_mode eq 'false') {
my @delete_list = @{ $cfg_diff{'delete'} };
@@ -219,10 +220,45 @@ foreach (@set_list) {
}
foreach (@deactivate_list) {
- my ( $cmd_ref, $rank ) = @{$_};
- my @cmd = ( "$sbindir/vyatta-activate-config.pl deactivate", @{$cmd_ref} );
- my $cmd_str = join ' ', @cmd;
- system("$cmd_str 1>/dev/null");
+ #need to remove .disable nodes recursively in tree through activate command
+ my $cmd = "$sbindir/vyatta-activate-config.pl deactivate $_";
+ system("$cmd 1>/dev/null");
+ #ignore error on complaint re: nested nodes
+}
+
+foreach (@comment_list) {
+ my ( $cmd_ref ) = $_;
+ #apply comment if it doesn't have an empty element at the array and a .comment file exists and this is not a merge
+ if ($merge_mode eq 'false' && $cmd_ref =~ /\"\"$/) {
+ my @cmd_array = split(" ",$cmd_ref);
+ pop(@cmd_array);
+ my $rel_path = join '/', @cmd_array;
+ my $path = "/opt/vyatta/config/active/" . $rel_path . "/.comment";
+ if (-e $path) {
+ my @cmd = ( "$sbindir/vyatta-comment-config.pl ", $cmd_ref );
+ my $cmd_str = join ' ', @cmd;
+ system("$cmd_str 1>/dev/null");
+ }
+ else {
+ #not found, maybe a leaf?
+ pop(@cmd_array);
+ $rel_path = join '/', @cmd_array;
+ my $leaf = "/opt/vyatta/config/active/" . $rel_path . "/node.val";
+ if (-e $leaf) {
+ $path = "/opt/vyatta/config/active/" . $rel_path . "/.comment";
+ if (-e $path) {
+ my @cmd = ( "$sbindir/vyatta-comment-config.pl ", $cmd_ref );
+ my $cmd_str = join ' ', @cmd;
+ system("$cmd_str 1>/dev/null");
+ }
+ }
+ }
+ }
+ else {
+ my @cmd = ( "$sbindir/vyatta-comment-config.pl ", $cmd_ref );
+ my $cmd_str = join ' ', @cmd;
+ system("$cmd_str 1>/dev/null");
+ }
#ignore error on complaint re: nested nodes
}
diff --git a/src/cli_def.l b/src/cli_def.l
index 804d142..a7de87d 100644
--- a/src/cli_def.l
+++ b/src/cli_def.l
@@ -257,7 +257,7 @@ RE_TYPE_NAME (txt|u32|ipv4|ipv4net|ipv6|ipv6net|bool|macaddr)
/* values */
RE_VAL_U32 [0-9]+
RE_VAL_BOOL (true|false)
-RE_VAL_TEXT [a-zA-Z]+
+RE_VAL_PRIORITY (PARENT)
/* operators */
RE_OP_COND (==|!=|<|>|<=|>=|in)
@@ -445,7 +445,7 @@ RE_ACT_FIELD (help|syntax|commit|delete|update|activate|create|begin|end|comp_he
return VAR;
}
-<INITIAL,expression>{RE_VAL_TEXT} { return return_value(TEXT_TYPE); }
+<INITIAL,expression>{RE_VAL_PRIORITY} { return return_value(PRIORITY_TYPE); }
<INITIAL,expression>{RE_VAL_U32} { return return_value(INT_TYPE); }
<INITIAL,expression>{RE_IPV4} { return return_value(IPV4_TYPE); }
<INITIAL,expression>{RE_IPV4NET} { return return_value(IPV4NET_TYPE); }
diff --git a/src/cli_new.c b/src/cli_new.c
index f6a22ea..c4d1b86 100644
--- a/src/cli_new.c
+++ b/src/cli_new.c
@@ -206,23 +206,23 @@ void add_val(valstruct *first, valstruct *second)
{
assert (first->free_me && second->free_me);
assert(second->cnt == 0);
- if (first->val_type != second->val_type) {
- printf("Different types\n\n");
- } else {
- if (first->cnt%MULTI_ALLOC == 0) {
- /* convert into multivalue */
- first->vals = my_realloc(first->vals, (first->cnt + MULTI_ALLOC) *
- sizeof(char *), "add_value");
- if (first->cnt == 0) { /* single value - convert */
- first->vals[0] = first->val;
- first->cnt = 1;
- first->val = NULL;
- }
+ if (first->cnt%MULTI_ALLOC == 0) {
+ /* convert into multivalue */
+ first->vals = my_realloc(first->vals, (first->cnt + MULTI_ALLOC) *
+ sizeof(char *), "add_value 1");
+ first->val_types = my_realloc(first->val_types,(first->cnt + MULTI_ALLOC) *
+ sizeof(vtw_type_e), "add_value 2");
+ if (first->cnt == 0) { /* single value - convert */
+ first->vals[0] = first->val;
+ first->val_types[0] = first->val_type;
+ first->cnt = 1;
+ first->val = NULL;
}
- second->free_me = FALSE; /* we took its string */
- first->vals[first->cnt] = second->val;
- ++first->cnt;
}
+ second->free_me = FALSE; /* we took its string */
+ first->vals[first->cnt] = second->val;
+ first->val_types[first->cnt] = second->val_type;
+ ++first->cnt;
}
/*****************************************************
append - append node to the tail of list
@@ -697,7 +697,7 @@ valstruct str2val(char *cp)
/****************************************************
STATIC FUNCTIONS
****************************************************/
-int char2val_notext(vtw_def *def, int my_type, char *value, valstruct **valp, char *buf);
+int char2val_notext(vtw_def *def, int my_type, int my_type2, char *value, valstruct **valp, char *buf);
int char2val_text(vtw_def *def, char *value, valstruct **valp);
/**************************************************
@@ -731,18 +731,9 @@ int char2val(vtw_def *def, char *value, valstruct *valp)
//currently fails to handle mixed text + non-text case...
char buf1[2048];
- if (char2val_notext(def,my_type,value,&valp,buf1) != 0) {
- if (my_type2 != ERROR_TYPE) {
- char buf2[2048];
- if (char2val_notext(def,my_type2,value,&valp,buf2) != 0) {
- fprintf(out_stream,"%s%s",buf1,buf2);
- return -1;
- }
- }
- else {
- fprintf(out_stream,"%s",buf1);
- return -1; //only single definition
- }
+ if (char2val_notext(def,my_type,my_type2,value,&valp,buf1) != 0) {
+ fprintf(out_stream,"%s",buf1);
+ return -1; //only single definition
}
return 0;
}
@@ -753,13 +744,22 @@ int char2val(vtw_def *def, char *value, valstruct *valp)
//non-text type processing block
-int char2val_notext(vtw_def *def, int my_type, char *value, valstruct **valpp, char *err_buf)
+int char2val_notext(vtw_def *def, int my_type, int my_type2, char *value, valstruct **valpp, char *err_buf)
{
valstruct *valp = *valpp;
int token;
boolean first = TRUE;
cli_val_len = strlen(value);
cli_val_ptr = value;
+
+ char type_buf[256];
+ if (my_type2 != ERROR_TYPE) {
+ sprintf(type_buf,"%s or %s",type_to_name(my_type),type_to_name(my_type2));
+ }
+ else {
+ sprintf(type_buf,"%s",type_to_name(my_type));
+ }
+
while(1) {
token = yy_cli_val_lex();
@@ -774,19 +774,20 @@ int char2val_notext(vtw_def *def, int my_type, char *value, valstruct **valpp, c
print_msg("Wrong type of value in %s, "
"need %s\n",
m_path.path_buf + m_path.print_offset,
- type_to_name(my_type));
+ type_buf);
token = yy_cli_val_lex();
sprintf(err_buf, "\"%s\" is not a valid value of type \"%s\"\n",
- value, type_to_name(my_type));
+ value, type_buf);
}
return -1;
}
return 0;
}
- if (my_type != get_cli_value_ptr()->val_type) {
+ if (my_type != get_cli_value_ptr()->val_type &&
+ (my_type2 != ERROR_TYPE && my_type2 != get_cli_value_ptr()->val_type)) {
if (def->def_type_help){
set_at_string(value);
(void)expand_string(def->def_type_help);
@@ -795,12 +796,12 @@ int char2val_notext(vtw_def *def, int my_type, char *value, valstruct **valpp, c
print_msg("Wrong type of value in %s, "
"need %s\n",
m_path.path_buf + m_path.print_offset,
- type_to_name(my_type));
+ type_buf);
token = yy_cli_val_lex();
sprintf(err_buf, "\"%s\" is not a valid value of type \"%s\"\n",
- value, type_to_name(my_type));
+ value, type_buf);
}
my_free(get_cli_value_ptr()->val);
if (first) {
@@ -870,6 +871,7 @@ int char2val_text(vtw_def *def, char *value, valstruct **valpp)
cnt = (linecnt + MULTI_ALLOC - 1) / MULTI_ALLOC;
cnt *= MULTI_ALLOC;
valp->vals = my_malloc(cnt * sizeof(char *), "char2val 2");
+ valp->val_types = my_malloc(cnt * sizeof(vtw_type_e), "char2val 3");
for(cp = value, cnt = 0; cnt < linecnt; ++cnt) {
endp = strchr(cp, '\n');
if (endp)
@@ -914,8 +916,6 @@ boolean val_cmp(const valstruct *left, const valstruct *right, vtw_cond_e cond)
else
rstop = 1;
- DPRINT("val_cmp: type=%d count=(%d,%d) val=(%s,%s)\n",
- val_type, lstop, rstop, left->val, right->val);
for(lcur = 0; lcur < lstop; ++lcur) {
if (!lcur && !left->cnt)
lval = left->val;
@@ -947,6 +947,11 @@ boolean val_cmp(const valstruct *left, const valstruct *right, vtw_cond_e cond)
(void) sscanf(lval, format, left_parts, left_parts+1,
left_parts+2, left_parts+3, left_parts+4,
left_parts+5);
+
+ if ((rcur || right->cnt)
+ && right->val_types[rcur] != NULL) {
+ format = cond_formats[right->val_types[rcur]];
+ }
(void) sscanf(rval, format, right_parts, right_parts+1,
right_parts+2, right_parts+3, right_parts+4,
right_parts+5);
@@ -971,16 +976,21 @@ boolean val_cmp(const valstruct *left, const valstruct *right, vtw_cond_e cond)
res = 0;
}
done_comp:
- if(res > 0) res = 1;
- else if(res < 0) res = -1;
+ if (res > 0)
+ res = 1;
+ else if (res < 0)
+ res = -1;
+
ret = ((res == cond1[cond]) ||
(res == cond2[cond]));
+
if (ret && cond == IN_COND) {
set_in_cond_tik(rcur); /* for delete */
/* one success is enough for right cycle
in case of IN_COND, continue left cycle */
break;
}
+
if (!ret && cond != IN_COND)
/* one failure is enough in cases
other than IN_COND - go out */
@@ -1675,6 +1685,8 @@ void free_val(valstruct *val)
my_free(val->vals[cnt]);
if(val->vals)
my_free(val->vals);
+ if(val->val_types)
+ my_free(val->val_types);
}
/*****************************************************
free_string - dealloc string
diff --git a/src/cli_val.h b/src/cli_val.h
index e6182e7..00ed103 100644
--- a/src/cli_val.h
+++ b/src/cli_val.h
@@ -30,7 +30,8 @@ typedef enum {
MACADDR_TYPE,
DOMAIN_TYPE, /*end of addr types */
TEXT_TYPE,
- BOOL_TYPE
+ BOOL_TYPE,
+ PRIORITY_TYPE
}vtw_type_e;
typedef enum {
@@ -65,6 +66,7 @@ typedef struct {
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;
diff --git a/src/common/unionfs.c b/src/common/unionfs.c
index 151c6ce..2f7cd70 100644
--- a/src/common/unionfs.c
+++ b/src/common/unionfs.c
@@ -227,10 +227,10 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op)
//either multi or tag--shouldn't have made a difference, but arkady was confused.
vn->_config._multi = (def.tag | def.multi);
- if (def.def_tag > 0) {
+ if (def.def_tag != 0) {
vn->_config._limit = def.def_tag;
}
- else if (def.def_multi > 0) {
+ else if (def.def_multi != 0) {
vn->_config._limit = def.def_multi;
}
else {
diff --git a/src/delete.c b/src/delete.c
index f432934..4f38f54 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -322,8 +322,8 @@ int main(int argc, char **argv)
bye("Corrupted old value ---- \n%s\n-----\n", cp);
res = val_cmp(&new_value, &old_value, IN_COND);
if (!res) {
- fprintf(out_stream, "%s is not a configured value\n", new_value.val);
- bye("Not in multivalue");
+ fprintf(out_stream, "%s is not a configured value, %s\n", new_value.val,old_value.val);
+ bye("Not in multivalue");
}
touch();
if (old_value.cnt) {
diff --git a/src/set.c b/src/set.c
index 47db90c..08db114 100644
--- a/src/set.c
+++ b/src/set.c
@@ -93,7 +93,10 @@ boolean set_validate(vtw_def *defp, char *valp, boolean empty_val)
}
//apply limit count here, needs to be defined as a tag,multi and have a value set
- if ((defp->tag || defp->multi) && (defp->def_tag > 0 || defp->def_multi > 0)) {
+
+ //NOTE: changed behavior for def_tag==1. Needs signed 32 support in parser where -1
+ //represents embedded tag node... TODO
+ if ((defp->tag || defp->multi) && (defp->def_tag != 0 || defp->def_multi != 0)) {
//get count of siblings
char path[2048];
@@ -124,7 +127,7 @@ boolean set_validate(vtw_def *defp, char *valp, boolean empty_val)
}
closedir(dirp);
- if (defp->tag && file_count == 1 && defp->def_tag == 1) {
+ if (defp->tag && file_count == 1 && defp->def_tag < 0) {
//this is the special case, where the previous value should be deleted here...
char command[8192];
//let unionfs handle the diff
@@ -133,14 +136,34 @@ boolean set_validate(vtw_def *defp, char *valp, boolean empty_val)
}
if (defp->tag) {
- if (defp->def_tag > 1 && file_count >= defp->def_tag) {
- fprintf(out_stream,"Number of values exceeded for %s, allowed: %d, actual: %d\n",val,defp->def_tag,file_count);
+ if (defp->def_tag > 0 && file_count >= defp->def_tag) {
+ char *p = rindex(path,'/');
+ char tmp[2048];
+ if (p != NULL) {
+ int off = p - path;
+ strncpy(tmp,path + off + 1, strlen(path) - off - 1);
+ tmp[strlen(path) - off - 1] = '\0';
+ fprintf(out_stream,"Number of values exceeded for '%s', allowed: %d, actual: %d\n",tmp,defp->def_tag,file_count);
+ }
+ else {
+ fprintf(out_stream,"Number of values exceeded, allowed: %d, actual: %d\n",defp->def_tag,file_count);
+ }
return FALSE;
}
}
else {
if (defp->def_multi > 1 && file_count >= defp->def_multi) {
- fprintf(out_stream,"Number of values exceeded for %s, allowed: %d, actual: %d\n",val,defp->def_multi,file_count);
+ char *p = rindex(path,'/');
+ char tmp[2048];
+ if (p != NULL) {
+ int off = p - path;
+ strncpy(tmp,path + off + 1, strlen(path) - off - 1);
+ tmp[strlen(path) - off - 1] = '\0';
+ fprintf(out_stream,"Number of values exceeded for '%s', allowed: %d, actual: %d\n",tmp,defp->def_tag,file_count);
+ }
+ else {
+ fprintf(out_stream,"Number of values exceeded, allowed: %d, actual: %d\n",defp->def_tag,file_count);
+ }
return FALSE;
}
}