module BBS::Zmodem
ZMODEM downloads: the sending side of Chuck Forsberg’s protocol, enough for the caller’s terminal to save files from the BBS: SyncTERM, NetRunner, Qodem, lrzsz’s rz behind a plain telnet, or zmodem.js in a web terminal.
BBS::Zmodem.send_files(session, [['README.TXT', bytes, Time.now]]) # => :ok, :cancelled, :timeout or :hangup
Every control character goes out ZDLE-escaped, so the stream holds no bare CR and needs no telnet BINARY mode, and 0xFF goes out as a doubled telnet IAC (telnet: false for a plain byte pipe). While it waits for the terminal to answer, Esc or Ctrl-C gives up.
Constants
- ABORT
-
The abort sequence: eight Ctrl-X followed by eight backspaces, which makes the receiver drop the transfer and erases the echo.
- ANSWER_WAIT
- BIN_HEADER
-
What starts a binary header, before
ZBINor ZBIN32:ZPADandZDLE. - BUDGET_FACTOR
-
The most bytes of a file sent, counting the restarts, as a multiple of its size (or of
SUBPACKETfor a smaller file); past it the transfer is given up. - CANCEL_COUNT
-
The
ZDLE(CAN) bytes in a row that cancel the transfer. - CANCEL_KEYS
-
The keys the caller cancels the start of a transfer with: Esc and Ctrl-C.
- CANFC32
-
ZRINITcapability flag: the receiver understands CRC-32 frames. - CRC16_MASK
-
The bits of a CRC-16.
- CRC16_POLY
-
The CRC-16/XMODEM polynomial.
- CRC16_SIZE
-
The bytes of a CRC-16 after a header or subpacket.
- CRC16_TOP
-
The top bit of a CRC-16, shifted out before the polynomial is added.
- CRC32_SIZE
-
The bytes of a CRC-32 after a header or subpacket.
- ESCAPED_C0
-
The C0 control bytes, sent escaped.
- ESCAPED_C1
-
The C1 control bytes, sent escaped.
- FILE_MODE
-
The Unix file mode sent in the
ZFILEheader, in octal. - FILE_TRIES
-
Times a
ZFILEheader is sent before the file is given up. - FIN_WAIT
-
Seconds to wait for the receiver’s
ZFIN. - HEADER_SIZE
-
The bytes of a header before its CRC: the type and four data bytes.
- HEX_DIGITS
-
The hex digits of a hex header after ZHEX: type, data and CRC-16.
- HEX_HEADER
- HEX_HEADER_RE
-
A hex header’s digits.
- Header
-
A parsed ZMODEM header:
typeis the header type (ZRINIT,ZRPOS, …),bytesthe four data bytes. - MAX_PENDING
-
The most bytes of the receiver kept while looking for a header; older ones are dropped.
- OVER_AND_OUT
-
“Over and out”, the sender’s last word after
ZFIN. - RESTARTS
-
The most times a file is sent again from where the receiver asks (
ZRPOS) before the transfer is given up. - RZ_COMMAND
-
The command that starts the receiver on a Unix shell:
rzand CR. - SUBPACKET
-
Bytes of file data per data subpacket.
- TELNET_IAC
-
The telnet IAC byte, doubled in the data on a telnet line.
- WAIT
-
Seconds to wait for the receiver’s answer, by default.
- XON
-
XON(Ctrl-Q), sent after hex headers andZCRCWsubpackets to restart a receiver that uses software flow control. - ZABORT
-
Headertype: receiver aborts the batch. - ZACK
- ZBIN
-
Headerformat byte: binary header with a CRC-16. - ZBIN32
-
Headerformat byte: binary header with a CRC-32. - ZCAN
-
Headertype: the other side cancelled the transfer. - ZCBIN
-
ZFILEconversion option: binary transfer, no line-end conversion. - ZCRC
-
Headertype: request for, or answer with, the file’s CRC-32. - ZCRCE
-
Subpacket end: CRC follows, frame ends, no answer expected.
- ZCRCG
-
Subpacket end: CRC follows, more data comes without waiting.
- ZCRCW
-
Subpacket end: CRC follows, the receiver must answer with
ZACK. - ZDATA
-
Headertype: data subpackets follow from the given position. - ZDLE
-
ZMODEM data link escape (Ctrl-X): prefixes escaped bytes and header formats; five in a row cancel the transfer.
- ZDLE_VALUES
-
The bytes a
ZDLEescape stands for when it is not the byte XOR 0x40. - ZDLE_XOR
-
XORed into an escaped byte after
ZDLE. - ZEOF
-
Headertype: end of file at the given position. - ZFERR
-
Headertype: receiver hit a fatal file error. - ZFILE
-
Headertype: file name and size follow in a subpacket. - ZFIN
-
Headertype: end of the session. - ZHEX
-
Headerformat byte: hex header with a CRC-16. - ZNAK
-
Headertype: last header was garbled, send it again. - ZPAD
-
Frame padding character (
*) that starts every header. - ZRINIT
-
Headertype: receiver is ready; carries its buffer size and capability flags. - ZRPOS
-
Headertype: receiver asks for data from the given file position. - ZRQINIT
- ZRUB0
-
ZRUB0:
ZDLEand this byte stand forZRUB0_VALUE. - ZRUB0_VALUE
-
The byte
ZRUB0stands for: DEL. - ZRUB1
-
ZRUB1:
ZDLEand this byte stand forZRUB1_VALUE. - ZRUB1_VALUE
-
The byte
ZRUB1stands for. - ZSKIP
-
Headertype: receiver skips the offered file.
Public Instance Methods
Source
# File lib/bbs/zmodem.rb, line 191 def crc16(bytes, crc = 0) bytes.each_byte do |b| crc ^= b << 8 8.times { crc = crc.anybits?(CRC16_TOP) ? ((crc << 1) ^ CRC16_POLY) & CRC16_MASK : (crc << 1) & CRC16_MASK } end crc end
Returns the CRC-16/XMODEM (polynomial 0x1021) of the String bytes, continuing from crc.
Source
# File lib/bbs/zmodem.rb, line 201 def escape(bytes) out = +''.b bytes.each_byte do |b| case b when ESCAPED_C0, ESCAPED_C1 then out << ZDLE << (b ^ ZDLE_XOR) else out << b end end out end
Returns a binary copy of bytes with every C0 and C1 control byte (0x00-0x1f, 0x80-0x9f) replaced by ZDLE and the byte XOR 0x40.
# File lib/bbs/zmodem.rb, line 185 def send_files(session, files, wait: WAIT, telnet: true) Sender.new(session, telnet: telnet).run(files, wait: wait) end
Sends files to the caller’s terminal over session.
- session
-
the
BBS::Sessionto send on - files
-
an Array of
[name, data]or[name, data, mtime]; only the base name ofnameis sent,mtimedefaults to now - wait
-
seconds to wait for a ZMODEM receiver to answer
- telnet
-
double 0xFF bytes as telnet IAC;
falsefor a plain byte pipe
Returns :ok when the terminal took the files (or skipped some), :cancelled when the caller or the terminal gave up (or the terminal asked for a file again more than RESTARTS times or for more than BUDGET_FACTOR times its bytes), :timeout when no receiver answered within wait seconds, :hangup when the line dropped.