[Title Bar]

Programs and other cool stuff I've done

[X] [C] [Go] [Python] [Perl]

General Tips:
[SMTP-AUTH config] [Intuos4-VirtualBox config] [Fixing Missing DLLs on Win10] [Sendmail not writing to a file]
Anyone can use the code I put here, just credit me if you do so.


Back in the day, in grad school, I had written a number of cool, cute little tools using X Windows. They include:

(Note that Tom Fine has improved and now taken over the maintenance of xlax. His page on it is here.)

, and finally
crock, consumer of much of my time, but sadly ignored by the world
( README file, source code, and image data).

I haven't used these programs in many years, so no guarantee bit rot hasn't taken place.


I've done a bunch of C hacking, but nothing that jumps to mind right now as worthy to showcase.


Go is a new-ish language (2009) from Google, designed Robert Griesemer, Rob Pike, and Ken Thompson that's compiled into a statically linked binary, is C-like with a bunch of differences, and has built-in support for concurrency. So I decided I should look into it.

After noticing lots of extra garbage (dozens of zip codes) in the weather program I regularly use, I re-wrote the it in Go as weather.go. It's twice as big as the Expect script version, but I had to use a lot more explicit error checking. It was a good exercise on spawning remote processes, with bi-directional, unbuffered I/O through pipes, regular expressions (matching and replacing), timeouts, and a minor bit of concurrency. It's not a bad language.


I figured I should learn Python, since it seems to be quite popular with "the kids" these days. I rewrote Dice Minion in it to give me something to do. It's a simple program to track D&D stats, using pygtk as the graphical user interface. (Note: the current version is DM4, rewritten in Python3, using GTK+ and YAML, and is now a tool for DMs instead of players.)

I wrote a simple 1-person bananagrams-like program in Python and GTK. The tar-file is here. Current version is 1.2 (updated Nov. 14, 2013).

I worked with others on a project that used git and github, and its built-in bug-tracking system. It was clunky to use their web interface, and I wanted to import the bug database into a spreadsheet. So this is a simple Python program that uses GitHub's web API to dump a bug database into a comma separated value (CSV) list.


Dice Minion is a program to track stats (hit points, healing surges, used powers, etc.) for 4th Edition D&D "character builder" generated character sheets. More information on the Dice Minion page. The current version is in Python.

Here's a weather script in perl to connect to the wunderground weather server and print useful information. It's the back-end behind xforecast, mentioned above.

As of January 2018, it seems the weather underground has discontinued their weather server. So I wrote a new weather script that pulls data from It just downloads a web page, parses the information, and prints it. Pretty straightforward. I'm sure the site will change soon enough and break it. Most servers now require an account with an ID token. But for now this works to get a simple view of the current conditions and the forecast for the week.

