scriptingsshinteractiveexpectzmodem

Help me drive Zmodem over ssh with expect


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!


Solution

    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.