procmail
[Top] [All Lists]

Re: Possible solution >> Re: IMAP filtering, how to mark my own messages read

2005-10-10 11:45:47
At 12:38 2005-10-10 -0400, Timothy Luoma wrote:

The filenames have a set format, but the format does not have to be
followed.(see footnote1)  If you can GUARANTEE that the filename will
be unique, you can use whatever filename you want, it just HAS to end
with

     :2,S

So I'm trying to think of the least CPU-intensive way to come up with
a a unique identifier.  The best one I've come up with thus far is
"date '+%s'"

If you receive two messages within the same second (check a busy mail 
server sometime - this isn't anywhere near as rare as you might think - ESP 
if your connectivity goes down for a while and your mail starts flowing in 
from a backup MX all at once), then this approach will pretty much be 
guaranteed to give you non-unique filenames.

Write yourself a tiny C program to create the file and return the filename 
to you.  'man mkstemp'

Here's a really simple scrawling:



// proctmp.c            SBS 20051010/1125

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXFNAMELEN     256

// simple C program to generate a unique filename and return it to the caller
// (with the file created, so it'll remain unique).
// retval is 0 on success, and 1 on failure, for easy check from caller.

int main ( int argc, char *argv[] )
{
         char    sFName[ MAXFNAMELEN ];
         char    sFNameNew[ MAXFNAMELEN ];

         if ( argc == 2 )
         {
                 // use path from commandline
                 strcpy ( sFName, argv[1] );
         }
         else
         {
                 // default to using current working directory
                 getcwd( sFName, MAXFNAMELEN );
         }

         strcat( sFName, "/mymailXXXXXX" );
         if ( mkstemp( sFName ) != -1 )
         {
                 strcpy ( sFNameNew, sFName );
                 strcat ( sFNameNew, ":2,S" );
                 if ( rename( sFName, sFNameNew ) == 0 )
                 {
                         // success
                         printf( "%s\n", sFNameNew );
                         exit ( 0 );
                 }
                 else
                 {
                         // remove the original file
                         unlink( sFName );
                 }
         }
         // error return
         exit( 1 );
}

//-----------


build with:
         gcc proctmp.c -o proctmp

With symbols stripped, this compiles to just 3.5KB on my system.  date is 25KB.


Lest you think this C program will be more intensive than your approach, 
please keep in mind that your invocation of 'date' will invoke a program 
many times larger and more complex.  This also makes use of mkstemp, which 
ensures kernel-level uniqueness to the filename (though admittedly, I'm 
then RENAMING the file, but that's on the presumption that the basename for 
a locked file should already be unique - your own recipe makes the same 
sort of assumption in that it used the date and then appends the string to 
the end) - your use of date will only ensure uniqueness if two messages are 
not processed during the same second.  Check your server logs sometime - if 
you process many messages, this simply will not be the case.

You _could_ deliver via piping to a program which creates the unique file 
(and verifies uniqueness during that process).


Anyone have any thoughts on this?  Is there a better/easier way to
get a unique identifier?

Uhm, use the one procmail saves the message with?  Shouldn't that be unique 
- if the message were to have ":2,S" trailing it when read, wouldn't a 
regular mail client have issues renaming the file, or do they rename it to 
a different basename as well?

         :0c
         $MAILDIR/.INBOX.Procmail/

         # if from self, mark it read by renaming it
         # (seems this would be faster than piping, but I haven't checked)
         :0
         * ^From:(_dot_)*lists(_at_)tntluoma\(_dot_)com
         * ? mv $LASTFOLDER $LASTFOLDER:2,S
         /dev/null

         # discard any unwarranted copy.
         :0
         /dev/null


I just caught Bart's post before sending this, and his approach of using 
TRAP seems much better.

The procmail recipes are untested.  The C code however is.

---
  Sean B. Straw / Professional Software Engineering

  Procmail disclaimer: <http://www.professional.org/procmail/disclaimer.html>
  Please DO NOT carbon me on list replies.  I'll get my copy from the list.


____________________________________________________________
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