Man Linux: Main Page and Category List

NAME

       qsf - quick spam filter

SYNOPSIS

       Filtering:       qsf [-snrAtav] [-d DB] [-g DB]
                            [-L LVL] [-S SUBJ] [-H MARK] [-Q NUM]
                            [-X NUM]
       Training:        qsf -T SPAM NONSPAM [MAXROUNDS] [-d DB]
       Retraining:      qsf -[m|M] [-d DB] [-w WEIGHT] [-ayN]
       Database:        qsf -[p|D|R|O] [-d DB]
       Database merge:  qsf -E OTHERDB [-d DB]
       Allowlist query: qsf -e EMAIL [-m|-M|-t] [-d DB] [-g DB]
       Denylist query:  qsf -y -e EMAIL [-m -m|-M -M|-t] [-d DB] [-g DB]
       Help:            qsf -[h|V]

DESCRIPTION

       qsf  reads  a single email on standard input, and by default outputs it
       on standard output.   If  the  email  is  determined  to  be  spam,  an
       additional  header  ("X-Spam:  YES")  will be added, and optionally the
       subject line can have "[SPAM]" prepended to it.

       qsf is intended to be used in a procmail(1) recipe, in a  ruleset  such
       as this:

               :0 wf
               | qsf -ra

               :0 H:
               * X-Spam: YES
               $HOME/mail/spam

       For  more  examples,  including  sample  procmail(1)  recipes,  see the
       EXAMPLES section below.

TRAINING

       Before qsf can be used properly, it needs to be trained.  A good way to
       train qsf is to collect a copy of all your email into two folders - one
       for spam, and one for non-spam.  Once you have done this, you  can  use
       the training function, like this:

               qsf -aT spam-folder non-spam-folder

       This  will generate a database that can be used by qsf to guess whether
       email received in the future is spam or not.  Note  that  this  initial
       training  run  may  take a long time, but you should only need to do it
       once.

       To mark a single message as spam, pipe it to qsf with  the  --mark-spam
       or  -m  ("mark  as  spam")  option.   This  will  update  the  database
       accordingly and discard the email.

       To mark a single message as non-spam, pipe it to qsf with  the  --mark-
       nonspam  or  -M  ("mark as non-spam") option.  Again, this will discard
       the email.

       If a message has been mis-tagged, simply send it to qsf as the opposite
       type,  i.e.  if it has been mistakenly tagged as spam, pipe it into qsf
       --mark-nonspam --weight=2 to  add  it  to  the  non-spam  side  of  the
       database with double the usual weighting.

