httpd_index_cgi_example 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #!/bin/sh
  2. # This CGI creates directory index.
  3. # Put it into cgi-bin/index.cgi and chmod 0755.
  4. #
  5. # Problems:
  6. # * Unsafe wrt weird filenames with <>"'& etc...
  7. # * Not efficient: calls stat (program, not syscall) for each file
  8. # * Probably requires bash
  9. #
  10. # If you want speed and safety, you need to code it in C
  11. # Must start with '/'
  12. test "${QUERY_STRING:0:1}" = "/" || exit 1
  13. # /../ is not allowed
  14. test "${QUERY_STRING%/../*}" = "$QUERY_STRING" || exit 1
  15. test "${QUERY_STRING%/..}" = "$QUERY_STRING" || exit 1
  16. # Outta cgi-bin...
  17. cd .. 2>/dev/null || exit 1
  18. # Strip leading '/', go to target dir
  19. cd "${QUERY_STRING:1}" 2>/dev/null || exit 1
  20. f=`dirname "$QUERY_STRING"`
  21. test "$f" = "/" && f=""
  22. # Pipe thru dd (need to write header as single write(),
  23. # or else httpd doesn't see "Content-type: text/html"
  24. # in first read() and decides that it is not html)
  25. {
  26. printf "%s" \
  27. $'HTTP/1.0 200 OK\r\n'\
  28. $'Content-type: text/html\r\n\r\n'\
  29. "<html><head><title>Index of $QUERY_STRING</title></head>"$'\r\n'\
  30. "<body><h1>Index of $QUERY_STRING</h1><pre>"$'\r\n'\
  31. $'<table width=100%>\r\n'\
  32. $'<col><col><col width=0*>\r\n'\
  33. $'<tr><th>Name<th align=right>Last modified<th align=right>Size\r\n'\
  34. \
  35. "<tr><td><a href='$f/'>..</a><td><td>"$'\r\n'
  36. IFS='#'
  37. for f in *; do
  38. # Guard against empty dirs...
  39. test -e "$f" && \
  40. stat -c "%F#%s#%z" "$f" | {
  41. read type size cdt junk
  42. dir=''
  43. test "$type" = "directory" && dir='/'
  44. cdt="${cdt//.*}" # no fractional seconds
  45. cdt="${cdt// /&nbsp;}" # prevent wrapping around space
  46. printf "%s" "<tr><td><a href='$f$dir'>$f</a><td align=right>$cdt<td align=right>$size"$'\r\n'
  47. }
  48. done
  49. printf "</table></pre><hr></body></html>"$'\r\n'
  50. } | dd bs=4k