.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "CM_PERL 7" .TH CM_PERL 7 "2020-11-09" "3.17.8-1+b1" "claws-mail-perl-filter" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" cm_perl \-\- A Perl Plugin for Claws Mail .SH "DESCRIPTION" .IX Header "DESCRIPTION" This plugin provides an extended filtering engine for the email client Claws Mail. It allows for the use of full Perl power in email filters. .SH "QUICK START" .IX Header "QUICK START" To get started, you can use the \fBmatcherrc2perlfilter.pl\fR script in the \fBtools\fR\-directory to translate your old filtering rules to Perl. Simply execute the script and follow the instructions. (note that with recent versions of Claws Mail, this script might not work due to upstream syntax changes. This will get updated in the future. Send me an email if you have problems getting started). .PP However, you might want to consider reading the rest of this manual and rewriting your rules if you choose to use the plugin, since the Perl code produced by this script is not exactly pretty. .PP Don't speak Perl? No problem, \*(L"perldoc perlintro\*(R" should give you enough information to do fancy stuff. .SH "USAGE" .IX Header "USAGE" The Perl plugin expects a Perl script file called \fBperl_filter\fR in Claws Mail' config directory (usually \f(CW$HOME\fR/.claws\-mail \*(-- try `claws\-mail \-\-config\-dir' if you're unsure). If that file doesn't exist on plugin start, an empty one is created. This file, which doesn't need to start with a sha-bang (!#/bin/perl), holds the Perl instructions for your email filters. To encourage some good manners, the code is executed in a \f(CW\*(C`use strict;\*(C'\fR environment. .PP Both Claws Mail' filtering \fBconditions\fR and \fBactions\fR are mapped to Perl functions with corresponding names, wherever this is possible. .SH "FUNCTION LISTING" .IX Header "FUNCTION LISTING" For a detailed function description, see section \*(L"\s-1FUNCTION DESCRIPTIONS\*(R"\s0, below. .IP "Standard Filtering Conditions" 4 .IX Item "Standard Filtering Conditions" .Vb 6 \& all, marked, unread, deleted, new, replied, \& forwarded, locked, ignore_thread, colorlabel, \& match, matchcase, regexp, S /dev/null' .IP "exit" 8 .IX Item "exit" Has been redefined to be an alias to 'stop'. You shouldn't use Perl's own 'exit' command, since it would exit Claws Mail. .IP "manual" 8 .IX Item "manual" Returns a true value if the filter script was invoked manually, that is, via the Tools menu. .IP "make_sure_folder_exists \s-1IDENTIFIER\s0" 8 .IX Item "make_sure_folder_exists IDENTIFIER" Returns a true value if the folder with id \s-1IDENTIFIER\s0 (e.g. #mh/Mail/foo/bar) exists or could be created. .IP "make_sure_tag_exists \s-1TAG\s0" 8 .IX Item "make_sure_tag_exists TAG" Returns a true value if the tag \s-1TAG\s0 exists or could be created. .IP "filter_log \s-1SECTION, TEXT\s0" 8 .IX Item "filter_log SECTION, TEXT" .PD 0 .IP "filter_log \s-1TEXT\s0" 8 .IX Item "filter_log TEXT" .PD Writes \s-1TEXT\s0 to the filter logfile. \s-1SECTION\s0 can be any of .RS 8 .IP "\(bu" 4 \&\*(L"\s-1LOG_MANUAL\*(R"\s0 .IP "\(bu" 4 \&\*(L"\s-1LOG_MATCH\*(R"\s0 .IP "\(bu" 4 \&\*(L"\s-1LOG_ACTION\*(R"\s0 .RE .RS 8 .Sp If the \s-1SECTION\s0 is omitted, \*(L"\s-1LOG_MANUAL\*(R"\s0 is assumed. .RE .IP "filter_log_verbosity \s-1VERBOSITY\s0" 8 .IX Item "filter_log_verbosity VERBOSITY" .PD 0 .IP "filter_log_verbosity" 8 .IX Item "filter_log_verbosity" .PD Changes the filter log verbosity for the current mail. \s-1VERBOSITY\s0 must be any of .RS 8 .ie n .IP "0" 2 .el .IP "\f(CW0\fR" 2 .IX Item "0" Be silent .ie n .IP "1" 2 .el .IP "\f(CW1\fR" 2 .IX Item "1" Log \s-1MANUAL\s0 type .ie n .IP "2" 2 .el .IP "\f(CW2\fR" 2 .IX Item "2" Log Action type .ie n .IP "3" 2 .el .IP "\f(CW3\fR" 2 .IX Item "3" Log \s-1MATCH\s0 type .RE .RS 8 .Sp For the meaning of those numbers, read section \*(L"\s-1LOGGING\*(R"\s0. If \&\s-1VERBOSITY\s0 is omitted, the filter logfile verbosity is not changed. .Sp This function returns the filter_log_verbosity number before the change (if any). .RE .PP \fIVariables\fR .IX Subsection "Variables" .ie n .IP "$permanent" 8 .el .IP "\f(CW$permanent\fR" 8 .IX Item "$permanent" This scalar keeps its value between filtered mail messages. On plugin start, it is initialized to the empty string. .SH "LOGGING" .IX Header "LOGGING" To keep track of what has been done to the mails while filtering, the plugin supports logging. Three verbosity levels are recognized: .ie n .IP "0" 4 .el .IP "\f(CW0\fR" 4 .IX Item "0" logging disabled .ie n .IP "1" 4 .el .IP "\f(CW1\fR" 4 .IX Item "1" log only manual messages, that is, messages introduced by the \&\f(CW\*(C`filter_log\*(C'\fR command in filter scripts .ie n .IP "2" 4 .el .IP "\f(CW2\fR" 4 .IX Item "2" log manual messages and filter actions .ie n .IP "3" 4 .el .IP "\f(CW3\fR" 4 .IX Item "3" log manual messages, filter actions and filter matches .PP The messages are logged in Claws Mail' log window. The default log level is 2. Log level 3 is not recommended, because the matcher functions log a message if they succeeded, and thus, if you have negative checks, you'll get confusing entries. If you want to keep track of matching, do it manually, using \f(CW\*(C`filter_log\*(C'\fR, or do it by temporary enabling matcher logging using \f(CW\*(C`filter_log_verbosity\*(C'\fR. .PP The first time you unload this plugin (or shut down Claws Mail), a section called \fB[PerlPlugin]\fR will be created in Claws Mail' configuration file \fBclawsrc\fR, containing one variable: .PP .Vb 1 \& * filter_log_verbosity .Ve .PP If you want to change the default behaviour, you can edit this line. Make sure Claws Mail is not running while you do this. .PP It will be possible to access these setting via the \s-1GUI,\s0 as soon as I find the time to write a corresponding \s-1GTK\s0 plugin, or somebody else is interested in contributing that. .SH "EXAMPLE" .IX Header "EXAMPLE" This section lists a small example of a Perl script file. I'm sure you get the idea.. .PP .Vb 2 \& #\-8<\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& # \-*\- perl \-*\- \& \& # local functions \& \& # Learn ham messages, and move them to specified folder. This is \& # useful for making sure a bayes filter sees ham as well. \& sub learn_and_move { \& execute(\*(Aqput command to learn ham here\*(Aq); \& move(@_); \& } \& \& # Two\-stage spam filter. Every email that scores higher than 15 \& # on SpamAssassin gets moved into the default trash folder. \& # All mails lower than that, but higher than SpamAssassin\*(Aqs \& # \*(Aqrequired_hits\*(Aq go into #mh/mail/Spam. \& sub spamcheck { \& my $surely_spam = 15; \& my $filepath = filepath; \& my $spamc = \`spamc \-c < $filepath\`; \& my ($value,$threshold) = ($spamc =~ m|([\-.,0\-9]+)/([\-.,0\-9]+)|); \& if($value >= $surely_spam) { \& mark_as_read; \& move_to_trash; \& } \& if($value >= $threshold) {mark_as_read; move \*(Aq#mh/mail/Spam\*(Aq;} \& } \& \& # Perl script execution starts here. \& \& # Some specific sorting \& learn_and_move \*(Aq#mh/mail/MailLists/Claws Mail/user\*(Aq \& if matchcase(\*(Aqsender\*(Aq,\*(Aqclaws\-mail\-users\-admin@lists.sourceforge.net\*(Aq); \& learn_and_move \*(Aq#mh/mail/MailLists/Sylpheed\*(Aq \& if matchcase(\*(Aqlist\-id\*(Aq,\*(Aqsylpheed.good\-day.net\*(Aq); \& \& # Implement incoming folders using addressbook \& # attributes. Target folders for specific email addresses are \& # stored directly in the addressbook. This way, if an email \& # address changes, we only have to update the addressbook, not \& # the filter rules! Besides that, we can greatly unclutter the \& # filter script. \& \& # get the email address in the from header \& my $fromheader = header "from"; \& my ($from) = extract_addresses $fromheader; \& \& # check if this email address has an associated attribute \& # called "incoming_folder". If if has, the value of this \& # attribute is supposed to be the target folder. \& my $value = get_attribute_value $from, "incoming_folder"; \& learn_and_move($value) if $value; \& \& # An example of a whitelist: If the from\-address is in my \& # "office" addressbook, move the mail to folder #mh/mail/office \& learn_and_move \*(Aq#mh/mail/office\*(Aq if from_in_addressbook("office"); \& \& # If the from\-address is in any other addressbook, move the \& # mail to folder #mh/mail/inbox/known \& learn_and_move \*(Aq#mh/mail/inbox/known\*(Aq if from_in_addressbook; \& \& # Feed the remaining mails through SpamAssassin. \& spamcheck; \& \& # mails that make it to the end of the script are passed on to \& # the internal filtering engine. If the internal rules don\*(Aqt say \& # otherwise, the mails end up in the default inbox. \& #\-8<\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- .Ve .SH "BUGS" .IX Header "BUGS" .IP "\(bu" 4 Do \fBnot\fR use this plugin together with other filtering plugins, especially the \fBSpamassassin\fR and \fBClamAV\fR plugins. They are registered on the same hook and the order in which the plugins are executed is not guaranteed. .IP "\(bu" 4 The filter script is not (yet) updated automatically when a folder gets renamed. The same applies for folder names in addressbook user attributes. .IP "\(bu" 4 This plugin has only be tested with \s-1POP3\s0 accounts. If you have experiences with \s-1IMAP\s0 or newsgroup accounts, drop me a message. .IP "\(bu" 4 Warning during compile time: .Sp .Vb 4 \& *** Warning: Linking the shared library perl_plugin.la against the \& *** static library \& /usr/lib/perl5/5.8.3/i586\-linux\-thread\-multi/auto/DynaLoader/DynaLoader.a \& is not portable! .Ve .Sp Ideas to solve this one are welcome :\-) .PP Please report comments, suggestions and bugreports to the address given in the \*(L"\s-1AUTHOR\*(R"\s0 section of this document. .SH "LICENSE and (no) WARRANTY" .IX Header "LICENSE and (no) WARRANTY" This program is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. .PP This program is distributed in the hope that it will be useful, but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \&\s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with this program. If not, see http://www.gnu.org/licenses/. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBclaws\-mail\fR\|(1), \fBperl\fR\|(1) .SH "AUTHOR" .IX Header "AUTHOR" Holger Berndt