Available through Git (Atom feed of changes):
git clone http://offog.org/git/misccode.git

About misccode

My misccode collection holds all the one-off things I've written that aren't polished or serious or general enough to merit their own repository, but might still be of interest to others.

General notes on things you might find here:

The original inspiration for making this stuff available was Andrew Tridgell's junkcode collection. It's worth noting that some of his throwaway programs do the same as some of mine, which suggests that other people have probably written the same code too. Help reduce code duplication by sharing your own miscellaneous code! Other misccode-like collections I'm aware of:


Set the system clock from the date in an HTTP response.
Test the digital outputs on a Velleman 8055 I/O board by doing Knight Rider-style running lights.
OO Perl interface for a collection of BibTeX files, with ways of resolving cross-references and formatting as HTML or plain text. I use this to generate my list of publications.
An implementation of the very silly OpenGiggle protocol in Python, providing both a client and a server.
Hello World in Haskell. (Yes, there are a few Hello Worlds in here; they're useful for testing that a compiler I've just built works, so I keep them around.)
Hello World in Java.
An implementation of the Corporate ICQ protocol in Python. What's there works, mostly, but it doesn't yet support sending messages except via the server or most of the inter-client protocols, and the interface is very primitive.
Unlikely to be of much use to you.
The licensing terms for most of this software.
A wrapper for ClamAV so that I can use it with procmail/maildrop.
Pull photos from my digital camera's memory card, date them and put them into directories. This has been through several generations of cameras, so it should be tweakable for yours.
Convert Advogato's recentlog page to RSS. Obsoleted by rsscomics.
Download an item (e.g. a Live Music Archive show, or an ebook) from archive.org, by digging out the direct download details from the web pages and running wget with the right arguments to fetch only the files you actually want. Invoke with the link that's given in their RSS feed (the "details" page).
My (very simplistic) blogging tool. I use it to generate my ideas pages. The input format's effectively Blosxom's, but using an RFC2822-like format so I can specify multiple headers. The output is static HTML pages and RSS files; no CGI necessary.
A udev script to renumber ALSA devices based on their device path. You can use this on a Linux system to make sure that your sound devices always have the same numbers — for example, if you've got several identical PCI cards, or if you use USB devices.
I'm a heavy sleeper, so when there's something that I really must be up for, I use this script and turn my stereo up loud. It's also useful when the batteries run down in my bedside alarm clock.
A tool for cataloguing books (somewhat unfinished at the moment), designed to be used with a barcode scanner.
Simple utility module for using Amazon's XML services from Python — in particular, for calling authenticated methods in their API.
Move messages older than a certain age from one maildir to another. I use this to stop my spam and linux-kernel folders from getting too big.
Makefile for building Arduino programs without using their GUI.
The standard Arduino flashy-light program.
Generate MIDI drum notes from an Arduino with a bunch of piezo transducers (or buttons, etc.) connected to its analogue inputs.
Incomplete attempt at an Arduino-based fan speed controller.
Flash out a message in Morse code on an Arduino's LED.
Test PWM output on an Arduino.
On an Arduino, decode signals from an RC5 remote control and send corresponding serial messages using the UIR protocol. This can be used directly with lirc's uirt2 driver.
Test analogue input on an Arduino.
A Python module to write Atom feeds from feedparser-format data structures. You can use this along with feedparser to convert other feed formats into Atom, or you can generate your own data structures to make writing Atom output more straightforward.
A very little version of the umount command for Linux, built when I was experimenting with the different flags you can give it.
Automounter script for Linux for automatically mounting CIFS filesystems. It'll do regular and NMB lookups on names, so it should be useful in an environment with Windows machines.
A wrapper for various JACK/ALSA-based software synthesisers that handles automatically connecting them up. Currently supports fluidsynth, Aeolus, Hexter, XSynth, WhySynth, nekobee and sineshaper. It'll automatically connect things via a JACK Rack instance if it finds one.
Makefile for Arduino programs that don't use the Arduino libraries (or, more generally, ATmega8 programs where you've got the Arduino firmware installed on the chip).
Another flashy light program.
The firmware for my ATmega8-based frequency counter. (See the source for more details on the hardware.)
Utility functions for driving an HD44780-based LCD display from an AVR.
Utility functions for driving the ATmega8's serial port.
Fed up with remembering how to list different sorts of XDCC server on IRC networks? This'll do it for you (as an irssi script), and remember the listings they return so you can search them.
Calculate a frequency table for Aeolus that lets you play in Bradley Lehman's Bach tuning.
Scripts to generate bandwidth-usage pie charts automatically from Linux firewall rules.
Python function to format an integer in an arbitrary base — i.e. the opposite of the int function. This is something I occasionally want, but it doesn't exist in the Python standard library at the moment.
Various BASIC programmes, mostly written while I was at school.
A tool to transmit disk images to a BBC Micro over a serial link. Unlike other programs I've found, this one checksums the data as it's sent, and verifies that the tracks were written correctly to the disk. You can transmit the BASIC program to the BBC using *FX 2,1 to tell the BBC to read keypresses from the serial port.
Show some information about a BBC Micro sideways ROM image.
Some Python code to play with the Beale ciphers; in particular, trying to identify where the errors were in the encoding of B1.
An utterly incomplete attempt to do text rendering like Tofu does. I really must get around to finishing this some day.
Given a bunch of BibTeX files, produce a one-per-line summary in plain-text Harvard style.
Given a directory of music files representing an album, try and get it into the standardised format I use ("Album - Artist/Track Song - Artist.type").
A slightly nicer version of the btdownloadheadless script that comes with BitTorrent. Relies on my BitTorrent patches to limit the number of inbound connections (which have since been merged, but with a different option name). Obsoleted by btqueue.
A BitTorrent queue-based downloading tool.
Given a collection of files, write them to CD, verify the CD was written correctly, and add it to the catalogue. Optionally overburn the CD, use different filename encoding approaches, or forget about the catalogue. Rather me-specific.
Burn an audio CD from a collection of files. Attempts to infer sensible CD-Text data.
Proto-version of burn that just writes an entire directory.
Generate a sheet of business cards for me as a PDF. This lets me produce customised cards in small quantities when I'm going to a conference, depending on which hat I'm wearing.
A brute-force Countdown number puzzle solver; on my old 450Mhz K6-2, it would search the entire problem space in 1.6 seconds. Combined with "ag", this takes all the fun out of watching the programme on TV. It can now list all solutions, list solutions falling in a certain range, and permit or forbid non-integer division results. (I'm pretty sure that it's still buggy — it doesn't look at some possible reorderings.)
My CD cataloguing system. Lets you add CDs to the catalogue, and search for files on them. Most effective when you tie it into an automated burning process (see "burn" above). cate edits the title of a disc; catl lists a disc by ID.
Produce web pages from cdcatalog's catalogue.
Run a program, changing to the directory it's in first.
Python module to extract the commit log from a version control repository in a standardised way.
Some music-theory Python classes, and code to automatically find how to play chords on various guitar-like instruments. It works best for mandola at the moment, since that's the instrument I play most often; guitarists will probably want to alter some of the parameters.
A header that can be included in CIF programs (the KRoC C interface) that sets insert debugging information appropriately for calls to the memory allocator. This allows dmem to produce correct memory trace output for CIF programs, which means you can use dmem-leakcheck (below) to find memory leaks in CIF code. This is perhaps also useful as an example of how to set KRoC's insert debugging information from C (normally it's done from the generated assembler code).
A couple of nifty-but-not-useful Python classes. OutputWriter wraps a file object and lets you print to it using a C++-style << operator; Internet represents the Internet, so you can say Internet().org.slashdot["tcp"][80] to open a socket to Slashdot's webserver.
Convert various web comics into RSS format. Very far from ideal, because it links to the original images rather than grabbing them (which means a hit on the original site every time you refresh your rawdog page unless you're careful about web caching). Obsoleted by rsscomics, which does this correctly.
Convert audio files (usually MP2 radio recordings from MythTV) into an appropriate format for my Samsung MP3 player. I run this automatically overnight on my directory of things to listen to.
Read a CDROM (or similar potentially-dodgy removable medium) into a directory. I use this for large student assessment submissions.
Given the output of darcs log, check that all the years in which a file was modified are mentioned in its copyright notice. (This'd be easy enough to adapt to other version control systems.)
Some Core Wars robots I wrote a long time ago.
Produce statistics for the UKC CS auction. Quite a lot of effort went into making this as efficient as possible, since the machine that the auction runs on is somewhat underpowered; it's therefore very careful about caching values it calculates. Perhaps interesting as an example of using Gnuplot from a CGI application to produce live graphs.
Generate blog entries automatically based on the Darcs history of a file of individual notes.
Provide Atom feeds for changes to all my Darcs repositories. The script will need some tweaking for your setup, but the XSLT file should be usable as-is.
Synchronise directory trees to a WebDAV server — specifically, to Blackboard's somewhat-nonstandard WebDAV server. I use this for uploading teaching materials at work.
Take pictures from a Kodak DC-20 digital camera (old, cheap, very low-quality CCD with non-square pixels) and convert them to correctly-scaled PPMs.
Emulate mIRC's /dccserver command (or, at least, the commonly-used bits of it that you can't easily fake with netcat). NIH's dccserver (it's difficult to come up with a creative name for this sort of thing) does a more complete job.
Using apt, check to see whether any updates need installing on a Debian system. I run this every few hours from cron; it'll mail me if it finds anything.
The CGI script that produces the Us-Lot Log. It's a browser for the output from The Daily Chump Bot.
A Python module to decode SMS messages as received over a serial link from a mobile phone. Written for a friend's IRC bot.
A generic exclusion file for use with diff -X; this ignores most of the generated files you're likely to find in automake-built software.
Flash keyboard lights in response to music.
In a distutils-based Python package directory, copy the generated tarballs into my web tree and sign them. I use this for distributing rawdog and my other distutils packages.
Z80 machine code disassembler (based on a less complete one from somewhere else; full details in disz80.c). Given a Z80 object file, it produces source appropriate for asl. Slightly better than trivial in that it tries to figure out sensible locations for labels, and also produces a file with DB statements for the bytes in the input so you can cut-and-paste data sections. I wrote this to reverse-engineer the MPF-1 BASIC ROM.
Given a log of memory allocations produced by CCSP (the KRoC runtime), print a list of memory leaks sorted by where they were allocated. Useful for tracking down memory leaks in KRoC's output, and in CIF programs when used with ciftrackdmem.h (above).
Draw the scale for a DIN (IEC 60268-10 Type I) peak programme meter.
Given a sorted list of md5sums, identify duplicate files.
Emacsclient is very nice (if you're an Emacs user), but it doesn't start Emacs if it's not already running. This does.
Transcode a video file (for example, a MythTV recording) to MPEG4 with Vorbis audio, aiming for a fixed size, using the heuristics from the MPlayer documentation to pick a sensible resolution and bitrate to get decent-quality video. This needs MPlayer, vorbis-tools and mkvtoolnix.
Python module to decode XML entities.
Run a program with argc == 0. This isn't a useful thing to do, but it's technically legal, and a surprising number of programs crash if you do it...
Look for decimal numbers in text that could plausibly be Unix timestamps, and expand them into human-readable GMT strings. Handy for reading logfiles.
A specialised hit-counter: I used mod_rewrite to rewrite anything that looked like an attempted IIS exploit against my webserver to this script, and graphed the number of attempted exploits per day. This was reasonably entertaining when there were IIS worms around.
Search a directory tree for archives of various kinds, and extract each one into a directory named the same as the archive. If an archive contains a single directory, move the contents up. I use this for unpacking student work submissions.
A simple plugin for SpamAssassin that looks for messages where the sender's first name is in the Subject line.
A program for drawing family trees from a GRAMPS database. The style of the output was designed to imitate some family trees that my father drew by hand; while it offers a view that GRAMPS doesn't provide itself, it doesn't conform to any standards for that sort of thing. It uses Cairo for drawing, so it should be able to generate high-quality Postscript output with a small tweak to the source code.
Run feedparser on a feed, and pretty-print the output.
Python module to write RSS feeds.
A plugin script for ssh to make it use ssh and netcat to retrieve mail from a machine running a non-SSL imapd. This script works very nicely, but doing an SSH login every five minutes may produce more log entries than you're expecting. (Yes, I speak from personal experience here.)
Convert VOB files to lower-quality AVI using mencoder. There are much better tools around for doing this, but I needed a quick-and-dirty script for this at one point.
Print the tabs open in a Firefox session, with titles and URLs. This is useful when I'm at work, and know I've got something important open in a browser tab at home, but can't remember what the URL is...
Given some fifos in the filesystem, provide buffered versions of them, and periodically print a report on buffer usage. Intended originally for use with mythtranscode, but should be useful for other streaming-data applications too.
Python module to make it easy to filter data through a given command. Includes a utility class to provide a persistent cache, which is useful with compute-intensive filters.
Find ext2 and ext3 filesystems inside a disk image. Useful if you've accidentally overwritten your partition table, or if you've got a virtual machine image in an unknown format.
Find Geocities URLs in input text, and try to guess reasonable starting points for mirroring.
Locate JPEG images inside a bigger file and write them out as separate files. Written to extract JPEG images from a Quicktime slideshow for David.
I managed to get my org-mode diary into an odd state where I had some duplicate entries in my archive file. This finds suspicious-looking entries.
Fix the length headers in a RIFF WAV file — useful if you were recording something, forgot to stop it, and the recorder died without writing the header once the file got bigger than 2 GiB.
Download all the medium-size images from a Flickr set.
Given a file with occam-style folds ({{{ }}}), check that the folds are consistent — opening and closing folds are at the same indentation level, and every opening fold has a matching closing fold.
Display today's menus at the University of Kent. Since the menus page is partly generated by Javascript, this script implements a (very limited) Javascript interpreter, and renders simple HTML as text. This is installed as "food" on the UKC CS hosts.
Start a copy of Firefox with a brand new, throwaway profile; the profile is created from a template, and removed when Firefox exits.
Helper module for writing in-memory userspace filesystems using FUSE and Python.
My web gallery script. Everyone's written one of these, right? Uses Python and ImageMagick, and generates static pages stashed into a separate directory from a template file, so it's fairly non-intrusive if you just want to make an existing image collection web-visible without installing CGI/PHP scripts. (I prefer systems that generate static HTML to CGI scripts where possible, which is why there are several in here.)
fetchmail is really slow over a laggy dialup link. This isn't, but requires some server-side support (and customisation).
A shell script that attempts to figure out the endianness of the current machine using only SuS tools.
"Obfuscated C" implementation of an OpenGiggle client. Not very obfuscated, and not really very interesting; I was trying to make a client that'd fit in a signature, but you can't really do it portably without including headers.
Generate an Atom feed from the commit history of a Git repository.
Import a series of snapshot tarballs into a Git repository. Useful when reconstructing the history of a project.
Greasemonkey script to convert embedded objects (e.g. Flash animations) into links. This isn't very smart; it ought to do the same as youtubeget.
Greasemonkey script to make some web pages narrower. Useful if you like big browser windows.
Greasemonkey script to detect some sorts of Java image rollovers and replace them with Javascript equivalents.
Greasemonkey script to undo some of the more annoying things that web authors do with links.
Greasemonkey script to fill in your details on UK government petitions automatically. You'll need to edit the script yourself so it knows your details.
Convert newsgroup archives (as produced by newsarchive below) into something suitable for feeding into AI programs like MegaHAL.
A Gale gsubrc that archives messages. I was going to write some more tools to go with this, but since I fixed the ginsu bug that was preventing it from working on my system the problem became much less interesting.
Convert Project Gutenberg electronic books into HTML. Use with html2prc to read Gutenberg stuff on a PalmPilot. (Again, I'm sure there are better ways of doing this now.)
BBC1 Teletext news in the UK has the interesting feature that all the news headlines are the same number of characters long, so with a bit of mangling it makes a nice desktop background display. Uses alevtd (needs to be a recent one after my plaintext patch got merged).
Hello World in C. (Yes, any C programmer can recreate this in about thirty seconds, but sometimes it's nice to save thirty seconds of typing.)
The Hep news aggregator, which I used briefly before I wrote rawdog, worked pretty well (modulo odd blocking behaviour owing to some of the approaches the author took not really working well in the Twisted environment), but never expired articles it knew about. This script uses Hep's POP3 interface to expire old articles.
Compare hexdumps of two files.
Like darcsatom, but for Mercurial: generate Atom feeds of the latest changes to a set of Mercurical repositories.
The service manual for the Honda Stream comes on a CD as HTML with some horrific IE-only scripting. This program generates an index page so that it's reasonably navigable with any browser. (Or: how Python helped me install my car radio.)
Convert /etc/hosts to tinydns format.
A Python module to convert colours in the HSV colourspace to RGB.
"Human XML": convert to and from an alternate syntax for XML, with the aim being to make it a bit more convenient to edit by hand (notably: no end tags, and easier syntax for comments and CDATA blocks).
A VIM syntax highlighting mode for hux.
T2s s4t t3s the m4e l5s out of w3s in t2t g3n to it, and r6s t2m w2h the c3t of l5s r5d. It's c4d i18n b5e "i18n" is o3n s7d to t2t.
Convert iCalender files into org-mode entries.
Convert iCalendar files into the format showtodo expects.
Safely increment a count in a file. Useful if you want to count how many times a procmail rule has matched (for graphing spam/non-spam, for instance). Needs setlock from freedt.
Like sed -i, but for any filter: inplace sort -- file1 file2 ....
Python module for parsing Windows-style configuration files. This is designed to be much less awkward to use than the standard ConfigParser module, since it provides a dictionary-like interface; it also allows multiple attributes with the same name.
The Inmos-provided libraries for occam contain inline human-readable documentation in a fairly standard format. This program converts it to OccamDoc as best it can; the output will need some hand-editing, but it's certainly a lot easier than rewriting the documentation by hand.
Connect to an IRC server, then copy lines from the standard input to a channel. This is intended for writing simple IRC bots (for example, news gateways).
A kludge to get around irssi not supporting multiple visible windows very well. I gave up and just use multiple full-screen windows.
Convert IRC topics to an RSS feed. This is an irssi script (that writes topics to a database) and a CGI script (that reads the database and spits out RSS).
Python module to read antique electronic mail archives from ITS systems. There are some interesting mailboxes in the ITS source code documentation at nocrew.org. Since these mailboxes somewhat predate RFC822, this scripts copes with a large number of different syntaxes for dates and other parts of messages.
View arbitrary images using anytopnm and xli (which remains my favourite image viewer, since it's fast and makes scrolling around in a big image really easy). This was more useful before xli had PNG support patched in.
Wait for a JACK application to start up.
Like jack_connect, but repeat until the connection is successfully made. This is useful for scripting complex JACK setups, where the applications might start in an unpredictable order.
An obfuscated "Just another Python hacker" program, based on an idea by Moof. His original program just used offsets into the module docstrings and thus behaved differently on different versions of Python. This one computes hashes (using a functional version of the DJB hash) to try and locate the docstrings even if we don't know the location. Unfortunately, it's a bit big for a signature, and doesn't actually work very well across different Python versions...
Given a list of JPEG images, generate a PDF file with them embedded, one per page. I use this for PDF-ifying scanned documents.
Extract just the audio stream from a MythTV MPEG recording. This saves quite a bit of disk space for radio recordings (typically a factor of five or so), since MythTV always records a dummy video stream along with the audio.
Download videos from kewego.com.
List people in a Gnus killfile.
A low-tech solution to syntax-highlighting examples in LaTeX files, having not found a listings class that works well for me. Have a look at the demo to see how to use it; the idea is that you tag alltt environments with a magic comment to say they should be highlighted, and the script will then edit your LaTeX file to update the highlighting.
Command-line program to control a Sony LDP-3600D (or -1500, or similar) laserdisc player via its serial port.
Feed all the messages in a maildir to SpamAssassin, then move them to a different maildir. I use this to speed up spam learning; to mark something as spam, I move it to my spam-learn folder, and then this script will run from cron later and learn it in the background.
A disassembler for the Royal McBee LGP-30.
Convert an Apache mime.types file into the equivalent lighttpd configuration.
Given a URL to an HTML file, print the links from it, one per line. You can then filter the output and xargs wget, or similar.
Python wrappers for various Linux-specific system calls, including unshare and prctl; you can use this to set up Linux container facilities from Python.
A tool which will list the people who've posted to a given newsgroup, and can maintain a list to identify new posters. This was built to make it easier to automatically send "welcome" messages to new posters on an internal newsgroup.
Tune in a MythTV decoder, read the MPEG stream from it, and write it to stdout. You can pipe this into MPlayer to watch live TV from a MythTV machine without using the MythTV client — which is much more convenient if you just want a TV window in the corner of your desktop.
Grab all the articles from an issue of Linux Journal. Useful for later PalmPilot reading.
Specialised version of rsscomics for Looka.
Run a command, and use eflite to speak a message saying whether it succeeded (e.g. loudly make all on a big project).
You don't really need an lpd on a single-user machine with an inkjet attached, provided you can write to the printer port. This script uses setlock and ghostscript to safely print Postscript without needing a daemon.
lsh is an implementation of SSH that's a bit more paranoid about security than OpenSSH is; when first connecting to a machine, it won't automatically remember the host key. This automates the process of adding "captured" host keys to lsh's cache.
A script I wrote back when I first learnt LaTeX to perform a reasonably accurate word count on a LaTeX document. You'll need to fix the embedded path.
Make it easy to log into remote machines when you've got some that use ssh, some that use Kerberised telnet, and so on.
Unfinished magnetic poetry hack for xscreensaver. Based on xscreensaver code, so it should be under the xscreensaver license.
Uses hashes of Message-Id headers to identify duplicate messages in a Maildir; pipe the output from this into xargs rm to delete the duplicates.
Given a maildrop log file, generate statistics on how many messages get delivered per day to folders matching regular expressions. I use this to graph how much of my mail is spam or viruses.
Older mailman installations don't let you automatically discard messages from people not on the list. If you administer a mailman list that gets a lot of spam, this gets very annoying. This Python script logs into mailman's web interface and discards any messages that are waiting to be moderated. It needs the mechanize modules.
In 2003, UKC were having performance problems with their mailservers: mail was taking several hours to be delivered. This suite of scripts sent a test message through each mailserver every minute, used an Exim forward file to catch the responses, and produced web pages with graphs showing the time taken to deliver throughout the day; it was interesting to watch the delay ramp up as the load increased during the working day.
Construct a video file from several large collections of frames, selecting sections by times and adding captions. This is really intended for use with the video capture support in some of the KRoC libraries; I used it to make the CoSMoS and Kent CRG demo reels.
My lightly-modified version of the web.py-related markdown module for Python.
Do a quick, dirty and incomplete job of converting Markdown syntax to MoinMoin's Wiki syntax. You'll need to check the output afterwards, but this'll do most of the work for you.
Pretend to be an IRC Service, and op a given user in a given channel. We used to use this on UKCIRC before we had an ircd that allowed server ops to do this anyway.
A script to generate colour definition resources for pterm based on those that you've configured for rxvt-unicode.
Produce a Gnuplot graph of messages per time period in a mailbox. This works well with newsarchive to plot messages per week in a newsgroup over time.
Generate an HTML page from Markdown with M25 macros, optionally adding an index of headings. I use this when I need to produce some one-off standalone HTML.
The two parts of an analogue ADSL bandwidth meter system. My home router runs the src program as a daemon under onenetd, and the sink program runs on a Beaglebone Black with an analogue meter attached to a PWM output. The system shows network bandwidth in dB relative to 1Mbps with PPM ballistics, which works very nicely.
Convert MH mailboxes to maildirs.
Send a MIDI reset command to stdout. (I think I wrote this when I had a soundcard with a MIDI synth that sometimes got confused.)
Convert a standard MIDI file to a sysex dump. I wrote this so I could poke around my D110's patches with an editor.
A basic fortune program, with the standard misbehaviour of favouring long fortunes (because it works by seeking to a random location, then printing the next fortune it finds). This has the dubious distinction of being one of the first C programs I wrote, using NorthC on the Amiga. "atsUNIX" was an environment I'd kludged together from descriptions of Unix commands and the examples in the K&R book.
Script to generate the CD images for my periodic backup; handles splitting the tar archive across multiple discs, and generating parity volumes to allow recovery from damaged media.
Given a directory full of scanned menu images, join them together and scale them to the size I use on the fivegeeks menus page.
Automatically generate CVS snapshots from a repository. It only creates a new tarball if the content will differ from the old one, so you don't end up wasting space on a snapshot per day when no progress has been made.
Generate sparse files of the given size.
Print commands to pipe into an FTP client to recreate a directory hierachy.
Convert a .wav file to a mono .mp3. I use this for processing lecture recordings, after editing and normalising in mhwaveedit.
Given a directory of music files, create symlinks so they can be easily sorted by author or song title, and generate playlists. I originally wrote this back when xmms was called x11amp.
Wrapper script for MPlayer to find the First Audio Stream in an MPEG file (i.e. the lowest-numbered one) and select that. This is for use with MythTV's MPEG recordings from DVB, where higher-numbered streams are audio description rather than programme audio.
Convert media files to Ogg Vorbis audio, using MPlayer to do the decoding. Useful when you've got a damaged or oddly-encoded file that other players can't handle.
A Python module to read values from a serial-attached multimeter (currently only the Digitek INO2513).
Edit filenames in a text editor.
Scripts for MythTV to drive a Philips OnDigital digibox automatically. You would have to be mildly insane to want to do this.
Attempt to figure out XMLTV IDs automatically for MythTV DVB-S channels by fuzzily matching the names to channels.dat, removing teleshopping and other junk channels at the same time. This works well for a lot of channels, but names like "ITV2" and "ITV3" confuse it since it's just using the edit distance.
Convert kingofsat.net's transponder listings into the format that dvbutils understands. Handy for initial setup of DVB-S for MythTV.
Extract audio and video recordings from MythTV's archive, and produce them in a format that I can watch with a regular video or audio player. I mostly use this for shifting radio recordings onto my portable player, to listen to while I'm walking to/from work.
Convert an old MythTV .nuv recording into MPEG4. Don't use this; use encode-prog (above) instead.
Search MythTV's recorded programmes database, optionally printing commands to copy the appropriate files into an archive directory.
Force MythTV to reschedule. Handy if you've got a script (like reuse-listings.pl) that does magic stuff to MythTV's database behind its back. Like anything that talks MythTV's network protocol, this will be fragile with regards to MythTV versions.
Given a MythTV recording (in the old .nuv format — I haven't used this for several years), generate a synthetic recordings entry for it and copy it back into the storage directory.
An LD_PRELOAD-able library that traps the V4L set-video-standard ioctl and turns any PAL entry into PAL-I. I wrote this for old versions of MythTV that didn't know about PAL-I, but it should work with any bit of software that has the same problem.
If you've got a MythTV machine in the UK that has both DVB-T (Freeview) and FTA DVB-S (Freesat) tuners, you're probably finding it annoying that listings data for the satellite channels is hard to come by — in particular, there's no XMLTV source that provides listings for the radio channels. However, there's a perfectly good EPG on the equivalent DVB-T channels! This script copies the listings from one set of channels to the other (matching them up by channel number) and harmonises the names and callsigns, so MythTV will use either source for recordings. Run this from cron periodically. (I was really proud of this, but I suspect its potential userbase can be counted on the fingers of one hand...)
Update the XMLTV config automatically from the MythTV channel list. Run this nightly before mythfilldatabase.
Python module for interacting with MythTV. This was abstracted from some of the programs in the mythtv directory. Since talking the MythTV protocol itself is difficult — it's messy and tends to change between versions of MythTV — this makes use of database queries and direct access to the storage directories.
A CDDB client that renames files in a directory. Obsoleted by cdsuite (twice).
The Netgear DG834GT router is based on Linux 2.6 internally. This script lets you abuse a bug in its web interface to run shell commands (provided you've got the admin password). I use this to add some extra iptables rules to get 6to4 tunnelling working.
Convert firewall rules from a Netgear DG834 to the format that OpenWRT uses. (It was slightly quicker to write this than do it by hand.)
Start a second webserver on a Netgear DG834GT router with a couple of CGI scripts to output statistics.
Back when I used mutt for reading mailing lists and my mail folders were stored as mboxes (i.e. two generations ago at the time of writing, since I moved to MH and then to maildirs and Gnus), this script listed the mboxes with new messages in.
Recent versions of the Linux kernel support per-process filesystem namespaces. This tool spawns a process in a new namespace and waits for it to exit. It must be run as root.
Archive messages from a newsserver into gzipped mboxes. The advantage of doing this is that you can keep a lot of history around without slowing down your newsserver very much, and it's typically much easier to search an mbox (using Mutt or grepmail). Written to work with Leafnode, since it figures out the list of groups by listing the interesting.groups directory, but it'd be easy to modify it so the list were configurable or obtained from another source.
Produce statistics on the top posters to a newsgroup. I used to take printouts from this script along to ukc.misc meets. It can exclude users by pattern, and highlight users in a file (I used this to list the users I'd killfiled).
An implementation of the classic Nibbles game (called "Snake" by Nokia) in Bash shell script: you guide a worm around the screen eating food, and the worm's length increases as you eat more. Does terminal-independent output, adapts to terminal size, and includes a high score table. This may be interesting as an example of how to write an interactive game in shell script, although I wouldn't really recommend doing it yourself.
A kernel module for Linux 2.4 that disables the ptrace system call for non-root users. Based on sacrine's module, with the prototypes corrected to match 2.4. Later vulnerabilities have rendered this obsolete; if you're running a kernel old enough to need it, then you've got more serious local root holes to worry about.
Use osd_cat and setlock to flash messages in the corner of the screen.
A quick Perl script to mangle some nroff source I was given into MoinMoin Wiki syntax.
A miniature command-line client for the NX remote desktop system. This needs the binaries from the NX open source releases, and should work against the demo server and the OpenNX server.
Given objdump disassembly output, convert the absolute addresses into function-relative addresses. This means that you can diff two dissassemblies more effectively.
A one-process-per-cell implementation of Life in occam. Compiled with KRoC, this runs at about two frames per second on a 140x140 grid (i.e. 19,600 processes) on my old K6-2 machine. Screenshot showing the R pentomino a few hundred generations down the line. (I wrote this as an undergrad, but I keep coming back to it; see my CPA2005 paper for some of what I got up to...)
A programmatic and command-line interface to the OED Online. To use this, you'll need access to the OED; I use it through UKC's proxies, which mean I don't have to authenticate to it. If you do, you'll probably have to change the code.
Utility module for several of the other Python programs here.
A "true" clone? Yup, but what it's used for is things in my crontab that should only run when I've got an Internet connection; they're invoked as "online && whatever". Editing this turns off all the stuff at once.
A suite of commands for opening new browser windows. Pick a browser and symlink the appropriate script to openurl; you can then do "openurl someurl" to open that URL in a browser window, openurlnew to open a new browser window on your home page (that you'll need to configure), openurlsel to open the URL in the X selection in a new window, and opengoogle to do a Google search for the X selection.
Origami-style fold display function for VIM. Mario's Kent VIM Extensions provide a more complete Origami emulation.
Run an application as another user, creating a temporary home directory from a template and allocating a unique user ID. This uses Linux container facilities (user and filesystem namespaces). I use it most often to launch a temporary vanilla Firefox session: otherme firefox -no-remote.
The original version of otherme, which used real users and ssh to localhost; it's less elegant than otherme, but portable to platforms other than Linux.
Like xargs, but run the generated commands using a configurable number of parallel processes. This is useful if you've got a set of jobs that you want to run on a multiprocessor machine — for example, you could do "find . -name '*.jpg' | parargs -n4 mogrify -resize 100x100" to use four processors. I wrote it for Mirror Service statistics processing.
A pretty specialised tool for handling assessment marking. This takes a text file with comments and marks for each student, expands M25 macros (very handy with big classes), computes overall marks, and generates email feedback and CSV reports. If you've had assessment feedback from me at Abertay, it's come from this tool.
Persistent cat. Read a file and write it to stdout; if it gets a read error, it closes the file, reopens it, seeks to where it was and tries again repeatedly. I wrote this for recovering data from unreliable CDRs: this will usually pull data off a CDR that's giving read errors. (It's not magic: if the data substrate's actually damaged it won't get the data back, but it's quite often effective against fingerprints and scratches.)
Extract a range of pages from a PDF file using Ghostscript. Analogous to psselect.
Attempt to find mnemonics for phone numbers based on the letters marked on phone keypads. (Not very useful for me, since all my phone numbers contain 1s or 0s!)
Calculate dependencies for occam-pi programs, and update the list of dependencies in a Makefile.am automatically. I wrote this for use with the pony source, but it should be applicable to any automakified occam library.
A wrapper script around the Plucker crawler program: you can point this at a set of directories or Zip files, and it'll do its best to turn each one into a sensible Plucker database. It's designed specifically to work well with the Baen HTML books.
The Travelling Salesman Problem route plotter, as used by four generations of UKC CS students. I wrote it in my first year and put it up on a web page for people to use, and it turned out to be popular enough that the lecturer asked for it again the next year. Needs a coords file listing towns (in the format "Fort William 56n49 5w07").
Add simulated CCD noise to an image. Useful if you want to simulate the appearance of a webcam from a static picture.
Download media files from a podcast. I'll probably turn this into a rawdog plugin at some point.
Add a prefix to all the given filenames.
Download shows from American Public Media, and encode into a reasonable format for my portable player.
Use a simple genetic algorithm to generate "primal squares".
Python module for showing progress displays.
Trivially simple (and essentially useless) memory tester. Use memtestx86 instead.
Output a random dark background colour for a terminal. Using this each time you open a terminal window looks a bit odd, but does make it easy to tell windows apart.
The daemon for my electricity usage monitor.
An example of how to do cheap-and-cheerful timed recording with sox. I used to record UKCR shows this way.
Given some HTML, reformat it such that each sentence starts on a new line. (Doing this means that CVS diffs between revisions of the file have less noise, since minor changes only change individual sentences.) This turned out to be a remarkably interesting problem to solve.
Convert a MythTV recording into an MPEG file that gopdit can edit. Useful if you want to trim a recording before feeding it to encode-prog.
Extract a script from a compiled Ren'Py game.
Re-encode a PDF file using pdftops and ps2pdf. I use this for producing print-ready PDFs of conference proceedings.
Reset an Arduino by toggling the DTR line on the serial port. This works out of the box on newer Arduinos; on older ones, you can get the same effect by adding a 0.1uF capacitor between the FT232R's DTR pin and the AVR's reset pin.
Figure out who's using each Solaris workstation in a lab. More complex than it sounds, because you can do a remote X login from the CDE login box without actually logging in to the machine; this script therefore checks the server they're most likely to be using. Very much obsolete — the machines that it ran on were sold off at auction last month (many to people who'd grown attached to them as users).
Apply the ROT-13 transform (13-step Caesar cypher) to text. Every machine should have this script.
My replacement for MRTG: pull data from various (configurable) sources, update RRD databases, and generate some simple HTML with some graphs. It's a bit rough-and-ready, but it seems to work pretty well, and it's more efficient and easier to configure than MRTG for the sorts of sources I use (which tend to be random fields parsed out of text files, rather than SNMP). Have a look at the config files for some examples of how I'm using it.
Get a matrix into row-reduced echelon form. Written in my first year at UKC, because I very rapidly got bored with doing this by hand for maths assignments.
The script that by all rights ought to be called "godwar", because it does the opposite of rawdog: it takes HTML pages and produces RSS from them. This provides a few moderately-fancy options for dealing with pages where you're interested in the images rather than the content (web comics, for instance). The configuration file has lots of examples. Requires Python 2.3 and curl.
Import tickets from RT into Trac. This does a fairly quick-and-dirty conversion that'll need some tweaking by hand afterwards, but it worked pretty well for migrating the KRoC bug database.
Run a program with standard output connected to a file, where the file is named using an strftime pattern; when the filename changes, the program is restarted. I use this with zvbi-capture to take timed snapshots of Teletext.
Python module for reading and writing files atomically.
A little tool for generating Sallows pangrams by using Robinson's random technique. ("Adam Sampson found this sentence, which includes five As, one B, four Cs, five Ds, thirty-two Es, eight Fs, two Gs, nine Hs, fourteen Is, one J, one K, two Ls, three Ms, twenty-three Ns, sixteen Os, two Ps, one Q, seven Rs, thirty Ss, twenty-one Ts, five Us, seven Vs, nine Ws, two Xs, five Ys and one Z.")
Convert Openbox 2 menus to Openbox 3 format. Obsoleted by sanemenus (for me, at least).
Convert menus in a standard format to Openbox 2, Openbox 3 and XFCE formats; should be easy to extend to cope with more (since it can do both "nested" and "linked" menus).
Speak a phrase using a speech synthesiser. (I like eSpeak's Northern English voice.)
A procmail filter that uses a speech synthesiser to announce incoming mail. This turned out to be really annoying after a while (particularly once spam became a problem).
Run a program in a new GNU screen window, and wait for it to finish. I use this to wrap my editor as a background editing command in ginsu.
Stitch together a screenshot on a dual-head, non-Xinerama X system.
The core of a simple WSPR receiver using a tuneable SoftRock radio.
Send a X keypress to a program. Based on some lircd source that did approximately the same thing. This is useful for "press return in that window in ten minutes"-style automation tasks.
A few years ago, quite a lot of Linux machines didn't have the "seq" command. Since I use it quite frequently, this script emulated enough of it to be useful.
The Fivegeeks shopping list. The list is displayed in the order that items can be found in the supermarket (which saves a lot of time), and prints an estimate of the price. Unless you go to the same supermarket as me, you'll want to customise the items file for locations and prices in your local supermarket.
Copy a stream of data from stdin to a Shoutcast (or similar) server. I wrote this originally for Funkmaster, but it's quite useful if you want to set up some ad-hoc audio streaming system.
Wrapper for feh that rotates and scales a digital photo appropriately to fit on the screen.
Display my to-do list (which also includes dated entries and so doubles as a diary) in a nicely-formatted fashion.
Firmware and hardware for the Simple Microcontroller-Based Autorecorder, a PIC-based device I designed for timing radio recordings (or anything, really).
Given a list of files, identify those which differ only by a few bytes. I wrote this to help sort through a big collection of EPROM images.
Convert Samba config file to NFS exports.
Suppose you've got two machines connected by a relatively slow network, and a large collection of data that you want to sync from one to the other periodically. This script will let you do so by carrying a hard disk back and forth between the two machines.
An easy frontend for the Festival speech synthesis system.
Spell out words using the ICAO spelling alphabet ("india charlie alfa oscar").
Another useful little program: "while (1) ;". Useful for testing tools that manipulate or display processes or system load.
Solve (in a horrendously inefficient way) the square-packing problem where you have to fit squares of size 1 .. N into a square of size M. The display is quite nice, but it'd be much faster if it just tracked the corners of the squares...
Extract files from a .srf-format archive, as used by "You Don't Know Jack" and a few other games.
Start SDR-Shell for a SoftRock RXTX Ensemble.
Read a message from stdin and deliver it into an MH folder. Extremely useful with formail for bursting mail digests.
C code that provides a varargs strjoin function.
Yet another useful-but-trivial program: make this setuid, and it'll give you a root shell. Last used when I managed to lock myself out of root on my machine, but could still drop this onto an NFS filesystem it mounts.
The simple approach I used to create System-V-style init scripts before I switched over to using Upstart.
Synchronise files onto an MP3 player, converting formats where appropriate.
Attempt to tag Ogg Vorbis and MP3 files automatically based on their filenames. (I don't use tags myself, but I wanted to try out Rhythmbox at one point.)
Produce a diff between the contents of two tarballs. Useful for comparing two released versions of a piece of software to see what's changed.
A frontend for tar, gzip etc. which makes handling multiple archives in different formats relatively straightforward; tart t <files> will list the contents of the given files, and tart x will extract them. tart copes with tar archives in gzip, bzip2 and compress format, and could easily be extended to cope with other compressors and archivers. I have t and x aliased to tart t and tart x in bash.
A web-based bookmarks manager, heavily based upon the old del.icio.us interface before it got Yahooed. It uses SQLite, provides Atom feeds, and supports del.icio.us's XML format for backups.
Convert Telsa Gwynne's diary to RSS. Obsoleted by rsscomics.
Some package I was installing a while ago wanted a "tempfile" program that'd print out a temporary file name (which is unsafe, but I didn't particularly want to fix the program). debian-utils includes one, but in case you don't want to install all of that, here's my implementation.
The clock in the corner of my screen is a urxvt terminal running this program. This shows the time, and a CPU meter that's sorted to make it easier to get a feel for the load.
Clean up various oddities in a Git repository resulting from previous conversions from CVS, Darcs and Mercurial. This is very specific to my repositories.
Runs a program for a period of time, sending it SIGTERM once done. I wrote this for doing timed recordings of radio and TV programmes.
Measure how long it takes to read the time using various mechanisms on Unixlikes.
Given tinydns-format DNS records, notify secondary nameservers using nsd-notify.
Given tinydns-format DNS records, generate BIND-format zone files. I wrote this for use with PowerDNS and nsd, but it should work with most nameservers. It has some extensions for IPv6 support.
Send mail to myself with the provided subject. Who needs a to-do list when you've got an inbox?
Convert Wiki text from UseMod (at least, the subset that Compsoc was using) to MoinMoin format.
Generate square wave sample data.
Encode audio files, applying sensible tags based on the filenames. I use this along with Ardour, to automatically produce sets of lossily-compressed tracks from live recordings; I can just name CD track markers appropriately in Ardour, and this'll figure out appropriate tags.
Convert filenames from one character set to another recursively. Most software expects UTF-8 filenames these days; this tool is useful if you're transferring files to or from a machine that uses a different encoding.
Incrementally reencode my music collection from FLAC to Ogg Vorbis, for use on portable devices. (I have enough disk space at home that I can keep both versions around, but only the Ogg version will fit on my laptop.)
The Transpose-O-Matic CGI script; takes text files containing chords and lyrics, and transposes the chords or generates Nashville numbers.
The CGI script that powers my all-purpose search box. This just mangles its arguments into the right format for the chosen search engine and redirects the user there.
Decode base64 strings on stdin, coping intelligently with broken or missing padding at the end of the input.
Read pairs of hex digits on stdin, and write the characters they represent to stdout. I think I wrote this for converting some EPROM images at one point.
Utility module for writing Unix tools in Python (e.g. simple filters).
Execute a command only if a filesystem isn't full. I use this as a wrapper for fetchmail, to prevent my mail system from digging itself into a hole if my home directory fills up.
Reformat IRC log snippets into the format I use for my quotes collection. This'll cope with the output from most IRC clients.
Scan my maildirs directory (which contains all my mail folders), and create appropriate symlinks for Gnus. I run this periodically from cron; if I decide that I don't want Gnus to see a folder, I mv the symlink from .nnmaildir to .nnmaildir-not.
Various scripts for maintaining virtual hosts that we host on us-lot.org's machines. Given a tree of directories, it builds Apache, tinydns, qmail, exim and webalizer configuration automatically. There are more sophisticated automatic systems out there, but this one works quite nicely for us on the small scale.
Extract strings that look like radio frequencies from arbitrary text, and emit a tk500 CSV file for my radio scanner.
A target for a "validate this" link; redirects to the W3C validator for the referring page. Obsolete, since the W3C validator can do this itself now.
Read the contents of a CD to verify it's been burnt correctly. (Uses md5sum, since that guarantees that every byte's been read; an alternative would be just to cmp against the original files.)
... and this is that alternative; I use it now instead of verify. This compares a burnt CD to the image file it was created from, showing a handy progress display as it goes. It's smart enough to ignore errors inside the 300 KB pad that cdrecord appends to images.
Record video using MEncoder.
Generate MIDI events from a Guitar Hero controller. This binds various useful notes and chords to different combinations of fret buttons (triggered when you press the strum bar, like in the game), and lets you switch between different keys and between guitar and bass using the Select/Start buttons. It's probably a bit specific to the USB adaptor I was using, but it's definitely fun to play with; you can manage a fairly convincing "Smoke On The Water" and "Come As You Are" with it, at least.
Start VLC, tuned to a satellite channel from szap's channels.conf. The command-line options needed for VLC's DVB support are a bit arcane, so the wrapper makes it much easier.
Run a command, and see whether its output is different from the last time it was run. You can run this from cron to monitor, for instance, DNS changes, or the contents of a web page. (I wrote it to alert me when the mirror.ac.uk handover occurred in August 2004.)
Using inotify, watch a directory for files that have just been closed for writing, and print their names. I've used this to automatically play/view downloaded files.
Fix up a particular variety of broken WAV file (one which claims to have 24-bit samples but actually has 32-bit samples). Writing this was somewhat quicker than doing the recording again.
A reasonably fancy script for exporting a directory of files through a web server. As well as nice index pages, it also does download rate limiting on a per-connection basis.
Programmatically upload pages to a MoinMoin Wiki. Note that MoinMoin's rate limiting will bite you if you want to upload a lot of pages; do a sleep 30 between them.
The Dining Philosophers problem implemented using Win32 threads and locks. (I was playing with some debugging tools on a training course.)
Look up prices for all the items on my Amazon wishlist, and report them in a single list from cheapest to most expensive. Useful for spotting whether anything's currently available cheap second-hand.
Compare my Amazon wishlist with the appropriate file from the source to my web site, and tell me which items need adding and removing to bring them back in sync.
Given a patch reject file, try to figure out why it didn't apply by showing the diff between the file being patched and the original file the patch came from. This is designed to make fixing patches while merging easier.
First steps towards a Python program that can dynamically rearrange the windows on my desktop. Includes a not-very-useful spring embedder layout algorithm.
Write a given byte to the data lines on the parallel port. Useful if you occasionally build random devices that need a few control lines from a PC.
Convert XFCE 3's GTK configuration into X resources for various applications. XFCE ended up with their own script to do the same thing, and XFCE 3 is long obsolete anyway.
Summarise a list of files into a single one, using a command that takes two files and produces one output. For example, if you've got a bunch of images of the same subject and you want to stack them all to reduce noise, you can use this along with an appropriate ImageMagick tool to do the job.
A little program that lets you set arbitrary XVideo attributes — useful for changing the overlay colour or head at runtime, for example.
I'm currently using a Radeon 9200SE card with Xorg, using a monitor plugged into its RGB output. XV output by default goes to the first head, which is the DVI output; on the RGB output, you just get a plain dark blue window. This tool changes the appropriate XV property to get output to go to the second head.
Convert "You Don't Know Jack"'s sound files into more useful formats: WAV for the uncompressed music tracks, and AIFC for the compressed speech (which you can then uncompress to WAV using aifc2wav).
A three-way coin toss implemented in Befunge. (OK, so I got fed up with writing "Hello World" programs...)
Download video files from YouTube. VLC will play the Flash video files this outputs.