#!/usr/bin/gawk -f # BEGIN { program = "3q"; configdir = "/etc/" program; cfgsfx = "-" program ".conf"; magicext = "." program; allownoconfig = 1; # Use temporary files for the script. usefiles = 1; } function skipws(string) { sub(/^[ \t\r\n]+/, "", string); return (string); } function noctrl(string) { sub(/[ \t\r\n]+$/, "", string); return (string); } function shellquote(string) { gsub(/'/, "'\\''", string); string = "'" string "'"; return (string); } # requires gawk's 3.1.? PROCINFO array. function gettmpfile( s) { s = sprintf ("/var/tmp/3q-%04X-%02d.tmp", PROCINFO["pid"], ++ntmpfiles); tmpfile[ntmpfiles] = s; return (s); } function getval(name, val) { val = ""; if (name in var) val = var[name]; else val = ENVIRON[name]; return (val); } function getabspath(filename, dir) { if (substr(filename, 1, 1) != "/" && dir != "") filename = dir "/" filename; filename = rewritepath(filename); return (filename); } function makefilename(string, path, filename, i, n, q, x, z) { if (string ~ /^"[^"]+"$/ || string ~ /^'[^']+'$/) { filename = substr(string, 2, length(string) - 2); filename = getabspath(filename, workdir); } else { filename = string; filename = getabspath(filename, workdir); } return (filename); } function doinclude(cmd, fn, i, n, x) { fn = makefilename(fn); pushfile(fn); return (0); } function pushfile(filename) { if (filename in _inq) { printf ("%s: include loop detected: %s, line= %s\n", program, filename, getinputpos()) >>STDERR; return (1); } isp = isp + 1; inputfile[isp] = filename; _inq[filename] = 1; return (isp); } function nextline( line, data) { while (isp > 0) { if (getline line 0) { data = line; lineno[isp] += gsub(/\n/, "", data); return (line); } close (inputfile[isp]); delete _inq[inputfile[isp]]; isp--; } return ("<\001>"); } function getinputpos( s) { s = sprintf ("%s:%d", inputfile[isp], lineno[isp]); return (s); } function __readxml(item, k, mode, tag, sp, idx, data, line, tstack, lstack, x) { _ORS = RS; RS = ">"; sp = 0; while ((line = nextline()) != "<\001>") { if (lastmode == "pi" && substr(line, 1, 1) == "\n") line = substr(line, 2); lastmode = ""; if (mode == "cdata") { if (line ~ /\]\]$/) { sub(/\]\]$/, "", line); mode = ""; } item[idx] = item[idx] RT line; if (mode == "") item[idx, "raw"] = ""; continue; } else if (mode == "script") { if (line ~ /<\/SCRIPT/) mode = ""; item[idx] = item[idx] line; if (mode == "") item[idx, "raw"] = item[idx] ">"; continue; } else if (mode == "comment") { if (line ~ /--$/) { sub(/--$/, "", line); mode = ""; } item[idx] = item[idx] RT line; if (mode == "") { item[idx, "raw"] = ""; } continue; } else if (mode == "pi") { if (line ~ /\?$/) { sub(/\?$/, "", line); lastmode = "pi"; mode = ""; } item[idx] = item[idx] RS line; if (mode == "") item[idx, "raw"] = ""; continue; } else if (mode == "") { if ((k = index(line, "<")) != 1) { idx += 1; item[idx, "type"] = "data"; if (k == 0) { item[idx] = line; continue; } else { item[idx] = substr(line, 1, k - 1); line = substr(line, k); } } } if (line ~ /^ 0) { doinclude(x[1], noctrl(x[2])); continue; } idx += 1; item[idx, "raw"] = line RS; item[idx, "type"] = "pi"; line = substr(line, 3); if (line ~ /\?$/) { sub(/\?$/, "", line); lastmode = "pi"; } else mode = "pi"; item[idx] = line; continue; } idx += 1; item[idx, "raw"] = line ">"; if (substr(line, 1, 2) == ">STDERR; exit(1); } if (item[idx, "type"] == "begin") { sp += 1; tstack[sp] = tag; _here[sp] = idx; item[idx, "nattr"] = 0; } else if (item[idx, "type"] == "end") { if (tag != tstack[sp]) { printf ("%s: unexpected close tag: %s, line= %s, expected= %d\n", program, tag, getinputpos(), tstack[sp]) >>STDERR; exit(1); } item[idx, "begin"] = _here[sp]; item[_here[sp], "end"] = idx; sp -= 1; } sub(/[^ \r\n\t/]*[ \r\n\t]*/, "", line); if (line == "") continue; k = 0; while (line != "") { idx += 1; if (line == "/") { item[idx, "type"] = "end"; item[idx] = tag; item[_here[sp], "end"] = idx; item[idx, "begin"] = _here[sp]; sp -= 1; break; } if (match(line, /^([A-Za-z][-+_A-Za-z0-9]*)(=('[^'>]*'|"[^">]*"|[^ >]*))?(.*)$/, x) == 0) { printf ("%s: attribute format error: %s, line= %s\n", program, line, getinputpos()) >>STDERR; exit (1); } item[idx, "type"] = "attrib"; item[idx] = x[1]; if (x[2] == "") item[idx, "value"] = x[1]; else if (x[3] !~ /^['"]/) item[idx, "value"] = x[3]; else { item[idx, "value"] = substr(x[3], 2, length(x[3]) - 2); } item[_here[sp], "nattr"]++; line = x[4]; sub(/^[ \n\r\t]*/, "", line); } } RS = _ORS; return (idx); } function finalize(wantexit) { SCRIPT = "BEGIN {\n" SCRIPT; if (wantexit != 0) SCRIPT = SCRIPT "\n\texit (0);\n"; SCRIPT = SCRIPT "\t}\n"; return (0); } function addstring(string, encoded) { if (encoded == 0) SCRIPT = SCRIPT sprintf ("%s\n", string); else { gsub(/%/, "%%", string); gsub(/"/, "\\\"", string); gsub(/\n/, "\\n\\\n", string); SCRIPT = SCRIPT sprintf ("\tprintf(\"\\\n"); SCRIPT = SCRIPT sprintf ("%s\");\n", string); } return (0); } function addvar(var, val) { gsub(/\\/, "\\\\", val); gsub(/"/, "\\\"", val); gsub(/\n/, "\\\n", val); SCRIPT = SCRIPT sprintf ("\tENVIRON[\"%s\"] = \"%s\";\n", var, val); return (0); } function decode(s, i, n, x, y, p) { if (__decode_init == "") { n = split("&:amp <:lt >:gt", x, " "); for (i=1; i<=n; i++) { split(x[i], y, ":"); DECODE[y[2]] = y[1]; } } p = ""; while (match(s, /^([^&]*)&([a-z]+|#[0-9]+);(.*)$/, x) > 0) { c = x[2]; if (substr(c, 1, 1) == "#") c = sprintf ("%c", substr(c, 2)); else if (c in DECODE) c = DECODE[c]; else { printf ("%s: unknown char: &%s;\n", program, c) >>STDERR; exit (1); } p = p x[1] c; s = x[3]; } p = p s; return (p); } function process(filename, resp, i, k, m, n, sp, p, r, s, x, blockend, expr, type, item) { if (filename != "") pushfile(filename); n = __readxml(item); sp = 0; k = 1; while (k <= n) { p = item[k, "type"]; if (p == "pi" && match(item[k], /[ \t\r\n]*awk[ \t\r]*\n?(.*)/, x) > 0) { s = x[1]; while (match(s, /(^|\n)[ \t]*#use[ \t]+([^\n]+)[ \t]*\n?/, x) > 0) { fn = x[2]; LIBLIST = LIBLIST " -f " makefilename(fn, LIBPATH); #printf ("** use= %s\n", fn) >>STDERR; s = substr(s, 1, RSTART-1) substr(s, RSTART + RLENGTH); } while (match(s, /(^|\n)[ \t]*#header[ \t]+([A-Za-z][-A-Za-z0-9]*):?[ \t]+([^\n]+)[ \t]*\n?/, x) > 0) { p = x[2]; r = x[3]; resp[tolower(x[2])] = x[3]; #printf ("** header= %s: %s\n", x[2], x[3]) >>STDERR; s = substr(s, 1, RSTART-1) substr(s, RSTART + RLENGTH); } addstring(s, 0); k++; } else if (p == "begin" && tolower(item[k]) == "awk") { blockend = item[k, "end"]; expr = ""; type = ""; m = item[k, "nattr"]; for (i=1; i<=m; i++) { k++; if (item[k] == "if") type = item[k, "value"]; else if (item[k] == "expr") expr = decode(item[k, "value"]); } if (expr != "") { s = sprintf ("\tif (%s) {\t# %d\n", expr, blockend); addstring(s, 0); endif[++sp] = blockend; } } else if (p == "end" && tolower(item[k]) == "awk") { if (k == endif[sp]) { s = sprintf("\t\t}\t# %d\n", k); addstring(s, 0); sp--; } k++; } else { s = item[k, "raw"]; while (1) { if (k > n) break; p = item[k, "type"]; if (p == "pi" && match(item[k], /[ \t\r\n]*awk[ \t\r]*\n?(.*)/, x) > 0) break; else if (item[k] == "AWK" && (p == "begin" || p == "end")) break; if (p == "data") s = s item[k]; else s = s item[k, "raw"]; k++; } if (s != "") addstring(s, 1); } } return (0); } function __dump_xml() { for (i=1; i<=n; i++) { printf ("%4d %s %s", i, item[i, "type"], item[i]); if ((p = item[i, "type"]) == "begin") printf (" %d %d", item[i, "end"], item[i, "nattr"]); else if (p == "end") printf (" %d", item[i, "begin"]); else if (p == "attrib") printf (" %s", item[i, "value"]); if (item[i, "raw"] != "") printf (" `%s'", item[i, "raw"]); printf ("\n"); } exit (0); } # # HTTP/CGI Interface # function decodecgi(value, result, k, a, b, c) { HEX = "123456789ABCDEF"; result = ""; while ((k = index(value, "%")) > 0) { a = substr(value, k+1, 1); b = substr(value, k+2, 1); c = sprintf ("%c", index(HEX, a) * 16 + index(HEX, b)); result = result substr(value, 1, k-1) c; value = substr(value, k+3); } result = result value; return (result); } function getcgivars(string, i, k, n, v, w, x, list) { gsub(/\+/, " ", string); n = split(string, x, "&"); for (i=1; i<=n; i++) { if ((k = index(x[i], "=")) > 0) { v = "CGI_" toupper(substr(x[i], 1, k-1)); gsub(/-/, "_", v); w = decodecgi(substr(x[i], k+1)); if (v in var) var[v] = var[v] "," w; else { var[v] = w; list = list " " v; } } } # var["QUERY_PARAMETERS"] = substr(list, 2); var["CGIVARS"] = substr(list, 2); return (0); } # ------------------------------------------------------------------- function rewritepath(path, i, k, n, x, y) { n = split(path, x, /\/+/); k = 0; for (i=1; i<=n; i++) { if (x[i] == "") { if (i == n) y[k++] = ""; continue; } if (x[i] == ".") continue; else if (x[i] == "..") { if (k >= 1) k--; } else y[k++] = x[i]; } path = (substr(path, 1, 1) == "/"? "/": "") y[0]; for (i=1; i < k; i++) path = path "/" y[i]; return (path); } function stat(path, sbuf, gettime, cmd, line, filename, i, n, x, y, z) { cmd = sprintf ("/bin/ls -fld %s 2>/dev/null", path); # path is already quoted! ##printf ("cmd= %s\n", cmd) >>STDERR; cmd | getline line; close (cmd); if ((n = split(line, x, /[ \t]+/)) == 9) ; # ok - "old style" ls else if (n == 8 && x[6] ~ /-[0-9][0-9]-/) ; # also ok - "modern style" else { # other output means `does not exist'. return (1); } # # Take some data from the `ls' output. # sbuf["type"] = substr(x[1], 1, 1) == "d"? "dir": "file"; sbuf["perm"] = x[1]; gsub(/\/+/, "/", x[n]); sbuf["filename"] = filename = x[n]; ##printf ("filename= %s\n", filename) >>STDERR; sbuf["size"] = x[5]; if (gettime != 0) { # # Try to compute the last-modification time. # if (n == 8) { # # Yes, "modern style" simplyfies things. # split(x[6], z, "-"); split(x[7], y, ":"); line = sprintf ("%04d %02d %02d %02d %02d %02d", z[1], z[2], z[3], y[1], y[2], y[3]); } else { n = split("jan feb mar apr may jun jul aug sep oct nov dec", y, " "); for (i=1; i <= n; i++) z[y[i]] = sprintf ("%d", i); if (x[8] !~ /:/) line = sprintf ("%04d %02d %02d 00 00 00", x[8], z[tolower(x[6])], x[7]); else { split(x[8], y, ":"); line = sprintf ("%04d %02d %02d %02d %02d %02d", strftime("%Y", systime()), z[tolower(x[6])], x[7], y[1], y[2], y[3]); } } sbuf["rawtime"] = line; sbuf["mtime"] = mktime(line); sbuf["lastmod"] = strftime("%a, %d %b %Y %H:%M:%S %z", sbuf["mtime"]); } return (0); } function getmimetype(filename, type, ext) { sub(/^.*\//, "", filename); if (match(filename, /\.[^\.]+(\.gz)?/) == 0) { # No extension is `text/plain' type = "text/plain"; } else { ext = substr(filename, RSTART); sub(/\.gz$/, "", ext); # # Get MIME type for some well known extensions. # if (ext == magicext) type = "script"; else if (ext == ".w") type = "wrapper"; else if (ext == ".html" || ext == ".htm") type = "text/html"; else if (ext == ".txt" || ext == ".text") type = "text/plain"; else if (ext == ".gif") type = "image/gif"; else if (ext == ".jpg" || ext == ".jpeg") type = "image/jpg"; else if (ext == ".png") type = "image/png"; else if (ext == ".css") type = "text/css"; else if (ext == ".js") type = "text/javascript"; else if (ext ~ /\.cgi|\.pl/) type = "cgi"; else type = "application/octet-stream"; } return (type); } function checkfile(basedir, path, sbuf, i, n, filename, q, x) { sbuf["path"] = path; if (path == "") { sbuf["location"] = "/"; return (302); } # # Check if path refers to a dot-file and deny access. # if (path ~ /^\./ || path ~ /\/\./) return (403); # # Check if path contains any invalid characters. # if (path == "") ; # Refers to the "homepage". else if (path !~ /^[-_a-zA-Z0-9,+\.\/]+$/) return (403); # # As far as we know the request is valid. Does the requested # item exist and, if yes, what is it? # if (path != "" && path !~ /\/$/) filename = sprintf ("'%s/%s'", basedir, path); else { # # If the request points to a directory (trailing slash) # we have to look for a list of files. # n = split("index.3p index.html index.htm", x, " "); for (i=1; i <= n; i++) filename = filename " " sprintf ("'%s/%s/%s'", basedir, path, x[i]); filename = substr(filename, 2) " " sprintf("'%s/%s/.'", basedir, path); } if (stat(filename, sbuf, 1) != 0) return (404); # File not found. if (sbuf["type"] == "dir") { # # If the filename has a trailing dot it's a directory # without default file and the request was done with # a trailing slash. If not redirect. # if (match(sbuf["filename"], /\/\.$/) == 0) { sbuf["location"] = "/" path "/"; return (302); } } if (sbuf["type"] == "file") sbuf["mimetype"] = getmimetype(sbuf["filename"]); if (sbuf["mimetype"] == "cgi") sbuf["script"] = sbuf["filename"]; sbuf["workdir"] = sbuf["filename"]; if (sbuf["type"] == "dir") { sub(/\/\.$/, "", sbuf["workdir"]); } else { sub(/\/[^\/]*$/, "", sbuf["workdir"]); } return (sbuf["type"]); } # ------------------------------------------------------------------- function httpheader(code, message, type, resp, u, v, w) { # printf ("HTTP/1.0 %03d %s\r\n", code, message); printf ("Status: %03d\r\n", code); if (type != "") { if (tolower(type) ~ /text\/[a-z]+$/) type = type "; charset=\"iso-8859-1\""; printf ("Content-type: %s\r\n", type); } for (w in resp) { # Beautify header names. if (w == "" || tolower(w) == "content-type") continue; u = toupper(substr(w, 1, 1)) tolower(substr(w, 2)); v = ""; while (match(u, /-[a-z]/) > 0) { v = substr(u, 1, RSTART) toupper(substr(u, RSTART+1, 1)); u = substr(u, RSTART+2); } v = v u; printf ("%s: %s\r\n", v, resp[w]); } printf ("\r\n"); RESPONSE["status"] = code; RESPONSE["content-type"] = type; return (0); } function starthtml(title, printbody) { printf ("\n"); printf ("\n"); printf (" %s\n", title); printf ("\n"); if (printbody != 0) printf ("\n"); return (0); } function endhtml() { printf ("\n"); printf ("\n"); return (0); } function senderror(code, message, resp) { if (message == "" && match(code, / /) > 0) { message = substr(code, RSTART+1); code = code + 0; } httpheader(code, message, "text/html", resp); starthtml(message, 1); printf ("Request: %s
\n", ENVIRON["PATH_INFO"]); printf ("Status: %s %s
\n", code, message); endhtml(); return (0); } function sendredirect(code, location, sbuf, resp, message) { location = getredir(location, sbuf); resp["location"] = location; message = "Item moved"; httpheader(code, message, "text/html", resp); starthtml(message, 1); printf ("%s %s: %s
\n", code, message, location); endhtml(); return (0); } function sendresponse(status, sbuf, resp) { #printf ("status= %d\n", status) >>STDERR; if (status == 204) { httpheader(status, "OK, no content", "", resp); } else if (status == 301 || status == 302) { if (resp["location"] != "") sbuf["location"] = resp["location"]; sendredirect(302, sbuf["location"], sbuf, resp); } else if (status == 403) senderror(status, "Access denied"); else if (status == 404) senderror(status, "File not found"); else if (status == 415) senderror(status, "Item or service unavailable"); else senderror(500, "Server error"); sbuf["size"] = 0; sbuf["mimetype"] = "text/html"; exit (0); } function runcgi(script, sbuf, resp, status, cmd, line, p, v, x, data, dd) { status = 0; # # Construct the shell command, pass parameters as environment # variables. # cmd = sprintf ("cd %s && /usr/bin/env", shellquote(workdir)); for (v in var) { p = v; sub(/^%/, "_", p); if (p ~ /^[_a-zA-Z]/) { cmd = cmd " " p "=" shellquote(var[v]); } } cmd = cmd " " script; printf ("") |& cmd; close(cmd, "to"); status = 200; if (resp["content-type"] == "") resp["content-type"] = "text/html"; while (cmd |& getline line > 0) { ##printf ("resp: %s\n", line) >>STDERR; if (line == "") break; if (match(line, /^([^:]+): (.*)$/, x) == 0) { data = line RT; break; } if (tolower(x[1]) == "status") status = x[2] + 0; else resp[tolower(x[1])] = x[2]; } SRS = RS; RS = "\567"; while (cmd |& getline line > 0) data = data line RT; RS = SRS; sbuf["data"] = data; #printf ("content: %s\n", resp["content-type"]) >>STDERR; close (cmd); if (status == 0) status = "501"; return (status); } #ifdef WITH_IPACL function ipval(str, i, n, x, val) { if ((n = split(str, x, ".")) != 4) return (0); val = x[1]+0; for (i=2; i<=4; i++) val = lshift(val, 8) + x[i]; return (val); } function ipmask(str, val) { if (index(str, ".") == 0) { str = str + 0; if (str < 0 || str > 32) str = 32; val = (str == 0)? 0: lshift(compl(0), 32 - str); } else { val = ipval(str); if (val == 0) val = compl(0); } return (val); } function checkacl(ipnum, acllist, allow, c, i, n, p, q, r, s, x, ip, mask) { ipnum = ipval(ipnum); allow = q = 0; n = split(skipws(noctrl(acllist)), x, /[ \t,]+/); for (i=1; i<=n; i++) { if ((p = x[i]) == "") continue; c = ""; if (substr(p, 1, 1) == "-") { c = "-"; p = substr(p, 2); } if ((k = index(p, "/")) == 0) { ip = ipval(p); mask = ipmask(32); } else { ip = ipval(substr(p, 1, k-1)); mask = ipmask(substr(p, k+1)); } r = and(ip, mask); s = or(ip, compl(mask)); ##printf ("p= %s, , ip= %08X, mask= %08X, r= %d, s= %d\n", p, ip, mask, r, s) >>STDERR; if (q == 0 || (s - r) < q) { if (r <= ipnum && ipnum <= s) { allow = (c == "-")? 0: 1; q = s - r; } } } return (allow); } #endif function readconfig(dir, config, mainconfig, filename, n, p, line, lines) { if (mainconfig != 0) { configname = (config == "")? "main": config; var["%CONFIG"] = configname; } filename = sprintf ("%s/%s%s", dir, configname, cfgsfx); lines = 0; while (getline 0) { $0 = noctrl($0); lines++; sub(/(^|[ \t]+)#.*$/, "", $0); if ($0 == "") continue; if ($1 == "dir" && mainconfig != 0) basedir = $2; else if ($1 == "env" || $1 == "set") { p = $2; $1 = $2 = ""; var[p] = skipws($0); } #ifdef WITH_IPACL else if ($1 == "allow") { $1 = ""; acllist = acllist " " $0; } else if ($1 == "deny") { for (i=2; i<=NF; i++) acllist = acllist " " "-" $i; } #endif else printf ("%s: unknown configuration option: %s\n", program, $1) >>STDERR; } close (filename); if (mainconfig != 0) { if (lines == 0) { if (allownoconfig == 1 && config == "") { var["%CONFIG"] = configname = ""; basedir = ENVIRON["DOCUMENT_ROOT"]; return (0); } senderror(200, "No such configuraion: " configname); exit (0); } configfile = filename; } return (0); } function getredir(location, sbuf, p) { if (location ~ /:\/\//) return (location); else if (substr(location, 1, 2) == "//") return (substr(location, 2)); p = ENVIRON["SCRIPT_NAME"]; if (config != "") p = p "/-" config; if (substr(location, 1, 1) != "/") location = sbuf["basedir"] "/" location; p = p location; gsub(/\/+/, "/", p); return (p); } function nextarg(par, arg) { if (argi >= ARGC) { printf ("%s: missing argument: %s\n", program, par) >STDERR; exit (1); } arg = ARGV[argi]; ARGV[argi++] = ""; return (arg); } BEGIN { STDERR = "/dev/stderr"; OUTPUT = "/dev/stdout"; argi = 1; while (argi < ARGC && substr(ARGV[argi], 1, 1) == "-") { options = nextarg("option"); if (options == "--") break; for (i = 2; i<=length(options); i++) { c = substr(options, i, 1); if (c == "d") debug = 1; else if (c == "p") { fn = nextarg("filename"); debug = "file"; } else { printf ("%s: unkown option: -%s\n", program, c) >STDERR; exit (1); } } } var["INCLUDE"] = var["INCLUDE"] ":" ENVIRON["INCLUDE"]; if (debug == "file") { workdir = fn; sub(/[^\/]*$/, "", workdir); if (workdir == "") workdir = "."; process(fn, resp); finalize(); printf ("%s\n", SCRIPT); exit (0); } path = ENVIRON["PATH_INFO"]; path = rewritepath(path); sbuf[""] = resp[""] = ""; var["%PATH"] = path; var["%BASEADR"] = ENVIRON["SCRIPT_NAME"]; # # Read options from URL # config = ""; if (match(path, /^\/-[^\/]*\//)) { options = substr(path, RSTART+2, RLENGTH-3); path = substr(path, RSTART+RLENGTH-1); n = split(options, x, configdelim); config = x[1]; for (i=2; i<=n; i++) { if (match(x[i], /^([a-z][a-z0-9]*)=(.*)$/, y) > 0) opt[y[1]] = y[2]; options = options "," x[i]; } } # # Read configuration # var["_BASEADR"] = BASEADR; readconfig(configdir, config, 1); #ifdef WITH_IPACL if (acllist != "") { if (checkacl(ENVIRON["REMOTE_ADDR"], acllist, 0) == 0) { senderror(403, "Access denied."); exit (0); } } #endif # # Get CGI variables # if (ENVIRON["REQUEST_METHOD"] == "POST") { if (ENVIRON["CONTENT_TYPE"] ~ /^multipart\/form-data/) ; else { cmd = sprintf ("dd bs=1 count='%d' 2>/dev/null", ENVIRON["CONTENT_LENGTH"]); cmd | getline POSTDATA; close(cmd); getcgivars(POSTDATA); } } else { if (ENVIRON["QUERY_STRING"] != "") { getcgivars(ENVIRON["QUERY_STRING"]); } } # # Locate the requested file relative to the base directory. # type = checkfile(basedir, path, sbuf); if (type+0 > 0) sendresponse(type, sbuf, resp); workdir = var["_WORKDIR"] = sbuf["workdir"]; var["_FILENAME"] = sbuf["filename"]; resp[""] = ""; # Initialise as array mimetype = sbuf["mimetype"]; if (mimetype == "script") { # # Process the file ... # pushfile(sbuf["filename"]); process("", resp); # # ... and execute the resulting script. # finalize(1); if (usefiles != 0) { var["_SCRIPTFILE"] = fn = gettmpfile(); printf ("%s\n", SCRIPT) >fn; close (fn); var["_TMPFILE"] = gettmpfile(); SCRIPT = ""; for (v in var) addvar(v, var[v]); finalize(0); vs = gettmpfile(); printf ("%s\n", SCRIPT) >vs; close (vs); cmd = sprintf ("gawk %s -f %s -f %s", LIBLIST, vs, fn); } else { cmd = sprintf ("gawk %s --source %s", LIBLIST, shellquote(SCRIPT)); } rc = runcgi(cmd, sbuf, resp); if (rc != 200 && rc != 503) sendresponse(rc, sbuf, resp); httpheader(rc, "OK", resp["content-type"], resp); printf ("%s", sbuf["data"]); } else if (mimetype == "wrapper") { pushfile(sbuf["filename"]); process("", resp); httpheader(200, "OK", resp["content-type"], resp); printf ("%s", SCRIPT); } else if (mimetype == "cgi") { rc = runcgi(sbuf["filename"], sbuf, resp); if (rc != 200) sendresponse(rc, sbuf, resp); httpheader(rc, "OK", resp["content-type"], resp); printf ("%s", sbuf["data"]); } else { httpheader(200, "OK", mimetype, resp); filename = sbuf["filename"]; while (getline line 0) printf ("%s%s", line, RT); close (filename); } exit (rc); } END { if (ntmpfiles > 0) { for (i=1; i<=ntmpfiles; i++) list = list " " shellquote(tmpfile[i]); cmd = "rm -f " list; #printf ("** cmd= %s\n", cmd) >>STDERR; system(cmd); } }