diff options
-rwxr-xr-x | nocompile/libexec/gopherd.sh | 36 | ||||
-rw-r--r-- | src/bin/normalpath.c | 51 |
2 files changed, 76 insertions, 11 deletions
diff --git a/nocompile/libexec/gopherd.sh b/nocompile/libexec/gopherd.sh index f627657..130d861 100755 --- a/nocompile/libexec/gopherd.sh +++ b/nocompile/libexec/gopherd.sh @@ -1,14 +1,23 @@ #!/bin/bash +#usage: $1 is the directory to be served over gopher. +# If a file is executable it is going to be used as a program. +# If there's a .header file in any directory it'll get printed +# before the directory listing. +# gopherd.sh tries to guess the hostname to use for people accessing the +# server (since there isn't a header for it like in HTTP). +# this requires rDNS records to be set correctly. +# Or you can just comment out that code and put a value at +# "export hostname" down there. export PATH=$PATH:/usr/local/bin read -t 10 req base="$1" arg=$(echo "$req" | tr -d '\r' | cut -f2) req=$(echo "$req" | tr -d '\r' | cut -f1) -realpath="$(readlink -f "${base}${req}")" +realpath="$(normalpath "${base}${req}")" if grep -v "^${base}" <<< "${realpath}" > /dev/null;then - echo ${base} - echo ${realpath} - echo 'error!!! cant find base in realpath' + echo -e 'i'${base}'\tasdf\tasdf\tasdf\r' + echo -e 'i'${realpath}'\tadsf\tasdf\tasdf\r' + echo -e 'ierror!!! cant find base in realpath\tasdf\tasdf\tasdf\r' exit 1 fi myIP=$(hop0 $(/usr/local/libexec/peerip | head -n1)) @@ -30,19 +39,17 @@ else fi export hostname export port=70 -type=$(file "${realpath}" | cut -d: -f2-) +type=$(file -L "${realpath}" | cut -d: -f2-) if strstr "$type" "directory";then if [ -e "${realpath}/.header" ];then - cat "${realpath}/.header" | while read -r l;do - printf "i%s\t%s\t%s\t%s\r\n" "$l" "fake" "(NULL)" "0" - done + awk '{print "i"$0"\tfake\t(NULL)\t0\r"}' "${realpath}/.header" fi ls "${realpath}" | while read i;do - stype=$(file "${realpath}/${i}" | cut -d: -f2-) + stype=$(file -L "${realpath}/${i}" | cut -d: -f2-) if strstr "$stype" "directory"; then printf "1%s\t%s\t%s\t%s\r\n" "${req}/${i}" "${req}/${i}" $hostname $port else - if stat "${realpath}/${i}" | cut '-d ' -f3 | grep x >/dev/null;then + if [ "_$(stat -L "${realpath}/${i}" | grep -v l | cut '-d ' -f3 | tr 'x' '\n' | wc -l | tr -d ' ')" = "_4" ] ;then printf "7%s\t%s\t%s\t%s\r\n" "${req}/${i}" "${req}/${i}" $hostname $port else printf "0%s\t%s\t%s\t%s\r\n" "${req}/${i}" "${req}/${i}" $hostname $port @@ -51,9 +58,16 @@ if strstr "$type" "directory";then done printf ".\r\n" else - if stat "${realpath}" | cut '-d ' -f3 | grep x >/dev/null;then +#this shit is ugly + numX="$(stat -L "${realpath}" | grep -v l | cut '-d ' -f3 | tr 'x' '\n' | wc -l | tr -d ' ')" + if [ "_$numX" = "_3" ];then + #an executable that outputs text and pretends to be a type 0. + "${realpath}" + elif [ "_$numX" = "_4" ];then + #a type 7 "${realpath}" $arg | sed "s/\$/"`printf "\r"`"/g" else + #output the text of the file cat "${realpath}" fi fi diff --git a/src/bin/normalpath.c b/src/bin/normalpath.c new file mode 100644 index 0000000..96f5506 --- /dev/null +++ b/src/bin/normalpath.c @@ -0,0 +1,51 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +int main(int argc,char *argv[]) { + int i,j,k,l; + char *s=argv[1]; + char *out=malloc(MAXPATHLEN+1); + switch(s[0]) { + case '/': + strcpy(out,"/"); + break; + case '~': + strcpy(out,(char *)getenv("HOME")); + break; + default: + getcwd(out,MAXPATHLEN); + strcat(out,"/"); + } + strcat(out,s); + l=strlen(out)-1; + if(out[l] == '.' && out[l-1] == '/') strcat(out,"/"); + if(out[l] == '.' && out[l-1] == '.' && out[l-2] == '/') strcat(out,"/"); + for(i=0;out[i];i++) { + if(out[i] == '/' && out[i+1] == '.' && out[i+2] == '.' && out[i+3] == '/') { + for(j=i-1;out[j] != '/';j--) { + } + for(k=j;out[k];k++) { + out[k]=out[k+(i-j)+3]; + } + i=0; + } + if(out[i] == '/' && out[i+1] == '.' && out[i+2] == '/') { + for(j=i;out[j];j++) { + out[j]=out[j+2]; + } + i=0; + } + if(out[i] == '/' && out[i+1] == '/') { + //leftshift over it. + for(j=i;out[j];j++) { + out[j]=out[j+1]; + } + i=0; + } + } + printf("%s\n",out); + return 0; +} |