This script gets aviation weather reports (METARs and TAFs) for U.S. airports using (Updated Oct 24, 2013 to use

I wrote an address book program to manage addresses as well as remind me of birthdays. Here is a page that documents the program. Once, when I was stuck at an airport and out of touch, electronically, I realized I needed a way to print a hardcopy of the address book. So, I wrote a script to print a "little white book". It generates postscript output and requires that you have this postscript header file too.

Altavista was a cool search engine. I like google better. However, babelfish was very cool. So I wrote a script that provides a command line interface to babelfish, suitable to be use with pipes as a filter.

I'm working on a web based adventure game. I've got the basic engine done and the world will be created based on a story Pierce and I wrote. Unfortunately, I haven't had much time to put into this in a while. At some point there'll be a link to it.

As part of the GIAC Certified Forensic Analyst (GCFA) practical exam, I wrote a tool to help investigators conduct experiments on the effects of different archiving programs. The tool is called tar2d2 and (sort of) stands for "Testing of Archivers for Reference of Restored Disk Data," but in fact it is just "a little helpful droid."

Pretty much all of the code running MyCause is mine. That is not public, at the moment.

Junk Mail Filters

I got sick of getting too much crap junkmail, so I wrote a simple procmail filter that puts my mail in either my inbox or a junkmail box, based on the output of a program. The junkmail program applies 4 rules.
  1. Does the Received: line match the From: line?
  2. Is the host in the Received: line listed in the open relay data base (
    [Update] ceased to exist in 2006, so that check should be removed from the code before use!
  3. Is my name listed in the To: or Cc:? and
  4. Does the mail have a Content-type: text/html or multipart tag?
If the answer to any of these questions is "yes" then the message is considered to be junkmail. (Yes, all HTML mail is considered junk by default. There are 3 exceptions to the above rules.
  1. If the From: address is included in the EvilFucks list, then no matter what, it is considered junk.
  2. If the From: address is in the GoodFroms list, then it's OK. All aliases in my .mailrc file are automatically added to the list.
  3. If the To: address is in the GoodTos list, then it's OK (this handles people that send Bcc:'s a lot or mailing lists that put the list name in the To:).

It seems to do a pretty good job filtering mail. But then I wondered, exactly how good of a job was it doing? So I modified the script to automatically add an entry to a log file for each message it processes. Of course, it sometimes gets things wrong. So then I write the jmlc (Junk Mail Log Corrector) Program. Run it and cut-and-paste the "From " (note: not the "From:") line of the mail message as standard input and it'll mark the proper entry in the log file as being misfiled.

Then I wrote the jstats (junkmail stats) program. It takes two command line arguments, a start time and and end time, both of the form: MM/DD/YYYY [HH:MM[:SS]]. It prints out:

Sample output is:
$ 09/01/2003 09/17/2003 23:09
1062388800 1063854540
1329 total messages
201 filed as good, 1128 filed as junk
18 misfiled as good, 5 misfiled as junk
188 actual good, 1141 actual junk
Junkmail is 85.85% of total mail
False positive is: 2.66%, false negative is: 1.58%

Not too bad. On average I get 60-80 pieces of junkmail a day and this makes it manageable (under 3% failure rate).

Linux Graphic Battery Monitor

I use the fvwm2 window manager under Linux; I don't use GNOME or KDE. Every damn battery program I've seen seems to assume you're using one of those window managers. So I decided to write a quick wrapper around the acpi(1) command to provide a visual indication of the battery status using Perl/Tk. Below is an example of what it looks like.

image of battery monitor graphic

It indicates the percent battery power, shows a graphic, showing 1-10 rectangles (1 rectangle=10 percent power, 10=100 percent power), and the rectangles change from green, blue, yellow, and red, to indicate full, good, low, and critial levels of battery power. Below the graphic are optional messages that indicate how much time is left on the battery (e.g., "03:14:34 remaining") or how long till it's fully charged (e.g., "00:15:35 until charged").

An appropriate entry in /etc/X11/fvwm2/system.fvwm2rc or one's own personal .fvwm2rc file to put it in the Button or Menu bar would be something like:
*FvwmButtons: (Swallow FvwmXbattery 'Exec -name "FvwmXbattery" -geometry +0+0 -padding 1 -bg rgb:91/ae/d6 &')

Here's the source for

As an aside, I was at a conference (Usenix 2008) when I started writing this, as I wanted to know how much battery power was left when I was working while not plugged in. Within a few hours, my battery died—we're talking fried, going from working fine to totally holding no charge. Nothing I did, really (calling acpi won't damage it), but the timing was amusing. I was very tempted to simplify this whole process by just displaying a permanent "0%" in red in a window and being done with it.

General Tips

The following are things that took me time to figure out, sometimes on my own and sometimes putting together bits and pieces from various sources posted on Internet sites. I wanted to put them somewhere, so maybe someone with a similar problem might see how I did it and save some time.

Configuring imap and sendmail smtp auth

I set up a new mail server and wanted to read mail remotely via imap and post (relay) mail via smtp auth. It turned out to be a rather painful process that required me to dig into imap, sendmail, pam, sasl, openssl, xinted, certificates (and CAs), and more. While this information is pretty specific to my configuration (CENTOS 5) and some of it is due to some SASL libraries missing, and there's no central place to put the information I discovered, I figured a write up on what I did might help someone somewhere. So here's my writeup on this adventure.

Configuring an Intuos4 tablet under VirutalBox

I got a Wacom Intuos4 pen tablet and wanted to use it on my Windows XP VM under VirtualBox (with Ubuntu Linux as the host) on my laptop. This is the description of how I got it to work. Sort of.

Fixing missing DLLs and other Win10 problems

Windows Photo Viewer under Windows 10 stopped working, complaining about a missing .dll file, which was still there. The fix was straighforward but tedious. Things seemed to work afterwards.

First off run start a command shell (DOS) with admin priviledge. Then:

sfc /scannow

Details will be in %WinDir%\Logs\CBS\CBS.log. It will be long and useless.

Then run:
dism /Online /Cleanup-Image /CheckHealth
dism /Online /Cleanup-Image /ScanHealth
dism /Online /Cleanup-Image /RestoreHealth

And then once again:
sfc /scannow

All of these commands will take a long time to run. Afterwards things might work again.

Errors making Sendmail write to a file via aliases file

This is a short one. I created a mailing list and wanted to add an extra entry in the /etc/aliases file so it would archive the messages to a file. I was getting bounced email with error messages of the form:

----- Transcript of session follows -----
550 5.0.0 /home/username/Mail/mailinglist-log... Can't create output

The fix was to create the file and make it owned by group "mailnull" and give it group-write persmissions. In other words:

# touch /home/username/Mail/mailinglist-log
# chgrp mailnull /home/username/Mail/mailinglist-log
# chmod 664 /home/username/Mail/mailinglist-log

And then things worked.

This page last modified Mar 20, 2018.
RSS Feed