#!/bin/bash
#
# This is a sample shell script for sFTP.  This script should be installed
# as either /usr/lib/sftp/sftp99default or /usr/local/lib/sftp/sftp99default.
# In addition, this shell script should also be linked as sftp98UNIX-nols-al
# in the same directory.
# sFTP searched these two directories as well as $HOME/.sftp for files
# starting with "sftp", when looking for a shell script to interpret certain
# remote FTP server replies.  When this shell script is run, its standard
# input, output, and error are pipes to the sFTP program.
#
# Args to this shell script:
#
#    $1 - What the server replied to SYST, "UNKNOWN" if server did not grok
#         the SYST command.
#
#    $2 - host name, as entered in the 'new' or 'open' connection dialog.
#         This lets me do host-specific processing
#
#    $3 - command to do, one of:
#         SYST - exit with code of 0 if we are willing to interpret this
#         host.  sFTP executes shell scripts in alphabetical order, so when
#         and it must find a shell script that exits with code of 0, otherwise
#         it will not run, therefore, this particular script, as sftp99default
#         will always return 0, and be the alphabetically last file in the
#         directory.
#
#         LIST - shell script should print the command to transfer directory
#         listing from the FTP server, then terminate with code of 0.
#
#         DIR - filter directory listing.  This is the biggie.  sFTP will
#         feed me the remote directory listing in whatever format it gets it
#         from the FTP server.
#
#         We have to reformat it into a very specific format: one file or
#         directory per line.  If this is a directory, the file has to be
#         followed by a "/" to indicate so.  "." and ".." do not have to
#         be included.
#
# This brings me to an important point.  Some FTP servers may not recognize
# the "-al" option to LIST.  They may either respond with an error message, or
# ignore the option and proceed to produce a "ls -aF" type listing.
# To fix this, the following trick is used.  $2 is set to the host name, when
# this script is invoked.  This script should be linked as either
# "sftp99default" or "sftp98UNIX-nols-al".  This script checks if it is
# invoked as "sftp98*".  If so, and the host name matches the host name
# that _YOU_ know exhibits this kind of a behavior, then we terminate with
# exit code of 0, thus causing this shell script to be always invoked as
# sftp98UNIX-nols-al.  Otherwise, the non-0 exit code will eventually
# cause this script to be run as sftp99default.
# When this script gets a LIST command, it checks if it was invoked as
# sftp98*, if so, we respond with a plain "LIST".
#
# However, we still have a case where the FTP server ignores the -al flags,
# and proceed to send me the a ls -aF type listing.  Therefore, this script
# will try to guess which output it is getting.  It will look at the first
# line of input.  If it looks like "[tT]otal ####" exactly, we assume a long
# listing, else we assume a short listing
#
# Symbolic links are shown as directories. >>>NOTE:  All filters MUST strip
# carriage returns!!!
#
#         COUNT - A reply from the FTP server is provided as input to the
#         shell.  This is the reply received after sending to the FTP
#         server the RETR command.  Try to extract the byte count of the
#         file being transferred from this message.  If the byte count is
#         identified, the shell script should print the byte count to standard
#         output.
#
#         CWD - We changed changed directories on the FTP server.  $4 was our
#         previous directory, as reported by PWD.  $5 is the SUBdirectory (this
#         script is not called after a CDUP) we just changed into.  The shell
#         script should echo on standard output what the name of the current
#         directory SHOULD be.  sftp uses it to detect symbolic links.
#
#
# You must enter a list of known stupid FTP servers over here

STUPID_SERVERS="stupidserver.net1.net stupidserver.net2.net"

case $3 in
SYST)
	case `basename $0` in
	sftp98*)
		for server in $STUPID_SERVERS
		do
			if [ "$server" = "$2" ]
			then
				echo "Generic UNIX driver, ls -al not supported ($1)"
				exit 0
			fi
		done
		exit 1
		;;
	esac

	echo "Generic UNIX driver ($1)"
	exit 0
	;;
LIST)
	case `basename $0` in
	sftp98*)
		echo "LIST";
		;;
	*)
		echo "LIST -al";
		;;
	esac
	exit 0
	;;

DIR)
	# Let's try to do it in one pipe, OK!!!!
	tr -d '\015' | tr '\011' ' ' | awk ' BEGIN {
			FORMAT="S"
			FIRSTLINE=1
			SKIPLINE=0
			}
		/^[^ \t]*:$/ && FIRSTLINE {
				FORMAT="L";
			}
		/^[Tt]otal *[0-9]+$/ && FIRSTLINE {
				FORMAT="L";
				SKIPLINE=1;
			}

		! SKIPLINE	{
				print FORMAT $0;
			}

			{
				SKIPLINE=0;
				FIRSTLINE=0;
			}
		' | sed '
# Long format - strip permission bits, #links

		s/^\(L.\)\(.........\)[ ]*/\1/
		s/^\(L.\)\([^ ][^ ]*\)[ ]*/\1/
		s/^\(L.\)\([^ ][^ ]*\)[ ]*/\1/
		s/^\(L.\)\([^ ][^ ]*\)[ ]*/\1/
		s/^\(L.\)\([^ ][^ ]*\)[ ]*/\1/

		' | tee $HOME/t2 | sed '

# Date/Time always fixed length, 13 chars
		s/^\(L.\)............./\1/
#
# Attempt to strip the name of the link
#
		s/^Ll\(.*\) ->.*/Ld\1/
#
# -l also can give us / or *, ('@' taken care of already)

		s/^\(L.*\)\/$/\1/
		s/^\(L.*\)\*$/\1/
#
# Remove FIFOs and sockets from both long and the short listing

		/\(.*\)=$/d
		/\(.*\)[\|]$/d
#
# Convert long listing to final listing
#
		s/^Ld\(.*\)/F\1\//
		s/^L.\(.*\)/F\1/
#
# For short listing, convert link to a directory, drop trailing *
#
		s/S\(.*\)@/S\1\//
		s/S\(.*\)\*/S\1/

		s/^.//
	'
	exit 0
	;;
COUNT)
	tr '\011' ' ' | sed '
		s/.*"//g
		s/^/X/
		s/^.*[^0-9]\([0-9][0-9]*\) *[bB]yte.*/Y\1/
		/^X/d
		s/^.//'
	exit 0
	;;
CWD)
	echo "$4/$5" | sed 's:^//:/:'
	exit 0
	;;
esac
exit 1
