1#!/bin/sh 2# 3# Generate sudo_defs_table and associated defines 4# 5# Input should be formatted thusly: 6# 7# var_name 8# TYPE 9# description (or NULL) 10# array of struct def_values if TYPE == T_TUPLE [optional] 11# *callback [optional] 12 13# Deal with optional -o (output) argument 14if [ "$1" = "-o" ]; then 15 OUTFILE="$2" 16 shift 2 17else 18 OUTFILE=def_data 19fi 20if [ $# -gt 0 ]; then 21 INFILE="$1" 22 shift 23else 24 INFILE=def_data.in 25fi 26if [ $# -gt 0 ]; then 27 echo "usage: $0 [-o output] [input_file]" 1>&2 28fi 29 30${AWK-awk} -f - -v outfile=$OUTFILE $INFILE <<'EOF' 31BEGIN { 32 tuple_values[0] = "never" 33 tuple_keys["never"] = 0 34 ntuples = 1 35 header = outfile ".h" 36 cfile = outfile ".c" 37 38 type_map["T_INT"] = "ival" 39 type_map["T_UINT"] = "uival" 40 type_map["T_STR"] = "str" 41 type_map["T_FLAG"] = "flag" 42 type_map["T_MODE"] = "mode" 43 type_map["T_LIST"] = "list" 44 type_map["T_LOGFAC"] = "ival" 45 type_map["T_LOGPRI"] = "ival" 46 type_map["T_TUPLE"] = "tuple" 47 type_map["T_TIMESPEC"] = "tspec" 48 type_map["T_TIMEOUT"] = "ival" 49} 50{ 51 sub(/#.*/, "", $0) 52 if (/^[[:blank:]]*$/) next 53 if (/^[[:alpha:]]/) { 54 # Store previous record and begin new one 55 if (var) 56 records[count++] = sprintf("%s\n%s\n%s\n%s\n%s\n", var, type, desc, values, callback) 57 var = $1 58 type = "" 59 desc = "" 60 values = "" 61 callback = "" 62 state = 0 63 } else { 64 state++ 65 # Strip leading/trailing whitespace 66 gsub(/^[ \t]+|[ \t]+$/, "") 67 if (state == 1) { 68 # type 69 type = $1 70 } else if (state == 2) { 71 # description 72 if ($0 == "NULL") { 73 desc = "NULL" 74 } else { 75 # Strip leading and trailing double quote and escape the rest 76 gsub(/^"|"$/, "") 77 gsub(/"/, "\\\"") 78 desc = sprintf("N_(\"%s\")", $0) 79 } 80 } else if (state == 3 || state == 4) { 81 if (/^\*/) { 82 callback = substr($0, 2) 83 } else { 84 if (type ~ /^T_TUPLE/) { 85 values = $0 86 # Add to tuple_values as necessary 87 n = split(values, vals) 88 for (i = 1; i <= n; i++) { 89 if (!(vals[i] in tuple_keys)) { 90 tuple_keys[vals[i]] = ntuples 91 tuple_values[ntuples++] = vals[i] 92 } 93 } 94 } 95 } 96 } else { 97 die("syntax error in input near line " NR) 98 } 99 } 100} 101END { 102 if (var) 103 records[count++] = sprintf("%s\n%s\n%s\n%s\n%s\n", var, type, desc, values, callback) 104 105 print "/* generated file, do not edit */\n" > header 106 print "/* generated file, do not edit */\n" > cfile 107 108 # Print out value arrays 109 for (i = 0; i < count; i++) { 110 split(records[i], fields, "\n") 111 if (fields[4]) { 112 if (fields[2] !~ /^T_TUPLE/) 113 die("Values list specified for non-tuple " records[1]) 114 printf "static struct def_values def_data_%s[] = {\n", fields[1] > cfile 115 n = split(fields[4], t) 116 for (j = 1; j <= n; j++) { 117 printf " { \"%s\", %s },\n", t[j], t[j] > cfile 118 } 119 print " { NULL, 0 }," > cfile 120 print "};\n" > cfile 121 } 122 } 123 124 # Print each record 125 print "struct sudo_defs_types sudo_defs_table[] = {\n {" > cfile 126 for (i = 0; i < count; i++) { 127 print_record(records[i], i) 128 } 129 print "\tNULL, 0, NULL\n }\n};" > cfile 130 131 # Print out def_tuple 132 print "\nenum def_tuple {" > header 133 for (i = 0; i < ntuples; i++) 134 printf "%s %s", i ? ",\n" : "", tuple_values[i] > header 135 print "\n};" > header 136} 137 138function die(msg) { 139 print msg > "/dev/stderr" 140 exit 1 141} 142 143function print_record(rec, recnum) { 144 split(rec, fields, "\n") 145 type = fields[2] 146 sub(/\|.*/, "", type) 147 if (!(type in type_map)) 148 die("unknown defaults type " fields[2]) 149 150 # each variable gets a macro to access its value 151 defname = "I_" toupper(fields[1]) 152 printf "#define %-23s %d\n", defname, recnum > header 153 printf "#define def_%-19s (sudo_defs_table[%s].sd_un.%s)\n", 154 fields[1], defname, type_map[type] > header 155 156 printf "\t\"%s\", %s,\n\t%s,\n", fields[1], fields[2], fields[3] > cfile 157 printf "\t%s,\n", fields[4] ? "def_data_" fields[1] : "NULL" > cfile 158 if (fields[5]) { 159 printf "\t%s,\n", fields[5] > cfile 160 } 161 print " }, {" > cfile 162} 163EOF 164