2 # ftp-inband - copy files over a telnet/rlogin/etc link
3 # Author: Don Libes, NIST
6 # Program follows usual conventions and is otherwise self-documenting.
7 # Assumes standard UNIX conventions on both sides. It uses "compress"
8 # which can be replaced with gzip or removed totally - it's just there
10 # Assumes error-free transmission (i.e., MNP modems), telnet links, etc.
11 # Assumes remote shell does not reset tty modes after each command.
13 # Note, there is very little error checking. This script was written
14 # primarily as an exercise - just to demonstrate Expect.
16 set prompt "(%|#|\\\$) $" ;# default prompt
17 catch {set prompt $env(EXPECT_PROMPT)}
22 proc send_verbose {msg} {
30 proc get {infile outfile} {
31 global prompt verbose_flag
37 send_verbose "disabling echo: "
41 send_verbose "remote pid is "
43 expect -re "(.*)\r\n.*$prompt" {set rpid $expect_out(1,string)}
46 # pid is local pid, rpid is remote pid
48 set infile_plain "/tmp/$rpid"
49 set infile_compressed "$infile_plain.Z"
50 set infile_encoded "$infile_compressed.uu"
52 set outfile_plain "/tmp/$pid"
53 set outfile_compressed "$outfile_plain.Z"
54 set outfile_encoded "$outfile_compressed.uu"
56 set out [open $outfile_encoded w]
58 send_verbose "compressing\n"
59 send "compress -fc $infile > $infile_compressed\r"
62 # use label corresponding to temporary name on local system
63 send_verbose "uuencoding\n"
64 send "uuencode $infile_compressed $outfile_compressed > $infile_encoded\r"
67 send_verbose "copying\n"
68 send "cat $infile_encoded\r"
76 } -re "^(\[^\r]*)\r\n" {
77 puts $out $expect_out(1,string)
84 send_user "\n" ;# after last "."
88 expect -re $prompt ;# wait for prompt from cat
90 send_verbose "deleting temporary files\n"
91 send "rm -f $infile_compressed $infile_encoded\r"
94 send_verbose "switching attention to local system\nuudecoding\n"
95 exec uudecode $outfile_encoded
97 send_verbose "uncompressing\n"
98 exec uncompress -f $outfile_compressed
100 send_verbose "renaming\n"
101 if [catch "exec cp $outfile_plain $outfile" msg] {
102 send_user "could not move file in place, reason: $msg\n"
103 send_user "left as $outfile_plain\n"
104 exec rm -f $outfile_encoded
106 exec rm -f $outfile_plain $outfile_encoded
109 # restore echo and serendipitously reprompt
115 proc put {infile outfile} {
116 global prompt verbose_flag
118 if (!$verbose_flag) {
122 send_verbose "disabling echo: "
126 send_verbose "remote pid is "
128 expect -re "(.*)\r\n.*$prompt" {set rpid $expect_out(1,string)}
131 # pid is local pid, rpid is remote pid
133 set infile_plain "/tmp/$pid"
134 set infile_compressed "$infile_plain.Z"
135 set infile_encoded "$infile_compressed.uu"
137 set outfile_plain "/tmp/$rpid"
138 set outfile_compressed "$outfile_plain.Z"
139 set outfile_encoded "$outfile_compressed.uu"
141 set out [open $outfile_encoded w]
143 send_verbose "compressing\n"
144 exec compress -fc $infile > $infile_compressed
146 # use label corresponding to temporary name on local system
147 send_verbose "uuencoding\n"
148 exec uuencode $infile_compressed $outfile_compressed > $infile_encoded
150 send_verbose "copying\n"
151 send "cat > $outfile_encoded\r"
155 set fp [open $infile_encoded r]
157 if {-1 == [gets $fp buf]} break
163 send_user "\n" ;# after last "."
170 send_verbose "deleting temporary files\n"
171 exec rm -f $infile_compressed $infile_encoded
173 send_verbose "switching attention to remote system\n"
175 expect -re $prompt ;# wait for prompt from cat
177 send_verbose "uudecoding\n"
178 send "uudecode $outfile_encoded\r"
181 send_verbose "uncompressing\n"
182 send "uncompress -f $outfile_compressed\r"
185 send_verbose "renaming\n"
186 send "cp $outfile_plain $outfile\r"
189 send_verbose "deleting temporary files\n"
190 send "rm -f $outfile_plain $outfile_encoded\r"
193 # restore echo and serendipitously reprompt
201 send_user "g\nget remote file \[localfile]: "
203 -re "(\[^ ]+) +(\[^ ]+)\n" {
204 send_user "copying (remote) $expect_out(1,string) to (local) $expect_out(2,string)\n"
205 get $expect_out(1,string) $expect_out(2,string)
207 send_user "copying $expect_out(1,string)\n"
208 get $expect_out(1,string) $expect_out(1,string)
218 send_user "p\nput localfile \[remotefile]: "
220 -re "(\[^ ]+) +(\[^ ]+)\n" {
221 send_user "copying (local) $expect_out(1,string) to (remote) $expect_out(2,string)\n"
222 put $expect_out(1,string) $expect_out(2,string)
224 send_user "copying $expect_out(1,string)\n"
225 put $expect_out(1,string) $expect_out(1,string)
236 send_user "current directory is [pwd], new directory: "
237 expect_user -re "(.*)\n" {
238 cd $expect_out(1,string)
246 set verbose_flag [expr !$verbose_flag]
247 send_user "verbose [verbose_status]\r\n"
250 proc verbose_status {} {
263 send_user "command (g,p,? for more): "
272 send_user "~~g get file from remote system\n"
273 send_user "~~p put file to remote system\n"
274 send_user "~~c change/show directory on local system\n"
275 send_user "~~~ send ~~ to remote system\n"
276 send_user "~~? this list\n"
277 send_user "~~v verbose mode toggle (currently [verbose_status])\n"
278 send_user "~~^Z suspend\n"
282 exec kill -STOP [pid]
285 -re . {send_user "unknown command\n"}
287 send_user "resuming session...\n"
290 spawn -noecho $env(SHELL)
292 send_user "Once logged in, cd to directory to transfer to/from and press: ~~\n"
293 send_user "One moment...\n"