procmail
[Top] [All Lists]

RE: adding a missing Date: header

2008-10-03 19:29:04
A. Lester Buck III wrote Friday, October 03, 2008 8:56 PM:

I decided to add the date to any message missing that header in
procmail.  I didn't want to calculate the date string unless
the Date: header was missing, so this is what I came up with:

# Generate any missing Date: header
:0
* ! ^Date:
{
  :0
  { DATE_=`ruby -e "require 'time'; print Time.now.rfc2822"`}

  :0 fhw:
  | formail -a "Date: ${DATE_}" -a "X-Date: added date header"
}


While this does add a Date: header to any message without it, it also
ends up being evaluated as a delivering recipe. 

Actually, no, it's not a delivering recipe, thanks to your fw headers.

You don't want or need the lockfile colon, however.
That will give you an error message in your log.  It won't
actually do anything bad to the mail, though.

I would streamline this in any case.  You certainly don't need ruby,
perl, python, or anything like that.  Formail is useful (though it's
possible to do it even without that; it gets clumsy, though), so we
can just use that.

First of all, even if you were going to keep your current method,
you could have just done:

  :0
  * ! ^Date:
  {
     DATE_ = `your expression`

     :0 fw h
     | your filtering action
  }

IOW, you don't need the first recipe in the nested braces.  Just
a statement setting the var is enough.

For the expression, we could just use /bin/date -- much less work
than loading ruby.

  DATE_ = `date '+%a, %d %b %Y %H:%M:%S %z'`
  :0 fw h
  | formail -a "Date: $DATE_"

We could stop there.  But note that each message coming in has a
timestamp in the From_ header.  Let's use it.


  # ----------- start date-adding rc-file ------------

  :0
  * ! ^Date:
  * ^^.* \/(Mon|Tue|Wed|Thu|Fri|Sat|Sun).*
  {
      FROM_DATE = $MATCH

      :0
      * FROM_DATE ?? ^^\/[^ ]+
      { a_ = $MATCH }  # weekday

      :0
      * FROM_DATE ?? ()\/[0-9]+
      * MATCH ?? ..
      { d_ = $MATCH }

      :0 E
      { d_ = 0$MATCH }

      :0
      * FROM_DATE ?? () \/[A-Z]+
      { b_ = $MATCH }

      :0
      * FROM_DATE ?? ()\/[0-9]+:[^ ]+
      { HMS_ = $MATCH }

      :0
      * FROM_DATE ?? ()\/20[01][0-9]^^
      { Y_ = $MATCH }

      DATE_ = "$a_, $d_ $b_ $Y_ $HMS_ +0200"  # add your own TZ; that's mine

      # You could put all of this in a separate rcfile and run
      # INCLUDERC as desired.

     :0 fw h
     | formail -a "Date: $DATE_" -a "X-Date: added date header"
  }

  # ----------- stop date-adding rc-file ------------

It works.  Here's the test.  I put the above in a file called "rc".  
I added one more recipe at the bottom:

  # Test for Date:
  :0
  * ^\/Date:.*
  { LOG = "The Date header shows: $MATCH
" }

Now I ran it against /dev/null (which obviously won't have a Date: header).
I used the -f- flag to invoke procmail so that a From_ header would
be generated even on null input from /dev/null.  (You won't need the -f-
stuff in your .procmailrc.)

 1:13am [~/Mail] 691[0]> procmail -mf- DEFAULT=/dev/null VERBOSE=y rc < 
/dev/null"
procmail: [16537] Sat Oct  4 01:13:30 2008
procmail: Assigning "MAILDIR=."
procmail: Rcfile: "rc"
procmail: Match on ! "^Date:"
procmail: Assigning "MATCH="
procmail: Matched "Sat Oct  4 01:13:30 2008"
procmail: Match on "^^.*\/(Mon|Tue|Wed|Thu|Fri|Sat|Sun).*"
procmail: Assigning "FROM_DATE=Sat Oct  4 01:13:30 2008"
procmail: Assigning "MATCH="
procmail: Matched "Sat"
procmail: Match on "^^\/[^ ]+"
procmail: Assigning "a_=Sat"
procmail: Assigning "MATCH="
procmail: Matched "4"
procmail: Match on "()\/[0-9]+"
procmail: No match on ".."
procmail: Assigning "d_=04"
procmail: Assigning "MATCH="
procmail: Matched "Oct"
procmail: Match on "() \/[A-Z]+"
procmail: Assigning "b_=Oct"
procmail: Assigning "MATCH="
procmail: Matched "01:13:30"
procmail: Match on "()\/[0-9]+:[^ ]+"
procmail: Assigning "HMS_=01:13:30"
procmail: Assigning "MATCH="
procmail: Matched "2008"
procmail: Match on "()\/20[01][0-9]^^"
procmail: Assigning "Y_=2008"
procmail: Assigning "DATE_=Sat, 04 Oct 2008 01:13:30 +0200"
procmail: Executing "formail,-a,Date: Sat, 04 Oct 2008 01:13:30 
+0200,-a,X-Date: added date header"
procmail: Assigning "MATCH="
procmail: Matched "Date: Sat, 04 Oct 2008 01:13:30 +0200"
procmail: Match on "^\/Date:.*"
procmail: Assigning "LOG=The Date header shows: Date: Sat, 04 Oct 2008 01:13:30 
+0200
"
The Date header shows: Date: Sat, 04 Oct 2008 01:13:30 +0200
procmail: Assigning "LASTFOLDER=/dev/null"
procmail: Opening "/dev/null"
From dman  Sat Oct  4 01:13:30 2008
  Folder: /dev/null                                                         101

Btw, my procmail incantation knows my TZ, so I could have just
asked it to print the value of $TZ instead of typing it in hardwired.
But it will depend on your .forward file or you manner of invoking
procmail whether TZ is set right or not.

Dallman

____________________________________________________________
procmail mailing list   Procmail homepage: http://www.procmail.org/
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail