summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xnocompile/libexec/gopherd.sh36
-rw-r--r--src/bin/normalpath.c51
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;
+}