Over a year ago I saw mod_mbox. I love they way it provided nice looking archives and an Atom1 feed for a mailbox archived in the mbox2 format. I knew immediately that I wanted this for some Mailman lists which I provide.
Mailman does store its archives in mbox format. Unfortunately mod_mbox wants one mbox file per month, named a very specific way.
Here is how I got there. First, the tools:
- Mhonarc is a mail to html converter used by popular sites such as mail-archive.com and lists.debian.org.
- Mharc is a web-based mail archiving system for multiple mailing lists.
- Mharc has a tool called mbox-month-pack which does (almost)exactly what I want.
- Mailman is already configured.
- mod_mbox just needs to be plugged into a pre-configured apache.
The Procedure:
Mailman stores its archives in /var/lib/mailman/archives/private/ with complete mbox archives in one file in a file named ${list}.mbox/${list}.mbox. I just need to feed that to Mharc’s mbox-month-pack.
Massage the filenames a bit:
for i in ????-?? ; do mv $i ${i/-/}.mbox ; done
Setup Apache as the mod_mbox docs say.
Modify mailman’s list_members program to extract a encrypted password for each member, with output suitable for basic http authentication.
— /var/lib/mailman/bin/list_members   2007-06-12 08:49:33.000000000 -0400
+++ /var/lib/mailman/bin/list_members_pass      2007-11-08 23:04:20.000000000 -0500
@@ -80,6 +80,10 @@  
from email.Utils import formataddr  
+import crypt
+from random import randint
+import string
+
PROGRAM = sys.argv[0]
ENC = sys.getdefaultencoding()
COMMASPACE = ‘, ‘
@@ -140,6 +144,11 @@
         return status <> MemberAdaptor.ENABLED
     return status == WHYCHOICES[why]  
+salt_chars = ‘./’ + string.ascii_letters + string.digits
+
+def crypt_password(password):
+    salt = salt_chars[randint(0, 63)] + salt_chars[randint(0, 63)]
+    return crypt.crypt(password, salt)  
def main():
@@ -258,14 +267,16 @@
         rmembers.sort()
         for addr in rmembers:
             name = fullnames and mlist.getMemberName(addr) or ”
+            password = crypt_password(mlist.getMemberPassword(addr) or ”)
             # Filter out nomails
             if nomail and not whymatches(mlist, addr, why):
                 continue
–            print >> fp, formataddr((safe(name), addr))
+            print >> fp, formataddr((safe(name), addr)) +”:”+password
     if digest:
         dmembers.sort()
         for addr in dmembers:
             name = fullnames and mlist.getMemberName(addr) or ”
+            password = crypt_password(mlist.getMemberPassword(addr) or ”)
             # Filter out nomails
             if nomail and not whymatches(mlist, addr, why):
                 continue
@@ -278,7 +289,7 @@
                 # They’re getting MIME digests
                 if kind == ‘plain’:
                     continue
–            print >> fp, formataddr((safe(name), addr))
+            print >> fp, formataddr((safe(name), addr)) +”:”+password  
 
Wrap all of this up in a nice little script and insert into cron so that messages, usernames and passwords are refreshed hourly or daily.
#!/bin/bash  
MAILMAN=/var/lib/mailman
MBOXMONTHPACK=/usr/local/mharc/bin/mbox-month-pack
LISTLISTS=$MAILMAN/bin/list_lists
LISTMEMBERSPASS=$MAILMAN/bin/list_members_pass  
for list in `$LISTLISTS -b` ; do
  INPUTFILE=/var/lib/mailman/archives/private/$list.mbox/$list.mbox
  OUTDIR=/var/mbox/$list
  if [[ ! -d $OUTDIR ]]; then mkdir $OUTDIR; fi
  if [[ ! -f $OUTDIR/.htaccess ]]; then
    cat >$OUTDIR/.htaccess <<EOD
AuthType Basic
AuthName “mailman Password Required”
AuthUserFile /var/passwords/$list.pwfile
Require valid-user
EOD
  fi  
  $LISTMEMBERSPASS $list > /var/passwords/$list.pwfile  
  $MBOXMONTHPACK $INPUTFILE -outdir $OUTDIR
  pushd $OUTDIR
    for i in ????-?? ; do mv $i ${i/-/}.mbox ; done
    mod-mbox-util -v -c .
  popd  
done  
 
libapache2-mod-mbox is available on my Launchpad PPA.
mhonarc is available by default in debian.
mharc you will have to get the source and build.
- Say what you want about RSS vs Atom. I don’t care. Any tool that matters supports both… except mod_mbox.
- Yes, mbox isn’t the ideal mailbox format, but in this case it works