Skip to content

ZModem support? #279

@mqliang

Description

@mqliang

support ZModem so that we could receive/send files using lrzsz? Does this sounds interesting?

Activity

parisk

parisk commented on Sep 20, 2016

@parisk
Contributor

Could you please get into some more details on how this would work on xterm.js?

mqliang

mqliang commented on Sep 20, 2016

@mqliang
Author

I use xterm.js to connect to a bash(a full-feature bash) and let user interact with the bash. I'd like support user to upload/download file through web terminal by using rz/sz.

mqliang

mqliang commented on Sep 20, 2016

@mqliang
Author

If I connect to a machine' shell with SecureCRT/Xshell, I can upload/download files with rz/sz command. I'd like use zterm.js to connect to a machine's shell, and upload/download files with rz/sz command

jerch

jerch commented on Sep 20, 2016

@jerch
Member

Zmodem is a protocol feature of is the underlying serial line abstraction of the PTY system. This is already usable with tools like zssh in xterm.js. xterm.js itself is just forwarding the master IO of the PTY to the browser. In reality you are operating on the system where the xterm.js server part is hosted.

This is quite different to a terminal emulator operating on the same machine like SecureCRT does.

So the question is - From which machine to which machine do you want to move files through the terminal? (Remember your local machine has no terminal channel to the server part of xterm.js).

mqliang

mqliang commented on Sep 21, 2016

@mqliang
Author
+-----------------------------------+
|       local machine               |
|   +----------------------------+  |
|   |       browser              |  |
|   |   +-------------------+    |  |               +---------------------------+          +------------------------+
|   |   |                   |    |  |               |   proxy                   |          |                        |
|   |   |   web terminal    >----------------------->   server part of xterm.js >----------| romote machine terminal|
|   |   |                   |    |  |               +---------------------------+          +------------------------+
|   |   |                   |    |  |
|   |   +-------------------+    |  |
|   +----------------------------+  |
+-----------------------------------+

I'd like to move files from local machine to remote machine. The remote machine can not be accessed by local machine directly, since it has no external ip.

Remember your local machine has no terminal channel to the server part of xterm.js

Is there any workaround for this?

jerch

jerch commented on Sep 21, 2016

@jerch
Member

Well you can use zssh (with zmodem support), sftp or scp from the proxy.

Unless someone implements it there is no way to up/download files directly from the webterminal in your browser to the remote machine. One of the modem protocols could be used that way (there is a XModem JS implementation), but since the browser has very limited filesystem access I question the usefulness. The hard part would be to provide a download interaction with the browser for big files (since the data is landing directly in the browser through the websocket, JS would have to hold all data until it can be saved.)

Another approach would be to enhance the server part with rz/sz functionality and map that transparently to the browser. This would circumvent the FS limitations of the browser but would need to hook another parser into the terminal stream to catch the 'rz\r' initialisation of the modem protocols.

FGasper

FGasper commented on Sep 5, 2017

@FGasper
Contributor

I’ve been working on a ZMODEM implementation in JavaScript and have it transferring files in both directions via xterm.js.

The browser does indeed have to buffer the entire file when it receives. :( That’s really the only downside, though, and it’s not bad unless you’re sending very large files. Uploads can be done via FileReader, and downloads happen via the “download” attribute of <a> elements.

I’m still testing and documenting it, but is ZMODEM integration a feature that would interest xterm.js?

jerch

jerch commented on Sep 5, 2017

@jerch
Member

@FGasper Nice :) Sounds promising, if you implemented it with node's stream API it could also be useful for big files as a server side extension, that proxies those files to the browser endpoint via download link.

FGasper

FGasper commented on Sep 5, 2017

@FGasper
Contributor

The library itself is platform-agnostic, so it should work anywhere. (Knock on wood.)

parisk

parisk commented on Sep 7, 2017

@parisk
Contributor

@FGasper sounds neat 😄!

We can definitely consider a zmodem addon, if it works in the browser.

What are usually the use cases for using zmodem?

FGasper

FGasper commented on Sep 7, 2017

@FGasper
Contributor

I use it to do file transfers within a terminal session to/from my workstation. It allows you not to have to scp/sftp or what not.

Similar to this for iTerm2:
https://github.com/mmastrac/iterm2-zmodem

jerch

jerch commented on Sep 7, 2017

@jerch
Member

@parisk The X/Y/Z-MODEM protocols allow to "abuse" a terminal connection for direct file transfer from and to the other side. This is very useful if you want to orchestrate a server only through a single terminal session. For POSIX systems there are the rz/sz tools to accomplish this.

Well for xterm.js it is a perfect addon, it will raise the usefulness of xterm.js for server admins in restricted environments. 👍

FGasper

FGasper commented on Sep 7, 2017

@FGasper
Contributor

NB: XMODEM and YMODEM both have the drawback of not “prompting” the other side that there’s a file transfer ready. (It’s unfortunate because they’re much simpler!)

ZMODEM sends what is essentially a “magic string” that can be watched for; then you prompt the user, “ZMODEM detected; proceed with file transfer?” At that point the implementation provides means either to provide files to transfer or to accept/skip files as the sender offers them.

17 remaining items

FGasper

FGasper commented on Sep 15, 2017

@FGasper
Contributor

