0

I am trying to use lrzsz to send a file by zmodem by reading stdio in java and forwarding it to a socket of a connected client.

private void sendFiles(ArrayList<String> filenames) {
    Process p;
    ProcessBuilder pb;

    filenames.add(0, "/opt/local/bin/sz");

    try {

        pb = new ProcessBuilder(filenames);

        p = pb.start();

        InputStreamReader  lrzszin = new InputStreamReader(p.getInputStream());
        OutputStreamWriter lrzszout = new OutputStreamWriter(p.getOutputStream());

        InputStreamReader telnetin = new InputStreamReader(socket.getInputStream());
        OutputStreamWriter telnetout = new OutputStreamWriter(socket.getOutputStream());


        while (p.isAlive()) {
            if (lrzszin.ready()) {
                telnetout.write(lrzszin.read());
                telnetout.flush();
            }
            if (telnetin.ready()) {
                lrzszout.write(telnetin.read());
                lrzszout.flush();
            }
        }


    } catch (IOException ex) {

    } 
}

However the zmodem downloads are coming through corrupted. and it errors out.

2 Answers2

1

You tagged your question "telnet" but you don't explicitly say you're using telnet to connect remotely.

Telnet is not 8-bit clean. It uses "escape" characters to exchange configuration information between the client and server. Your transfer program likely expects a raw connection.

You could try implementing basic Telnet support into your application. For your purposes, it probably means just escaping and un-escaping the IAC (0xFF) character that is used to prefix Telnet commands. Telnet interfaces will turn these bytes from the raw stream into double IAC characters on the network, much like "\\" in a string to get a single backslash.

There's no point in using zmodem over network interfaces -- it was designed for serial lines which had no built-in error detection/correction. scp or rsync (which uses ssh) are your best bets though I sometimes use the socket program (or netcat) to create a raw listening port and connect directly to that to transfer files.

Machine 1: socket -q -l 12345 <archive.zip

Machine 2: socket -q machine1 12345 >archive.zip

(commands are typed from memory and my not be strictly accurate)

Community
  • 1
  • 1
Brian White
  • 8,332
  • 2
  • 43
  • 67
  • It's for a telnet BBS. I just tried SEXYZ from the Synchronet BBS package which has a telnet option and a stdio option, but still it's not working. And it does say "via a java telnet server" in my question title. – Andrew Pamment Mar 27 '15 at 20:24
  • The last option then would be to implement the Telnet protocol into your code. It should be pretty simple for your purposes; I'll update the answer. – Brian White Mar 27 '15 at 20:29
  • I've solved it.. seems I needed to set the right character encodings on my stream readers and writers. – Andrew Pamment Mar 27 '15 at 21:24
  • Be sure to post your own answer with the details of such. – Brian White Mar 27 '15 at 21:29
0

Answering my own question...

I needed to add the correct character encodings to the input and output streams.

        BufferedReader  lrzszin = new BufferedReader(new InputStreamReader(p.getInputStream(), "ISO-8859-1"));
        BufferedWriter lrzszout = new BufferedWriter(new OutputStreamWriter(p.getOutputStream(), "ISO-8859-1"));

        BufferedReader telnetin = new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
        BufferedWriter telnetout = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1"));

While SEXYZ telnet option accounts for the IAC characters, I am not sure if lrzsz does (probably not) so I added Brian's suggestion of escaping them as well.