0

I have the below procmail recipe that for years has faithfully worked (passed senders email and subject) to the perl script and saved the attachments.

FROM=""
:0
* ^FROM:.*
* ^From:[    ]*\/[^  ].*
{
       FROM=$MATCH
}
#grab the subject
SUBJECT=""
:0
* ^FROM:.*
* ^Subject:[    ]*\/[^  ].*
{
       SUBJECT=$MATCH
}

:0 ifw  #  rip & save attachements  

|ripmime -i - -d /home/carrdocs/.pmdir/attachments/ &&\
/usr/bin/perl -e 'require "/home/carrdocs/.pmdir/test_carr_subject.pl"; rename_att($ENV{SUBJECT},$ENV{FROM},$ENV{MESSAGE}); exit(0)'

:0 A
filed

I am trying to modify the recipe to also send the contents of the email's body to the perl script as a scalar variable. Accordingly, I added:

:0b w
MESSAGE=| cat 

just before the line (with one line of space between):

:0 ifw 

This results in the program sometimes working as hoped to and other times failing to pass the variables and save the attachments with the error:

procmail: Program failure (-11) of "ripmime -i - -d /home/carrdocs/.pmdir/attachments/ &&\
/usr/bin/perl -e 'require "/home/carrdocs/.pmdir/test_carr_subject.pl"; rename_att($ENV{SUBJECT},$ENV{FROM},$ENV{MESSAGE}); exit(0)'"

Does anyone know how I can correctly pass the body's contents as a scalar variable to the perl script?

gatorreina
  • 864
  • 5
  • 14
  • The `Program failure (-11)` indicates a segfault or similar in the `ripmime` recipe. I'm vaguely guessing the message body is larger than Procmail's `LINEBUF` variable when this happens. – tripleee Jan 18 '21 at 05:48
  • A better solution anyhow is probably to refactor your Perl script into a separate recipe, and give it the body -- or the entire message -- as standard input. – tripleee Jan 18 '21 at 05:53

1 Answers1

1

This probably happens when MESSAGE is longer than LINEBUF (or even actually when it is only slightly shorter, so that the entire ripmime command line ends up exceeding LINEBUF).

Check in the log for a message like this immediately before the failure:

procmail: Assigning "MESSAGE="
procmail: Executing "cat"
procmail: Exceeded LINEBUF
procmail: Assigning "PROCMAIL_OVERFLOW=yes"

The assignment of MESSAGE is fine, but attempting to use its value in a subsequent recipe will fail because the string is longer than Procmail can accommodate.

So, TL;DR; don't try to put things which are longer than a handful of bytes into variables. (For the record, the default value of LINEBUF on my Debian test box is 2048 bytes.)

Probably for other reasons too, refactor your recipe so that your Perl script receives the message on standard input instead. Without exact knowledge of what ripmime does or how it's supposed to interface with your Perl script (looks to me like actually combining the two is completely crazy here, but perhaps I'm missing something), this is tentative at best, but something like

:0w  #  rip & save attachements  
|ripmime -i - -d /home/carrdocs/.pmdir/attachments/
:0Afw
| /usr/bin/perl -e 'require "/home/carrdocs/.pmdir/test_carr_subject.pl"; \
     ($body = join("", <>)) =~  s/^.*?\r?\n\r?\n//s; \
     } rename_att($ENV{SUBJECT},$ENV{FROM},$body))'

I also took out the exit(0) which seemed entirely superfluous; and the i flag is now no longer topical for either of these recipes.

I guess you could easily inline the extraction of the Subject: and From: headers into Perl as well, with some benefits e.g. around RFC2047 decoding, assuming of course you know how to do this correctly in Perl.

tripleee
  • 175,061
  • 34
  • 275
  • 318