OPTIONS

       The qsf options are listed below.

       -d, --database [TYPE:]FILE
              Use  FILE  as the spam/non-spam database.  The default is to use
              /var/lib/qsfdb and, if that is not available  or  is  read-only,
              $HOME/.qsfdb.   This  option  can  also  be useful if there is a
              system-wide database but you do not want to use it -  specifying
              your own here will override the default.

              If   you   prefix   the  filename  with  a  TYPE,  of  the  form
              btree:$HOME/.qsfdb, then this will specify what kind of database
              FILE is, such as list, btree, gdbm, sqlite and so on.  Check the
              output of qsf -V to see which database backends  are  available.
              The default is to auto-detect the type, or, if the file does not
              already exist, use list.  Note that TYPE is not  case-sensitive.

       -g, --global [TYPE:]FILE
              Use   FILE   as   the   default   global  database,  instead  of
              /var/lib/qsfdb.  If you also specify a database  with  -d,  then
              this  "global"  database  will  be  used  in  read-only  mode in
              conjunction with the read-write database specified with -d.  The
              -g option can be used a second time to specify a third database,
              which will also be used in read-only mode.  Again, the  filename
              can  optionally  be  prefixed  with  a  TYPE which specifies the
              database type.

       -P, --plain-map FILE
              Maintain a mapping of all database tokens  to  their  non-hashed
              counterparts in FILE, one token per line.  This can be useful if
              you want to be able to list the contents of your database  at  a
              later  date,  for  instance  to get a list of email addresses in
              your allow-list.  Note that using this option may slow qsf down,
              and  only  entries  written to the database while this option is
              active will be stored in FILE.

       -s, --subject
              Rewrite the Subject line of any email that turns out to be spam,
              adding "[SPAM]" to the start of the line.

       -S, --subject-marker SUBJECT
              Instead  of  adding "[SPAM]", add SUBJECT to the Subject line of
              any email that turns out to be spam.  Implies -s.

       -H, --header-marker MARK
              Instead of setting the X-Spam header to "YES", set it to MARK if
              email  turns  out  to be spam.  This can be useful if your email
              client can only search all headers for a string, rather than one
              particular  header (so searching for "YES" might match more than
              just the output of qsf).

       -n, --no-header
              Do not add an X-Spam header to messages.

       -r, --add-rating
              Insert an additional header X-Spam-Rating which is a  rating  of
              the  "spamminess"  of  a message from 0 to 100; 90 and above are
              counted as spam, anything under 90 is not considered  spam.   If
              combined with -t, then the rating (0-100) will be output, on its
              own, on standard output.

       -A, --asterisk
              Insert an additional  header  X-Spam-Level  which  will  contain
              between 0 and 20 asterisks (*), depending on the spam rating.

       -t, --test
              Instead  of  passing  the message out on standard output, output
              nothing, and exit 0 if the message is not spam, or exit 1 if the
              message is spam.  If combined with -r, then the spam rating will
              be output on standard output.

       -a, --allowlist
              Enable the allow-list.  This causes the email addresses given in
              the  message’s  "From:" and "Return-Path:" headers to be checked
              against a list; if either  one  matches,  then  the  message  is
              always  treated  as  non-spam,  regardless  of  what  the  token
              database says. When specified with  a  retraining  flag,  -a  -m
              (mark  as  spam) will remove that address from the allow-list as
              well as marking the message as spam, and -a  -M  (mark  as  non-
              spam) will add that address to the allow-list as well as marking
              the message as non-spam.  The idea is that you add all  of  your
              friends  to the allow-list, and then none of their messages ever
              get marked as spam.

       -y, --denylist
              Enable the deny-list.  This causes the email addresses given  in
              the  message’s  "From:" and "Return-Path:" headers to be checked
              against a second list; if either one matches, then theh  message
              is  always  treated  as spam.  Training works in the same way as
              with -a, except that you must specify -m or -M twice  to  modify
              the  deny-list  instead  of the allow-list, and with the reverse
              syntax: -y -m -m (mark as spam) will add  that  address  to  the
              deny-list,  whereas -y -M -M (mark as non-spam) will remove that
              address from the deny-list.  This  double  specification  is  so
              that  the  usual retraining process never touches the deny-list;
              the  deny-list  should  be  carefully  maintained  rather   than
              automatically generated.

              Normally you would not need to use the deny-list.

       -L, --level, --threshold LEVEL
              Change  the  spam  scoring threshold level which must be reached
              before an email is classified as spam.  The default is 90.

       -Q, --min-tokens NUM
              Only give a score if more than  NUM  tokens  are  found  in  the
              message  -  otherwise the message is assumed to be non-spam, and
              it is not modified in any way.  The default is 0.   This  option
              might  be  useful if you find that very short messages are being
              frequently miscategorised.

       -e, --email, --email-only EMAIL
              Query or update the  allow-list  entry  for  the  email  address
              EMAIL.   With no other options, this will simply output "YES" if
              EMAIL is in the allow-list, or "NO" if it is not.  With  -t,  it
              will  not output anything, but will exit 0 (success) if EMAIL is
              in the allow-list, or 1 (failure) if it  is  not.  With  the  -m
              (mark-spam) option, any previous allow-list entry for EMAIL will
              be removed. Finally, with the -M  (mark-nonspam)  option,  EMAIL
              will be added to the allow-list if it is not already on it.

              If  EMAIL is just the word MSG on its own, then an email will be
              read from standard input, and the email addresses given  in  the
              "From:" and "Return-Path:" headers will be used.

              Using -e automatically switches on -a.

              If  you also specify -y, then the deny-list will be operated on.
              Remember that -m and -M are reversed with the deny-list.

              If you specify an email address of  the  form  @domain  (nothing
              before  the  @),  then  the  whole  domain will be allow or deny
              listed.

       -v, --verbose
              Add extra X-QSF-Info headers to any filtered  email,  containing
              error  messages  and  so on if applicable.  Specify -v more than
              once to increase verbosity.

       -T, --train SPAM NONSPAM [MAXROUNDS]
              Train the database using the two mbox folders SPAM and  NONSPAM,
              by testing each message in each folder and updating the database
              each time a message is miscategorised.   This  is  done  several
              times, and may take a while to run.  Specify the -a (allow-list)
              flag to add every sender in the NONSPAM folder  to  your  allow-
              list  as a side-effect of the training process.  If MAXROUNDS is
              specified, training will end after this number of rounds if  the
              results  are  still not good enough. The default is a maximum of
              200 rounds.

       -m, --mark-spam
              Instead of passing the message out on standard output, mark  its
              contents  as  spam  and update the database accordingly.  If the
              allow-list (-a) is enabled, the message’s "From:"  and  "Return-
              Path:"  addresses are removed from the allow-list.  If the deny-
              list (-y) is enabled and you specify  -m  twice,  the  message’s
              addresses are added to the deny-list instead.

       -M, --mark-nonspam
              Instead  of passing the message out on standard output, mark its
              contents as non-spam and update the  database  accordingly.   If
              the  allow-list  (-a)  is  enabled,  the  message’s  "From:" and
              "Return-Path:" addresses are added to the allow-list (see the -a
              option above).  If the deny-list (-y) is enabled and you specify
              -M twice, the message’s addresses are removed from the deny-list
              instead.

       -w, --weight WEIGHT
              When  marking  as  spam  or non-spam, update the database with a
              weighting of WEIGHT per token  instead  of  the  default  of  1.
              Useful  when  correcting  mistakes,  eg  a message that has been
              mistakenly detected as spam should be marked as non-spam using a
              weighting  of  2, i.e. double the usual weighting, to counteract
              the error.

       -D, --dump [FILE]
              Dump the contents of the database as a platform-independent text
              file, suitable for archival, transfer to another machine, and so
              on.  The data is output on stdout or into the given FILE.

       -R, --restore [FILE]
              Rebuild the database from scratch from the text file  on  stdin.
              If  a  FILE  is  given,  data is read from there instead of from
              stdin.

       -O, --tokens
              Instead of filtering, output a list of the tokens found  in  the
              message read from standard input, along with the number of times
              each token was found.  This is only useful if you  want  to  use
              qsf  as  a  general  tokeniser  for  use  with another filtering
              package.

       -E, --merge OTHERDB
              Merge the OTHERDB database into the current database.  This  can
              be  useful  if  you want to take one user’s mailbox and merge it
              into the system-wide one, for instance (this would be  done  by,
              as  root,  doing  qsf -d /var/lib/qsfdb -E /home/user/.qsfdb and
              then removing /home/user/.qsfdb).

       -B, --benchmark SPAM NONSPAM [MAXROUNDS]
              Benchmark the training process using the two mbox  folders  SPAM
              and  NONSPAM.  A temporary database is created and trained using
              the first 75% of the messages  in  each  folder,  and  then  the
              entire  contents  of each folder is tested to see how many false
              positives and false negatives occur. Some timing information  is
              also displayed.

              This can be used to decide which backend is best on your system.
              Use -d to select a backend, eg qsf -B spam  nonspam  -d  GDBM  -
              this   will   create  a  temporary  database  which  is  removed
              afterwards.

              The exception to  this  is  the  MySQL  backend,  where  a  full
              database      specification      must      be      given     (-d
              MySQL:database=db;host=localhost;...)  and  the  database  table
              given will not be wiped beforehand or dropped afterwards.

              As  with  -T,  if MAXROUNDS is specified, training will never be
              done for more than this number of rounds; the default is 200.

       -h, --help
              Print a usage message on standard output and exit  successfully.

       -V, --version
              Print   version  information,  including  a  list  of  available
              database backends, on standard output and exit successfully.

