#!/usr/bin/awk -f # The caller must pass arg: daemon-parm.txt# The resulting code is output into daemon-parm.h BEGIN { heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */\n\n" sect = psect = defines = accessors = prior_ptype = "" parms = "\nstatic const struct parm_struct parm_table[] = {" comment_fmt = "\n/********** %s **********/\n" tdstruct = "typedef struct {"} /^\s*$/ { next }/^#/ { next } /^Globals:/ { if (defines != "") { print "The Globals section must come first!" defines = "" exit } defines = tdstruct values = "\nstatic const all_vars Defaults = {\n { /* Globals: */\n" exps = exp_values = sprintf(comment_fmt, "EXP") sect = "GLOBAL" psect = ", P_GLOBAL, &Vars.g." next} /^Locals:/ { if (sect == "") { print "The Locals section must come after the Globals!" exit } defines = defines exps "} global_vars;\n\n" tdstruct values = values exp_values "\n }, { /* Locals: */\n" exps = exp_values = sprintf(comment_fmt, "EXP") sect = "LOCAL" psect = ", P_LOCAL, &Vars.l." next} /^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ { ptype = $1 name = $2 $1 = $2 = "" sub(/^[ \t]+/, "") if (ptype != prior_ptype) { comment = sprintf(comment_fmt, ptype) defines = defines comment values = values comment parms = parms "\n" accessors = accessors "\n" prior_ptype = ptype } if (ptype == "STRING" || ptype == "PATH") { atype = "STRING" vtype = "char*" } else if (ptype ~ /BOOL/) { atype = vtype = "BOOL" } else if (ptype == "CHAR") { atype = "CHAR" vtype = "char" } else { atype = "INTEGER" vtype = "int" } # The name might be var_name|public_name pubname = name sub(/\|.*/, "", name) sub(/.*\|/, "", pubname) gsub(/_/, " ", pubname) gsub(/-/, "", name) if (ptype == "ENUM") enum = "enum_" name else enum = "NULL" defines = defines "\t" vtype " " name ";\n" values = values "\t" $0 ", /* " name " */\n" parms = parms " {\"" pubname "\", P_" ptype psect name ", " enum ", 0},\n" # The shell-executed hook params (whose %RSYNC_*% expansion is fed to # /bin/sh) use the _SHELL accessor, which single-quotes peer-controlled # values to prevent injection. Ordinary string params must NOT quote -- # it would corrupt a documented `path = /home/%RSYNC_USER_NAME%` etc. if (atype == "STRING" && (name == "early_exec" || name == "prexfer_exec" || name == "postxfer_exec" || name == "name_converter")) accessors = accessors "FN_" sect "_STRING_SHELL(lp_" name ", " name ")\n" else accessors = accessors "FN_" sect "_" atype "(lp_" name ", " name ")\n" if (vtype == "char*") { exps = exps "\tBOOL " name "_EXP;\n" exp_values = exp_values "\tFalse, /* " name "_EXP */\n" } next} /./ { print "Extraneous line:" $0 defines = "" exit} END { if (sect != "" && defines != "") { defines = defines exps "} local_vars;\n\n" defines = defines tdstruct "\n\tglobal_vars g;\n\tlocal_vars l;\n} all_vars;\n" values = values exp_values "\n }\n};\n\nstatic all_vars Vars;\n" parms = parms "\n {NULL, P_BOOL, P_NONE, NULL, NULL, 0}\n};\n" print heading defines values parms accessors > "daemon-parm.h" } else { print "Failed to parse the data in " ARGV[1] exit 1 }}
#!/usr/bin/awk -f
# The caller must pass arg: daemon-parm.txt
# The resulting code is output into daemon-parm.h
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */\n\n"
sect = psect = defines = accessors = prior_ptype = ""
parms = "\nstatic const struct parm_struct parm_table[] = {"
comment_fmt = "\n/********** %s **********/\n"
tdstruct = "typedef struct {"
}
/^\s*$/ { next }
/^#/ { next }
/^Globals:/ {
if (defines != "") {
print "The Globals section must come first!"
defines = ""
exit
}
defines = tdstruct
values = "\nstatic const all_vars Defaults = {\n { /* Globals: */\n"
exps = exp_values = sprintf(comment_fmt, "EXP")
sect = "GLOBAL"
psect = ", P_GLOBAL, &Vars.g."
next
}
/^Locals:/ {
if (sect == "") {
print "The Locals section must come after the Globals!"
exit
}
defines = defines exps "} global_vars;\n\n" tdstruct
values = values exp_values "\n }, { /* Locals: */\n"
exps = exp_values = sprintf(comment_fmt, "EXP")
sect = "LOCAL"
psect = ", P_LOCAL, &Vars.l."
next
}
/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ {
ptype = $1
name = $2
$1 = $2 = ""
sub(/^[ \t]+/, "")
if (ptype != prior_ptype) {
comment = sprintf(comment_fmt, ptype)
defines = defines comment
values = values comment
parms = parms "\n"
accessors = accessors "\n"
prior_ptype = ptype
}
if (ptype == "STRING" || ptype == "PATH") {
atype = "STRING"
vtype = "char*"
} else if (ptype ~ /BOOL/) {
atype = vtype = "BOOL"
} else if (ptype == "CHAR") {
atype = "CHAR"
vtype = "char"
} else {
atype = "INTEGER"
vtype = "int"
}
# The name might be var_name|public_name
pubname = name
sub(/\|.*/, "", name)
sub(/.*\|/, "", pubname)
gsub(/_/, " ", pubname)
gsub(/-/, "", name)
if (ptype == "ENUM")
enum = "enum_" name
else
enum = "NULL"
defines = defines "\t" vtype " " name ";\n"
values = values "\t" $0 ", /* " name " */\n"
parms = parms " {\"" pubname "\", P_" ptype psect name ", " enum ", 0},\n"
# The shell-executed hook params (whose %RSYNC_*% expansion is fed to
# /bin/sh) use the _SHELL accessor, which single-quotes peer-controlled
# values to prevent injection. Ordinary string params must NOT quote --
# it would corrupt a documented `path = /home/%RSYNC_USER_NAME%` etc.
if (atype == "STRING" && (name == "early_exec" || name == "prexfer_exec" || name == "postxfer_exec" || name == "name_converter"))
accessors = accessors "FN_" sect "_STRING_SHELL(lp_" name ", " name ")\n"
else
accessors = accessors "FN_" sect "_" atype "(lp_" name ", " name ")\n"
if (vtype == "char*") {
exps = exps "\tBOOL " name "_EXP;\n"
exp_values = exp_values "\tFalse, /* " name "_EXP */\n"
}
next
}
/./ {
print "Extraneous line:" $0
defines = ""
exit
}
END {
if (sect != "" && defines != "") {
defines = defines exps "} local_vars;\n\n"
defines = defines tdstruct "\n\tglobal_vars g;\n\tlocal_vars l;\n} all_vars;\n"
values = values exp_values "\n }\n};\n\nstatic all_vars Vars;\n"
parms = parms "\n {NULL, P_BOOL, P_NONE, NULL, NULL, 0}\n};\n"
print heading defines values parms accessors > "daemon-parm.h"
} else {
print "Failed to parse the data in " ARGV[1]
exit 1
}
}