spaceflight, technology, anime, politics, and whatever else I feel like writing about

C-Kermit the Frog goes lpribbit


Earlier this week, when I was staring at my work machine bored out of my skull, watching paint dry a long rsync between servers run, I decided to poke around the options menu of MinTTY, the Cygwin terminal emulator I use when I'm on Windows. Under the Terminal settings menu, I found a curious setting called "Printer." I thought this would be something to do with text output, fonts, and the like, so imagine my surprise when I saw a drop-down menu with my network printer and the default Windows XPS writer in there. I was initially confused as all hell, since this didn't seem to have much of a connection to CUPS, lpd(8), or any other printing system that could reasonably be expected to talk to a program running in an xterm.

Way back in the Palaeozoic era when VAXen roamed the earth, many people connected to their Unix machines over serial terminals made by DEC and Wyse. These terminals had secondary ports on them, often labeled "AUX" or "PRINT". On this VT520, the printer port is the third large port from the left, with an icon that looks either like a desktop printer or a box of tissues under it.

What an ugly mess.  Aren't you glad we have USB now?

This port could be connected to a printer (serial or parallel, depending on the terminal), which would intercept input from the terminal if a certain ANSI escape sequence was received, and stop receiving input when another certain ANSI escape sequence was received. These are the same sort of escape sequences that let you have colors, bold, reverse video, blinking, and set the terminal window title. If you want to see a whole bunch of them in use at once, ask an Arch Linux user to show you his bash $PS1 or his zsh $PROMPT. This is a hideous kludge that doesn't leave any room for error correction, formatting, or binary data like images or PostScript, so it was of limited use in the long run.

Time passed, the Reagan administration ended, VAXen in the big office gave way to PCs on your desk, and slowly the world forgot that time-sharing systems ever existed.

Enter Linux VPSes, and the Raspberry Pi. Now suddenly, everyone and his dog has their own cheap little Unix system of reasonable power that they can do their work on, but don't have a sane, simple way of printing from them. You have to open another, separate connection to download an output file, save it to the computer you're sitting in front of, open THAT copy in a program that can read PDF files, and send it to the printer. That's not going into the complexities of and pitfalls of managing your printers, but enough bile has been spewed about that over the years to skeletonize a large whale, so we'll leave it alone.

That's not a whole lot of fun. It would be much nicer if you could just type a word or two inside your SSH session on the remote machine, wait briefly for a file download, and have it automatically sent to your printer so you could get back to whatever else you wanted to do in your system besides babysit printers.

As it turns out, you can. This is where C-Kermit comes in. C-Kermit is the last actively developed branch of the Kermit project, which started at Columbia University in NYC in the 1980s as a way to get IBM mainframes and CP/M computers to talk to each other nicely. Kermit has since been ported to everything from MS-DOS to VMS, and every variety of Unix ever made unless you count Cygwin (which you shouldn't, it's terrible). C-Kermit is the Unix branch of the family tree. In its long life, it has evolved from a simple error-correcting serial communication and file transfer program to a fairly complete scripting language. It gained support for internet protocols like HTTP, FTP, and telnet, SSL encryption, Kerberos authentication, and most relevant for our purposes, SSH.

At this point, if you use Windows, you're out of luck, and have to rely on kludgy raw terminal passthrough with MinTTY or similar. Kermit 95 has been out of development for over a decade, which means its SSH implementation is only moderately more secure than mailing your actual credit card to the Russian mob. Dilbert said it best.

I suppose these days it would be a Debian install CD instead of a nickel.

If you're using a Mac, Linux, or some other unix-like operating system, read on. You will need a system on which you have already configured printing, a package manager, and a text editor. If you're on OS X, I recommend Homebrew or MacPorts, otherwise just use whatever package manager came with your OS.

Setup Instructions

  1. Install C-Kermit. This is usually packaged as kermit or ckermit. RHEL, CentOS, etc. will need to install the EPEL repository.

  2. Open ~/.kermrc in your preferred editor and append the following line:

    SET PRINTER |lpr

    This means that kermit-downloaded files destined for a printer will be piped to lpr. If you have flags you need to pass to lpr or use a different printing command, substitute them as needed.

  3. Start Kermit. Your terminal should display output that looks something like this:

    C-Kermit 9.0.302 OPEN SOURCE:, 20 Aug 2011, for Linux+SSL+KRB5 (64-bit)
     Copyright (C) 1985, 2011,
       Trustees of Columbia University in the City of New York.
      Type ? or HELP for help.
    (/home/tidux/) C-Kermit>
  4. Connect to your remote system inside Kermit. This basically works like an SSH connection from the shell, since Kermit is calling your system's ssh command directly.

    (/home/tidux/) C-Kermit>ssh
  5. Now we need to install C-Kermit on the remote system, just like in step 1 above.

  6. Still on the remote system, open a file called "kermit-print" somewhere in your $PATH that you have write access. This is usually /usr/local/bin or $HOME/bin. Put the following lines in it:

    #!/usr/bin/env kermit 
    SEND /PRINT: \%1

    Save it, and set the file executable. Rehash your path if you're using (t)csh for some godawful reason.

    Kermit syntax is pretty simple. The file is opened with Kermit as the interpreter, and the first argument to the script is read as a filename, and then sent to the printer we configured in step 2 on your local machine. The EXIT line tells kermit to return you to the remote machine's shell rather than keep running kermit inside of kermit.

  7. Now you've got it all configured, so test it to make sure everything works as expected.$ kermit-print war-and-peace-complete.pdf

    You should see Kermit take over the screen and present a nice pseudographical display of the file download, and when completed be returned to your shell on the remote system. If you just want to save the file to your local machine and not print it, kermit's built in -s flag is what you want.$ kermit -s war-and-peace-complete.pdf

Final Thoughts

If you want instant PDF preview of remote files, you could make your default printer destination in ~/.kermrc a PDF printer or a document viewing program that accepts files on stdin.