#!/bin/sh # This CGI creates directory index. # Put it into cgi-bin/index.cgi and chmod 0755. # # Problems: # * Unsafe wrt weird filenames with <>"'& etc... # * Not efficient: calls stat (program, not syscall) for each file # * Probably requires bash # # If you want speed and safety, you need to code it in C # Must start with '/' test "${QUERY_STRING:0:1}" = "/" || exit 1 # /../ is not allowed test "${QUERY_STRING%/../*}" = "$QUERY_STRING" || exit 1 test "${QUERY_STRING%/..}" = "$QUERY_STRING" || exit 1 # Outta cgi-bin... cd .. 2>/dev/null || exit 1 # Strip leading '/', go to target dir cd "${QUERY_STRING:1}" 2>/dev/null || exit 1 f=`dirname "$QUERY_STRING"` test "$f" = "/" && f="" # Pipe thru dd (need to write header as single write(), # or else httpd doesn't see "Content-type: text/html" # in first read() and decides that it is not html) { printf "%s" \ $'HTTP/1.0 200 OK\r\n'\ $'Content-type: text/html\r\n\r\n'\ "Index of $QUERY_STRING"$'\r\n'\ "

Index of $QUERY_STRING

"$'\r\n'\
$'\r\n'\
$'\r\n'\
$'
NameLast modifiedSize\r\n'\ \ "
.."$'\r\n' IFS='#' for f in *; do # Guard against empty dirs... test -e "$f" && \ stat -c "%F#%s#%z" "$f" | { read type size cdt junk dir='' test "$type" = "directory" && dir='/' cdt="${cdt//.*}" # no fractional seconds cdt="${cdt// / }" # prevent wrapping around space printf "%s" "
$f$cdt$size"$'\r\n' } done printf "

"$'\r\n' } | dd bs=4k