[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.

Making scrollbars wider on Ubuntu 18

[Written on Jan 7th, 2019.]

User interfaces must get worse as time goes on. Useful functions get removed, and unwanted, unnecessary, and difficult ones get added. Navigation gets more difficult by requiring inefficient actions and the meaning of the iconography is obscured, so it's harder to find out where things actually are and what they mean.

Sadly, in computer science and user interfaces (and many things in general), that is, in essence, the definition of progress.

I have a (new) laptop computer.

It has a trackpad.

I hate trackpads.

I cannot type without it interpreting my hands being near the keyboard as commands for it to scroll the window I'm typing in or move the cursor, so I'm overwriting text or program code that I did not want to erase or corrupt.

So I disable the trackpad. To be fair, it seems like Macs have long ago been able to filter out extraneous input, though I've only used them a small number of times for brief periods. And Windows seems to have improved as well, but again, I didn't use it for long. The trackpad on Linux, on the other hand, is unusuable to me. But for various reasons that are off-topic, I choose to use Linux.

My laptop, a ThinkPad, has a trackpoint mouse (the little red eraser thingy) which I find very convenient, so that is my main way of navigating user interfaces.

The current fad in user interfaces is to make scrollbars really, really thin, and possibly have them disappear unless you happen to move across them, then they will appear, only to disappear as you pass over them. This might be great for smart phones, but I use a laptop and a mouse where, contrary to assorted hype, it is not great.

Ubuntu 18 has embrached this shitty design. And the variant tha I'm using, Pop!_OS (a terrible name, but it was the first O/S that didn't lock up when I tried to install it on my new laptop) has the fake, shitty Mac look to the user interface that inspires the very popular "experience" of rage. Also, my screen is 4K, which means it's even more frustrating to play "find the scrollbar". (I do have magnification on, which helps but has its own bugs.)

I am using the Mate UI because the Pop!_OS UI is, for me, very difficult to use and a piece of crap. MATE is good enough in terms of layout and functions and stuff, mostly. But I wanted wider scrollbars. And while people have asked and talked about it on various web sites for about a decade, a lot of it didn't work for me.

So here's what I had to do to make Firefox, Palemoon, programs using Gtk+, gnome-terminal (mate-terminal ignores the settings, but I like gnome-terminal and it works), and others to have wider scrollbars. I've got mine set to 40px. Adjust your setting to what suits you best. If the files mentioned below do not already exist, then create them. If they do exist, add this to them (shouldn't matter where).

Programs like Palemoon use Gtk 2.0. Add the following to the file ~/.gtkrc-2.0:

style "scroll"
    GtkScrollbar::slider-width = 40

class "*" style "scroll"

Note the following fixes the scrollbar width and the too-wide spacing of icons to start programs on the top of the screen. The first few lines below packs the icons in the Mate launcher at the top of the screen tighter together. Last section is what worked for the Gtk+ programs for me.

Then add the following to ~/.config/gtk-3.0/gtk.css:

.mate-panel-menu-bar menuitem {
    padding: 0 0px;

scrollbar {
	-GtkScrollbar-has-backward-stepper: true;
	-GtkScrollbar-has-forward-stepper: true;

slider {
	min-width: 15px;
	min-height: 15px;

And finally, to fix it so clicking button 1 in the scrollbar's trough will scroll a page at a time instead of jumping to the location, add the following to ~/.config/gtk-3.0/settings.ini:

gtk-primary-button-warps-slider = false 

Note that clicking mouse button 2 warps to the location, like always. Programs must be restarted for these changes to take effect. So you must shutdown all instances of xterm (or gnome-terminanl or Firefox or whatever).

Most likely things will change (i.e., more progress) and these fixes will break. You know, more progress. The GtkInspector was useful for figuring out the names of what elements or properties to change.

This page last modified May 28, 2021.
RSS Feed