Thursday, January 31, 2008


In a quick, pop-up, chat session, yesterday, Vergil Mueller pointed me at this set of palindromes.

He was alluding to my Gmail chat status line: "A man, a canal, Panama."

This is a deeply geeky in-joke.

The program finger(1) dates from the early days of Unix. By typing finger dmr you could find out if Dennis Ritchie was logged in, and information like his login, home directory, and shell. finger would even run the finger protocol over the internet and give you the same information from the remote machine.

If you had a $HOME/.plan file, it would print out the contents, so you could tell everyone what you were doing: a primitive Twitter. (Chat and instant messaging are, themselves, just gussied-up talk(1).)

If you didn't have a .plan file, it would announce "No Plan."

I was too lazy to keep mine updated (really, everyone was), but I wanted to have it say something, so my .plan file always read "A man, a canal, Panama."

Yep: "no plan."

Vergil asked whether the Linux finger had ".plan" files. You bet. Try it yourself:
$ finger $LOGNAME | tail -2
No mail.
No Plan.
$ echo "Whatever" > ~/.plan
$ finger $LOGNAME | tail -2
At least on Berkeley systems, root's default plan was "Rootin' around in the file system," but that seems not to be true on either Linux or OS/X.

Sondra Blanchard

Here's Sondra, illustrating another phone-camera setting: night mode.

Both pictures were taken last night, at the Wednesday-night old-timey jam, which I've hosted for the last twenty-five years or so.

Last night, the weather was grim -- on my drive home from work, I was watching the buses in front of me slide around -- so the only other folks who showed up were Sondra, Sandra-Leigh Sprecker, and Hal Landem. Sondra and Sandra-Leigh are both beginners, so Hal and I walked them through Sugar in the Gourd, in an impromptu beginners' workshop.

I also gave Hal three fiddle bows that I picked up in the Hospice Thrift Store for $6 apiece. They'd had their hair clipped off, so he took them home to see if he could figure out how to re-hair them.

Wednesday, January 30, 2008

Kristina Williams

Kristina Williams, who showed me the trick to not losing the caps from my USB devices, took me out for a walk yesterday. It was cold and blustery.

I'd poked through the menus on my camera phone, and found a "sequence" setting. It takes seven pictures, in sequence, with one click of the shutter.

I explained to Kristina that I wanted to try it, to see how closely spaced the photos in the sequence were.

So, I want you to move around while I take this shot. I'll count to three, then snap it and see what comes out.

Uh. Okay.

One ... two ... three.

Here are the first two of the sequence. In the other five, she's grinning at me.

Easy Backups: Cleanliness is Next to Godliness, part 2

Yesterday, I talked about how I back up my machine at work, and why.

I build my backup scheme around SVN, which I also use in my day job as Software Configuration Manager at Aztek Networks. It's easy, it's powerful, I know how to use it, and it even has unexpected side benefits.

How about my home machine?

On my home machine, I use git.

git is the SCM system used for the Linux kernel. The basic use is the same as SVN, but it has some real design differences. Every tree controlled by git contains the whole repository. It's self-contained, so you can carry it around with you.

It's built to be distributed: there is no central repository. This lets the thousands of kernel developers each have their own, entire, SCM system, without having to go through a central bottleneck.

As you'd expect, some very good synchronization tools come as part of it.

Actually, a lot of things come as part of it. Basic usage is commands that look like CVS or SVN -- git checkout and git merge instead of cvs checkout and cvs merge or svn checkout and svn merge -- but there's a lot more. My current suite has 58 git commands.

A pair of these are git clone and git pull. git clone creates a tree that's a clone of another. Later, git pull pulls new changes from the tree you cloned.

I keep my home directory under git. I used git clone to put a copy on a USB key drive. Every morning, I
  1. check in my latest changes
  2. plug in the key drive
  3. use git pull to synchronize the backup copy with this laptop

Where do you get git? Here.

And why didn't I just embed the video? I've never done that and didn't have time to figure it out in this 15'.

Tuesday, January 29, 2008

Marcia Derr

Marcia does Latent Semantic Analysis, for Pearson.

Her photographic advice is, "Don't have a tree coming out of your subject's head."

So, we tried it. In the first picture, an intentional tree. Not good. In the second picture, meant to be the "see how much better this is?" she's grown antennae.

At least, now, I know what she means.

Easy Backups: Cleanliness is Next to Godliness

I do backups. No, really.

I even back up my own desktop box at work. For historical and manpower-shortage reasons, IT only backs up servers; I may be the only person whose desktop is backed up.

I don't bother to back up my OS. I take updates every day, as they come in, and I install the most recent release of whatever Linux distro I'm running as soon as it appears.

