On Wed, 2013-07-24 at 10:48 -0500, Kareem Dana wrote: > I am using SpamAssassin 3.3.2 on FreeBSD 9.1. I'd just like to confirm > that I can pipe messages to sa-learn. The following commands should do > the same thing, correct? > > # cat spammail | sa-learn --spam > # sa-learn --spam spammail
Correct. $ formail -1 -s < mbox > msg $ sa-learn --spam msg Learned tokens from 1 message(s) (1 message(s) examined) $ formail -1 -s < mbox | sa-learn --spam Learned tokens from 0 message(s) (1 message(s) examined) That confirms sa-learn accepts mail being piped in, and that there is absolutely no difference to using a file as intermediate storage. NOTE: Be careful of using sa-learn in different environments or ways in parallel. For example via the dovecot anti-spam plugin, from a cron job harvesting mbox files, maildir, processed through formail or even worse an MUA... Slight modifications to the MIME structure can result in SA treating them as different messages, learning twice. In fact, a mere (additional) trailing newline at the end of the MIME message suffices. > I have tested and they appear to be identical, but ultimately I will > be invoking sa-learn through the dovecot antispam plugin > (http://wiki2.dovecot.org/Plugins/Antispam) and their webpage has a > whole section about how sa-learn does not support piped input and I > need a wrapper script. I believe that is outdated, but I want to be > absolutely sure that I can pipe mail to sa-learn and it will work > properly. That claim appears to be based on reading the sa-learn documentation, rather than actually trying it. No, wait, I do not mean to imply it is bad to read the docs. Not at all. It is, maybe, just slightly inferior to verifying something not mentioned equals not supported... I can confirm this works at least since SA 3.2, which IIRC even predates the dovecot anti-spam plugin, let alone its documentation. ;) -- char *t="\10pse\0r\0dtu\0.@ghno\x4e\xc8\x79\xf4\xab\x51\x8a\x10\xf4\xf4\xc4"; main(){ char h,m=h=*t++,*x=t+2*h,c,i,l=*x,s=0; for (i=0;i<l;i++){ i%8? c<<=1: (c=*++x); c&128 && (s+=h); if (!(h>>=1)||!t[s+h]){ putchar(t[s]);h=m;s=0; }}}