note: I am trying to publish, a piece at a time a lots of tricks that I use in my email management system, in such a format that each of them is usable separately. This is why it may be a bit difficult to understand certain parts of this and other pages, until I have published all of them. In the meantime, please let me know about anything you find not clear in these pages, so I can improve them, and read this article of mine on how to Build your own email server with Postfix, because it is a good synthesis of the whole picture

All email messages have a set of hidden headers that can be used to filter email in a million different ways, for example to ignore uninteresting threads in mailing lists. Some kinds of filtering require that you first extract and write to a file some header from each email message. The rest of this page shows to way to do this, one for the Mutt email client and another that is much more general and can be even used with webmail, if you have the right environment. The examples below show the code I use to extract the headers of mailing list messages I want to ignore, but the technique can be easily generalized.

The Mutt way

Mutt is a powerful text-based email client that many people (including me) still use not because they like to suffer, but simply because Mutt is much more configurable than all other clients around. in Mutt you can independently define macros for the “index view”, that is the listing of all messages in the current mailbox, and for the “pager view”, which is the one displaying the content of the selected message.

Here are the two macros that you need in order to extract an header from whatever view you’re in and write it to a file:

  macro index X     "|formail -XMessage-ID: | cut -d: -f2  | cut -c2- >> $HOME/.MAIL/ignore.MUA.cachen"
  macro pager X     "|formail -XMessage-ID: | cut -d: -f2  | cut -c2- >> $HOME/.MAIL/ignore.MUA.cachen"

in this case, the selected header is Message-ID. We extract it with a chain of three commands. To understand what each of them does, let’s run the first alone, then the first two, then all of them:

  [marco@polaris]$ cat sample_email |  formail -XMessage-ID:
  Message-ID: <BA3D918879B942D48484D4F6B9D1DC6A@example.com>
  [marco@polaris]$ cat sample_email |  formail -XMessage-ID: |  cut -d: -f2
   <BA3D918879B942D48484D4F6B9D1DC6A@example.com>
  [marco@polaris]$ cat sample_email |  formail -XMessage-ID: |  cut -d: -f2 | cut -c2-
  <BA3D918879B942D48484D4F6B9D1DC6A@example.com>
  [marco@polaris Procmail_irrelevant_threads]$

As you can see, the formail program extracts from the message the whole line containing the requested header. The first invocation of the cut utility (cut -d: -f2) splits that line in two fields, using the colon as separator, and keeps the second one. The last command (cut -c2-) strips the first character of its input, becaus it takes all the characters of the received string, starting from the second one. Therefore, we’re left with the

The general way

If you use the maildir format for mailboxes, every mailbox is a directory and every message is a text file in one of its subdirectories. You can still use procmail to add the Message-ID of a message to a cache file in this way.

First of all, create a separate maildir folder (let’s call it .uninteresting/) reserved to uninteresting messages. Second, create a cron job that every few minutes scans all the files in the .uninteresting/ subdirectories and feeds each of them to procmail with a command like this:

  /usr/bin/procmail -m irrelevant_files_recipe.rc < ${CURRENT_FILE}

This is the content of irrelevant_files_recipe.rc:

  :0hc:ignore.cache$LOCKEXT
  | formail -D 524288 ignore.cache

  .archive_of_irrelevant_threads/

This is a recipe that just locks the cache file, adds to it the Message-ID header of the current email with formail and then writes a copy of the message to a dedicated folder (you could just tell procmail to add that copy to /dev/null, which is like not doing it, but I prefer to keep a copy anyway, just in case).

Once you have that maildir folder and the script using this procmail recipe set up, you’re set. Instead of telling your email client to run a macro on the uninteresting messages, simply move them to the .uninteresting/ mailbox. The cron job will find it and tell procmail to add its Message-ID header to the cache, so the other procmail recipe will block every replies before they enter your mailbox. As you can see, the good thing in this other approach is that it works whatever email client you use, even if you switch client, as long as you have access to maildir mailboxes on a Linux/Unix server.