Mostly Helpful Stuff

Helpful Stuff

Free Carrots #3: Additional Software (2021/01/27)

Free Carrots is an ongoing series of helpful tips for using Plan 9.

For once, application development on 9front is outpacing OS development. It can be hard to keep up, especially if, like myself, you hardly ever find yourself sitting in front of a computer. The following is a list of interesting recent projects by 9front users that are not currently included with the 9front distribution.

9pzone - Public registry service for 9p services, OS agnostic.

bar - Displays battery, date and time in a small, auto-topping bar placed in a corner of the screen.

castor9 - Surf gemini pages in a GUI.

gemnine - Surf gemini pages in a text window.

minivmac - Boot a Mac on 9front instead of booting 9front on a Mac.

neindaw - DAW as a file system (use with orca).

netsurf - APE port with Plan 9 native frontend. Works.

orca - ORCĪ› for Plan 9.

picker - Color picker.

rc-gemd - Serve gemini pages.

rio live theming with /dev/theme - It’s not treason (see below).

riow - Virtual desktops and window management (like dwm).

treason - Video player. Can be used to view YouTube videos.

whiteboardfs - Collaborative drawing.

zuke - Music player. Like juke(7), but good.

cat playing with a carrot

Free Carrots #2: TLS boot over WiFi (2020/05/13)

Free Carrots is an ongoing series of helpful tips for using Plan 9.

Picture it: My desk, some years ago.

Lenovo ThinkPad X301

I didn’t really feel comfortable leaving my data lying around where it might be confiscated, but at the same time I wanted to 9front while I was supposed to be working. Fortunately I had remembered to bring my bootable USB stick, and some helpful soul had plugged a WiFi router into the U-Verse in the break room.

Back then 9front didn’t have TLS booting over WiFi, but it does now. The following explains how to set it up, obviating the need for all the crazy-ISO-tricks I used to pull, back in the day.

First, configure your file server to listen for network connections. This will cause the machine to listen on port 564 (by default, the system is already running a TLS listener that bounces incoming TLS connections to port 564).

Next, your client (the machine that is TLS booting over WiFi) needs only a few alterations to its plan9.ini:


Note: Your auth and fs machines are not really Google DNS servers.

The boot scripts will attempt to authenticate to the WiFi access point specified, and then obtain an IP address via DHCP. The auth and fs servers listed will be used to access the remote environment.

To bypass DHCP, arguments to ipconfig(8) may be entered on the bootargs line:

   bootargs=tls!-g ether /net/ether0

That’s all there is to it, but curiously for some reason I never actually tried it until this week.

Anyway, it works.

Free Carrots #2: TLS boot over WiFi

Free Carrots #1: VNC over SSH (2020/05/06)

Free Carrots is an ongoing series of helpful tips for using Plan 9.

The canonical teaching tool for demonstrating Plan 9’s private name spaces and file interfaces is this:

   deckard; bind /net/tcp /proc
   deckard; ps
   qin               0    0:00   0:00        0K 0        Listen
   qin               1    0:00   0:00        0K 0        Listen
   qin               2    0:00   0:00        0K 0        Listen
   qin               3    0:00   0:00        0K 0        Listen
   qin               4    0:00   0:00        0K 0        Listen
   qin               5    0:00   0:00        0K 0        Established
   qin               6    0:00   0:00        0K 0        Established
   qin               7    0:00   0:00        0K 0        Established
   qin               8    0:00   0:00        0K 0        Established
   qin               9    0:00   0:00        0K 0        Finwait1

The value of this example is not that the result itself is especially useful, but that the design of the system almost inevitably produces tools that can be reused in new and surprising ways, sometimes without modification.

In Plan 9, you get a lot for free.

