procmail
[Top] [All Lists]

Re: maintaining a list that procmail can check

2001-07-06 16:00:29
Before I get lost and forget, thank you, Don.

| It would surely break miserably if the list of files is large, but if the
| list of files is small enough to be contained comfortably in a variable,
| something like this may be an alternative.

It won't get large, and your use of LOG= to append was inspired.

| files=^A@@@@@^Aabc123^Adef456^Aghi789^A

There's a way around needing the @@@@@, which I bumped into by accident.
More on that later.

What surprised me -- and I tested it on the system where I'll be setting
up whatever I finally decide on -- is that INCLUDERC doesn't mind the ab-
sence of a trailing newline.

| The lack of a newline takes advantage of the fact that procmail does not
| append a newline (unless specifically told to).

I had no idea what you meant there until later I saw that you would be using
LOG=.

One thing it seems I didn't make clear: there won't be control messages to
test whether a name exists.  The testing will occur on all incoming mail, the
name applying to each message being derived from earlier recipes.  If the
name does not exist, procmail must add it and invoke the program that creates
the actual thing; I've written all that already and it's working.  Control
messages will for updating the listing when I do an add (of the actual thing
being listed) manually or when I do a delete (of the actual thing being
listed -- procmail will not be able to delete them but can update the list
when I delete one).

|     :0 E
|     * WHATTODO ?? ^^rm^^
|     {
|       :0
|       * $ files ?? ^A${FILE}\/^A.*

Let's move the ^A that follows the name to the left of the extractor, so that
$aftFILE starts with the next name (or is null in the case of the last entry).

        * $ files ?? ^A${FILE}^A\/.*

|       {
|         aftFILE="$MATCH"
|         :0 c:$TESTDIR/filelist.LCK

That needs an `i' ...

|         | cat /dev/null >$TESTDIR/filelist

Truth is, I'd put filelist$LOCKEXT as a regional lockfile around the whole
rm biz, not just as a local lockfile on the command that zeroes it out.
I don't know about your shell, Don, but I also would zap it with just

           : > $TESTDIR/filelist

within the shell (which that needs anyway) and not call cat.  We could also
just rm the thing and not invoke a shell.

|         :0 a
|         * $ files ?? ^^\/.*^A${FILE}^A
|         * MATCH ?? ^^\/.*[^^A]

or 
          * MATCH ?? ^^\/.*^A.

might be more efficient for procmail; every name will have at least one
character!

|         * MATCH ?? ^^\/.*[^A]

Anyhow, if the right side starts *after* the separator, we won't need this
next condition:

|         * MATCH ?? ^^\/.*[^^A]

now want it, because the value of $MATCH that saves the left side will have
to end with a separator.  That also means we don't need the dummy "@@@@@"
entry at the start.

|         {
|           LOGFILE=$TESTDIR/filelist
|           LOG="files=${MATCH:-''}$aftFILE"

I'm not at all sure why you are using ${MATCH:-''} instead of just $MATCH.
If $MATCH is null or unset, that will substitute null, right?  With my change,
it won't ever be null or unset anyway but $aftFILE might be.

|           LOGFILE=$LOGFILERC
|           RESULT=ok
|       }
|     }
|     :0 E
|     { RESULT="not listed" }
|   }
|   LOG="$WHATTODO $FILE: ${RESULT:-who knows?}$NL"   # Note 3
| }

| 1. The purpose of "@@@@@" in the data file is to preclude the need
| for special handling of "rm filename" when "filename" is the first
| in the list. This kind of borrows from part of Sean's suggestion.

In trying to skip that last MATCH ?? condition I accidentally obviated that.

| 2. Any character except ^A in the filename should be ok (maybe even
| newline?), but this assumes that at least one "sane" character is used
| in each filename.

Not newline (nor space nor tab), because then new names would have to be
inserted before a closing quotation mark rather than just appended.  (Those
characters will not appear in the names either.)  ^A is a fine choice.

My small tweaks aside, it's an interesting approach, Don.  You found a way
to handle adds without an outside process.  Still, once that file grows past
sixty-four characters, separators included (currently it would be thirty-
nine characters, assuming a single-letter name for the variable instead of
"files"), it will bloat my disk usage by 4Kb, while adding hard links to an
existing inode (to a seven-character file) won't increase my disk use unless
I get so many at a time that the directory header exceeds 4 Kb and is allot-
ted another 4 Kb.

Thanks for helping me think through this, folks; I'm going to stick with the
hard links for now.

Hmm...

If files shorter than sixty-five characters take up no disk space in that OS
because their contents are included in their directory entries ...

If deleting an entry requires an outside process no matter what ...

Then I could use Don's LOG= idea to add listings as new files (inodes cost
nothing) instead of forking ln.

Thus,

exists=!
INCLUDERC=.$NAME  # if .$NAME exists, it will clear $exists

:0
* command ?? ^^add\>
{
 :0
 * ! $ $exists
 {
  LOCKFILE=.newname$LOCKEXT
  oldlogfile=$LOGFILE  LOGFILE=.$NAME  LOG=exists # no trailing newline needed
  LOGFILE=$oldlogfile  LASTFOLDER="adding .$NAME"
 }
 :0E
 { LASTFOLDER=".$NAME already existed" }

 HOST
}
:0E
* command ?? ^^del(ete)?\>
{
 :0i
 * $ $exists
 | rm -f .$NAME

 LASTFOLDER=".$NAME didn't exist"  HOST
}

In an OS that didn't keep short files in the directory header and wasn't so
profligate as 4Kb at a time with disk space, I'd go back to ln.

_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail