#!/bin/sh # track ftp dialog and construct batch file PATH=/usr/ucb:/usr/bin:/bin trap 'exit' 2 3 15 # can be terminated with SIGINT host=$1 # our partner [ "$host" ] || { echo >&2 "usage: `basename $0` host"; exit 1; } input=/tmp/bftp.$$ # we write to ftp using FIFO on fd 9 mkfifo=/usr/local/gnu/bin/mkfifo mode=binary # initially: binary transfer grep -s 'machine '"$host" ~/.netrc 2>/dev/null || { echo >&2 "$host: not in ~/.netrc"; exit 1; } $mkfifo $input; ftp $host < $input > /dev/tty & exec 9> $input; rm $input verbose () { # do $* verbosely echo >&9 verbose echo >&9 "$*" echo >&9 verbose } n=1 # we save commands as Cmd_1 .. save () { # add command line to job eval Cmd_$n=\"\$*\" n=`expr $n + 1` } undo () { # remove command line from job if [ $n -gt 1 ] then n=`expr $n - 1` eval echo >&2 undone: \"\$Cmd_$n\" unset Cmd_$n else echo >&2 nothing to undo... fi } job () { # show job echo binary i=1 while [ $i -lt $n ] do eval echo \"\$Cmd_$i\" i=`expr $i + 1` done echo quit } while read cmd a b c do case "$cmd" in '#'* | '') continue # ignore # and empty ;; [aA]*) mode=ascii; continue # ascii ;; [bB]*) mode=binary; continue # binary ;; [cC]*) # cd path if [ "$a" ] then echo >&9 "cd $a"; save "cd $a" verbose pwd; continue fi ;; [dD]*) echo >&9 "dir $a"; continue # dir [path] ;; [gG]*) # get path [path] if [ "$a" ] then echo >&9 "dir $a" save $mode; save "get $a $b" continue fi ;; [jJ]*) job >&2; continue # show job ;; [lL][cC]*) # lcd path if [ "$a" ] then verbose "lcd $a"; save "lcd $a" continue fi ;; [lL][sS]*) echo >&9 "ls $a"; continue # ls [path] ;; [pP][uU]*) # put path [path] if [ "$a" ] then ls >&2 "$a" save $mode; save "put $a $b" continue fi ;; [pP][wW]*) verbose pwd; continue # pwd ;; [qQ]*) break # quit ;; [uU]*) undo; continue # undo esac echo >&2 ' Ascii # use text transfer mode' echo >&2 ' Binary # use image transfer mode' echo >&2 ' Cd path # change remote directory' echo >&2 ' Dir [path] # verbose directory listing' echo >&2 ' Get remote [local] # ask to retrieve file' echo >&2 ' Job # show job' echo >&2 ' LCd path # change local directory' echo >&2 ' LS [path] # short directory listing' echo >&2 ' PWd # show remote directory' echo >&2 ' PUt local [remote] # ask to store file' echo >&2 ' Quit # done' echo >&2 ' Undo # undo last batched command' done exec 9>&- echo cd `pwd` '&&' ftp -v $host "<< 'end of job'" job echo end of job sleep 1; echo >&2