my $directive = shift; # presumed tainted
my $directive_file_contents = shift; # temporary scaffold
+ my @errors;
+
my %options = ( replace => undef );
my %header = ( version => undef, options => \%options,
package => undef, directory => undef, filename => undef );
if (scalar @versions == 1) {
$versions[0][1] =~ /^(\d+\.\d+)$/
- or fatal("invalid version $versions[0][1]",1,$directive_file_contents);
+ or push @errors, "invalid version $versions[0][1]";
my $val = $1; # so far so good
# We only support version 1.1/1.2 right now!
- fatal("invalid version $val, not supported",1,$directive_file_contents)
+ push @errors, "invalid version $val, not supported"
if (($val ne '1.1') and ($val ne '1.2'));
$header{version} = $val; # TODO: parse?
$info{"version"} = $val; #ok.
} elsif (scalar @versions > 1) {
- fatal("invalid multiple version elements",1,$directive_file_contents);
+ push @errors, "invalid multiple version elements";
} else { # no version at all; no longer allowed
# This will be caught later, when the operation list is validated.
}
} elsif ($tainted_cmd eq 'filename') {
# We use the same filename restrictions as scan_incoming
$tainted_val =~ /^($RE_filename_here)$/
- or fatal("invalid filename $tainted_val",1,$directive_file_contents);
+ or push @errors, "invalid filename $tainted_val";
my $val = $1; # so far so good
# Only let them specify one filename directive.
- fatal("Only one filename directive is allowed per directive file. "
- ."Error at filename directive: $val.",1,$directive_file_contents)
+ push @errors,
+ "Only one filename directive is allowed per directive file. "
+ ."Error at filename directive: $val."
if defined $header{filename};
$header{filename} = $val;
# already handled above
} elsif ($tainted_cmd eq 'symlink') {
$tainted_val =~ /^($RE_filename_relative)\s+($RE_filename_relative)$/
- or fatal("invalid parameters for symlink command: $tainted_val",
- 1,$directive_file_contents);
+ or push @errors,
+ "invalid parameters for symlink command: $tainted_val";
# $1 -- link target $2 -- link name
push @ops, [symlink => $1, $2];
$info{"symlink-$1"} = {"link" => $2, "order" => $cnt++}; #ok.
} elsif ($tainted_cmd eq 'rmsymlink') {
$tainted_val =~ /^($RE_filename_relative)$/
- or fatal("invalid parameters for rmsymlink command: $tainted_val",
- 1,$directive_file_contents);
+ or push @errors,
+ "invalid parameters for rmsymlink command: $tainted_val";
push @ops, [rmsymlink => $1];
$info{"rmsymlink-$1"} = {"order" => $cnt++}; #ok.
} elsif ($tainted_cmd eq 'archive') {
$tainted_val =~ /^($RE_filename_relative)$/
- or fatal("invalid parameters for archive command: $tainted_val",
- 1,$directive_file_contents);
+ or push @errors,
+ "invalid parameters for archive command: $tainted_val";
push @ops, [archive => $1];
$info{"archive-$1"} = {"order" => $cnt++}; #ok.
} elsif ($tainted_cmd eq 'replace') {
# This command is only supported from v1.2
$tainted_val =~ /^(true|false)$/
- or fatal("invalid parameters for replace command: $tainted_val",
- 1,$directive_file_contents);
+ or push @errors,
+ "invalid parameters for replace command: $tainted_val";
+
+ push @errors,
+ "invalid directive 'replace', not supported prior to version 1.2"
+ if $header{version} eq '1.1';
+
$options{replace} = ($1 eq 'true');
$info{"replace"} = $1; #ok.
} elsif ($tainted_cmd eq 'comment') {
push @ops, ['no-op'];
$info{'no-op'} = {order => $cnt++};
} else {
- fatal("Invalid directive line:\n\n $tainted_cmd $tainted_val",
- 1,$directive_file_contents);
+ push @errors, "Invalid directive line:\n\n $tainted_cmd $tainted_val";
}
if (!defined($install)
{ push @ops, ($install = [install => $header{filename}]) }
}
+ if (@errors) {
+ # TODO: eventually report all errors found
+ # for now, just report the first error, to emulate an immediate fatal()
+ fatal($errors[0],1,$directive_file_contents);
+ }
+
return \@ops;
}
my $ops = interpret_directive($directive, $directive_file_contents);
my $op_header = $ops->[0][1];
- if (exists($info{"replace"}) && ($info{"version"} eq '1.1')) {
- fatal("invalid directive 'replace', not supported prior to version 1.2",
- 1,$directive_file_contents);
- }
-
# Phone home. E-mail the contents of the directive file to the maintainer,
# for debugging purposes. After this point, we don't need to pass the
# $directive_file_contents to any subsequent fatal calls.
validate,bad-version "invalid version rejected"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
validate,bad-version "invalid version rejected"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
validate,bad-version-repeat "version key repeated"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
validate,bad-version-repeat "version key repeated"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
"directive file with bogus filename rejected"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
"directive file with repeated filename rejected"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
"directive file with ambiguous filename rejected"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}
"invalid replace flag value rejected"
} email-to {
ftp-upload-script@gnu.org foo@example.gnu.org
+ foo@example.org foo@example.net
}
}