4

There's a nifty little tool called zssh that makes it easy to use the lszrz utilities to transfer files using zmodem over an existing ssh connection. It's surprisingly convenient...but it seems like I ought to be able to accomplish the same thing using expect. I've gotten this far...

#!/usr/bin/expect -f

spawn ssh $argv
set ssh_spawn_id $spawn_id
send_user "ssh is: $ssh_spawn_id\n"

interact -o "\030B0000" {
    send_user "\nStarting zmodem receive.\n"

    spawn rz -v
    set rz_spawn_id $spawn_id
    send_user "rz is: $rz_spawn_id\n"

    while {1} {
        expect {
            eof break

            -i $rz_spawn_id -re .+ {
                send -raw -i $ssh_spawn_id $expect_out(buffer)
            }
            -i $ssh_spawn_id -re .+ {
                send -raw -i $rz_spawn_id $expect_out(buffer)
            }
        }
    }

    send_user "\nFinished zmodem receive.\n"
    set spawn_id $ssh_spawn_id
}

This start up rz after seeing a ZRQINIT frame, and it apparently connects rz to the ssh session, but it doesn't work. rz says:

Retry 0: Bad CRCe.**B0100000023be50
Retry 0: Bad CRC**B0600000023d984
Retry 0: Bad CRC**B0600000023d984

...and so forth.

Is there a way to make this work? Thanks!

larsks
  • 277,717
  • 41
  • 399
  • 399
  • I'm curious, if you're already using ssh, why not file transfer with scp? – glenn jackman Feb 16 '11 at 18:13
  • Mostly (a) I'm just interested in trying to understand expect better, and (b) using scp requires a second connection, which may or may not be easy (for example, if there multiple hops in between my desktop and the remote system, being able to transfer files over the *existing* channel is tremendously convenient). – larsks Feb 16 '11 at 19:02
  • Hi Iarsks, have you solved this problem yet? I'd appreciate if you share any progress. – Shawyeok Apr 13 '20 at 16:02

2 Answers2

4

I've found that using -e / --escape (escape all control characters) option on sender side helps with some problems initiating the zmodem connection.

for example:

sending file:

sz -e somefile.ext

receiving file:

rz -e

This is handy for transfering files over IPMI sol (serial-over-lan) link.

There is iterm2-zmodem on OSX and Konsole on Linux with Zmodem integration.

Lari Hotari
  • 5,190
  • 1
  • 36
  • 43
2
  1. using exp_internal 1 while debugging is extremely useful. You're able to view how expect is matching the incoming text.

  2. I wonder if the terminal is getting in the way. Before spawning rz, try stty raw. Then after send_user "Finished..." do stty -raw.

  3. You can use exp_continue instead of a while loop:

    spawn rz -v
    set rz_spawn_id $spawn_id
    send_user "rz is: $rz_spawn_id\n"
    
    expect {
        -i $rz_spawn_id -re .+ {
            send -raw -i $ssh_spawn_id $expect_out(buffer)
            exp_continue
        }
        -i $ssh_spawn_id -re .+ {
            send -raw -i $rz_spawn_id $expect_out(buffer)
            exp_continue
        }
        eof
    }
    

    This doesn't have anything to do with the problem, just a matter of style.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Thanks for the suggestions. I believe that when using `interact`, everything is operating in `raw` mode by default...in any case, I added the explicit calls to `stty` and that doesn't seem to have changed the behavior. Setting `exp_internal 1` certainly provides some additional diagnostics; I'll have to look at them more closely to see if I can tell exactly what's going on. – larsks Feb 16 '11 at 21:15