Packages? Yum and apt are such good package installers, that I can't remember the last time I built something from a tarball. I'm more accustomed to apt and its relatives, like Synaptic, because I'm running Ubuntu, but I've used both.

By default, bash on Ubuntu even tells me what package I'm missing if I try to use a command and it isn't installed.
jsh@jsh-laptop:~$ logtail
The program 'logtail' is currently not installed. You can install it by typing:
sudo apt-get install logtail
bash: logtail: command not found
(For other distros, this behavior is a shell option.)

My home directory is a different story: it's idiosyncratic and irreplaceable.

What do I use? I do Source Code Management on it. I'm an SCM guy, so it's second-nature.

At work, I set up a Subversion (SVN) repository on my desktop, and check-in my home directory every day. Then I rsync my SVN database with a 4G USB thumb drive. The drive's not even close to full, and affordable key drives are growing faster than my repository.

An unanticipated side-effect is that I finally, now, clean up my home directory.

I'm a pack-rat, and used to accrue files, which stayed around for years after I'd forgotten what they were for.

Now, I just do an "svn stat" at the top level and deal with every file that SVN tells me it doesn't know about. Either they go into the repository, with a comment that says what they're for, or they get removed. Daily.

My script to "snapshot $HOME to SVN" doesn't let me take the snapshot until all these files are handled.

So, first thing in the morning, I come in, pull the key drive out of my desk, pop it in, and run the script. It forces me to clean up, then snapshots to SVN, and then rsyncs the repository with the thumb drive.

Then I put it away. GTD.

Cleanliness is next to Godliness.

Large code trees, which I always have several of sitting around for work, are handled by the corporate SVN server, hosted on CVSDude. I put them in ~/tmp, where they come and go, and use svn:ignore to tell my desktop tree that it doesn't need to nag me about them.

But how do I handle my home machine -- this laptop? Stay tuned. My 15' is up for today.

Monday, January 28, 2008

How to Embed Presentations in Web Pages

Google is growing its on-line presentation tool -- its PowerPoint. The presentations aren't animated -- I hate animated presentations anyway -- but they do have several things going for them.
  1. I can make them, in a browser, from anywhere. You can see them, in a browser, from anywhere.
  2. Sharing. I can co-build a presentation.
  3. I don't need to carry them around. I can walk in, connect someone else's box to a projector, and show my presentation from the web.
  4. I can embed presentations in a web page.
I can create simple spreadsheets with Google's spreadsheet tool that have the first three properties, but not the fourth. To see how cool that is, here's a presentation I did for Larry Hunter's lab, down at the med school, a couple of months ago:

I just created the presentation, clicked on Publish, and cut-and-pasted the HTML it gave me.

If someone reading this knows how to do this with spreadsheets, tell me.

Sunday, January 27, 2008

Luke Eisenhauer and Joy

Mike Rosenlof, another photographer I know, says, "If your equipment sucks, get closer." (He says this isn't his idea, but I'll take stolen advice, anytime.)

I experimenting with distance last night , with pics of Luke Eisenhauer, and his sweetie, Joy, at a Stanleytones show.

Here's a series of three distances -- near to far.

The first shot is Luke.

The next three are Joy and her friend, Mary. Joy's the brunette, Mary, the readhead.

The last one is the Stanleytones. Luke's the bass player, way in the back. It was supposed to be a picture of the Stanleytones; it's a picture of stairs, with a chopped-off, Bose column at the center left.

Mike's right, eh?

Using Google Calendar to Monitor Software, part 5

Last, but least, here's a cheap trick I sometimes use with the code to make Google calendar entries from the command-line.

(1) Set up a calendar to monitor a set of events.

The instructions for setting this up are in the previous posts. Basically, you just create a Google calendar for each kind of event you want to monitor, and then stick the calls to the code into the scripts that run the events.

In my case, the events are nightly checkouts, builds, and tests, plus weekly CVSDude dumps, and releases.

(2) Make a file containing the code for embedding the calendar

Go to Google calendar, and click on:

Manage calendars -> Share this calendar -> Calendar Details

Then copy the HTML to embed the calendar and paste it into a file, like /home/jsh/bin/frog.html.

(3) Create a bookmark for that file.

