QSF(1)				 User Manuals			       QSF(1)

NAME
       qsf - quick spam filter

SYNOPSIS
       Filtering:	qsf [-snrAtav] [-d DB] [-g DB]
			    [-L LVL] [-S SUBJ]
       Training:	qsf -T SPAM NONSPAM [-d DB]
       Retraining:	qsf -[m|M] [-d DB] [-w WEIGHT] [-aN]
       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]
       Help:		qsf -[h|l|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	addi-
       tional  header  ("X-Spam: YES") will be added, and optionally the sub-
       ject 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 EXAM-
       PLES 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 -T 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 accord-
       ingly 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	oppo-
       site 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 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.

       -g, --global 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 con-
	      junction 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.

       -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.

       -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 address given  in
	      the  message's  "From:" header to be checked against a list; if
	      it 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.

       -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.

       -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 address given in the
	      "From:" header will be used.

	      Using -e automatically switches on -a.

       -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
	      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.

       -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:" address is
	      removed from the allow-list.

       -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:"  address
	      is added to the allow-list (see the -a option above).

       -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 counter-
	      act the error.

       -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.

       -D, --dump
	      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.

       -R, --restore
	      Rebuild the database from scratch from the text file on  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
	      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
	      final 25% of messages in each folder is tested to see how	 many
	      false positives and false negatives occur. Some timing informa-
	      tion is also displayed.

	      This is probably only of use to developers, when trying differ-
	      ent classification algorithms.

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

       -l, --license
	      Print details of the program's license on standard  output  and
	      exit successfully.

       -V, --version
	      Print  version information on standard output and exit success-
	      fully.

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	 sys-
	      tem-specific  changes, and this second database can be periodi-
	      cally 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.

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.

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@yourdo-
       main.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	 mes-
       sages  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	proc-
       mailex(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 mul-
       tiple tagged messages. For that, you'd need something like this:

	       macro  index  <f5>  ":set   pipe_split\n<tag-prefix><pipe-mes-
	      sage>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:" addresses  to
       be  checked  against  a list of people you have said to allow all mes-
       sages from, and if a message's "From:" 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 auto-
       matically 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, attach-
       ments, etc) are used to calculate the spam rating, see  the  TOKENISA-
       TION 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 "spammi-
       ness" 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  probabil-
       ity 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,  it is automatically
       pruned after every 500th update (or, in training mode, after every  15
       rounds).	  The pruning step removes any tokens with very small message
       counts, and scales all counts down if they start getting too large.

       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	 per-
       sonal  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, 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 conso-
       nants, 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 instal-
	      lation 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).

       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:" address on
	      its own.

       GIBBERISH-FROMVOWL
	      Like GIBBERISH-VOWELS, but only for the "From:" address on  its
	      own.

       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-IMG
	      Adds a token for every HTML <img> (image) 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.

MYSQL BACKEND
       You can skip this section if you are not using qsf with MySQL.

       In some special situations it may be more convenient to use qsf with a
       MySQL  database	backend.  If you passed --with-mysql to the configure
       script, or you installed the qsf-mysql RPM,  then  the  MySQL  backend
       will  be available (with the RPM, it is available if you run qsf-mysql
       instead of qsf).

       To use it you will need to create a table with the fields key1,	key2,
       token,  value1  and value2.  The token, value1, and value2 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,
		  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.

       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 -d qsfdb.spec) and put the specifica-
       tion 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 equiva-
	      lent.

	      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 process-
	      ing 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.
	      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 back-
	      ends).  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

AUTHOR
       The author:

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

       Project home page:

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

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 license.

Linux				February 2005			       QSF(1)
