3 # Copyright Gerhard Rieger and contributors (see file CHANGES)
4 # Published under the GNU General Public License V.2, see file COPYING
6 # example how to write a shell script that communicates with stdio on the front
7 # end and with a socat address on the back end
10 # ftp.sh [opts] server directory/ # show directory contents on stdout
11 # ftp.sh [opts] server file # print file contents to stdout
13 # -socks socksserver # use given socks server, port 1080
14 # -proxy proxyserver # use given proxy server, port 8080
15 # # must be http proxy that accepts CONNECT
16 # # method to ports 21 and >=1024
17 # -user username # default: "ftp"
18 # -passwd password # default: "anonymous@domain.org"
19 # -t # shell script trace+debug
20 # -d # debug on control connection (use up to 4 times)
21 # -D # debug on data connection (use up to 4 times)
22 # -b # block size for data connection
24 # -l* # socat logging options
26 # ftp.sh -v -d -d -D -D -D -b 65536 -proxy proxy ftp.ftp.org /README >README
29 passwd
="anonymous@domain.org"
30 #method="socks4:socks" # socks4 is address spec, socks is socks server name
40 -socks|
-socks4) shift;
42 *:*) method
="socks4:${1%%:*}"; addropts
="socksport=${1#*:}" ;;
43 *) method
="socks4:$1" ;;
47 *:*) method
="socks4a:${1%%:*}"; addropts
="socksport=${1#*:}" ;;
48 *) method
="socks4a:$1" ;;
52 *:*) method
="proxy:${1%%:*}"; addropts
="proxyport=${1#*:}" ;;
53 *) method
="proxy:$1" ;;
55 -user) shift; user
="$1" ;;
56 -passwd) shift; passwd
="$1" ;;
60 -b) SO2
="$SO2 -b $2"; shift ;;
62 -l*) SO1
="$SO1 $1"; SO2
="$SO2 $1" ;;
63 -*) echo "unknown option \"$1\"" >&2; exit 1;;
73 echo "addr=$method:$server:21,$addropts"; exit
75 ### this is the central part to establish communication with socat ###
76 ### copy these lines to make new communication shell scripts
77 TMPDIR
=$
(if [ -x /bin
/mktemp
]; then
78 /bin
/mktemp
-d /tmp
/$USER/FTPSH.XXXXXX
80 (umask 077; d
=/tmp
/$USER/FTPSH.$$
; mkdir
$d; echo $d)
82 TO
="$TMPDIR/to"; FROM
="$TMPDIR/from"
83 socat
$SO1 fifo
:$TO,nonblock
,ignoreeof
!!fifo
:$FROM $method:$server:21,$addropts &
85 while ! [ -p "$TO" -a -p "$FROM" ]; do sleep 1; done
86 exec 4>$TMPDIR/to
3<$TMPDIR/from
88 #trap "echo cleaning up...>&2; rm -r $TMPDIR; [ -n "$S1" ] && kill $S1" 0 3
89 trap "rm -r $TMPDIR" 0 3
90 ### here the central part ends
93 # this function waits for a complete server message, checks if its status
94 # is in the permitted range (terminates session if not), and returns.
97 local errlevel
="$2"; [ -z "$errlevel" ] && errlevel
=300
98 if [ -n "$cmd" ]; then echo "$cmd" >&4; fi
99 while read status message
<&3;
100 ( case "$status" in [0-9][0-9][0-9]-*) exit 0;; [0-9][0-9][0-9]*) exit 1;; *) exit 1;; esac )
102 #echo "got \"$status $message\"" >&2
103 if [ -z "$status" ]; then echo ftp data connection failed
>&2; exit; fi
104 if [ "$status" -ge "$errlevel" ]; then
106 echo "QUIT" >&4; exit 1
112 # wait for server greeting
115 ftp_chat
"USER $user" 400
117 ftp_chat
"PASS $passwd"
122 */) ftp_chat
"TYPE A" ;;
123 *) ftp_chat
"TYPE I" ;;
126 echo "PASV" >&4; read status message
<&3
127 info
=$
(expr "$message" : '.*[^0-9]\([0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*\).*')
128 echo $info |
tr ',' ' ' |
(read i1 i2 i3 i4 p1 p2
131 port
=$
(echo "256*$p1+$p2" |
bc)
135 # open data connection and transfer data
136 socat
-u $SO2 $method:$server:$port,$addropts -
141 */) ftp_chat
"NLST $dir" ;;
142 #*/) ftp_chat "LIST $dir" ;;
143 *) ftp_chat
"RETR $dir" ;;
149 #echo "waiting for process $S2 to terminate" >&2
156 #echo "waiting for process $S1 to terminate" >&2