#!/bin/sh -u # Usage: kermit-upload [localname|-] [-[a|A] remotename] [option ...] # # Note that the sense of "local" and "remote" as used herein is always # with respect to the `kermit' process(es) run by this script # (the sole exceptions being some `echo'ed message text intended to be read # and interpretted by the user of the `kermit' on the other side). # # If there is no localname, '-' is assumed ('-' is interpretted as STDOUT); # otherwise, the first argument is taken as the name of the file to fetch # (unless it looks like an option). # # If an alternate remotename is specified, '-a' (or '-A') must be the FIRST # option; otherwise, a remotename is solicited iff STDERR is a tty # (the default is `basename "$1"`, but this default is inhibited if # "$1" =~ '/tmp/*' or "$1" =~ '/usr/tmp/*' or "$1" =~ '/var/tmp/*' # in order to benefit `pine'). # # Only one of '-a remotename' or '-A remotename' may be specified; either may # specify a remote directory path (if it ends in any of [:\/]) or a remote # filename (which will be considered fully qualified it contains any of [:\/]). # Specifying '-a remotename' suppresses any interactive solicitation of a # remotename; '-A remotename' permits the interactive solicitation of a # remotename (if STDERR is a tty) and is used as the default remotename if the # solicited remotename is nil (or if such solicitation is not possible). # # In any case, if the resulting remotename is a directory path (ending in any # of [:\/]), the basename of the local file (or 'stdin' if localname is nil) # is suffixed to form a complete remote filename. # # Note that '-a' is a standard `kermit' option, but may here also just specify # a remote path; '-A' is NOT a standard `kermit' option, and works as follows: # -A remotename Handled like '-a remotename' if STDERR is not a tty; # otherwise, a remotename is interactively solicited # (the specified remotename is used if the input is nil). # If the specified remotename is a directory path, it will # be prefixed to any unqualified input filename; any qualified # input will be interpretted as the remote filename or as the # remote directory path (suffixed with the local filename). # Note: No attempt is made to replace the basename component of a # specified remotename with an unqualified input filename # (the interactive solicitations should make this clear). # Also note that -a (although a standard `kermit' option) is NOT interpretted # here in the way `kermit' would normally handle it (i.e., the local filename); # -a (or -A) is used here to identify the alternate remote filename (or path) # [making the use of -a (and -A) consistent with the `kermit-download' script; # if this becomes too confusing, this sucker can be re-designed!]. # # If '-a remotename' is NOT specified, a remote filename is solicited provided # that STDERR is a tty (null input uses the displayed default and care it taken # to permit ALL characters in the input -- but '\\' for '\' is required here!); # otherwise, an appropriate default remote filename is used (if one exists) or # `kermit' is invoked in a way that allows the remote user to select the file. # # All interactive output is to STDERR, and any interactive input from /dev/tty. # Note that `kermit' pretty much requires that STDIN and/or STDOUT be /dev/tty # (in order to effectively communicate with the other remote `kermit' process!) # but unfortunately makes little (if any) use of either STDERR or /dev/tty # in order to directly communicate with the user of the local `kermit' process. # Particulary problematic is "textual" output by the local `kermit' to /dev/tty # (or to STDOUT or STDERR if either is underlyingly /dev/tty) or input from # the remote `kermit' from /dev/tty (or STDIN if it's underlyingly /dev/tty) # while any file transfer is in progress. It's grim, folks! # In particular, `kermit' offers no helpful advice if either STDIN or STDOUT # in not a tty (this appears unnecessarily conservative in many cicumstances). # Where necessary and possible, I/O redirection is forced within this script, # and advice if offered (to STDERR) in cases where `kermit' would offer none. # # In any case, both the local and remote filenames are determined and passed # (along with any additional option arguments) to `kermit' as follows: # If neither localname nor remotename: # echo "Return to your local Kermit and give a SEND command." >&2 # kermit -k [option ...] # `kermit -k' offers no advice! # or kermit -k [option ...] >tmpfile && cat tmpfile # if necessary. # If no localname but remotename: # echo "Return to your local Kermit and SEND 'remotename'." >&2 # kermit -k [option ...] # `kermit -k -g remotename' is not supported! # or kermit -k [option ...] >tmpfile && cat tmpfile # if necessary. # If localname but no remotename: # echo "Return to your local Kermit and give a SEND command." >&2 # kermit -a localname -r [option ...] >&2 # If both localname and remotename: # echo "Return to your local Kermit and give a SERVER command." >&2 # kermit -a localname -g remotename [option ...] >&2 ; kermit -f >&2 # # This script was originally written to be invokable by pine-3.95 and # assumes features available in C-kermit-5A(150). Some of the design # decisions were made to maximize the functionality of this script for `pine'. IFS=' ' # Better safe than sorry! debug=1 # 0 => no diagnostic displays to STDERR; # 1 => echo commands before executing them; # 2 => echo commands but do NOT execute them! tmp=${TMPDIR:-'/usr/tmp'} # Directory for any needed temporary files ... #tmp=${TMPDIR:-${TMP:-'/usr/tmp'}} # [Honor `pgp's $TMP if no $TMPDIR?] Basename='/bin/basename' # Where `basename' really lives ... Cat='/bin/cat' # Where `cat' really lives ... Echo='/usr/ucb/echo' # Could be just `echo' if builtin ... Echo_n='/usr/ucb/echo -n' # ... what does `echo -n' (or just `echo'). Kermit='/usr/uucc/exec/kermit' # Where `kermit' really lives ... Sleep='/bin/sleep' script=`$Basename "$0"` # Get our name (for diagnostic messages) if [ -t 2 ] # and then # then $Echo "$script" >&2 # say who we are ... $Echo >&2 # ... with blank line. fi if [ "$debug" -gt 0 ] then ### Debug ### $Echo $script debug: $0 ${1+"$@"} >&2 if [ "$debug" -lt 2 ] then $Echo $script debug: commands listed and then executed >&2 else $Echo $script debug: commands listed but not executed >&2 fi fi file='' # Assume no default filename, local='' # no local [path/]filename, default='' # no default filename (or path), remote='' # and no remote filename (or path). # # Look for a local filename (or default to STDOUT). # if [ $# -ne 0 ] # Any arguments? then # Yes. case "$1" in =) : # Kermit's end-of-arguments convention ;; -) : # STDOUT explicitly specified shift 1 ;; -*) : # No filename specified (it's an option!) ;; $tmp/*|/tmp/*|/usr/tmp/*|/var/tmp/*): # Handle a tmp filename specially ... local="$1" # Use first argument as the local filename and shift 1 # then discard it (no default remote filename). ;; *) : # Filename specified local="$1" # Use first argument as the local filename and shift 1 # then discard it. if [ -n "$local" ] # [The standard /bin/basename spits out '.' then # if its argument is '' -- gads!!] file=`$Basename "$local"` # Set a default remote filename. fi ;; esac fi # # Look for a (default) remote filename (or path). # if [ $# -ne 0 ] # Any (more) arguments? then # Yes. case "$1" in -a) : # Alternate remote name specified shift 1 if [ $# -ne 0 ] then remote="$1" # Use specified remote filename (or path). shift 1 fi ;; -A) : # Alternate default remote name specified shift 1 if [ $# -ne 0 ] then default="$1" # Use specified default filename (or path). shift 1 fi ;; esac fi # # Interactively solicit a remote filename (or just use the default). # if [ -z "$remote" -a -t 2 ] then $Echo '^D cancels upload, \ quotes the following character (use \\ for a single \)' >&2 case "$default" in *[:\\/]): # Default path? $Echo_n "Upload (from directory '$default') file [$file]: " >&2 # Yes. ;; *) : # No - it's a default filename (or nil). $Echo_n "Upload file [$default]: " >&2 # Solicit remote filename. ;; esac IFS='' read remote &2 if [ -n "$local" -a -f "$local" ] then $Echo 'Upload cancelled (existing file not modified)' >&2 else $Echo 'Upload cancelled' >&2 fi $Sleep 2 exit $status # [Abort if ^D] fi fi # # Determine the remote filename. # case "$remote" in *[:\\/]): # Is the remote filename a path? if [ -z "$file" ] # Yes - is there a local filename? then # No. remote="$remote"'stdin' # Just use 'stdin' as the remote filename. else # Yes - use the local filename remote="$remote$file" # as the remote filename. fi ;; *[:\\/]*): # Just use any qualified remote filename as is! ;; ?*) : # Was any (unqualified) remote filename specified? case "$default" in # Yes. *[:\\/]): # Was a default remote path specified? remote="$default$remote" # Yes - prepend the default remote path. ;; # Otherwise just use the remote filename as is. esac ;; *) : # No remote filename was specified -- do what's right case "$default" in # by using the default (if any was specified)! *[:\\/]): # Was a default remote path specified? if [ -z "$file" ] # Yes - is there a local filename? then # No. remote="$default"'stdin' # Just use 'stdin' as the remote filename. else # Yes - use the local filename remote="$default$file" # as the remote filename. fi ;; ?*) : # Is there any (non-nil) default filename? remote="$default" # Yes - use it for the remote filename. ;; esac ;; esac # # Invoke `kermit' with the appropriate options to upload the file. # if [ -z "$local" ] # Was a local filename specified? then # No - assume STDOUT. if [ -t 1 ] # Is STDOUT a tty? then # Yes. local="$tmp/$script.$$" # Use a tmp spool file for STDOUT. fi if [ -t 2 ] # Is STDERR a tty? then # Yes - comment here because `kermit -k' won't! if [ -z "$remote" ] then # Case 1: Neither localname nor remotename specified. $Echo "Return to your local Kermit and give a SEND command." >&2 else # Case 2: No localname but remotename specified. $Echo "Return to your local Kermit and SEND '$remote'." >&2 fi fi if [ -z "$local" ] # Using a spool file for STDOUT? then # No. if [ "$debug" -gt 0 ] then ### Debug ### $Echo $script debug: $Kermit -k ${1+"$@"} >&2 status=$debug fi if [ "$debug" -lt 2 ] then $Kermit -k ${1+"$@"} # Do `kermit -k' status=$? fi else # Yes - need to use a spool file for STDOUT. if [ "$debug" -gt 0 ] then ### Debug ### $Echo $script debug: $Kermit -k ${1+"$@"} \>$local \&\& $Cat $local >&2 status=$debug fi if [ "$debug" -lt 2 ] then $Kermit -k ${1+"$@"} >$local && $Cat $local # Spool STDOUT status=$? fi fi else # Yes - a local filename was specified. if [ -z "$remote" ] # Was a remote filename specified, too? then # Case 3: Localname but no remotename specified. if [ ! -t 0 -a -t 2 ] # Will `kermit' fail to comment (and can we)? then # Yes - comment here because `kermit -r' won't! $Echo "Return to your local Kermit and give a SEND command." >&2 fi if [ "$debug" -gt 0 ] then ### Debug ### $Echo $script debug: $Kermit -a "$local" -r ${1+"$@"} \>\&2 >&2 status=$debug fi if [ "$debug" -lt 2 ] then $Kermit -a "$local" -r ${1+"$@"} >&2 # Do `kermit -r' status=$? fi else # Case 4: Both localname and remotename specified. if [ ! -t 0 -a -t 2 ] # Will `kermit' fail to comment (and can we)? then # Yes - comment here because `kermit -g' won't! $Echo "Return to your local Kermit and give a SERVER command." >&2 fi if [ "$debug" -gt 0 ] then ### Debug ### $Echo $script debug: $Kermit -a "$local" -g "$remote" ${1+"$@"} \>\&2 \; $Kermit -f \>\&2 >&2 status=$debug fi if [ "$debug" -lt 2 ] then $Kermit -a "$local" -g "$remote" ${1+"$@"} >&2 # Do `kermit -g file' status=$? # and $Kermit -f >&2 # then do `kermit -f' to "finish" the server. if [ $? -ne 0 ] then $Echo >&2 $Echo "$script: unable to 'finish' server mode on your local Kermit" >&2 fi fi fi fi if [ "$debug" -gt 0 ] then ### Debug ### $Sleep 2 # Allow time to read debug output ... fi exit $status ### Local Variables: ### ### mode:fundamental ### ### sh-shell:sh ### ### sh-shell-file:/bin/sh ### ### End: ###