#!/usr/bin/gawk -f # function stat(path, sbuf, gettime, cmd, line, filename, i, n, x, y, z) { cmd = sprintf ("/bin/ls -fld %s 2>/dev/null", path); cmd | getline line; close (cmd); if (split(line, x, /[ \t]+/) < 9) { # Less than 9 elements mean the item does not exist. return (1); } # # Take some data from the `ls' output. # sbuf["type"] = substr(x[1], 1, 1) == "d"? "dir": "file"; sbuf["perm"] = substr(x[1], 2); gsub(/\/+/, "/", x[9]); sbuf["filename"] = filename = x[9]; sbuf["size"] = x[5]; if (gettime != 0) { # # Try to compute the last-modification time. # 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 checkfile(basedir, path, sbuf, i, n, filename, x) { sbuf["path"] = path; # # 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.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. # if (match(sbuf["filename"], /\/\.$/) == 0) { sbuf["location"] = "/" path "/"; return (302); } } return (sbuf["type"]); } BEGIN { sbuf[""] = ""; while (getline line > 0) { delete sbuf; type = checkfile("/tmp", line, sbuf); printf ("%s: %s %s %d %s\n", line, type, sbuf["filename"], sbuf["size"], sbuf["lastmod"]); } }