Another popular demonstration is borrowing the network stack of a remote machine:

   deckard; cat /net/iproute         /96   4    dhcp   0     /120         /96   4    dhcp   0   /128     /120     4i   ifc    0         /96     /120     4i   ifc    0   /128     /128     4b   ifc    0   /128   /128   4u   ifc    0         /96   /128   4b   ifc    0   /128 /128 4b   ifc    0   /128
   deckard; rimport /net
   deckard; cat /net/iproute         /96  4    none   0  /123         /96  4    none   0  /128   /128   4b   ifc    0  /128  /123  4i   ifc    0         /96  /123  4i   ifc    0  /128  /128  4b   ifc    0  /128  /128  4u   ifc    0         /96  /128  4b   ifc    0  /128 /128 4b   ifc    0  /128 /128 4b   ifc    0  /128
   fe80::          /64  fe80::          6i   ifc    0 fe80::5054:ff:fe09:9935 /128
   ff02::          /16  ff02::1         6m   ifc    0 fe80::5054:ff:fe09:9935 /128
   ff02::1         /128 ff02::1         6m   ifc    0 fe80::5054:ff:fe09:9935 /128
   fe80::5054:ff:fe09:9935 /128 fe80::5054:ff:fe09:9935 6u   ifc    0 fe80::5054:ff:fe09:9935 /128
   ff02::1:ff09:9935 /128 ff02::1:ff09:9935 6m   ifc    0 fe80::5054:ff:fe09:9935 /128

Now, any network connections leaving deckard from within this namespace will be routed through the encrypted connection to mars2 before they hit the outside world.

Many tools in 9front have been rewritten or otherwise created from scratch to satisfy user (read: developer) requirements, including a modern SSH client. The peculiar features of the operating system as described above suggest an opportunity to combine facilities in such a way that enables a more-or-less free capability to borrow the network stack of operating systems other than Plan 9.

Enter sshnet(4), which, you guessed it, allows for importing the network stack of another operating system over SSH.

   deckard; sshnet   # borrow network stack from openbsd machine
   deckard; ls /net     # iproute not implemented, but needed files are present
   deckard; window -m vncv    # vnc to host behind rachael

Note that any other program on the system can also take advantage of this makeshift VPN without having to know anything at all about the SSH tunnel.

Together, ssh.c and sshnet.c comprise less than 3,000 lines of code.

Free Carrots #1

Concealed Carry (2020/03/05)

Everything I use I have to carry with me. That means paper books are usually out of the question. But I do manage to lug around quite a lot of other useful tools, toys, and materials. It helps to conceal it all inside socially low observable prop gear. No one questions this stuff because either they believe I’m on their side, or they’re afraid I’ll mention politics. Owing to differences in geography and climate, YMMV.

It all adds up to only two bags, which I can actually lift, even with my compromised back. This is my roving office, from which I create comics, zines, and write blog posts such as the one you’re reading right now.


5.11 Tactical 56892

5.11 Tactical 56892

Upper pouch contents:

5.11 Tactical 56892 - lower pouch

Lower pouch contents:

5.11 Tactical 56892 - top pocket

Top pocket contents:

5.11 Tactical 56892 - interior

Interior contents:

Messenger Bag

5.11 Tactical 56176

5.11 Tactical 56176

Left pouch contents:

Right pouch contents:

5.11 Tactical 56176 - back

Back pouch contents:

5.11 Tactical 56176 - interior

Interior contents:

Side pocket contents:

OK, china. (2020/02/19)

I bought a unihertz Titan to replace my BlackBerry Passport. Nagging complaints about the Passport included: short battery life, flaky Qi charging, terrible cameras. Complaints about the Titan include: Android, the unit itself is heavy (with sharp edges around the case), and also, Android. I’m not sure yet which is worse. The Titan does offer some pleasing upgrades: IP67 dust/water resistant, good battery life, Qi charging works well, wider range of working/performant Andoid apps. But it’s still Android.

I’m documenting my experience. I’ve posted some tips on the device’s quirks and workarounds here.

How To View The Web From 9front (2019/12/05)

The World Wide Web is a wretched hive of scum and villainy, a fact all too familiar to refugees from the old Internet. September merged with IRL, and now everyone who was busy telling you to go outside and play for the past twenty-five years can’t be convinced to put down their phones. Sorry, teacher’s pets, but government and big business are both in on the scam. Dangers abound, and navigation is fraught with opportunities for disaster. Fortunately, some browsers don’t support Javascript or CSS.