DEPRECATED OPTIONS

       The following options are  only  for  use  with  the  old  binary  tree
       database backend or old databases that haven’t been upgraded to the new
       format that came in with version 1.1.0.

       -N, --no-autoprune
              When marking as spam or nonspam, never automatically  prune  the
              database.  Usually the database is pruned after every 500 marks;
              if  you  would  rather  --prune  manually,  use  -N  to  disable
              automatic pruning.

       -p, --prune
              Remove  redundant  entries  from  the database and clean it up a
              little.  This is  automatically  done  after  several  calls  to
              --mark-spam  or --mark-nonspam, and during training with --train
              if the training takes a large number of  rounds,  so  it  should
              rarely be necessary to use --prune manually unless you are using
              -N / --no-autoprune.

       -X, --prune-max NUM
              When the database is being pruned, no more than NUM entries will
              be  considered  for  removal.  This is to prevent CPU and memory
              resources being taken over.  The default is 100,000 but in  some
              circumstances  (if  you  find  that pruning takes too long) this
              option may be used to reduce it to a more manageable number.

FILES

       /var/lib/qsfdb
              The default (system-wide) spam database.  If you wish to install
              qsf  system-wide,  this  should  be read-only to everyone; there
              should be one user with write access who  can  update  the  spam
              database  with  qsf  --mark-spam  and  qsf  --mark-non-spam when
              necessary.

       /var/lib/qsfdb2
              A second, read-only, system-wide database. This  can  be  useful
              when  installing  qsf  system-wide  and  using  third-party spam
              databases; the first global database can be updated with system-
              specific  changes,  and this second database can be periodically
              updated when the third-party spam database is updated.

       $HOME/.qsfdb
              The default spam database  for  per-user  data.   Users  without
              write  access  to  the system-wide database will have their data
              written here, and the two databases will be read together.   The
              per-user  database  will  be  given a weighting equivalent to 10
              times the weighting of the global database.

