procmail
[Top] [All Lists]

Re: Recipes based on date and time

1996-10-30 16:39:50
I had written,

| > Running date(1) for every incoming letter just to repeat information that
| > is already there is a waste of cycles.

Alan Stebbens replied,

| David, I appreciate your efforts at keeping the processing load down,
| but other factors to consider are:
| 
|  * how much time does it take me to write the recipe?
|  * how much time will I spend in maintaining the recipe?

Those two are fair considerations but will vary from person to person and
situation to situation.  You can't declare that one approach is always easier
to install and maintain than the other.  But more significantly, this last
objection of yours ...

|  * will the date be used to references files on my system; in other
|    words, should the date output be *consistent* and *reliable*?  

is not a problem, because the From_ line *is* consistent and reliable.

| Other folks, however, find it extremely convenient to use a line like:
| 
|     HOUR=`date +%H`           # get the hour

Now, note carefully: the preceding, which you are championing, Alan, gives
the current hour at the time of execution.  Procmail runs through the recipes
in your .procmailrc when the letter arrives on your system, not when it is
(re)sent to you and hasn't gotten there yet.  HOUR=`date +%H`, as you are
recommending, gives the hour of the clock when the message ARRIVES.  Keep
that in mind as you read on.

| As proof of how difficult it is to do things with dates and strings in
| the "procmail way", I have included my "date.rc" recipe file below.  

Major error, Alan.  What you proved is entirely different from what I said.

The reason your date.rc file is so complicated is that it tries to parse
the Date: header or the Resent-Date: header and thus tries to deal with the
various formats that assorted sending mailers may have used.

But the Date: or Resent-Date: header says when the letter was DISPATCHED. 
Mail does not arrive instantaneously, the (re)sender's system clock may be
misset, the time zone indicator may be one the recipient has never heard of
before and didn't allow for, or the (re)sender [I see this often] may have
copied the setup of someone in another time zone and reset the clock but not
adjusted the time zone abbreviations.  It's difficult to get the time of dis-
patch from headers, and the results are unreliable.  [On the other hand,
figuring out time of dispatch by your suggested alternative of running
date(1) when the message arrives is *impossible*.]  But here's the kicker:
the time of dispatch isn't what we want to know anyway!  It certainly has
nothing to do with Gilles's question.

What counts is the time of arrival.  The people who want to run different
recipes at different times are not talking about different recipes for mail
DISPATCHED at different times; they are talking about different recipes for
mail RECEIVED at different times.  For that, you need parse only the From_
line.  Maybe your incoming From_ lines have a different syntax from mine, but
what's important is that all your incoming From_ lines have the same syntax
as all of your other incoming From_ lines, and the (re)sending site can't
affect them.

Your claim that we need to parse assorted forms of Date: and Resent-Date:
headers to get the desired information is just plain false.  You called it
"proof", but you're comparing apples to oranges.  Proof that one can cut
oneself peeling an orange with a knife is no proof that it will happen
when one bites into an apple.  You showed it is difficult and unreliable to
determine time of dispatch from headers -- and it is -- but then you claimed
to have demonstrated the difficulty and unreliability of determining time of
receipt from headers.

The incoming From_ line has the proper information (timestamp of receipt)
and its syntax is consistent for any single user, regardless of the place
from which the message was (re)sent, the person or daemon who (re)sent it,
the time of the day, or the day of the week.

Here is my .datestringrc.  Notice that it is much simpler than your date.rc 
because it tackles a much simpler problem: it deals with a consistent input
syntax (the From_ line), it parses the information we actually want to know,
and it doesn't set up the combination variables that the user might not need:

 :0 # get date variables from From_ line but lose any trailing space
 * ^^From +[^   ]+ +\/[FMSTW].*[0-9]
 { WDMTY=$MATCH }

 :0
 * WDMTY ?? ^^\/...
 { WEEKDAY=$MATCH }

 :0
 * $ WDMTY ?? ^^$\WEEKDAY \/.*
 { MDTY=$MATCH }

 :0
 * MDTY ?? ^^\/...
 { MONTH=$MATCH }

 :0
 * $ MDTY ?? $\MONTH +\/[0-9].*
 { DTY=$MATCH }

 :0
 * DTY ?? ^^\/[0-9]+
 { DAY=$MATCH }

  :0
  * DAY ?? ^^.^^
  { ZERODAY=0$DAY }
  :0E
  { ZERODAY=$DAY }

 :0
 * DTY ?? ()\/..:..:..
 { TIME=$MATCH }

 :0
 * $ DTY ?? $\TIME +\/[0-9]+
 { YEAR=$MATCH }

 :0
 * TIME ?? ^\/..
 { HOUR=$MATCH }

 :0
 * TIME ?? ^..:\/..
 { MINUTE=$MATCH }

 :0
 * TIME ?? ()\/..$
 { SECONDCOUNT=$MATCH } # maybe another variable is named $SECOND or $SECONDS

 WMDTY MDTY DTY # no longer useful, clear them out

You want something that runs while you're at the office (ok, gross oversim-
plifications here, I acknowledge)?

  DAYHOUR="$WEEKDAY $HOUR"

  # all day weekends, every day until 7:59 AM, every night from 6 PM on
  :0
  * DAYHOUR ?? ^^(Sat|Sun)|(0[0-7]|1[89]|2.)^^
  { out_of_office_routine }

  # weekdays from 8:00 to 8:59 AM and from 5:00 to 5:59 PM
  :0E
  * HOUR ?? 08|17
  { commuting_time_routine }

  # weekdays from 9:00 AM to 4:59 PM
  :0E
  { in_office_routine }

Of course, that is not ideal if your goal is to get mail to the mailbox
you're going to read next; what you'll really want is to run the
in_office_routine from the last time you usually check email at home to the
last time of the workday that you usually check email at work (and a routine
for commuting time is unnecessary unless you don't drive and your laptop has
a special email address).

Additionally, keeping the load down is not a trifling matter.  The load
difference is not serious if someone mistakenly types

 cat file | program

once instead of the preferable

 program < file

but calls to date(1) in .procmailrc might be run with every piece of mail
received and for every user who runs date(1) in .procmailrc.

<Prev in Thread] Current Thread [Next in Thread>