#!/bin/awk -f
#
#  Decode CGI form results for shell etc. processing.
#  Written in part by Jim Monty.

#  hex2dec:
#    Convert hexadecimal (base 16) to decimal (base 10)
#    - Excess parameters (1 actual parameter vs. 5 formal parameters)
#      are actually intended to create local variables for the function.
#    - Exotic operators not used in many awk programs:
#        %  Integer modulus:  largest even multiple
#        ^  Power: 16 ^ 0 is 1, 16 ^ 1 is 16, etc.
#    - index() and substr(): built in functions, search for
#      and extract substrings.  Character positions start at 1.
#
function hex2dec(x,    h, n, l, i) {
    h = "0123456789ABCDEF..........abcdef"
    for (i = l = length(x); i > 0; i--)
        n += (index(h, substr(x, i, 1)) - 1) % 16 * 16 ^ (l - i)
    return n
}

# dehex:
#   - Note that nstr is composed by concatenation,
#     expressions separated by only white space are
#     simply joined.
#
function dehex(string,     nstr, xstr, d) {
    xstr = string
    nstr = ""
    while (xstr) {
        d = match(xstr, "%[0-9A-Fa-f][0-9A-Fa-f]")
        if (d) {
            nstr = nstr substr(xstr, 1, d - 1) \
                   sprintf("%c", hex2dec(substr(xstr, d + 1, 2)))
            xstr = substr(xstr, d + 3)
        } else {
            nstr = nstr xstr
            xstr = ""
        }
    }
    return nstr
}

#  BEGIN:
#    -  Allow invoker to choose a value for "separator" on the
#       command line
BEGIN {
	if (!separator)
		separator = ":"
}

#  Default action:
#    -  gsub() and other built in functions operate on $0 by default.
#
{
	# Transform + to SP
	gsub("[+]", " ")
	# Transform & to separator (default :, set with -v separator=c)
	gsub("[&]", separator)
	# Delete presumably trailing CR.
	gsub("[\r]", "")

	print dehex($0)
}

# EOF