NOTES

       Currently, you cannot use qsf to check for spam while the  database  is
       being  updated.   This  means  that while an update is in progress, all
       email is passed through as non-spam.

       There is an upper size limit  of  512Kb  on  incoming  email;  anything
       larger  than this is just passed through as non-spam, to avoid tying up
       machine resources.

       The plaintext  token  mapping  maintained  by  --plain-map  will  never
       shrink,  only  grow.   It  is intended for use by housekeeping and user
       interface scripts that, for instance, the user  can  use  to  list  all
       email addresses on their allow-list.  These scripts should take care of
       weeding out entries for tokens that are no longer in the database.   If
       you  have no such scripts, there is probably no point in using --plain-
       map anyway.

       Avoid using the deny-list (-y) in any automated retraining, as  it  can
       be cause the filter to reject mail unnecessarily.  In general the deny-
       list is probably best left unused unless explicitly  required  by  your
       particular setup.

       If  both  the  allow-list  and  the  deny-list  are enabled, then email
       addresses will first be checked against the deny-list, then the  allow-
       list, then the domain of the email address will be checked for matching
       "@domain" entries in the deny-list and then in the allow-list.

EXAMPLES

       To filter all of your mail through qsf, with the allow-list enabled and
       the  "spam  rating"  header  being  added, add this to your .procmailrc
       file:

               :0 wf
               | qsf -ra

       If you want qsf to add "[SPAM]" to the subject line of any messages  it
       thinks are spam, do this instead:

               :0 wf
               | qsf -sra

       To  automatically mark any email sent to spambox@yourdomain.com as spam
       (this is the "naive" version):

               :0 H
               * ^To:.*spambox@yourdomain.com
               | qsf -am

       To   do   the   same,   but   cleverly,   so   that   only   email   to
       spambox@yourdomain.com which qsf does NOT already classify as spam gets
       marked as spam in the database (this stops  the  database  getting  too
       heavily weighted):

               # If sent to spambox@yourdomain.com:
               :0
               * ^To:.*spambox@yourdomain.com
               {
                  :0 wf
                  | qsf -a

                  # The above two lines can be skipped if you’ve
                  # already piped the message through qsf.

                  # If the qsf database says it’s not spam,
                  # mark it as spam!
                  :0 H
                  * ^X-Spam: NO
                  | qsf -am
               }

       Remove the -a option in the above examples if you don’t want to use the
       allow-list.

       A more complicated filtering example  -  this  will  only  run  qsf  on
       messages which don’t have a subject line saying "your <something> is on
       fire" and which don’t have a sender address  ending  in  "@foobar.com",
       meaning  that  messages  with  that subject line OR that sender address
       will NEVER be marked as spam, no matter what:

               :0 wf
               * ! ^Subject: Your .* is on fire
               * ! ^From: .*@foobar.com
               | qsf -ra

       For  more  on  procmail(1)   recipes,   see   the   procmailrc(5)   and
       procmailex(5) manual pages.

       A couple of macros to add to your .muttrc file, if you use mutt(1) as a
       mail user agent:

               # Press F5 to mark a message as spam and delete it
               macro index <f5> "<pipe-message>qsf -am\n<delete-message>"
               macro pager <f5> "<pipe-message>qsf -am\n<delete-message>"

               # Press F9 to mark a message as non-spam
               macro index <f9> "<pipe-message>qsf -aM\n"
               macro pager <f9> "<pipe-message>qsf -aM\n"

       Again, remove the -a option in the above examples if you don’t want  to
       use the allow-list.

       Note,  however,  that  the  above  macros  won’t work when operating on
       multiple tagged messages. For that, you’d need something like this:

               macro   index   <f5>    ":set    pipe_split\n<tag-prefix><pipe-
              message>qsf            -am\n<tag-prefix><delete-message>\n:unset
              pipe_split\n"

       If you use qmail(7), then to get procmail working with it you will need
       to  put  a  line  containing just DEFAULT=./Maildir/ at the top of your
       ~/.procmailrc file, so that procmail delivers to  your  Maildir  folder
       instead  of  trying  to  deliver to /var/spool/mail/$USER, and you will
       need to put this in your ~/.qmail file:

               | preline procmail

       This will cause all your mail to be delivered via procmail  instead  of
       being delivered directly into your mail directory.

       See the qmail(7) documentation for more about mail delivery with qmail.

       If you use postfix(1), you can set up  a  system-wide  mail  filter  by
       creating  a  user account for the purpose of filtering mail, populating
       that account’s .qsfdb, and then creating a shell script, to run as that
       user, which runs qsf on stdin and passes stdout to sendmail(8).

       Doing  this  requires  some knowledge of postfix configuration and care
       needs to be taken to avoid mail loops.  One qsf user’s  full  HOWTO  is
       included in the doc/ directory with this package.