In Firefox, go to that file [ e.g., file:///home/jsh/bin/frog.html ], and bookmark it. (I'm sure there's something analogous in IE, but I've never used IE so I
wouldn't know.)

(4) Make it into a sidebar.

Left-click on the bookmark, select "Properties", and check the box that says "Load this bookmark in the sidebar."

I have a folder, on my bookmarks toolbar, that contains all my monitoring sidebars. Whenever I want to see how something's been doing, and I don't want to load my entire calendar, I just open the folder and click on that sidebar.

Using Google Calendar to Monitor Software, part 4

Here's the last piece of the code I use for monitoring cron jobs with Google calendar. If you want to use it, this is the only piece you should need to customize.

You can use it for any number of calendars you want, but you need to put them all into the hash. This requires being geeky enough to know Perl. If you're geeky enough to want to monitor cron jobs with Google calendar, that's probably not a stretch.

#!/usr/bin/perl -w
# $Id: 5853 2007-04-02 16:46:01Z jhaemer $

# hash of calendar names and urls
our %url = (
frog =>

# put your gCal login and password here
our $login = '';
our $passwd = "your_password_here";

# or, you could call this
sub getpw {
use Term::ReadKey;
print "password: ";
my $password = ReadLine(0);
chomp $password;


Using Google Calendar to Monitor Software, part 3

I use Google Calendar to monitor automatic software execution in cron jobs. Here's the code.


#!/usr/bin/perl -w
# $Id: cal_event 5853 2007-04-02 16:46:01Z jhaemer $

use strict;

# get proprietary information from the accompanying file
# ""

my $app_dir = `dirname $0`;
chomp $app_dir;
push @INC, $app_dir;
require cal_event_proprietary; # defines %url, username, passwords
our %url; # the calendar_name => url hash

# get calendar and event from command line
@ARGV > 1 || die "usage: $0 calendar_name description\n";
my $calname = shift;
my $url = $url{$calname} || die "$calname: no such calendar\n";
my $title = "@ARGV";

# login
our ( $login, $passwd );
use Net::Google::Calendar;
my $cal = Net::Google::Calendar->new( url => $url );
$cal->login( $login, $passwd );

# create entry
my $entry = Net::Google::Calendar::Entry->new();
$entry->when( DateTime->now,
DateTime->now() + DateTime::Duration->new( minutes => 1 ) );

my $tmp = $cal->add_entry($entry);
die "Couldn't add event: $@\n" unless defined $tmp;

# $Id: cal_event 5853 2007-04-02 16:46:01Z jhaemer $


=head1 NAME

cal_event - announce an event in a Google calendar


cal_event calendar_name description


Makes an entry in the named calendar.


This program makes it easy to track status of cron jobs from a simple, calendar
interface, just by calling the program from the cron job.

if [ $? -eq 0 ]
cal_event ${0##*/} SUCCEEDED
cal_event ${0##*/} FAILED

=head1 BUGS and CAVEATS


=item *

Expects username, password, and calendar info in F.
See F for details.

=item *

All calendars need to be in the same account.


=head1 FILES

=head1 SEE ALSO


=head1 AUTHOR

Jeffrey S. Haemer

Using Google Calendar to Monitor Software, Part 2

I've been keeping track of cron jobs with a shell script that posts calendar events. Here's the README file.


# $Id: cal_event_notes 5853 2007-04-02 16:46:01Z jhaemer $

Setting Up Your Google Calendar to Track Scheduled Events for Dummies

First, create a calendar to play with.

- Log in to If you don't have an account, follow the instructions and create one. Remember your login and password.

If you already have a Google calendar, you can use it, but I suggest setting up a separate account.

- On the left-hand-side, find the list of Calendars, then follow your nose, like this:

Calendars -> Manage calendars -> My Calendars -> Add calendar

- Start out by creating a calendar called "Frog", to convince yourself this all works. Don't bother to fill in the details: just take the defaults, including "Do not share this calendar with anyone." When you create a calendar to hold real events, you'll fill this stuff in. This is just a test.

- Click on "Create Calendar" and you'll be taken back to the main, calendar page. You should see "Frog" over on the left, in your list of calendars.

Make sure it's checked, so events in the Frog calendar actually display.

- Now go here:
Calendars -> Manage calendars -> My Calendars -> Frog
This time, you'll see calendar details. You want this:
Private Address -> HTML
gCal will put up a little pop-up with an amazingly long URL that the "cal_event" program needs. It'll start with "http://"

- Put your cursor on the URL, and right-click (on a Mac, control-click) to get a context menu, and select "Copy Link Location".

When you've copied it, go ahead and click "Okay" to get rid of the popup, and click on the "Google" logo, in the northwest part of the page, to return to the main calendar.

- Edit "" and insert that URL into the %url hash, like this:
%url = (
frog =>
All the punctuation is important, but you'll have a different URL.

- Now edit "" and put in your login where it says to:
our $login = '';
our $passwd = "foobarmumble!";
If you don't want anyone to see these, change the permissions of so only you have permission to read it.
chmod 600
For programmers:

Admittedly, you could put the login and password into environment variables, and use statements like this
our $login = $ENV{CAL_LOGIN};
our $passwd = $ENV{CAL_PASSWD};
but that just pushes back the problem. Where will you set those? You can also prompt for the password, but that makes running cal_entry from scripts impossible, and negates the whole point of having this script.

- Try (at last!) running the calendar notification program, "cal_event" like this
cal_event frog A sample event
In a moment, you should see the event appear on your Frog calendar.

That's it. Now, go back and add as many real calendars as you want to this account, and then post events to them to your heart's content. They'll all display in the same place, and the different calendars will be in different colors. To look at or hide individual calendars, just check or uncheck boxes over on the left.

I tend to use the month view, and to drill down, I click the Day view tab.

If you've done this in a separate account from your own calendar, you can share the calendar with yourself, and watch the events from the comfort of your own calendar page. Go here:
Calendars -> Manage calendars -> My Calendars -> Frog -> Calendar Address -> Change sharing settings -> Share with specific people
and share it with your normal calendar account.

The calendars are searchable (Google's a search company), so I put enough information in the description to let me search. For example, if my dump script fails, it calls
cal_event dumps "FAIL: dumps"
then, I can search for FAIL to find all failures or "dumps FAIL" to list all dump failures.

I keep my entries pretty spartan, but you can put more in if you like. See the man page for Simon Wistow's Net::Google::Calendar. You'll need to modify cal_event, which is a Perl program. If you don't program in Perl, go make friends with someone who does. You can always use more friends.

Saturday, January 26, 2008

Tom Christiansen

Here's Tom Christiansen. Tom came by my work yesterday, and took me out for a walk while our network was bouncing. My guess is that our router/firewall is dying.

These are cell-phone pics. I got a Nokia 6263 around Christmas, when my old phone started to die. This one has a camera -- they all seem to, nowadays.

A teeny cell-phone camera is a sharp technical limitation, but perhaps this will help me focus on what I can do within the form. Writing a good limerick or haiku is the same kind of problem. Confined within a sonnet, Shakespeare somehow managed.

What can I learn from trying to take better pics with a cell phone? Composition, for one. Not putting my thumb in the picture, for another.

What else? I'll find out. Expect to see a lot of pictures.

Tom, who's a serious photographer, had me take these two pics to show me how much effect lighting has. Well, okay, I see. The one on the left looks a lot better, to me.

The one on the right, in bright sun, has too many different light levels for the camera to be able to handle. Rembrandt, with oils, could do this kind of chiaroscuro. Me, with my Nokia 6263, not so much.

Using Google Calendar to Monitor Software, Part 1

I monitor things: builds, dumps, releases, automated tests. These are tasks that run periodically, from cron jobs, unattended. I don't need to intervene, but I do need a record of what happened, and an ability to see how things have been going, at a glance.

It's a lot to watch. I could use Nagios, or text logs, or spreadsheets, but none of these has the right feel for date-and-time data.

Date and time data belong on a calendar.

Somewhere, long forgotten, I saw a post by folks who'd used Java to turn system administration data into Google calendar entries. Google calendar has an API, so I tried it myself.

Google calendar means I can share it with other folks who care -- like my boss.

Google calendar means I can make little calendars for each thing -- each its own color -- and watch them all at once.

Google calendar means I can search it. It's my "to-did" list.

I used Perl because it's familiar. I've used it for years and so I can cobble stuff together, fast.

In the next couple of posts, I'll
  • show how to set up the calendar(s)
  • offer up the code, which makes entries from the command-line
  • show how to set up Firefox to watch the entries in a sidebar
The last one's just a convenience. Me, I mostly just go right to my calendar.

Friday, January 25, 2008

Jon Corbet

Yesterday, at work, we finished a Linux Device Drivers class, taught by Jon Corbet, senior author of ORA's Linux Device Drivers book and editor of Linux Weekly News.

I taught Jon in a class ,when he was a beginning grad student, freshly down from the high plains of Wyoming.

He reviewed the printing chapter of Barbie's Guide to Linux. In the draft he reviewed, I'd named a printer "haemer." His comment was "Haemer. Is he still alive?"

I renamed it "corbet."

Jon autographed my copy of the book, "Nice to be on the other side of the classroom after all these years."

Nice job, too, Jon.

I took these pics with my new, Nokia 6263, uploaded over bluetooth. That was fun.

USB Devices

I lose caps to USB devices. I'm amazed that I haven't lost the devices themselves.

To help me fix this, Kristina drilled holes in the caps of my two, USB key drives, and then attached the caps to the drives with dental floss, which is hard to break.

The drive I use to back up this Linux laptop is on a lanyard, looped around the iBook next to it. I pop off the top, stick it in, do the backup, then unplug and recap it.

Fifteen Minutes a Day

I write fine. I just don't write fast.

This blog will help fix that. I'm giving myself 15' a day to write something technical. I have a timer next to me, right now, ticking away.

Run, Jeff. Run.