Telnet and ZModem

As part of the Ridiculous Gopher Project, in which I make a blog and gallery using the gopher protocol, I wanted to make a way for readers to comment on the gopher-protocol blog. The gopher protocol does support telnet, so I thought I might write a minimal program that allowed one to comment via telnet.

This morphed into making a minimal BBS which I will call Pupper BBS. Pupper BBS is a tiny BBS with just enough functionality to let users read and write messages and to upload and download files. This is what BBS’s used to do.

The message-reading and message-writing functionality came together pretty quickly by using MySQL and ncurses++’s forms and menus. But the upload and download drew me down a rabbit hole. The BBS upload and download protocol is call ZModem. All modern day ZModem code
seems to descend from the venerable rzsz program by C Forsberg of Omen Technology. I spent a week converting lrzsz into a library I call libzmodem.

But to actually test out my BBS’s upload and download, I will need a telnet client program that can send and receive by ZModem. This seems like it was pretty common, but, everything seems to be a little bit broken. There are various projects call ztelnet and zssh, none of which compile on my Linux box.

I did finally happen upon this article on TechTinkering that explains how to use C-Kermit to do telnet with zmodem.

So, no maybe I can start debugging Pupper BBS’s upload and download, which are quite broken, apparently.

The Ridiculous Gopher Project: BBSs and ZModem

In the previous entry, I talked about the ridiculous Gopher project, in which I might try to make a presence for myself in Gopher Space.

So my first though was that I would have a blog and a webgallery over gopher.

The blog entries are a very simple prospect, since they need to be plain text. I don’t really like the block paragraph style, but, I did sketch out a conversion from markdown to troff to text that does some nice formatting.

The directory of the blog entries is a bit more complicated. I had an idea for a cgi that handled directory structures and indices that are date-based with a parallel directory structure and index that is keyword based.

But anyway, I got stuck on my first step, and fell down a rabbit hole, as per usual.

So I thought to myself, what if I wanted to have comments for my gopher blog? How would that work? What technology would I used? Well, in the original Gopher spec, there is a capacity for a Telnet session. I thought that I could make a tiny Telnet-based BBS with just enough functionality to let one leave a comment or read comments.

So I went on the internet to find a tiny BBS to examine. I found just about the simplest BBS one could imagine. It is called Puppy BBS.
I found it in here:MS-DOS archive on cd.textfiles.com

So there this California-based guy named Tom Jennings who does a lot of stuff in the intersection between tech and art. Once upon a time he was a driving force behind FidoNet, which was a pre-internet community of dial-up BBSs. He’s done many cool things since FidoNet.

Check out his cool art at Sensitive Research

I guess Tom wrote PuppyBBS as a reaction to how complicated BBSs had become back in the late 1980s.

So I thought, hey, does this thing still build and run? Well, not exactly. First off, it uses a MS-DOS C library that handles serial comms, which, of course, doesn’t work on Microsoft Windows 10 or on Linux. And even if that library did still exist, I couldn’t try it even if I wanted to. I mean, if I wanted to try it I would need two landlines and two dial-up modems so I could call myself. I do have a dial-up modem in a box in the garage, but, I’m not going to get another landline for this nonsense.

Anyway, I e-mailed Tom and asked if I could hack it up and post it on Github, and he said okay. And so this is what this is PuppyBBS.

Puppy BBS has four functions:

  • write messages
  • read messages
  • upload files
  • download files

From there, I started writing a Telnet-based BBS, which PupperBBS. And that went pretty well. It took very little time to get the message reading and writing running. I was on a roll, so I decided that I would quickly tackle the other two functions that PuppyBBS had: uploading and downloading files. And that was where it all got complicated.

PuppyBBS used XModem for file transfer, because it was the 80’s and that was what people did. But I thought ZModem, which was faster and more reliable, would be the way to go. So, I thought I’d just link a zmodem library to the BBS and I’d be ready to go.

But, I couldn’t find a zmodem library that was ready to go. All zmodem code seems to be derived for lrzsz, so I downloaded the code from lrzsz and made it into a library. To do that, I had to understand the code, so I tried to read it. That code is so very 1980s. It is terrible, so I had to fix it.

(Let the record show that by “terrible” I mean terrible from a reader’s point of view. It was written with so much global state and no indication of which procedures modify that state. There is no isolation, no separation of concerns. As a practical matter, it works great.)

And that led to a full week of untangling it all, which is what became the libzmodem library. Now my libzmodem isn’t really much more readable than the original code, but, at least it makes more sense to me.

Great, now I linked libzmodem to PupperBBS to add some ZModem send and receive functionality. Now to test it. I set up PupperBBS. I telnetted in to the system, got to the BBS, and tried to upload and download some files. It became apparent that for ZModem to work, the telnet program itself has to have some parnership with rz and sz, launching one or the other as appropriate.

Since this had to have worked in the past, some internet searches led me to zssh on sourceforge . zssh has a telnet program that has a built-in zmodem send and receive functionality. Unfortunately, it wasn’t packaged on Fedora didn’t compile out of the box, so I started trying to understand it and fix it.

So, anyway to summarize:

  • Let’s do a Gopher blog!
  • How do you do comments?
  • Telnet works on Gopher!
  • Let’s make a BBS
  • BBS’s do Zmodem
  • Let’s make a ZModem library
  • Let’s make a Telnet client that does ZModem.

And this is why I never finish anything.