THE ALLOW-LIST

       A  feature called the "allow-list" can be switched on by specifying the
       --allowlist or -a option.  This causes messages’ "From:"  and  "Return-
       Path:"  addresses  to be checked against a list of people you have said
       to allow all messages from, and if  a  message’s  "From:"  or  "Return-
       Path:"  address is in the list, it is never marked as spam.  This means
       you can add all your friends to an "allow-list" and qsf will then never
       mis-file  their  messages - a quick way to do this is to use -a with -T
       (train); everyone in your non-spam folder who has  sent  you  an  email
       will be added to the allow-list automatically during training.

       You  can  manually  add and remove addresses to and from the allow-list
       using the -e (email) option. For instance, to add  foo@bar.com  to  the
       allow-list, do this:

               qsf -e foo@bar.com -M

       To remove bad@nasty.com from the allow-list, do this:

               qsf -e bad@nasty.com -m

       And  to  see whether someone@somewhere.com is in the allow-list or not,
       just do this:

               qsf -e someone@somewhere.com

       In general, you probably always  want  to  enable  the  allow-list,  so
       always  specify  the -a option when using qsf.  This will automatically
       maintain the allow-list based on what you classify as spam or non-spam.

       The  only  times  you might want to turn it off are when people on your
       allow-list are prone to getting viruses or if a virus is causing  email
       to  be sent to you that is pretending to be from someone on your allow-
       list.

BACKUP AND RESTORE

       Because the database format is platform-specific, it is a good idea  to
       periodically  dump the database to a text file using qsf -D so that, if
       necessary, it can be transferred to another machine and  restored  with
       qsf -R later on.

       Also  note  that  since the actual contents of email messages are never
       stored in the database (see TECHNICAL DETAILS), you  can  safely  share
       your  qsf  database with friends - simply dump your database to a file,
       like this:

               qsf -D > your-database-dump.txt

       Once you have sent your-database-dump.txt to another person,  they  can
       do this:

               qsf -R < your-database-dump.txt

       They will then have an identical database to yours.