I’ve got this into what I think is a reasonable state to try it out.

  1. Set up https://github.com/FGasper/xterm.js.git as a remote.
  2. Check out that repo’s zmodem branch.
  3. git submodule init; git submodule update
  4. npm install (See below.)
  5. npm start, then load localhost:3000 in the browser. (Chrome is what I’ve tested.)
  6. ssh to a machine that has lrzsz installed.
  7. Type rz, and send one or more files from your workstation to the remote.
  8. sz <filename1> <filename2> … will send files in a batch to your workstation.

(The UI is minimal by design; assumedly a “real” deployment would polish it more.)

Concerning step 4: When I tested just now on my workstation I had to fix a permissions issue with the node-gyp package.

jerch

jerch commented on Sep 18, 2017

@jerch
Member

Nice, works like a charm (tested with text files in Firefox).

Just a few remarks:

  • Is it possible to trigger the init sequence by accident (e.g. random data output)? If so, the terminal would IMHO need an "enter file transfer" setting to make this explicit.
  • The "Start ZMODEM session" should be interruptable, selecting "No" does not abort rz on the other end atm.
  • Is it possible to draw some progress bar / indicator into the terminal widget while the transfer is ongoing? Or some other more fancy stuff, atm rz/sz prints some weird status numbers into the terminal.
FGasper

FGasper commented on Sep 18, 2017

@FGasper
Contributor

@jerch

  1. Yes, it’s possible to trigger the init sequence by accident. That’s what the “Start ZMODEM session” prompt is for: the user can still back out if needs be.

  2. Should be fixed now.

  3. The application receives progress events in sync with the browser’s FileReader API. Chrome seems to give content with progress; however, Firefox doesn’t actually give the file content in those events. If you send yourself a suitably large file in Chrome you’ll see something like:

image

  1. The weird characters at the start of a session are the printable parts of the ZMODEM receive-init sequence: ** + ASCII CAN + B01 + 10 hex characters + CR + 0x8a + XON. I agree that it’s ugly that they go to the screen; however, it’s pretty standard in ZMODEM-savvy terminals that I’ve used. I suppose it could send enough BS characters to the terminal to delete those characters? Or maybe just filter them out if they do arrive together (as I’d think they generally will). (UPDATE: “Problem” with sending BS characters is that it’ll only happen after the user accepts ZMODEM; the characters have to show on the terminal first because the user hasn’t yet confirmed that ZMODEM is what’s desired.)

There’s also a need to add a control to cancel an in-progress transfer. I’m still looking at the best way to handle that.

jerch

jerch commented on Sep 20, 2017

@jerch
Member

There’s also a need to add a control to cancel an in-progress transfer. I’m still looking at the best way to handle that.

Maybe this from the specs helps?

A ZFIN, ZABORT, or TIMEOUT terminates the session; a ZSKIP terminates the processing of
this file.
FGasper

FGasper commented on Sep 22, 2017

@FGasper
Contributor

Potentially. The spec isn’t always the most helpful thing; for example, it mentions an Attn sequence that is sent after a ZSINIT. The spec seems to suggest that that’s how to get a sender to pause a data send, but apparently nothing actually uses Attn. Likewise with the ESC8 option: it’s not actually implemented in lrzsz, and since that’s the de facto reference implementation, ESC8 is unusable—which is a shame because it would nicely work around that problem with the termios IEXTEN flag.

I’m in a bit of a time crunch on other projects right now but hope to return to this next week.

mofux

mofux commented on Sep 22, 2017

@mofux
Contributor
FGasper

FGasper commented on Sep 22, 2017

@FGasper
Contributor

@mofux That’s how I would want this to work as well. The UI components that I’ve put into the demo are meant just to demonstrate the controls.

tsl0922

tsl0922 commented on Sep 23, 2017

@tsl0922
Contributor

@FGasper Good job 👍

I'm going to add ZModem support for ttyd when your api is ready for use (tsl0922/ttyd#37), thanks for your work.

FGasper

FGasper commented on Oct 16, 2017

@FGasper
Contributor

https://www.npmjs.com/package/zmodem.js

I’ve made an ALPHA release of zmodem.js. From here I’ll look at the plugin interface for xterm.js, but anyone who wants to look at zmodem.js, please feel free to do so and let me know how it works for you.

FGasper

FGasper commented on Nov 8, 2017

@FGasper
Contributor

The ZMODEM addon is now merged, FYI.

zhengtulymGh

zhengtulymGh commented on Jun 23, 2018

@zhengtulymGh

win7 system

$ npm run start-zmodem

> xterm@3.4.0 start-zmodem E:\test\xterm\xterm.js
> node demo/zmodem/app

App listening to http://127.0.0.1:3100

why can't open File Explorer?
default

alanhe421

alanhe421 commented on May 29, 2022

@alanhe421

win7 system

$ npm run start-zmodem

> xterm@3.4.0 start-zmodem E:\test\xterm\xterm.js
> node demo/zmodem/app

App listening to http://127.0.0.1:3100

why can't open File Explorer? default

The code is written very clearly, you can change it yourself.

just like this.

function _handle_send_session(zsession) {
  var file_el = document.getElementById('zm_files');
  file_el.click(); // simulate click event.
...
}

I forked demo https://github.com/alanhg/xterm.js

zhengtulymGh

zhengtulymGh commented on May 29, 2022

@zhengtulymGh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @FGasper@parisk@tsl0922@Tyriar@mofux

        Issue actions

          ZModem support? · Issue #279 · xtermjs/xterm.js