#!/bin/sh dd=/bin/dd rm=/bin/rm tmp=/tmp/ddshttpd.$$ PATH='' . "$1" trap '$rm $tmp.? 2>/dev/null' 0 1 2 true () { return 0 } false () { return 1 } read cmd url proto cmd="`echo "$cmd" | $dd conv=ucase 2>/dev/null`" proto="`echo "$proto" | $dd conv=ucase 2>/dev/null`" head=false case "$proto" in HTTP/*) head=true ;; esac print_header () { if $head then echo "HTTP/1.0 $1 $2" echo "Server: ddshttpd/0.1" case "$4" in ?*) echo "Content-Type: $4" ;; *) echo "Content-Type: text/html" ;; esac case "$3" in ?*) echo "Content-Length: $3" ;; esac case "$5" in ?*) echo "Location: $5" ;; esac echo fi } case "$cmd" in GET) body=true ;; HEAD) body=false ;; *) print_header 501 "Bad command ($cmd)" echo "Bad command ($cmd)" exit 0 ;; esac urltofile () { case "$1" in *%*) echo "$1" > $tmp.1 relfile="" go=true ifs="$IFS" IFS='' exec 3<$charset read set0 <&3 read set1 <&3 read set2 <&3 read set3 <&3 read set4 <&3 read set5 <&3 read set6 <&3 read set7 <&3 read set8 <&3 read set9 <&3 read setA <&3 read setB <&3 read setC <&3 read setD <&3 read setE <&3 read setF <&3 IFS="$ifs" hex0=0 hex1=1 hex2=2 hex3=3 hex4=4 hex5=5 hex6=6 hex7=7 hex8=8 hex9=9 hexA=10 hexB=11 hexC=12 hexD=13 hexE=14 hexF=15 exec 3<$tmp.1 ;; *) relfile="$1" go=false ;; esac while $go do fst="`$dd of=$tmp.2 bs=1 count=1 <&3 2>&1`" case "$fst" in 0*) go=false ;; *) chr="`$dd bs=1 count=1 if=$tmp.2 2>/dev/null`" case "$chr" in %) fst="`$dd bs=1 count=1 conv=ucase 2>/dev/null <&3`" snd="`$dd bs=1 count=1 conv=ucase 2>/dev/null <&3`" case "$fst$snd" in 0A) chr=' ' ;; *) eval "set=\${set$fst:-\$set0}" eval "hex=\${hex$snd:-0}" chr="`echo "$set" | $dd bs=1 skip=$hex count=1 2>/dev/null`" ;; esac relfile="$relfile$chr" ;; *) relfile="$relfile$chr" ;; esac ;; esac done exec 3<&0 case "$relfile" in */) relfile="${relfile}index.html" ;; esac go=true while $go do case "$relfile" in '') relfile="/index.html" ;; .) relfile="/index.html" ;; ..) relfile="/index.html" ;; ./*) relfile="`echo "$relfile" | $dd bs=1 skip=2 2>/dev/null`" ;; ../*) relfile="`echo "$relfile" | $dd bs=1 skip=3 2>/dev/null`" ;; *) go=false ;; esac done file="$documentroot/$relfile" } urltofile "$url" check_directory () { case "$1" in */) ;; *) if cd "$file" >/dev/null 2>&1 then print_header 302 "Moved" "" "" "http://$hostname:$port$url/" echo "Is a directory: add a slash" exit 0 fi ;; esac } check_directory "$file" exec 2>/dev/null if exec 3<"$file" then : else print_header 404 "File not found" echo "File not found" exit 0 fi ifs="$IFS" IFS="+ " set `$dd bs=1 of=/dev/null if="$file" 2>&1` IFS="$ifs" len="$1" read_mime_table () { exec 3<$mimetypes smime='set_mime () { case "`echo $1 | $dd conv=lcase 2>/dev/null`" in ' while read type suff <&3 do set $suff co=true while $co do case "$#" in 0) co=false ;; *) smime="$smime *$1) mime='$type' ;; " shift ;; esac done done smime="$smime *) mime=text/plain ;; esac }" exec 3<&0 eval "$smime" } case "$relfile" in /ddsh-bin/*) exec "$file" "$relfile" "$url" "$proto" "$cmd" ;; *) read_mime_table set_mime "$relfile" print_header 200 "File follows" $len $mime if $body then $dd bs=1 if="$file" fi ;; esac