I run mutt as my primary mail reader, but I also use the webmail frontend SquirrelMail from time to time. It's nice to have both, because sometimes you want to check your mail on a random computer, and you don't want to install an ssh client to get a login to your system. With SquirrelMail, you can just go through the browser and chuckle at everyone stuck with hotmail and small mailboxes! Of course, you then need to maintain your own mail server...

Anyway, I use both mutt and squirrelmail, so I thought it would be nice to keep the address books in both programs synchronized. Mutt is my primary mail reader, so I made the decision to take the data from the mutt address book and use it to replace the data in squirrelmail. That makes the chore a little easier, as long as you understand that any changes in the squirrelmail address book will get erased.

First, I examined the respective address books. Luckily, both are simple flat text files. Mutt uses a whitespace-delimited file typically called /.aliases. SquirrelMail saves user address books in the web server document space, but the fields are bar (|) delimited instead. Clearly, I just needed to transform the one file to the other, and my task would be about done. Ha! There are some tricky corner cases to consider because the way delimiters work in the mutt alias file is kind of a nightmare.

Here's the resulting perl script. Careful, this one is not too pretty. The good news is it should parse just about any alias file you throw at it, whether or not the actual addresses are enclosed in angle brackets or not.


# mutt2squirrel - convert mutt alias file to squirrelmail addressbook
# format.
# Phil Hollenback
# [email protected]
# 6/11/03

while (<>) {
  # skip comments
  next if m|^#|;
  # skip empty lines
  next if m|^\s*$|;
  # skip lines with commas (indicating group aliases)
  next if m|,|;

  # this is tricky because the email address may or may not have
  # angle brackets around it.  Note use of '\b' to find the boundary between
  # alphanumeric and potential bracket - prevents bracket from getting
  # included in email address.
  ($alias, $name, $mail) = ($_ =~ m|alias\s+(\S+)\s+(.*)\s+<*(\S+)\b>*|);

  if ($name =~ m|.*\s.*|)
    # there is whitespace in the name, so extract first and last.
    ($first, $last) = ($name =~ m|\s*(\S+)\s+(.*)|);
    # trim whitespace from last name.
    $last =~ s/^\s+//;
    $last =~ s/\s+$//;
  } else {
    # no whitespace, so just duplicate the entry.
    $first = $name;
    $last = $name;
  # print out the line in squirrelmail addressbook format.
  print "$alias|$first|$last|$mail|\n";

Notes: this script expects a mutt alias file as input, and sends a squirrelmail address book format file to STDOUT. A couple of checks are made to avoid useless entries, like comments or group addresses.

I use this script with the following crontab entry:

32 * * * * $HOME/bin/ $HOME/.mutt/aliases.personal >/webdocs/vhosts/

(that's all one line). One caveat is I had to open the permissions on my squirrelmail address book slightly so that user phil could write to it, as by default only user www can. Another is that the first word of the username is used as the first name, and the rest of the words are all thrown into last name. That's because mutt doesn't make a distinction between those fields, but squirrelmail does.


Our Founder
ToolboxClick to hide/show