TECHNICAL DETAILS

       When  a message is passed to qsf, any attachments are decoded, all HTML
       elements are removed, and the message  text  is  then  broken  up  into
       "tokens",  where  a  "token"  is  a  single word or URL.  Each token is
       hashed using the MD5 algorithm (see below for why), and  that  hash  is
       then used to look up each token in the qsf database.

       For   full   details  of  which  parts  of  an  email  (headers,  body,
       attachments, etc) are used  to  calculate  the  spam  rating,  see  the
       TOKENISATION section below.

       Within the database, each token has two numbers associated with it: the
       number of times that token has been seen in spam,  and  the  number  of
       times  it has been seen in non-spam.  These two numbers, along with the
       total number of spam and non-spam messages seen, are then used to  give
       a  "spamminess"  value  for  that  particular token.  This "spamminess"
       value ranges from "definitely not spammy" at  one  end  of  the  scale,
       through "neutral" in the middle, up to "definitely spammy" at the other
       end.

       Once a "spamminess" value has been calculated for all of the tokens  in
       the  message, a summary calculation is made to give an overall "is this
       spam?"  probability rating for the message.  If the overall probability
       is 0.9 or above, the message is flagged as spam.

       In  addition  to  the probability test is the "allow-list".  If enabled
       (with the -a option), the whole probability check  is  skipped  if  the
       sender  of  the message is listed in the allow-list, and the message is
       not marked as spam.

       When training the database, a  message  is  split  up  into  tokens  as
       described  above,  and  then the numbers in the database for each token
       are simply added to: if you tell qsf that a message is  spam,  it  adds
       one  to  the "number of times seen in spam" counter for each token, and
       if you tell it a message is not spam, it adds one  to  the  "number  of
       times  seen  in  non-spam"  counter  for  each token.  If you specify a
       weight, with -w, then the number you specify is added instead of one.

       To stop the database growing uncontrollably, the database  keeps  track
       of  when  a  token  was  last used.  Underused tokens are automatically
       removed from the database.  (The old method was to  "prune"  every  500
       updates).

       Finally,  the  reason  MD5  hashes were used is privacy.  If the actual
       tokens from the messages, and the actual email addresses in the  allow-
       list,  were  stored,  you could not share a single qsf database between
       multiple users because bits of everyone’s  messages  would  be  in  the
       database - things like emailed passwords, keywords relating to personal
       gossip, and so on.  So a hash is stored instead.  A hash is a "one-way"
       function;  it  is  easy to turn a token into a hash but very hard (some
       might say impossible) to turn a hash back into the token  that  created
       it.   This  means  that  you  end  up  with a database with no personal
       information in it.

TOKENISATION

       When a message is broken up into tokens, various parts of  the  message
       are treated in different ways.

       First,  all header fields are discarded, except for the important ones:
       From, Return-Path, Sender, To, Reply-To, and Subject.

       Next, any MIME-encoded attachments are decoded.  Any attachments  whose
       MIME type starts with "text/" (i.e. HTML and text) are tokenised, after
       having  any  HTML  tags  stripped.   Any  non-textual  attachments  are
       replaced  with their MD5 hash (such that two identical attachments will
       have the same hash), and that hash is then used as a token.

       In addition to single-word tokens from textual message parts, qsf  adds
       doubled-up  tokens  so that word pairs get added to the database.  This
       makes the database a bit bigger (although the automatic  pruning  tends
       to take care of that) but makes matching more exact.

