diff options
Diffstat (limited to 'plugins/sudoers/mkdefaults')
-rwxr-xr-x | plugins/sudoers/mkdefaults | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/plugins/sudoers/mkdefaults b/plugins/sudoers/mkdefaults new file mode 100755 index 0000000..c1b9396 --- /dev/null +++ b/plugins/sudoers/mkdefaults @@ -0,0 +1,164 @@ +#!/bin/sh +# +# 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 [optional] +# *callback [optional] + +# Deal with optional -o (output) argument +if [ "$1" = "-o" ]; then + OUTFILE="$2" + shift 2 +else + OUTFILE=def_data +fi +if [ $# -gt 0 ]; then + INFILE="$1" + shift +else + INFILE=def_data.in +fi +if [ $# -gt 0 ]; then + echo "usage: $0 [-o output] [input_file]" 1>&2 +fi + +${AWK-awk} -f - -v outfile=$OUTFILE $INFILE <<'EOF' +BEGIN { + tuple_values[0] = "never" + tuple_keys["never"] = 0 + ntuples = 1 + header = outfile ".h" + cfile = outfile ".c" + + type_map["T_INT"] = "ival" + type_map["T_UINT"] = "uival" + type_map["T_STR"] = "str" + type_map["T_FLAG"] = "flag" + type_map["T_MODE"] = "mode" + type_map["T_LIST"] = "list" + type_map["T_LOGFAC"] = "ival" + type_map["T_LOGPRI"] = "ival" + type_map["T_TUPLE"] = "tuple" + type_map["T_TIMESPEC"] = "tspec" + type_map["T_TIMEOUT"] = "ival" + type_map["T_RLIMIT"] = "str" +} +{ + sub(/#.*/, "", $0) + if (/^[[:blank:]]*$/) next + if (/^[[:alpha:]]/) { + # Store previous record and begin new one + if (var) + records[count++] = sprintf("%s\n%s\n%s\n%s\n%s\n", var, type, desc, values, callback) + var = $1 + type = "" + desc = "" + values = "" + callback = "" + state = 0 + } else { + state++ + # Strip leading/trailing whitespace + gsub(/^[ \t]+|[ \t]+$/, "") + if (state == 1) { + # type + type = $1 + } else if (state == 2) { + # description + if ($0 == "NULL") { + desc = "NULL" + } else { + # Strip leading and trailing double quote and escape the rest + gsub(/^"|"$/, "") + gsub(/"/, "\\\"") + desc = sprintf("N_(\"%s\")", $0) + } + } else if (state == 3 || state == 4) { + if (/^\*/) { + callback = substr($0, 2) + } else { + if (type ~ /^T_TUPLE/) { + values = $0 + # Add to tuple_values as necessary + n = split(values, vals) + for (i = 1; i <= n; i++) { + if (!(vals[i] in tuple_keys)) { + tuple_keys[vals[i]] = ntuples + tuple_values[ntuples++] = vals[i] + } + } + } + } + } else { + die("syntax error in input near line " NR) + } + } +} +END { + if (var) + records[count++] = sprintf("%s\n%s\n%s\n%s\n%s\n", var, type, desc, values, callback) + + print "/* generated file, do not edit */\n" > header + print "/* generated file, do not edit */\n" > cfile + + # Print out value arrays + for (i = 0; i < count; i++) { + split(records[i], fields, "\n") + if (fields[4]) { + if (fields[2] !~ /^T_TUPLE/) + die("Values list specified for non-tuple " records[1]) + printf "static struct def_values def_data_%s[] = {\n", fields[1] > cfile + n = split(fields[4], t) + for (j = 1; j <= n; j++) { + printf " { \"%s\", %s },\n", t[j], t[j] > cfile + } + print " { NULL, 0 }," > cfile + print "};\n" > cfile + } + } + + # Print each record + print "struct sudo_defs_types sudo_defs_table[] = {\n {" > cfile + for (i = 0; i < count; i++) { + print_record(records[i], i) + } + print "\tNULL, 0, NULL\n }\n};" > cfile + + # Print out def_tuple + print "\nenum def_tuple {" > header + for (i = 0; i < ntuples; i++) + printf "%s %s", i ? ",\n" : "", tuple_values[i] > header + print "\n};" > header +} + +function die(msg) { + print msg > "/dev/stderr" + exit 1 +} + +function print_record(rec, recnum) { + split(rec, fields, "\n") + type = fields[2] + sub(/\|.*/, "", type) + if (!(type in type_map)) + die("unknown defaults type " fields[2]) + + # each variable gets a macro to access its value + defname = "I_" toupper(fields[1]) + printf "#define %-23s %d\n", defname, recnum > header + printf "#define def_%-19s (sudo_defs_table[%s].sd_un.%s)\n", + fields[1], defname, type_map[type] > header + + printf "\t\"%s\", %s,\n\t%s,\n", fields[1], fields[2], fields[3] > cfile + printf "\t%s,\n", fields[4] ? "def_data_" fields[1] : "NULL" > cfile + if (fields[5]) { + printf "\t%s,\n", fields[5] > cfile + } + print " }, {" > cfile +} +EOF |