#!/usr/pkg/bin/gawk -f # function skipws(string) { sub(/^[ \t\r]+/, "", string); return (string); } function noctrl(string) { sub(/[ \t\r\n]+$/, "", string); return (string); } function decodeheader(line, header, c, name, attr, val) { delete header; if (match(line, /^[^ \t:]+:/) == 0) return (""); name = substr(line, 1, RLENGTH-1); line = skipws(substr(line, RLENGTH+1)); if (match(line, /[^;]*(;|$)*/) == 0) return (""); val = substr(line, 1, RLENGTH); sub(/[ \t]*;$/, "", val); header[""] = val; line = skipws(substr(line, RLENGTH+1)); while (line != "") { if (match(line, /^[-A-Za-z0-9]+=/) == 0) break; attr = substr(line, 1, RLENGTH-1); line = skipws(substr(line, RLENGTH+1)); if ((c = substr(line, 1, 1)) == "\"") { if (match(line, /^"[^"]*"([ \t]*;)?/) == 0) break; val = substr(line, 2); sub(/".*$/, "", val); line = skipws(substr(line, RLENGTH+1)); } else { if (match(line, /^[^;]*(;|$)/) == 0) break; val = substr(line, 1, RLENGTH); sub(/;[ \t]*$/, "", val); line = skipws(substr(line, RLENGTH+1)); } header[attr] = val; } name = tolower(name); return (name); } function readpart(b1, b2, i, name, header, var, val, filename, prevline, line) { var = ""; while (getline line > 0) { line = noctrl(line); if (line == "") break; if ((name = decodeheader(line, header)) != "") { if (name == "content-disposition") { var = header["name"]; filename = header["filename"]; if (filename != "") { sub(/^.*[\/\\]/, "", filename); sub(/^\.+/, "", filename); sub(/[^-+_\.A-Za-z0-9]/, "", filename); if (filename == "") { printf ("%s: empty filename: var= %s\n", program, var) >STDERR; exit (1); } } } } } if (line != "") { printf ("%s: broken input\n", program) >STDERR; exit (1); } else if (name == "") { printf ("%s: no varname found\n", program) >STDERR; exit (1); } if (filename == "") { val = ""; while (1) { if (getline line <= 0) { printf ("%s: broken input, var= %s\n", program, var) >STDERR; exit (1); } if (line == b1 || line == b2) break; val = val noctrl(line) "\002"; } } else { basename = filename; filename = sprintf ("%s/%s", workdir, filename); prevline = "\n"; while (1) { if (getline line <= 0) { printf ("%s: broken input, var= %s\n", program, var) >STDERR; exit (1); } if (line == b1 || line == b2) { sub(/\r$/, "", prevline); printf ("%s", prevline) >filename; break; } if (prevline != "\n") printf ("%s\n", prevline) >filename; prevline = line; } close (filename); } if (filename == "") printf ("%s var %s\n", var, val); else printf ("%s file %s %s\n", var, basename, filename); return (line); } 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"; program = "wiki-receiver"; argi = 1; workdir = nextarg("directory"); if (ENVIRON["CONTENT_TYPE"] == "") { printf ("%s: empty or unset content-type\n", program); exit (1); } line = sprintf("content-type: %s", ENVIRON["CONTENT_TYPE"]); name = decodeheader(line, header); if (name == "") { printf ("%s: error decoding header: %s\n", program, line); exit (1); } else if (header["boundary"] == "") { printf ("%s: empty or unset boundary: %s\n", program, line); exit (1); } boundary = "--" header["boundary"] "\r"; b2 = "--" header["boundary"] "--\r"; while (getline line > 0) { if (line == boundary) break; } while (1) { line = readpart(boundary, b2); if (line != boundary) break; } exit (0); }