| InstallationThe first step is to get the  
           latest version of procmail. When this article was started the last version was 
	     3.11pre7. After getting the source code for the program, in order to install it 
	     it will be necessary to uncompress and unpack it using the following command: 
           tar -xzvf procmail.tar.gz The next step is to edit the files Makefile and 
           config.h. Since this article is only an introduction and to keep 
	     things simple in this first introduction, we will not explain the various 
	     configuration options of these files. The interested reader can consult the 
	     manual pages and the documentation provided with the sources. Nevertheless, it is convenient to mention the existence of the option 
           BASENAME in the Makefile. With this option we indicate  
	     the directory base where procmail will be installed. From the basename directory 
           we indicate will hang other directories as bin and man. Finally, to compile the package we must execute the command 
           make install. Procmail can be installed for the whole system and then be called through some 
	     rule of sendmail(8) or it can be by some user for his personal use. 
	     In the later case, the user will indicate the use of procmail in his  
           .forward, where a line like the following should be present:|IFS=' ' && exec /home/juan/procmail/bin/procmail -f- || exit 75 #juan In this line I assumed that the user juan has installed procmail in 
	     his HOME. For this particular line the  
           BASENAME that should have been specified during compilation 
           is /home/juan/procmail. Basic FunctionsProcmail reads from its standard input. It checks the file 
           .procmailrc which is a configuration file that the user should  
	     have in his HOME. This file defines certain rules that will tell procmail 
           what to do after reading a message. It can be directed to  
           check for certain strings in the header of the message, in order to  
	     decide whether to save the message, ignore it, reply automatically, etc.. Procmail also let us deal automatically with the arriving mail or the mail stored 
           in a file. ConfigurationThe configuration file used is .procmailrc and it 
	     must be placed in HOME. Every line started with # is considered a comment. Lines started with  :0 or :0: indicate the  
	     beginning of a new rule which tells procmail what to do with a message. The lines started with * indicate a condition to be satisfied for 
	     a rule to apply. This is the mechanism procmail uses to select which messages 
           require processing with the rule and which do not. The remaining lines, that is, those not starting with a 
           :, or  * are considered commands, in other words 
	     the action to be applied by procmail to the message satisfying the 
           condition. Some possible actions or commands are deleting a message, 
           forwarding a message, saving a message, saving a message... The first thing to be indicated in a  
           .procmailrc are some of the environment variables, here are some of 
           the variables I would recommend to define in your .procmailrc  MAILDIRIndicates the directory where procmail saves the files with mail messages. 
           This variable usually point to  $HOME/mail or $HOME/Mail. Whether is one or  
	     the other is a matter of the kind of mail reader being used.
 LOGFILEIndicates the name of a log file where procmail leaves record of all the transactions 
	     carried out.
 SENDMAILIndicates where to find sendmail, which will be used to automatically 
           reply messages.
 FORMAILIndicates where to find formail. This program is distributed together with 
           procmail and its purpose is to modify the mail headers or to reformat a 
           message before sending or storing a message.
 DEFAULTFile where a message is saved if procmail was not able to apply any of the 
           rules defined.
 Anywhere in  .procmailrc one can define an environment variable. 
           If the variable is written without the symbol = follow by a value, 
           such variable is removed. Regarding rules, they come in two groups: 
           Rules that consider the message delivered after applying their 
           action and rules that do not. The first rules are simple, after applying their action then 
           assume no further rules should apply to this message and therefore 
           deliver it. The second type of rules, those that do not consider the message delivered,  
	     upon applying their action are very useful when one wishes the possibility 
           of applying multiple rules and actions to the same message before delivery. The general syntax for a rule is the following:
  
           :0 [options] [ : [exclusion file] ] 
           * condition 1 
           * condition 2 
                 . 
                 . 
                 . 
           * condition N 
           command 
           Lets go by parts analyzing this construction. 
	     First every rule starts with a :0, after it may follow 
           any of these options:H The condition is applied to the mail header. B The condition is searched in the body of the message.
 D When the condition is investigated, upper and lower cases are 
                    distinguishable.
 A This rule is applied only if the previous one was.
 a Like A, except that the execution of the previous rule 
                    must have been carried out without errors. 
           E This rule is executed if the previous one was not.
 e This rule will be executed if the previous one was executed but 
                    exit with some error.
 h The message header is passed to the command.
 b The message body is passed to the command.
 f The command is interpreted as a filter.
 c Generate a carbon copy cc of the message. When executing a rule that 
                    considers the message delivered with this flag, then one accomplishes a work 
	              around its delivery, and further rules can be applied to the carbon copy 
                    of the message.
 w Wait until the command finish executing to receive its exit  code.
 W As the previous option but in case of error does not emit any messages.
 i Ignore the possible typing errors.
 r Writes the message such as it is. It does not test whether it ends 
                    with a blank line.
 
 By default, if no options are specified, the condition is tested on the 
           mail header (option H).  The command receives in its standard input 
           both header as boy of the message (options h and b). There is no distinction 
           between upper and lower case. After :0 and the possible options, a second  
           : may follow, if it does it indicates that the destination file 
 	     where the message is going to be written should be blocked to avoid two 
           processes writing simultaneously over the file. Optionally one can indicate the 
	     exclusion file which is used as a lock. Next follow the conditions, one per line and preceded by a  
           * character. Conditions are usually written as regular expressions 
           in order to find character string within the header or body of a message. 
           Regular expressions use the following symbols among others:^ Beginning of a line. $ End of a line 
           . Any character except a carriage return
 * Zero or more times.
 + One or more times.
 ? Zero or more times.
 [a-z] Range of characters, in this example from a to z.
 [^a-z]Any character outside the range a to z.
 a|b Either 'a' or 'b'
 
 After the conditions come a single command. If the first character 
           of the command is any of the following then a special behavior onsets:! The message is redirected to all the mail addresses indicated. | If this symbol is continued by an executable then it is run 
           whenever the condition is satisfied. If nothing follows the symbol  
           the full text of the message goes to the standard output. If instead  
           the name of a variable follows |, then the result of the indicated command 
           is saved into that variable.
 
 Mailing ListsA situation where procmail can be very useful is in the management  
           of our mail. Let us suppose that we are subscribed to three Linux mailing lists. 
           each list is identified by the address of origin, for instance we could have 
           the following addresses  
           l-linux@calvo.teleco.ulpgc.es 
           linux@nuclecu.unam.mx 
           linux-security@redhat.com 
         Under normal circumstances the messages from these mailing lists will 
           arrive together, at the same mail box, and if nothing  is done they will 
	     remain mixed up. It would be much easier if as the mail were arriving 
           if was sorted and stored in appropriate files. Procmail can solve this problem easily. We could use a file 
           .procmailrc with the following simple rules to sort our mail  
           from the Linux mailing lists:  
