Mark M. Hoffman on 9 Sep 2004 00:57:03 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] Using fetchmail to read from an Exchange public folder for learning spam


Hi Mike:

> On Wed, Sep 08, 2004 at 11:52:46AM -0400, Mike Leone said:
> > /usr/bin/fetchmail -a -s -n -p IMAP --folder 'INBOX.Learn Spam' -m 'bash -c
> > "/usr/bin/tee >(/usr/bin/sa-learn --spam --single \ 
> >                  > /dev/null)|/usr/bin/spamc|/usr/lib/cyrus-imapd/deliver
> > $LOGNAME"' mail.hughes-family.org

* Stephen Gran <steve@www.lobefin.net> [2004-09-08 19:38:09 -0400]:
> So it does this:
> Runs fetchmail, and fetches all (-a) mail in (-s) silent mode (no running
> ouput).  It uses norewrite (-n), to keep the headers intact, so that
> SA gets them as is.  Then it spawns a subshell as a delivery agent with
> the -m option.  The subshell uses tee to cat to stdout everything coming
> from fetchmail, and tee's output goes to sa-learn.  He is then delivering
> the mail to his cyrus account, although you won't want to do that.

Right... here's a little more detail about that:

Tee copies stdin to stdout and to one or more files which are specified
on the command line.  E.g.
                                                                                                                                                      
        $ cat file1 | tee file2
                                                                                                                                                      
The contents of file1 go to the screen, and get copied to file2.
                                                                                                                                                      
A common real-world usage is something like this:
                                                                                                                                                      
        $ make 2>&1 | tee build.log
                                                                                                                                                      
I.e. capture all stdout and stderr to the file build.log, but still throw
it onto the screen so I can watch.
                                                                                                                                                      
>> /usr/bin/fetchmail -a -s -n -p IMAP --folder 'INBOX.Learn Spam' -m 'bash -c
>> "/usr/bin/tee >(/usr/bin/sa-learn --spam --single \
>>                  > /dev/null)|/usr/bin/spamc|/usr/lib/cyrus-imapd/deliver
>> $LOGNAME"' mail.hughes-family.org
                                                                                                                                                      
I'll break the part in double quotes like this: tee $x $y
                                                                                                                                                      
First, $x is this: >(/usr/bin/sa-learn --spam --single > /dev/null)
                                                                                                                                                      
Within bash, the form ">(command)" is called a process substitution.
Bash is going to create a FIFO.  Whatever is written to that FIFO will
be passed to sa-learn.  The *name* of that FIFO will be substituted into
the command line of tee by bash.  Result: stdin is passed to sa-learn.
                                                                                                                                                      
Next, $y is this: | /usr/bin/spamc | /usr/lib/cyrus-imapd/deliver $LOGNAME
                                                                                                                                                      
So, that's just a simple pipe, where stdout is passed to that chain.  But
remember, tee passes stdin directly to stdout as well, so...
                                                                                                                                                      
The net result is: stdin is forked into two copies, one is passed to sa-learn,
the other is passed to the pipeline ending with deliver.
                                                                                                                                                      
>> And I would want:
>>
>> /usr/bin/fetchmail -a -s -n -p IMAP --folder '???????' -m 'bash -c
>> "/usr/bin/tee >(/usr/bin/sa-learn --spam --single > /dev/null)"'
>> exchange-server
                                                                                                                                                      
Since you removed the deliver pipeline, you don't need the tee to make a
copy of stdin anymore... just pass it straight to sa-learn:
                                                                                                                                                      
        'bash -c "/usr/bin/sa-learn --spam --single > /dev/null"'

I hope that helps.                                                                                                                                                      
Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com

___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug