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