157 lines
3.9 KiB
Perl
Executable File
157 lines
3.9 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
#
|
|
# Generate sudo_defs_table and associated defines
|
|
#
|
|
# Input should be formatted thusly:
|
|
#
|
|
# var_name
|
|
# TYPE
|
|
# description (or NULL)
|
|
# array of struct def_values if TYPE == T_TUPLE
|
|
|
|
# Deal with optional -o (output) argument
|
|
if ($#ARGV > 0 && $ARGV[0] eq "-o") {
|
|
shift;
|
|
$header = $cfile = shift;
|
|
$header .= '.h';
|
|
$cfile .= '.c';
|
|
}
|
|
die "usage: $0 [input_file]\n" unless $#ARGV == -1 || $#ARGV == 0;
|
|
|
|
$infile = $ARGV[0] || "def_data.in";
|
|
if (!defined($header)) {
|
|
$header = $infile;
|
|
$header =~ s/(\.in)?$/.h/;
|
|
}
|
|
if (!defined($cfile)) {
|
|
$cfile = $infile;
|
|
$cfile =~ s/(\.in)?$/.c/;
|
|
}
|
|
|
|
open(IN, "<$infile") || die "$0: can't open $infile: $!\n";
|
|
open(HEADER, ">$header") || die "$0: can't open $header: $!\n";
|
|
open(CFILE, ">$cfile") || die "$0: can't open $cfile: $!\n";
|
|
|
|
$count = 0;
|
|
@tuple_values = ( "never" );
|
|
@records = ();
|
|
while(<IN>) {
|
|
chomp;
|
|
s/\s*#.*$//;
|
|
next if /^\s*$/;
|
|
|
|
if (/^\S/) {
|
|
# Store previous record and begin new one
|
|
$records[$count++] = [$var, $type, $desc, $values, $callback] if defined($var);
|
|
|
|
$var = $_;
|
|
$type = '';
|
|
$desc = undef;
|
|
$values = undef;
|
|
$callback = undef;
|
|
$field = 0;
|
|
} else {
|
|
$field++;
|
|
s/^\s+//;
|
|
s/\s+$//;
|
|
if ($field == 1) {
|
|
# type
|
|
$type = $_;
|
|
} elsif ($field == 2) {
|
|
# description
|
|
if ($_ eq "NULL") {
|
|
$desc = "NULL";
|
|
} else {
|
|
# Strip leading and trailing double quote and escape the rest
|
|
s/^"//;
|
|
s/"$//;
|
|
s/"/\\"/g;
|
|
$desc = "N_(\"$_\")";
|
|
}
|
|
} elsif ($field == 3 || $field == 4) {
|
|
if (s/^\*//) {
|
|
$callback = $_;
|
|
} else {
|
|
die "$0: syntax error near line $.\n" if $type !~ /^T_TUPLE/;
|
|
$values = [ split ];
|
|
foreach $v (@$values) {
|
|
push(@tuple_values, $v) unless grep(/^$v$/, @tuple_values);
|
|
}
|
|
}
|
|
} else {
|
|
die "$0: syntax error near line $.\n";
|
|
}
|
|
}
|
|
}
|
|
$records[$count++] = [$var, $type, $desc, $values, $callback] if defined($var);
|
|
|
|
# Print out value arrays
|
|
for ($i = 0; $i < $count; $i++) {
|
|
if (defined($records[$i]->[3])) {
|
|
die "Values list specified for non-tuple\n" unless
|
|
$records[$i]->[1] =~ /^T_TUPLE/;
|
|
printf CFILE "static struct def_values def_data_%s[] = {\n", $records[$i]->[0];
|
|
foreach (@{$records[$i]->[3]}) {
|
|
print CFILE " { \"$_\", $_ },\n";
|
|
}
|
|
print CFILE " { NULL, 0 },\n";
|
|
print CFILE "};\n\n";
|
|
}
|
|
}
|
|
|
|
# Print each record
|
|
print CFILE "struct sudo_defs_types sudo_defs_table[] = {\n {\n";
|
|
for ($i = 0; $i < $count; $i++) {
|
|
&print_record($records[$i], $i);
|
|
}
|
|
print CFILE "\tNULL, 0, NULL\n }\n};\n";
|
|
|
|
# Print out def_tuple
|
|
if (@tuple_values) {
|
|
print HEADER "\nenum def_tuple {\n";
|
|
for ($i = 0; $i <= $#tuple_values; $i++) {
|
|
printf HEADER "\t%s%s\n", $tuple_values[$i],
|
|
$i != $#tuple_values ? "," : "";
|
|
}
|
|
print HEADER "};\n";
|
|
}
|
|
|
|
close(IN);
|
|
close(HEADER);
|
|
close(CFILE);
|
|
|
|
sub print_record {
|
|
my ($rec, $recnum) = @_;
|
|
my ($i, $v, $defname);
|
|
# each variable gets a macro to access its value
|
|
for ($rec->[1]) {
|
|
if (/^T_INT/) { $v = "ival"; }
|
|
elsif (/^T_UINT/) { $v = "uival"; }
|
|
elsif (/^T_STR/) { $v = "str"; }
|
|
elsif (/^T_FLAG/) { $v = "flag"; }
|
|
elsif (/^T_MODE/) { $v = "mode"; }
|
|
elsif (/^T_LIST/) { $v = "list"; }
|
|
elsif (/^T_LOGFAC/) { $v = "ival"; }
|
|
elsif (/^T_LOGPRI/) { $v = "ival"; }
|
|
elsif (/^T_TUPLE/) { $v = "tuple"; }
|
|
elsif (/^T_FLOAT/) { $v = "fval"; }
|
|
else { die "$0: unknown defaults type: $_\n"; }
|
|
}
|
|
printf HEADER "#define %-23s (sudo_defs_table[$recnum].sd_un.${v})\n",
|
|
"def_$rec->[0]";
|
|
|
|
$defname = "I_" . uc($rec->[0]);
|
|
printf HEADER "#define %-24s%d", $defname, $recnum;
|
|
#print HEADER "\t/* $rec->[2] */" if defined($rec->[2]);
|
|
print HEADER "\n";
|
|
|
|
print CFILE "\t\"$rec->[0]\", $rec->[1],\n\t$rec->[2],\n";
|
|
if (defined($rec->[3])) {
|
|
printf CFILE "\tdef_data_$rec->[0],\n";
|
|
} else {
|
|
printf CFILE "\tNULL,\n";
|
|
}
|
|
printf CFILE "\t$rec->[4],\n" if defined($rec->[4]);
|
|
print CFILE " }, {\n";
|
|
}
|