Help me drive Zmodem over ssh with expect

2.6k views Asked by At

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!

2

There are 2 answers

1
glenn jackman On BEST ANSWER
  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.

0
Lari Hotari On

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.