SPECIAL FILTERS

       As  well as using the textual content of email to detect spam, qsf also
       uses special filters which  create  "pseudo-tokens"  based  on  various
       rules.   This  means that specific patterns, not just individual words,
       can be used to determine whether a message is spam or not.

       For example,  if  a  message  contains  lots  of  words  with  multiple
       consonants,  like  "ashjkbnxcsdjh",  then each time a word like that is
       seen the special token ".GIBBERISH-CONSONANTS." is added to the list of
       tokens  found  in the message.  If it turns out that most messages with
       words that trigger this filter rule are spam, then other messages  with
       gibberish  consonant strings will be more likely to be flagged as spam.

       Currently the special filters are:

       GTUBE  Flags      any      message      containing      the      string
              XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-
              EMAIL*C.34X  as  spam  -  useful  for  testing  that  your   qsf
              installation is working.

       ATTACH-SCR

       ATTACH-PIF

       ATTACH-EXE

       ATTACH-VBS

       ATTACH-VBA

       ATTACH-LNK

       ATTACH-COM

       ATTACH-BAT
              Adds a token for every attachment whose filename ends in ".scr",
              ".pif", ".exe",  ".vbs",  ".vba",  ".lnk",  ".com",  and  ".bat"
              respectively (these are often viruses).

       ATTACH-GIF

       ATTACH-JPG

       ATTACH-PNG
              Adds a token for every attachment whose filename ends in ".gif",
              ".jpg" or ".jpeg", and ".png" respectively.

       ATTACH-DOC

       ATTACH-XLS

       ATTACH-PDF
              Adds a token for every attachment whose filename ends in ".doc",
              ".xls",  or  ".pdf"  respectively (these tend to indicate a non-
              spam email).

       SINGLE-IMAGE
              Adds a token if the message contains exactly one attached image.

       MULTIPLE-IMAGES
              Adds  a  token  if  the  message contains more than one attached
              image.

       GIBBERISH-CONSONANTS
              Adds a token for every word found that has  multiple  consonants
              in  a  row,  as described above.  Spam often contains strings of
              gibberish.

       GIBBERISH-VOWELS
              Adds a token for every word found that has multiple vowels in  a
              row, eg "aeaiaiaeeio".

       GIBBERISH-FROMCONS
              Like GIBBERISH-CONSONANTS, but only for the "From:" and "Return-
              Path:" addresses on their own.

       GIBBERISH-FROMVOWL
              Like GIBBERISH-VOWELS, but only for  the  "From:"  and  "Return-
              Path:" addresses on their own.

       GIBBERISH-BADSTART
              Adds  a  token  for  every word that starts with a bad character
              such as %.

       GIBBERISH-HYPHENS
              Adds a token for every word with  more  than  three  hyphens  or
              underscores in it.

       GIBBERISH-LONGWORDS
              Adds  a  token for every word with over 30 characters in it (but
              less than 60).

       HTML-COMMENTS-IN-WORDS
              Adds a token for every HTML comment found in  the  middle  of  a
              word.   Spam  often  contains  HTML  inside  words,  like  this:
              w<!--dsgfhsdgjgh-->ord

       HTML-EXTERNAL-IMG
              Adds a token  for  every  HTML  <img>  (image)  tag  found  that
              contains :// (i.e.  it refers to an external image).

       HTML-FONT
              Adds a token for every HTML <font> tag found.

       HTML-IP-IN-URLS
              Adds a token for every URL found containing an IP address.

       HTML-INT-IN-URL
              Adds  a  token  for every URL found containing an integer in its
              hostname.

       HTML-URLENCODED-URL
              Adds a token for every URL found containing  a  %  sign  in  its
              hostname.

       Normally, filters will just cause a token to be added, and these tokens
       are processed by the normal weighting  algorithm.   However  the  GTUBE
       filter  will  immediately  flag any matching message as spam, bypassing
       the token matching.

DATABASE BACKENDS

       The inbuilt "list" database backend will not  necessarily  provide  the
       best performance, but is provided because using it requires no external
       libraries.

       If, when qsf was compiled, the correct libraries were  available,  then
       it  will be possible to use qsf with alternative database backends.  To
       find out which backends you have available, run qsf -V (capital V)  and
       read  the  second  line of output.  To see how well a backend performs,
       collect some spam and non-spam and use qsf -d BACKEND -B  SPAM  NONSPAM
       (see the entry for -B above).

       Some  people  find  that  they get the best performance out of the gdbm
       backend; this is a library that is widely available on many systems.

       To efficiently share a qsf database across multiple machines,  you  may
       find  the  MySQL  backend  useful.   However, using it is a little more
       complicated.

       To use the MySQL backend you will need  to  create  a  table  with  the
       fields  key1,  key2,  token,  value1,  value2  and  value3.  The token,
       value1, value2, and value3 fields must be VARCHAR(64), BIGINT  or  INT,
       and  BIGINT  or  INT respectively, and indexing on the token field is a
       good idea. The key1 and key2 fields can be anything, but they  must  be
       present.

       For example:

                USE mydatabase;
                CREATE TABLE qsfdb (
                  key1      BIGINT UNSIGNED NOT NULL,
                  key2      BIGINT UNSIGNED NOT NULL,
                  token     VARCHAR(64) DEFAULT ’’ NOT NULL,
                  value1    INT UNSIGNED NOT NULL,
                  value2    INT UNSIGNED NOT NULL,
                  value3    INT UNSIGNED NOT NULL,
                  PRIMARY KEY (key1,key2,token),
                  KEY (key1),
                  KEY (key2),
                  KEY (token)
                );

       The  key1  and  key2 fields allow you to have multiple qsf databases in
       one table, by specifying different key1 and key2 values on  invocation.

       Instead  of specifying a database file with the --database / -d option,
       you must specify either a specification string as described  below,  or
       the name of a file containing such a string on its first line.

       The specification string is as follows:

                database=DATABASE;host=HOST;port=PORT;
                user=USER;pass=PASS;table=TABLE;
                key1=KEY1;key2=KEY2

       This string must be all on one line, with no spaces.

       DATABASE
              is the name of the MySQL database.

       HOST   is the hostname of the database server (eg "localhost").

       PORT   is the TCP port to connect on (eg 3306).

       USER   is the username to connect with.

       PASS   is the password to connect with.

       TABLE  is  the  database  table to use.  If a table with this name does
              not exist when qsf is called in update or training mode, then it
              will be created if permissions allow this to be done.

       KEY1   is the value to use for the key1 field.

       KEY2   is the value to use for the key2 field.

       Since  command  lines  can  be seen in the process list, it is probably
       best to specify a filename (eg qsf -d  mysql:qsfdb.spec)  and  put  the
       specification string inside that file.

