I have a procmail rule that works perfectly for me:
:0
* ^To:.*anonymized
* ^Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:
{
LOG="1"
:0 cw
* ^To:\/.+
| /etc/procmail/process_dmarc_report.sh "$MATCH"
}
But the subject is sometimes encoded, which breaks the rule. Based on
I wanted to replace the test on the Subject
header with a test on the SUBJECT
variable containing the possibly decoded subject, as follows:
:0
* ^Subject:.*=\?utf-8\?B\?
SUBJECT=`formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'`
:0 E
SUBJECT=`formail -cXSubject:`
:0
* ^To:.*anonymized
* SUBJECT ?? Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:.*
The subject is correctly decoded, but I'm doing it wrong because I have an error in the logs:
procmail: Skipped "[Preview] Report Domain: anonymized Submitter: enterprise.protection.outlook Report-ID: c136884d7adc4f5c82e2fdbbde75e2ab"
And the email is delivered to Folder: SUBJECT=Subject:
.
I tried with -x
instead of -X
and not including Subject:
in the test, and several other small adaptations, but without success. I can't find my mistake. It may be simple, but I can't seem to get it right.
If, as suggested, I do something like:
:0
* ^Subject:.*=\?utf-8\?B\?
SUBJECT=| formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'
:0 E
SUBJECT=| formail -cXSubject:
$SUBJECT is empty
My entire rule (not working) at the moment:
:0
* ^Subject:.*=\?utf-8\?B\?
SUBJECT=`formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'`
:0 E
SUBJECT=`formail -cXSubject:`
:0
* ^To:.*anonymized
* SUBJECT ?? Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:.*
{
LOG="1"
:0 cw
* ^To:\/.+
| /etc/procmail/process_dmarc_report.sh "$MATCH"
}
I have a procmail rule that works perfectly for me:
:0
* ^To:.*anonymized
* ^Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:
{
LOG="1"
:0 cw
* ^To:\/.+
| /etc/procmail/process_dmarc_report.sh "$MATCH"
}
But the subject is sometimes encoded, which breaks the rule. Based on https://stackoverflow/a/29715987/13463349
I wanted to replace the test on the Subject
header with a test on the SUBJECT
variable containing the possibly decoded subject, as follows:
:0
* ^Subject:.*=\?utf-8\?B\?
SUBJECT=`formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'`
:0 E
SUBJECT=`formail -cXSubject:`
:0
* ^To:.*anonymized
* SUBJECT ?? Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:.*
The subject is correctly decoded, but I'm doing it wrong because I have an error in the logs:
procmail: Skipped "[Preview] Report Domain: anonymized Submitter: enterprise.protection.outlook Report-ID: c136884d7adc4f5c82e2fdbbde75e2ab"
And the email is delivered to Folder: SUBJECT=Subject:
.
I tried with -x
instead of -X
and not including Subject:
in the test, and several other small adaptations, but without success. I can't find my mistake. It may be simple, but I can't seem to get it right.
If, as suggested, I do something like:
:0
* ^Subject:.*=\?utf-8\?B\?
SUBJECT=| formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'
:0 E
SUBJECT=| formail -cXSubject:
$SUBJECT is empty
My entire rule (not working) at the moment:
:0
* ^Subject:.*=\?utf-8\?B\?
SUBJECT=`formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'`
:0 E
SUBJECT=`formail -cXSubject:`
:0
* ^To:.*anonymized
* SUBJECT ?? Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:.*
{
LOG="1"
:0 cw
* ^To:\/.+
| /etc/procmail/process_dmarc_report.sh "$MATCH"
}
Share
Improve this question
edited Mar 21 at 21:15
Chris972
asked Mar 20 at 19:49
Chris972Chris972
1051 silver badge9 bronze badges
2 Answers
Reset to default 0It's of course possible to assign a value to a variable the way you did, however, not in a recipe action line. There the syntax requires a |
for the assignment. From the manpage for "procmailrc":
| Starts the specified program, possibly in $SHELL if any of the
characters $SHELLMETAS are spotted. You can optionally prepend
this pipe symbol with variable=, which will cause stdout of the
program to be captured in the environment variable (procmail
will not terminate processing the rcfile at this point). If you
specify just this pipe symbol, without any program, then proc‐
mail will pipe the mail to stdout.
So, in your case it should be
SUBJECT=| formail -cXSubject:
Same for the other "SUBJECT=" line, of course.
Regarding your edit saying that SUBJECT
would still be empty:
Replace the Perl code with e.g.
perl -mEncode=from_to -pe 'from_to $_, "MIME-Header", "UTF-8"'
The problem was about the variable test:
* ^Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:
won't work because of [^ ]*
but
* ^Subject:.*Report domain: anonymized Submitter: .* Report-ID:
works !
* variable ?? regex
Test the value of variable against regex.
The documentation says it's a regex, but it really isn't.
My final working rule is:
:0
* ^Subject: \/=\?utf-8\?B\?.+
{
SUBJECT=`echo $MATCH | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'`
}
:0E
* ^Subject: \/.+
{
SUBJECT=$MATCH
}
:0
* SUBJECT ?? Report domain: novazur\.fr Submitter: .* Report-ID:
{
:0 cw
* ^To:\/.+
| /etc/procmail/process_dmarc_report.sh "$MATCH"
}
NB: Never remove curly braces that you might think are unnecessary around variable assignments. They are essential, even in:
:0
* ^Subject: \/=\?utf-8\?B\?.+
{
SUBJECT=`echo $MATCH | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'`
}
:0E
* ^Subject: \/.+
{
SUBJECT=$MATCH
}