I don't know if anyone is still interested, but I found a solution to this problem. My mail goes Sendmail-->Procmail-->CyrusIMAP.

There are numerous discussions of how to configure the Sendmail-->Procmail portion, so I'll skip that.

The problem lies in the Procmail-->Cyrus part. Sendmail and/or Procmail insists on adding a "From" line to the top of the message, and this causes an error when trying to pass the message from the procmailrc file to /usr/lib/cyrus-imapd/deliver. So I wrote a little C-program that the email can be piped through (removing the "From" line); the resulting message is passed to /usr/lib/cyrus-imapd/deliver.

Here is my ~/.promailrc file. Note that all mail is first delivered to the user's CyrusIMAP box, then it goes through the procmail checks. This is because if I don't do this, then all mail that fails all the conditions (recipes) gets shoved into /usr/local/mail/~, which is basically a black hole if you are using Cyrus.

#     This file is: ~/.procmailrc
#
#     REQUIREMENTS:
#        1) cyrus-imap (specifically, "/usr/lib/cyrus-imapd/deliver").
# 2) the C-program "rmfromln" in a reachable place (like /usr/local/bin). # rmfromln: the email argument is piped in; if the email message
#            has been appended with starting "From" line, then this line is
#               removed, otherwise the message remains unchanged.

LOGFILE=/home/r2/procmail.log

###############################################################################
#     This is the default action; it delivers the email to the imap mailbox,
# and thus this happens regardless of the success|failure of the recipes.
#     RATIONAL: every email MUST have a "To" field, otherwise sendmail would
#    not have passed it to us!?
:0 c
* ^To:.
| rmfromln | /usr/lib/cyrus-imapd/deliver $LOGNAME ###############################################################################

:0
* ^Subject:.*(callalert|CALLALERT)
* ^Subject:.*(on|ON)
| /root/scripts/callalert on

:0
* ^Subject:.*(callalert|CALLALERT)
* ^Subject:.*(off|OFF)
| /root/scripts/callalert off


ALSO: I've attached the C-program "rmfromln" (and it's source code) which removes the "From" line (if it is present).

-Andy Swartz

Attachment: rmfromln
Description: Binary data

/*  NEW plan:
                        1) create a temp io-stream with tempfile()
                        2) read in from stdin and out to temp until EOL (or EOF)
                        3) dynamically create a string of the appropriate 
length 
                                 (i.e. the number of characters written to 
temp-stream)
                        4) copy temp-stream to the new string
                        5) search the string for "From"
                        6) if found, copy the string to stdout
                        7) copy the remaining stdin to stdout until EOF 
reached.  
                        */

#include "stdio.h"
#include "string.h"
#include "stddef.h"
#include "stdlib.h"


// ###############################################

#define EOL '\n'

// ###############################################

main () {

char            c;
int                     length;
int                     j;
FILE            *tempstream;
char            *tempstring;


// Create the temp-stream
tempstream = tmpfile();

// Read from stdin into tempstream until EOF or EOL is encountered. 
length = 0;
rewind(tempstream);
while ((c=fgetc(stdin)) && (c != EOL)) {
        fputc(c,tempstream);
        length++;
        }

// if no input, then just exit and do nothing.
if (length == 0)
        exit(0);
        
// the above code did not put the EOL in the temp-stream, so add it.
fputc(EOL,tempstream);
length++;

// create the tempSTRING and copy the tempstream into it.
// tempstring = new string[length];
tempstring = (char *) calloc(length,sizeof(char));
rewind(tempstream);
for(j=0;j<length;j++)
        tempstring[j] = fgetc(tempstream);

/* If we are at EOF, then there was no EOL, and thus no search for "From" is 
indicated;
         so simply write the temp-string to stdout and exit.  */
if (feof(stdin)) {
        for (j=0;j<length;j++)
                        fputc(tempstring[j],stdout);
        exit(0);
        }
        
// If we got to here, we need to search temp-string for "From".
if (strstr(tempstring,"From") == NULL) {
                /* i.e. "From" was NOT in the 1st line, so this line needs to 
                         be output before the remaining stdin is transferred to 
stdout  */
          for (j=0;j<length;j++)                                                
      
                                fputc(tempstring[j],stdout);
                }
// dynamically allocated string is done, so free up the memory.
free (tempstring);
                
// now just transfer the remaining stdin to stdout.
 c = getchar();
 while (c != EOF) {
          fputc(c,stdout);
          c = getchar();
    }


}  /* End of Main */
_______________________________________________
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to