TROUBLESHOOTING

       If  you  have  problems  with qsf, please check the list below; if this
       does not help, go to the qsf home  page  and  investigate  the  mailing
       lists, or email the author.

       Nothing is being marked as spam.
              First,  use the -r option to switch on the X-Spam-Rating header,
              and check that this header appears in email passed through  qsf.
              If  it  does not, then it is likely that qsf is not being run at
              all - check your configuration of procmail(1) or its equivalent.

              If  you  are  seeing X-Spam-Rating headers, and different emails
              have different scores, then you may simply need to retrain  your
              database a little more.  Take more spam email and pass it to qsf
              -m.

              If you are seeing X-Spam-Rating headers but they  all  give  the
              same spam rating, then the most likely reason is that qsf is not
              reading any database.  Make sure that whatever is processing the
              email  has  read permissions on /var/lib/qsfdb and/or ~/.qsfdb -
              and make sure  that,  if  you  are  using  ~/.qsfdb,  what  your
              database  creator thought was ~ ($HOME) is the same as it is for
              whatever is processing the email.

       Retraining sometimes takes a very long time.
              With the obtree backend or  2-column  MySQL  or  SQLite  tables,
              every 500th retrain (-m or -M), the database is pruned.  On some
              systems this may take  some  time,  and  during  this  time  the
              database  is  locked  (except  when  using  the  MySQL or SQLite
              backends).  If you constantly do a lot of retraining and want to
              avoid this, then use the -N option to suppress auto-pruning, and
              then have a cron(8) job or something run a manual prune (qsf -p)
              every now and again.

       Running qsf from procmail fails with an error.
              If  you  can run qsf from the command line, but in your procmail
              log file you get errors about "qsf: cannot execute binary file",
              then  contact your system administrator for help. It may be that
              incoming email is handled by a different server to the  one  you
              normally  shell  into,  and  either  they  are  of  a  different
              architecture or operating system, or  the  mail  server  is  not
              permitted to execute user-owned binaries.

ACKNOWLEDGEMENTS

       The  following  people have contributed suggestions, comments, patches,
       and testing:

              Tom Parker <http://www.bits.bris.ac.uk/palfrey/>
              Dr Kelly A. Parker
              Vesselin Mladenov <http://www.antipodes.bg/>
              Glyn Faulkner
              Mark Reynolds
              Sam Roberts
              Scott Allen
              Karsten Kankowski
              M. Kolbl
              Micha Holzmann
              Jef Poskanzer <http://www.acme.com/jef/>
              Clemens Fischer <http://ino-waiting.gmxhome.de/>
              Nelson A. de Oliveira
              Michal Vitecek
              Tommy Pettersson <http://www.lysator.liu.se/~ptp/>

AUTHOR

       The author:

              Andrew Wood <andrew.wood@ivarch.com>
              http://www.ivarch.com/

       Project home page:

              http://www.ivarch.com/programs/qsf/

BUGS

       If you find any bugs, please contact the author, either by email or  by
       using the contact form on the web site.

SEE ALSO

       procmail(1), procmailrc(5), procmailex(5)

       Someone  has  written a guide to using qsf with KMail that can be found
       at:
       http://www.softwaredesign.co.uk/Information.SpamFilters.html

LICENSE

       This is free software, distributed under the ARTISTIC 2.0 license.