From 464cedb474557f28b467164ae08bcb04a2d41ab3 Mon Sep 17 00:00:00 2001
From: KatolaZ <katolaz@freaknet.org>
Date: Thu, 19 Jul 2018 15:34:17 +0100
Subject: added support for different netcat versions

---
 README.md | 30 ++++++++++++++++++++++++-
 gosher    | 75 ++++++++++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 86 insertions(+), 19 deletions(-)

diff --git a/README.md b/README.md
index 15ac4f1..8b57ae0 100644
--- a/README.md
+++ b/README.md
@@ -9,13 +9,41 @@ You start the server using:
     $ ./gosher [<PORT> [<GOPHERDIR>]
 
 If PORT is not specified, it will bind on port 70. If GOPHERDIR is not
-provided, it defaults to "./".
+provided, it defaults to "./". Before starting `gosher` you might need
+to modify the values of the variables `NETCAT` and `STYLE` in `gosher`
+(see "Which netca?" below).
 
 If the selector is a directory, `gosher` will look for a file named
 `gophermap` to render the submenu. If a `gophermap` does not exist,
 `gosher` looks for the index.gph gopherfile in the folder and, if it
 exists, renders it as a gophermap.
 
+## Which netcat?
+
+There are currently several different implementations of `netcat`, and
+each of them works in a slightly different way and/or offers a different
+set of options. For the sake of using `gosher`, the main issue is
+whether your `netcat` implementation does exit or not when its standard
+input gets closed.  Notably, the original `netcat` implementation by
+hobbit@avian.org does **not** exit, while other common implementations
+(OpenBSD `netcat`, `ncat` from the nmap project, and GNU `netcat`).  The
+current version of `gosher` can work with different implementations of
+`netcat`, provided that the variable `NETCAT` points to the `netcat`
+version you want to use, and that the variable `STYLE` in `gosher` is set
+correctly. Please check below what is the recommended combination for
+your version of `netcat`:
+
+	+----------------+--------+
+	| netcat version | STYLE  |
+	+----------------+--------+
+	|  traditional   | 'fork' |
+	+----------------+--------+
+	|  OpenBSD       | 'pipe' |
+	+----------------+--------+
+	|  ncat          | 'pipe' |
+	+----------------+--------+
+
+	
 ## Why `gosher`?
 
 Just for fun. There are only a few TCP/IP application protocols left
diff --git a/gosher b/gosher
index 42fd49a..8203bf6 100755
--- a/gosher
+++ b/gosher
@@ -10,9 +10,9 @@
 ##  If PORT is not specified, the default is 70. If GOPHERDIR is not
 ##  specified, "./" is assumed
 ##
-##  
+##
 ##  (c) 2018 Vincenzo 'KatolaZ' Nicosia <katolaz@freaknet.org>
-##  
+##
 ##
 
 ######################
@@ -22,25 +22,49 @@
 ## server...
 ##
 
-NETCAT=netcat
+##
+## NETCAT: the netcat command to use, and any additional option
+##
+### Original netcat
+##NETCAT="nc.traditional"
+##
+### ncat (from nmap)
+##NETCAT="ncat"
+##
+### Openbsd netcat
+NETCAT="nc.openbsd"
+
+##
+## STYLE: The way in which netcat will talk to gosher_serve
+##
+### fork with "-c" (Does *not* work with OpenBSD netcat!!!!!)
+#STYLE='fork'
+##
+### use named pipes (Does *not* work with original netcat!!!!!)
+STYLE='pipe'
+
 OPREFIX=/tmp/outf_
 IPREFIX=/tmp/inf_
 
-##DEBUG=
-DEBUG=yes
+DEBUG=
+#DEBUG=yes
+
+
+[ -n "$DEBUG" ] && {
+	set -e
+	set -x
+}
 
 
 ## function
 cleanup(){
-	[ -p "${OPREFIX}$$" ] && rm -f ${OPREFIX}$$
-	[ -p "${IPREFIX}$$" ] && rm -f ${IPREFIX}$$
+	[ -n "$INF"  ] &&  [ -p "$INF"  ] && rm -f ${INF}
 	exit 1
-
 }
 
 MYNAME=$(basename $0)
 
-if [ -z "${MYNAME#gosher}" ]; then 
+if [ -z "${MYNAME#gosher}" ]; then
 	## we are called as gosher -- launch the server
 
 	PORT=${1:-70}
@@ -48,15 +72,23 @@ if [ -z "${MYNAME#gosher}" ]; then
 	
 	trap cleanup 0 HUP INT TRAP TERM QUIT
 	
-       	OUTF=${OPREFIX}$$
 	INF=${IPREFIX}$$
-	mkfifo -m 600 $OUTF $INF
-	while [ 1 -eq 1 ]; do
-		./gosher_serve ${GOPHERDIR} <$INF >$OUTF &
-		${NETCAT} -vv -l -p ${PORT} >$INF <$OUTF
-		ret=$?
-	done
-	exit 0
+	[ "$STYLE" = "pipe" ] && {
+		mkfifo -m 600 $INF
+		while [ 1 -eq 1 ]; do
+			./gosher_serve ${GOPHERDIR} <$INF | ${NETCAT} -vvvvv -l -p ${PORT} >$INF
+		done
+		rm -f $INF
+		exit 0
+	}
+	[ "$STYLE" = 'fork' ] && {
+		while [ 1 -eq 1 ]; do
+			${NETCAT} -vv -l -p $PORT -c "~/gosher_serve ${GOPHERDIR}"
+		done
+		exit 0
+	}
+	echo "Error!!! wrong STYLE specified!!!" >&2
+	exit 1
 fi
 
 
@@ -71,7 +103,9 @@ fi
 invalid_selector(){
 	sel="$1"
 	echo "3Error: Invalid selector: \"$sel\""
-	echo "."
+	printf ".\r\n"
+	exec 1>&-
+	exec 2>&-
 	exit 1
 }
 
@@ -80,6 +114,9 @@ serve_selector(){
 	sel="$1"
 
 	cat "${sel}"
+	echo "$0: selector $sel served -- exiting " >&2
+	exec 1>&-
+	exec 2>&-
 	exit 0
 }
 
@@ -104,6 +141,8 @@ serve_index(){
                 esac
         done < $IDX
 	printf ".\r\n"
+	exec 1>&-
+	exec 2>&-
 	exit 0
 }
 
-- 
cgit v1.2.3