Enter mothra(1). Written in 1995 as a toy for the 2nd edition of Plan 9, mothra doesn’t support <div> tags, color attributes, or even fonts beyond bold, italics, underline, and fixed width. When 9front developers discovered it tucked away on the old Bell Labs server (mirror), it was no longer even shipped with Plan 9. Since that time, some work has been done on it.

First was stopping it from printing the HTML version at the top of each document. Haha. The first fundamental change was to rip out all the network code (sorry, ftp:// lovers), and cause it instead to rely upon webfs(4), which brought it into line with all the other HTTP-eating programs in 9front. Next was implemented moth mode, empowered by the addition of a generic text entry box to event(2), which allowed for nibbling chunks out of web pages and saving them with arbitrary file names in arbitrary locations on the file system. Finally, text selection and copy/paste was added. Future improvements are planned to include a Plumb menu option, and easier customization of the browser’s default appearance.


9front’s webfs(4) was re-written from scratch. The program is a file server that takes requests from local programs (yes, even shell scripts), contacts remote HTTP serveres, and returns the results. Its user-agent string is configurable. You’re probably already thinking of uses for it.

mothra sends requests to webfs and renders the results as a graphical web page.


mothra does a pretty good job of rendering basic HTML, but many web pages have such wonky formatting, or otherwise rely so heavily upon CSS for layout, that sometimes quite a lot of vertical scrolling is required to get past the initial burst of banners, affiliate links, and menus. While some sites are irretrievably shitted up with mandatory Javascript, many still fall back to a relatively sane presentation via an RSS feed, which it turns out is the most efficient conduit for spraying web content onto your 9front screen.


Sidebar: Maybe you don’t really need to see images or click on interactive links. Ever heard of curl(1) or wget(1)? 9front’s re-written hget(1) offers a similar bag of tricks. Using hget and its companion tools, it’s even possible to fill out web forms from the command line. That’s right, say it again: everything is scriptable.


Anyway. Through some extended acrobatics it’s feasible to pull RSS feeds and deposit them into a format mothra can handle. A conveniently extant Go program called rrss runs independantly of webfs (the RSS parsing library it uses handles HTTP requests all by itself), and translates them into either human readable plain text, or a blog format compatible with werc (via its third-party barf plugin).

9front ships with most of what you need to build this self-contained RSS feed reading setup. The rest is easily installed. You can run everything on one machine, or you can pull the feeds to a remote 9front server and then surf to them from anywhere you want in whatever browser you choose. Do all of this:

That’s everything you need.

Configure cron(8) to periodically run rrss against a list of RSS feeds. This, too, is best customized with a shell script. It looks like I haven’t made significant changes to my script in over over four years so it must be doing something right.

Put something like rrss.barf in your $home/bin/rc/:

   # Dump RSS feeds into werc/apps/barf entries.
   # Run from cron.
   rfork en
   names=(read tumblr)
   if(! ~ $name $names){
          echo guess again. >[1=2]
          exit usage
   rm $log
   chmod +at $log       # +t so this file isn't copied to the dump.
   # go used to hang a lot, so we erect a safety net.
                 sleep 30
                 if(ps | grep -s -e 'Broken[ ]+rrss'){
                        {date; echo Kill Broken rrss} >>$log
                        Kill rrss | rc
   } &
   ' {
          for(i in `{cat $urls}){
                 ifs=$ofs {
                        j=`{echo $i}
                        alarm 60 rrss -f barf -r $root -t $"tag -u $"url >>[2]$log
                        echo $"url $"tag >>$log
   for(i in `{f $root/src}){ chgrp www $i }
   {date; echo Kill rrss.barf} >>$log
   Kill rrss.barf | rc

And in /cron/$user/cron:

   1 1,3,5,7,9,11,13,15,17,19,21,23 * * * local rrss.barf read
   1 2,4,6,7,8,10,12,14,16,18,20,22 * * * local rrss.barf tumblr

The files $home/lib/read and $home/lib/tumblr are lists of RSS feed URLs (one per line), and $home/lib/read.err, etc., contain any errors encountered when the script is run by cron.

When you surf to your barf page (in mothra or otherwise) a convenient heading will indicate the total number of feed items pulled. After logging in to barf, each item will likewise be accompanied by a button you can clicked to delete the item from your disk.


Voila. I’ve been getting by this way for several years. Surviving, if not living (as my mother used to say). Obviously, mothra is no one’s conception of an ideal browser, but then again the web is no one’s conception of an ideal mechanism for delivering content. At the end of the day at least I’ve imposed these usability constraints upon myself.



I used to be able to track Twitter and Instagram via RSS. Both have resorted to repeated and extensive measures to prevent humans from interacting with their services without first logging in via an approved client running on an approved operating system. Which obviously is the exact opposite of what I’m trying to do here. Only one of the several reasons I gave up on these services. Tumblr, and some other failed extraction operations, still offer RSS feeds.

Maye some of this is a blessing in disguise.

You Surrender

I know, this sounds like a lot of trouble to go through just to end up with diminished functionality on an operating system you’re probably only running in a virtual machine anyway.

If by some unlikely confluence of irregular events you are actually running 9front on bare metal, and you just can’t take it anymore, and life is starting to look bleak without access to 8chan’s AI-training captcha, you can always install OpenBSD or Linux in vmx(1).

I understand. At least you’re trying.

I won’t tell if you don’t.

How I Switched To Plan 9 (2019/12/03)


Hi, I’m SL. You may remember me from my classic appearances in contentious 9fans threads, or maybe you’ve read one of my books.

I’m a veteran UNIX admin of 20+ years. I produced a bunch of multimedia stuff on a Macbook in the mid-2000s. I ran 9front on all my production servers and on my personal laptop (my main personal computer) almost exclusively from 2011 to 2017. In early 2017 I moved to a new job that involved a lot of traveling and infrequent access to WiFi. It also turned out that carrying a second laptop (besides my work laptop) added too much bulk/weight to all the stuff I already had to carry everywhere I went. I bought one of those early iPad Pros equipped with an LTE connection and did most of my necessarily mobile computing via that device for the better part of two years. I was able to rig up a command line connection to 9front using a native iOS SSH client and drawterm -G. I explained how this was accomplished in a previous blog post. Infrequently, I carried a ThinkPad X230 Tablet, and later a ThinkPad X250 along with me, piggybacking off the iPad’s WiFi tethering.

The experience sucked. Replacing a general purpose computer with a jacked-up surveillance sensor package is not my idea of solving the problem of mobile computing. Lugging around extra pounds put a lot of strain on my already compromised back. Something had to give.

No pun intended.

Recently, I acquired a used ThinkPad X1 Tablet (1st Gen). This thing is small enough to fit in my bag, works well with both OpenBSD and 9front, and weighs almost as little as my iPad Pro with it’s folding keyboard cover. Finally, I’m back in business.

What Plan 9 Does For Me

Plan 9 excels at text manipulation. Conveniently, the entire system is controlled via text interfaces. Private namespaces ratchet this up into something even an idiot like me can use to construct efficient workflows.

I can’t understand something presented to me that’s very complex. – Ken Thompson

With the exception of multimedia and the modern web, all my needs are met. Pretty much anything people do with traditional UNIX terminals can be done at least as efficiently from a Plan 9 window. Even one accessed over SSH from an inferior operating system.

Is there support for playing audio (MP3, FLAC, etc.)? Yes.

Is there support for playing video? No.

Read this incomplete list of commonly requested software that ships with 9front:

Watch this introductory video:

Any more questions?

Spoiler: If you don’t care about my personal experience you can skip this blog post and proceed directly to the 9front Frequently Questioned Answers (FQA) section on using 9front, here: The information is more technically informative but lacks the endearing flavor of my personal bullshit.

Text Editing

I started trying to use Plan 9 in 2009. I had been editing tons of PHP code in OpenBSD using vi(1). A lot of fighting with cut and paste. In the midst of this gargantuan project at work I was reading my way through for the first time. I decided to give sam(1) a try.

It was love at first sight. I never wanted to go back, and consequently I didn’t. Here was the solution to my distaste with ex: structural regular expressions. I started out running the (at that time) very old portable version of sam in the OpenBSD ports tree, then ended up installing Plan 9 in QEMU, using the entire operating system as a glorified IDE. Wait, vi who?

I’m tired of using vi. – Bill Joy

Me too, buddy.


Programming from within Plan 9 naturally led to me wanting IRC and my text editor on the same screen at the same time. Luckily, there were several IRC clients to choose from. The simplest of which, ircrc, was a shell script. Remember that for later. Owing to Plan 9’s file interfaces, private namespaces, and modular design, much of the system is effectively built out of shell scripts.

Note: This would be a good time to familiarize yourself with Brian Kernighan and Rob Pike’s seminal The UNIX Programming Environment. I re-read it at about this time, and felt like I was really starting to understand it for the first time. Unlike modern UNIX, Plan 9 satisfies all the demands made by TUPE.

ircrc was fine, but eventually I wanted a persistent client, something that better approximated irssi running in tmux on a remote shell server. This desire coincided nicely with my first attempts to setup a permanent Plan 9 server. I found what I was looking for in irc7, a client split into its own client/server components, with one part holding open a persistent connection to an IRC server on an always-up Plan 9 machine, and the other part serving as my interface to IRC on my personal machine, whenever and wherever I happened to be located.


I found that I was spending more and more time in my Plan 9 installation in QEMU, and less and less time in UNIX proper. The next natural desire was getting e-mail into the mix. At this point I was still using Google’s gmail product, which I was able to access over IMAP using Plan 9’s native upas mail subsystem. I was shocked to discover that upas dated from 1984. (Footnote: It was not susceptible to the Morris worm.)

After a while I decided I didn’t want to be used by gmail anymore, so after many years I resumed hosting my own e-mail using the aforementioned upas' SMTPD and SMTP mechanisms. Yes, I’m still able to access my mailboxes over IMAP from whatever computer or device is readily at hand, or by simply logging in to the remote Plan 9 server and running mail(1) like a normal human being. One benefit of receiving mail on Plan 9 is that I’m able to configure spam filtering, mailing list sorting, autoresponders, etc., using the same kind of simple shell scripts that control the rest of the system. Here, again, learning the fundamentals pays dividends throughout the experience. It’s almost as if time spent learning one part of the system can be profitably applied elsewhere. As a heavy computer user for over thirty years, this still strikes me as suspiciously sensible.


9front ships with two web browsers, both written as jokes and abandoned by their authors in prior decades. Neither of them support Javascript, CSS, or anything beyond a meager subset of HTML. Of the two, 9front’s evolution of Tom Duff’s mothra(1) is perfectly usable if the aforementioned Rube Goldberg extensions are not required. Trying to use Plan 9 but still needing a modern web browser is a conundrum that has inspired many fledgling Plan 9 users to give up hope and retreat to the safety of their Macbooks. (See also: 9fans)

By the time I was ready to ditch the host operating system and install Plan 9 on bare hardware, my desire for the modern web experience had ebbed to an all time low. I went several years only touching a featureful browser when absolutely necessary. Which always felt gross. Your mileage may vary.


9front ships with a native torrent client that works very well but does not support magnet URLs. For a long time this didn’t bother me because magnet links were (unlike today) not often required, and in any case, I could always just use a UNIX machine to perform the download. At some point the sheer inadequacy of this excuse began to wear thin. Why did I want to be forever tethered to UNIX? I finally got rid of the modern web browser, and now this? Usefully, Plan 9 became a first class citizen in the Go programming language community. Some Go torrent clients actually work on Plan 9.

Note: Plan 9 may not be used to download legally encumbered material without the express permission of the rights holder.

Making Books

At the end of the day, what do I actually do with my computer?

I’m a writer. I write books. I use Plan 9 to type, format, collate, and prepare camera ready output for those books. Just like Brian Kernighan with his Linotron 202 (and, I should add, using many of the same software tools.)

Some examples of the build process include:

Start by reading each mkfile.

Is That It? I Gotta Go.

Seriously, what do you do with your computer?

Over time 9front sanded off its rough edges. I can do just about everything I need to do from a bare metal install. Today, we even have vmx(1) for hosting OpenBSD or Linux virtual machines (just in case you need to interface with the U.S. government via the now-required modern web browser). A previous release of the 9front DASH1 manual was created entirely on a ThinkPad running 9front (and Gimp running inside OpenBSD running inside vmx(1)). 9front now even ships with a primitive Microsoft Paint clone, several native Sega and Nintendo emulators, and a full port of DOOM. I never would have dreamed anything like this was possible back in 2009. As time goes by, there is less and less reason to boot anything else.

For what I do, I’m perfectly happy with it.

Hermes Rocket (2018/09/24)

Hermes Rocket, 1952

Typewriters can be useful. Specifically: lightweight, portable typewriters such as the Hermes Rocket provide a convenient, reliable alternative to computers. Type and file.

They may also ship with unique baggage:

The man who owned this typewriter was a US Air Force officer and engineer, who was principal designer of the SR-71 spy plane engines. Threaded up around the platen of this machine when I received it was a seemingly blank sheet of paper that revealed, upon careful inspection with a bright desk lamp, the imprint of some official military correspondence.

Update, 2019:

Sold the old (1952) model, and bought a slightly newer (1955) model. It’s in better condition.

Hermes Rocket, 1955

Install Classic Keyboard on xx30 Series ThinkPads (2018/04/16)

Lenovo ThinkPad T430 with T420 keyboard

This guide will explain exactly how to replace your xx30’s keyboard with an xx20 Classic keyboard.

Read more here.

Additional information here.

Even more information here.

Dealing with webshit: Configuring Firefox (2018/03/23)

This is the bare minimum necessary to configure Firefox so that it behaves in a reasonable manner. This document was last updated on 27 January 2017 and was tested with a clean install of Firefox 57. Verify these steps each time Firefox is updated.

Read more here.

Connect to Plan 9 from a mobile device (2018/03/08)

Help, my phone is my only Internet access

This article describes how a mobile phone (in this case, an iPhone) may be used to quickly and easily access a Plan 9 computer. Note: The path to victory is littered with compromises of necessity that terminate in reasonable functionality. Your mileage may vary.

SSH client

Any SSH client will do.

For iOS, there exists an app called Prompt 2 by Panic, Inc., whose features are sufficient to the task. Prompt 2 may be configured for one-click connection to a remote server, including the ability to automatically run a command once the connection is established (see below).

Remote UNIX SSH server

The following platforms are recommended: OpenBSD, FreeBSD, Solaris, MacOS. Other UNIX-like systems may also be able to compile and run drawterm (see below).

Terminal multiplexer

A terminal multiplexer such as tmux(1) may be used to sustain a drawterm connection across numerous SSH sessions. For convenience, create a script to re-attach your session that may be executed by the SSH client:

   tmux -u attach

drawterm -G

The 9front project has forked and updated Russ Cox’s original drawterm:

adding (among other things) support for a non-graphical, text-based command line mode:

   drawterm -G -h $host -a $auth_server -u $user

The drawterm command is likewise suitable for being run from a script.


All the pieces in place, configure your SSH client to connect to the remote UNIX SSH server and re-attach to your tmux(1) session.

Prompt 2 running on an iPhone 7 Plus

Related: 9front, Plan 9

mother (2017/11/29)

Mother is an rc(1) script that provides a similar experience to nedmail(1). Note: saved messages are copied manually to the mbox directory in mdir format (the default used by Erik Quanstro’s nupas and 9front’s upas). All other interactions between mother and mail messages occur via upasfs(4).

Read more here.

Related: 9front, Plan 9