:0 
* ^From.*l-linux@calvo.teleco.ulpgc.es 
l-linux 
 
:0 
* ^From.*linux@nuclecu.unam.mx 
linux-mx 
 
:0 
* ^From.*linux-security@redhat.com 
linux-security 
 Let us examine carefully one of the rules. If you understand the 
           inner workings of a rule, then is easy to understand the rest because 
	     the basic mechanism is always the same. First one finds a :0 string that indicates the beginning of 
           a new rule. There are no further options so procmail will take the default 
           options for this rule: upper and lower case are indistinguishable, the condition 
           applies only to the mail header, the command receives both header and body of 
           the message. In the next line one finds the condition, that as it was previously mentioned 
           is always identifiable because its first character is a *. The condition 
           is the following regular expression:^From.*linux@nuclecu.unam.mx 
 The substring ^From tells procmail to search for those lines   
           beginning by the substring From. The following .* character, means any number of characters. We saw  
	     before that in regular expressions a "." character is equivalent to  
	     any character and that * refers to zero or more. Then  
           .* means that after the initial From there may be zero or more 
           characters. Next should come linux@nuclecu.unam.mx, which is the address 
           from where the messages originate. Thinking a bit about the regular expressions, you will see that the following 
           lines would be recognize by this rule:  
From: linux@nuclecu.unam.mx 
From:linux@nuclecu.unam.mx 
FROM linux@nuclecu.unam.mx 
 With this rule one can already distinguish messages coming from this 
           address and the others. So now that one has the message what shall be done with 
           it?. The next line is the command (or action), and it indicates what to do with 
	     the message. In this case it is supposed to be deliver to the file 
           linux-mx where it should be stored. In case of not indicating the 
           absolute path to the file, by default it will be considered relative to the 
           environment variable $MAILDIR. Clearly messages arriving from different lists can now be distributed to 
	     various files according to their origin (From field). Automatic ReplyOther situation where procmail will be useful is for automatic replies. 
           It comes often handy, for example, if you wish to send your public PGP key 
           automatically to anyone that requests it by E-Mail To do this, write a rule that will consider as a petition for 
           our PGP public key any message with the string PGP in its subject. 
           This rule can be written as:  
