Tuesday, June 03, 2003

People who know me may have heard me claim from time to time that I came up with the idea of the "buddy list" before AOL. Well, here's the deal on that.

In 1993, I was a freshman at the University of Alabama. In spite of the new connections I was forming at school, I was still quite close to my friends from high school. At that time the University imposed a hard limit on the number of long-distance minutes that a student in the dorms could use in one month (now I think they you use as many as you want, and just bill you for it later), and I quickly found it was possible to overrun this limit.

One of my best friends, a certain Brandon Downey, was a freshman at Tulane at the time. I quickly learned that I could save a lot of phone calls by conducting our chats using the Unix talk program.

The challenge was how to know when Brandon was online. He had accounts on about four different systems at Tulane, and I would have to finger all of them to see where he was logged in. This quickly became tiresome.

So I wrote a program called "watch" that would read a .watchrc file in my home directory containing all of the logins and systems that I knew about, and then poll every few minutes to see if he was logged in. I would start it in the background from my login script, and then whenever Brandon happened to log into any of his systems I would be notified immediately.

The .watchrc looked something like this:

bdowney@rs1.tulane.edu
bdowney@rs2.tulane.edu
downey001@math.tulane.edu
brandon.a.downey@student162.res.tulane.edu

It wasn't good enough to just finger each line of this file, like so:

finger bdowney@rs1.tulane.edu
finger bdowney@rs2.tulane.edu
finger downey001@math.tulane.edu
finger brandon.a.downey@student162.res.tulane.edu

That would result in getting Brandon's somewhat wordy .plan file, and any indication of whether or not he was currenty logged in would be presented in a way that was difficult to recognize. The program had to parse out the host names, and run finger(1) on each of them:

finger @rs1.tulane.edu
finger @rs2.tulane.edu
finger @math.tulane.edu
finger @student162.res.tulane.edu

This would simply return a list of everyone who happened to be logged to those systrems at the time. The program would search each system's list for Brandon's login name on that system, and if it found him it would send some ASCII beep (0x07) characters to the terminal and print out something like "bdowney@rs1.tulane.edu is online!", interrupting whatever else I happened to be doing in the foreground. I would immediately shell out of whatever program I was using and initiate a talk session.

It was probably the first actually useful program I wrote on Unix. (I had previously written a similar extension to the WWIV BBS system, that would cause the computer to feep whenever certain people logged in, including anyone identified as female.)

This list of Brandon's logins was basically what the "buddy list" does in AIM and the various AIM imitations. It alerts you when your buddies log on. As far as I know, AOL (or possibly ICQ) "invented" the buddy list in 1995 or 1996. I think I had mine working perfectly by 1994 at the latest.

I no longer have any physical evidence of the "watch" program. The University has long since deleted my student user directory. I can't even remember if it was a shell script or a C program. The only proof of its existence is my memory and Brandon, who ought to remember being annoyed by me trying to start a talk session with him every single time he logged in.

Sometime later I re-wrote it in Perl. I managed to save that version, although I don't think I ever actually tried to run it (by that time nobody still let you finger their servers). It survived because I included it as part of email that I wrote to my self one night in 1997 while very intoxicated and/or bored. I just happen to have saved that email for posterity. Here it is, with only some especially self-incriminating parts excised. The perl script itself is pretty short:

#!/usr/bin/perl
#put the email address of all your friends in .watchrc

open(RCFILE,".watchrc") || die;

while(<RCFILE>)
{
    chop;
    push (@alist,$_) if $_;
}

$found=0;

while($found==0)
{
    foreach $thing (@alist)
    {
        ($uname,$host)=split(/\@/,$thing);
        open(FTEXT,"finger \@$host 2>/dev/null |");
        while ($fline = <FTEXT>)
        {
            if ($fline =~ /^$uname/)
            {
                print "\n\a" if ($found==0);
                print $fline;
                $found=1;
            }
        }
    }
}

Comments: