Re: Help with filter-flags
Robert Bonomi <[email protected]>
| Newsgroups | gmane.mail.procmail |
|---|---|
| Message-ID | <[email protected]> |
> Subject: Re: Help with filter-flags > From: Arthur Dent <[email protected]> > To: [email protected] > Date: Fri, 05 Aug 2011 09:21:58 +0100 > > On Thu, 2011-08-04 at 16:34 -0600, LuKreme wrote: > > Arthur Dent <[email protected]> squaked out on Thu 04-Aug-2011 = > 09:21 > > >=20 > >=20 > > I would check if clamd is running first, then proceed only if it is. > >=20 > > CLAMRUN=3D`ps -Uroot -co command | grep "\bclamd\b"` > >=20 > > :0 > > * CLAMRUN ?? clamd > > { > >=20 > > # Your existing recipes, with some fixes > >=20 > > } > > Hi LuKreme, > > This was my first idea too. Unfortunately there are other error cases I > want to catch as well as just the situation where clamd is simply not > running. For example, (this is a Fedora box) SELinux will prevent > Procmail accessing clamd even though clamd is running just fine. This > will produce an error along the lines of: > "ERROR: Can't connect to clamd: Permission denied". Another error I have > encountered is: > "ERROR: Can't connect to clamd: No such file or directory" > > I want to trap these errors and report them in the headers for further > investigation. > > I can modify your suggestion so that I only run my recipe if clamd does > not produce an error: > > VIRUS=3D`${CLAMDSCAN} --no-summary --stdout -` > # If clamd is not running or there is another error: > :0 > * VIRUS ?? !^ERROR > { > recipe > } > > But if I want to mark up the headers to show the failure I run into a > logic problem which I can't quite get my head around: > > Pseudocode > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > IF (no clamd error) > { > IF (malware detected) > { > mark up headers > deliver message to MALWARE folder > } > ELSE > { > mark up headers > return to calling recipe <--- NEEDS TO EXIT HERE! > } > } > ELSE > { > mark up headers to show clamd error > return to calling recipe <--- OR NEEDS TO EXIT HERE! > } "Re-order", and simplify the logic as: IF (clamd error) { mark up headers to show clamd error } ELSE { mark up headers IF (malware detected) deliver message to MALWARE folder } ## reach here if clamd failed *or* it worked _and_ there was no malware > In this recipe (in production) there will be only one case where the > mail is actually delivered. > > I don't know how to exit a procmail recipe and allow it to return to the > calling recipe. I have seen the SWITCHRC command - but I don't think > that is what I want here. You apparently don't have a clear understanding of how procmail works. :) Procmail has two basic kinds of recipes -- what it calls 'delivering', and 'non delivering' ones. A 'delivering' recipe is a "terminal' function -- _all_ processing *ends* after a delivering recipe is executed. Recipes are executed in the order encountered, subject to 'and'/'else' flags that make execution conditional on the _last_ prior recipe executed. These conditional flags are *NOT* 'block structured' --- there is -no- 'return to calling recipe', and 'and'/'else' flags after a '{' '}' block depend on the last recipe tested _inside_ the '{' '}' block, *if* that block recipe evaludated 'true'. 'switchrc' simply -- and _irrevocably_ -- switches to a different file for all subsequent recipe input. If you do a switch _inside_ a '{' '}' block, you have to have the extra 'closing' '}' in the file you switch to, or you'll get parse errors. DAMHIKT 'includerc' lets you logically switch to a new file, *and*return* to the original if you 'fall off the end' of the 'included' file. Howevr, if you execute a 'delivering' recipe in an included file, then that ends _all_ processing. If/when you need to differentiate between a 'failure' (i.e. 'no match') of an 'outer' recipe, vs a failure of an 'inner' recipe, you may have to set (and test) explict 'state variables', or repeat a (possibly inverted) test.