0: 
* ^Subject.*PGP 
| (formail -r ; cat $HOME/key.asc) | sendmail -t 
 This same idea can be applied to write the typical program that 
            lets people known we are off on vacation and that we will reply to 
            their E-Mail after coming back:  
0: 
| (formail -r; cat $HOME/vacations.txt) | sendmail -t 
 In the last case there is no condition since all messages should 
            be sent the same notice. Avoiding Infinite Loops in Automated RepliesIn the previous examples no attempt was made to handle possible infinite 
           loops that sometimes occur when mail is answered automatically. If a message whose origin is our own E-Mail address, the program would reply 
           to that address, then the reply would come back to us. This message would be 
           replied once more and so on in an infinity loop. In order to avoid it, 
           when answering the message one should add an extra line in the header to indicate 
           that message was already answered. Using the option -A of formail:formail -r -A"X-Loop: dir@email.es" 
 Where dir@email.es would be your own E-Mail address. This way when  
           generating the header for the reply the line  
           X-Loop is added so that later on one can check for it with a new rule:  
:0 
* !^X-Loop: dir@email.es 
| (formail -r -A"X-Loop: dir@email.es" ;  
    cat $HOME/vacation.txt) | sendmail -t 
This rule prevents an infinite loop because any message containing  
            in the header a line X-Loop will not satisfy the condition and 
            as a result will not be answered by procmail. Decoding FilesAnother interesting rule for our .procmailrc is that which 
	     decodifies the incoming mail encoded with uuencode(1) automatically. 
	     The rule could be given as:  
:0 B 
* ^begin 644 .* 
{ 
	MAILDIR=$HOME/files 
	 
	:0 
	| uudecode 
} 
Here it is explicitly indicated with the option 
            B that the rule's condition should only be tested on the 
            body of the message. If the rule finds a line beginning with the string 
            "begin 644" it means that it has found the beginning of a  file encoded with           
            uuencode(1) so it establishes the environment variable   
            MAILDIR, which is equivalent to changing the directory pointed by 
            that variable. From that moment on, all the print or display actions will be 
            perform taking the base directory indicated. In our case we are interested 
	      on saving the received messages in $HOME/files. Next there is a rule, without condition, that only pipes the message  
            to uudecode(1) for decodification. The original file will go to  
            $HOME/files. ConclusionHopefully after this brief introduction to procmail, it is clear that 
           procmail is extremely versatile and it can help to manage your mail 
            easy and conveniently. I recommend to experiment with the regular expressions 
            and the rules, adapt them to your needs because procmail possibilities 
            go well beyond what I have been able to discuss in this short introduction. |