summaryrefslogtreecommitdiffstats
path: root/plugins/sudoers/mkdefaults
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sudoers/mkdefaults')
-rwxr-xr-xplugins/sudoers/mkdefaults164
1 files changed, 164 insertions, 0 deletions
diff --git a/plugins/sudoers/mkdefaults b/plugins/sudoers/mkdefaults
new file mode 100755
index 0000000..885c1b5
--- /dev/null
+++ b/plugins/sudoers/mkdefaults
@@ -0,0 +1,164 @@
+#!/usr/bin/env perl
+#
+# 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
+
+use warnings;
+use strict;
+
+my ($header, $cfile, $infile);
+
+# 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";
+
+my $count = 0;
+my @tuple_values = ( "never" );
+my @records = ();
+my ($var, $type, $desc, $values, $callback, $field);
+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 my $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 (my $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 (my $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 (my $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);
+
+exit(0);
+
+sub print_record {
+ my ($rec, $recnum) = @_;
+ my ($i, $v, $defname);
+
+ # each variable gets a macro to access its value
+ $defname = "I_" . uc($rec->[0]);
+ printf HEADER "#define %-23s %d\n", $defname, $recnum;
+ 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_TIMESPEC/) { $v = "tspec"; }
+ elsif (/^T_TIMEOUT/) { $v = "ival"; }
+ else { die "$0: unknown defaults type: $_\n"; }
+ }
+ printf HEADER "#define %-23s (sudo_defs_table[$defname].sd_un.${v})\n",
+ "def_$rec->[0]";
+
+ 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";
+}