spamprobe-1.4d/0000777000076400007640000000000010527262426010535 500000000000000spamprobe-1.4d/depcomp0000775000076400007640000003033510526706577012045 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. base=`echo "$object" | sed -e 's/\.o$//' -e 's/\.lo$//'` tmpdepfile1="$base.o.d" tmpdepfile2="$base.d" if test "$libtool" = yes; then "$@" -Wc,-MD else "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. test -z "$dashmflag" && dashmflag=-M ( IFS=" " case " $* " in *" --mode=compile "*) # this is libtool, let us make it quiet for arg do # cycle over the arguments case "$arg" in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) # X makedepend ( shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift;; -*) ;; *) set fnord "$@" "$arg"; shift;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 spamprobe-1.4d/configure0000775000076400007640000062741510527227202012372 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE RANLIB ac_ct_RANLIB CPP EGREP LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-default-8bit Changes the default character handling to store 8 bit chars --enable-cdb Enables use of Berkeley DB concurrent data store --enable-no-deprecated Enables annoying deprecated warning --enable-big-endian Causes all database reads and writes to use big-endian byte order Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-assert Enables assertions for testing --with-pbl=PATH Specify path to PBL install --with-db=PATH Specify path to BerkelyDB install directory --with-gdbm=PATH Specify path to GDBM install directory - not a good idea --with-gif Enables processing of gif images (default) --with-png Enables processing of png images (default) --with-jpeg Enables processing of jpeg images (default) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version="1.9" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 test "$program_prefix" != NONE && program_transform_name="s,^,$program_prefix,;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$,$program_suffix,;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=spamprobe VERSION=1.4d cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dirent.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "regcomp" >/dev/null 2>&1; then cat >>confdefs.h <<\_ACEOF #define HAVE_REGEX_H 1 _ACEOF else { { echo "$as_me:$LINENO: error: POSIX regcomp() function not available" >&5 echo "$as_me: error: POSIX regcomp() function not available" >&2;} { (exit 1); exit 1; }; } fi rm -f conftest* # Check whether --enable-default-8bit or --disable-default-8bit was given. if test "${enable_default_8bit+set}" = set; then enableval="$enable_default_8bit" cat >>confdefs.h <<\_ACEOF #define USE_8BIT 1 _ACEOF fi; # Check whether --enable-cdb or --disable-cdb was given. if test "${enable_cdb+set}" = set; then enableval="$enable_cdb" cat >>confdefs.h <<\_ACEOF #define USE_CDB 1 _ACEOF fi; want_assert=0 # Check whether --with-assert or --without-assert was given. if test "${with_assert+set}" = set; then withval="$with_assert" if test "x$withval" != "xno" ; then want_assert=1 fi fi; if test $want_assert != 1 ; then CPPFLAGS="-DNDEBUG $CPPFLAGS" fi # Check whether --enable-no-deprecated or --disable-no-deprecated was given. if test "${enable_no_deprecated+set}" = set; then enableval="$enable_no_deprecated" CXXFLAGS="-Wno-deprecated $CXXFLAGS" fi; # Check whether --enable-big-endian or --disable-big-endian was given. if test "${enable_big_endian+set}" = set; then enableval="$enable_big_endian" cat >>confdefs.h <<\_ACEOF #define FORCE_NETWORK_ORDER 1 _ACEOF fi; have_database=0 # Check whether --with-pbl or --without-pbl was given. if test "${with_pbl+set}" = set; then withval="$with_pbl" if test "x$withval" != "xno" ; then if test -d "$withval/lib"; then LDFLAGS="-L${withval}/lib $LDFLAGS" else LDFLAGS="-L${withval} $LDFLAGS" fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include $CPPFLAGS" else CPPFLAGS="-I${withval} $CPPFLAGS" fi echo "$as_me:$LINENO: checking for pblIsamCommit in -lpbl" >&5 echo $ECHO_N "checking for pblIsamCommit in -lpbl... $ECHO_C" >&6 if test "${ac_cv_lib_pbl_pblIsamCommit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpbl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pblIsamCommit (); int main () { pblIsamCommit (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pbl_pblIsamCommit=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pbl_pblIsamCommit=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pbl_pblIsamCommit" >&5 echo "${ECHO_T}$ac_cv_lib_pbl_pblIsamCommit" >&6 if test $ac_cv_lib_pbl_pblIsamCommit = yes; then LIBS="$LIBS -lpbl" else echo "$as_me:$LINENO: checking for pblIsamClose in -lpbl" >&5 echo $ECHO_N "checking for pblIsamClose in -lpbl... $ECHO_C" >&6 if test "${ac_cv_lib_pbl_pblIsamClose+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpbl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pblIsamClose (); int main () { pblIsamClose (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pbl_pblIsamClose=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pbl_pblIsamClose=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pbl_pblIsamClose" >&5 echo "${ECHO_T}$ac_cv_lib_pbl_pblIsamClose" >&6 if test $ac_cv_lib_pbl_pblIsamClose = yes; then LIBS="$LIBS -lpbl" else { { echo "$as_me:$LINENO: error: No suitable PBL library found." >&5 echo "$as_me: error: No suitable PBL library found." >&2;} { (exit 1); exit 1; }; } fi fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pblIsamOpen (); int main () { pblIsamOpen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define USE_PBL 1 _ACEOF have_database=1 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi fi; if test $have_database = 0 ; then # Check whether --with-db or --without-db was given. if test "${with_db+set}" = set; then withval="$with_db" if test "x$withval" != "xno" ; then if test -d "$withval/lib"; then LDFLAGS="-L${withval}/lib $LDFLAGS" else LDFLAGS="-L${withval} $LDFLAGS" fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include $CPPFLAGS" else CPPFLAGS="-I${withval} $CPPFLAGS" fi fi else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "DB_VERSION_MAJOR *3|4" >/dev/null 2>&1; then : else { { echo "$as_me:$LINENO: error: No suitable BerkeleyDB db.h header file found. Use --with-db=PATH to specify the path to a version 3 or later install directory. You can download BerkeleyDB from http://www.sleepycat.com" >&5 echo "$as_me: error: No suitable BerkeleyDB db.h header file found. Use --with-db=PATH to specify the path to a version 3 or later install directory. You can download BerkeleyDB from http://www.sleepycat.com" >&2;} { (exit 1); exit 1; }; } fi rm -f conftest* fi; echo "$as_me:$LINENO: checking for BerkeleyDB library" >&5 echo $ECHO_N "checking for BerkeleyDB library... $ECHO_C" >&6 if test "${dac_cv_search_BerkeleyDB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else dac_save_LIBS=$LIBS dac_cv_search_BerkeleyDB=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { DB *db; DB_ENV *dbEnv; db_create(&db, dbEnv, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then dac_cv_search_BerkeleyDB="present" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "$dac_cv_search_BerkeleyDB" = no; then for dac_lib in db db4 db-4 db3 db-3 ; do LIBS="-l$dac_lib $dac_save_LIBS" rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then dac_cv_search_BerkeleyDB="-l$dac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext done fi LIBS=$dac_save_LIBS fi echo "$as_me:$LINENO: result: $dac_cv_search_BerkeleyDB" >&5 echo "${ECHO_T}$dac_cv_search_BerkeleyDB" >&6 if test "$dac_cv_search_BerkeleyDB" != no; then test "$dac_cv_search_BerkeleyDB" = "present" || LIBS="$dac_cv_search_BerkeleyDB $LIBS" ; cat >>confdefs.h <<\_ACEOF #define USE_DB 1 _ACEOF have_database=1 fi fi if test $have_database = 0 ; then # Check whether --with-gdbm or --without-gdbm was given. if test "${with_gdbm+set}" = set; then withval="$with_gdbm" if test "x$withval" != "xno" ; then if test -d "$withval/lib"; then LDFLAGS="-L${withval}/lib $LDFLAGS" else LDFLAGS="-L${withval} $LDFLAGS" fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include $CPPFLAGS" else CPPFLAGS="-I${withval} $CPPFLAGS" fi echo "$as_me:$LINENO: checking for library containing dbm_store" >&5 echo $ECHO_N "checking for library containing dbm_store... $ECHO_C" >&6 if test "${ac_cv_search_dbm_store+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_dbm_store=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dbm_store (); int main () { dbm_store (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_dbm_store="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_dbm_store" = no; then for ac_lib in gdbm ndbm; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dbm_store (); int main () { dbm_store (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_dbm_store="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_dbm_store" >&5 echo "${ECHO_T}$ac_cv_search_dbm_store" >&6 if test "$ac_cv_search_dbm_store" != no; then test "$ac_cv_search_dbm_store" = "none required" || LIBS="$ac_cv_search_dbm_store $LIBS" cat >>confdefs.h <<\_ACEOF #define USE_DBM 1 _ACEOF have_database=1 fi fi fi; fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char mmap (); int main () { mmap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define USE_MMAP 1 _ACEOF have_database=1 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test $have_database = 0 ; then { { echo "$as_me:$LINENO: error: No suitable database library (PDL or BerkeleyDB version 3 or higher) found. Specify location of proper package location using --with-db=PATH" >&5 echo "$as_me: error: No suitable database library (PDL or BerkeleyDB version 3 or higher) found. Specify location of proper package location using --with-db=PATH" >&2;} { (exit 1); exit 1; }; } fi want_gif=1 # Check whether --with-gif or --without-gif was given. if test "${with_gif+set}" = set; then withval="$with_gif" if test "x$withval" = "xno" ; then want_gif=0 fi fi; if test $want_gif = 1 ; then if test "${ac_cv_header_gif_lib_h+set}" = set; then echo "$as_me:$LINENO: checking for gif_lib.h" >&5 echo $ECHO_N "checking for gif_lib.h... $ECHO_C" >&6 if test "${ac_cv_header_gif_lib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_gif_lib_h" >&5 echo "${ECHO_T}$ac_cv_header_gif_lib_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking gif_lib.h usability" >&5 echo $ECHO_N "checking gif_lib.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking gif_lib.h presence" >&5 echo $ECHO_N "checking gif_lib.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: gif_lib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: gif_lib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: gif_lib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: gif_lib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: gif_lib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: gif_lib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: gif_lib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: gif_lib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: gif_lib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: gif_lib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: gif_lib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: gif_lib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: gif_lib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: gif_lib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: gif_lib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: gif_lib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for gif_lib.h" >&5 echo $ECHO_N "checking for gif_lib.h... $ECHO_C" >&6 if test "${ac_cv_header_gif_lib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_gif_lib_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_gif_lib_h" >&5 echo "${ECHO_T}$ac_cv_header_gif_lib_h" >&6 fi if test $ac_cv_header_gif_lib_h = yes; then echo "$as_me:$LINENO: checking for DGifOpen in -lungif" >&5 echo $ECHO_N "checking for DGifOpen in -lungif... $ECHO_C" >&6 if test "${ac_cv_lib_ungif_DGifOpen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lungif $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char DGifOpen (); int main () { DGifOpen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ungif_DGifOpen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ungif_DGifOpen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ungif_DGifOpen" >&5 echo "${ECHO_T}$ac_cv_lib_ungif_DGifOpen" >&6 if test $ac_cv_lib_ungif_DGifOpen = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNGIF 1 _ACEOF LIBS="$LIBS -lungif" else echo "$as_me:$LINENO: checking for DGifOpen in -lgif" >&5 echo $ECHO_N "checking for DGifOpen in -lgif... $ECHO_C" >&6 if test "${ac_cv_lib_gif_DGifOpen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgif $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char DGifOpen (); int main () { DGifOpen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_gif_DGifOpen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gif_DGifOpen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_gif_DGifOpen" >&5 echo "${ECHO_T}$ac_cv_lib_gif_DGifOpen" >&6 if test $ac_cv_lib_gif_DGifOpen = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNGIF 1 _ACEOF LIBS="$LIBS -lgif" fi fi fi fi want_png=1 # Check whether --with-png or --without-png was given. if test "${with_png+set}" = set; then withval="$with_png" if test "x$withval" = "xno" ; then want_png=0 fi fi; if test $want_png = 1 ; then if test "${ac_cv_header_png_h+set}" = set; then echo "$as_me:$LINENO: checking for png.h" >&5 echo $ECHO_N "checking for png.h... $ECHO_C" >&6 if test "${ac_cv_header_png_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5 echo "${ECHO_T}$ac_cv_header_png_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking png.h usability" >&5 echo $ECHO_N "checking png.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking png.h presence" >&5 echo $ECHO_N "checking png.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: png.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: png.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: png.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: png.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: png.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: png.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: png.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: png.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: png.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: png.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: png.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: png.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for png.h" >&5 echo $ECHO_N "checking for png.h... $ECHO_C" >&6 if test "${ac_cv_header_png_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_png_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5 echo "${ECHO_T}$ac_cv_header_png_h" >&6 fi if test $ac_cv_header_png_h = yes; then echo "$as_me:$LINENO: checking for png_set_progressive_read_fn in -lpng" >&5 echo $ECHO_N "checking for png_set_progressive_read_fn in -lpng... $ECHO_C" >&6 if test "${ac_cv_lib_png_png_set_progressive_read_fn+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char png_set_progressive_read_fn (); int main () { png_set_progressive_read_fn (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_png_png_set_progressive_read_fn=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_png_png_set_progressive_read_fn=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_set_progressive_read_fn" >&5 echo "${ECHO_T}$ac_cv_lib_png_png_set_progressive_read_fn" >&6 if test $ac_cv_lib_png_png_set_progressive_read_fn = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_PNG 1 _ACEOF LIBS="$LIBS -lpng" fi fi fi want_jpeg=1 # Check whether --with-jpeg or --without-jpeg was given. if test "${with_jpeg+set}" = set; then withval="$with_jpeg" if test "x$withval" = "xno" ; then want_jpeg=0 fi fi; if test $want_jpeg = 1 ; then if test "${ac_cv_header_jpeglib_h+set}" = set; then echo "$as_me:$LINENO: checking for jpeglib.h" >&5 echo $ECHO_N "checking for jpeglib.h... $ECHO_C" >&6 if test "${ac_cv_header_jpeglib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_jpeglib_h" >&5 echo "${ECHO_T}$ac_cv_header_jpeglib_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking jpeglib.h usability" >&5 echo $ECHO_N "checking jpeglib.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking jpeglib.h presence" >&5 echo $ECHO_N "checking jpeglib.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: jpeglib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: jpeglib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: jpeglib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: jpeglib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: jpeglib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: jpeglib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: jpeglib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: jpeglib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: jpeglib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: jpeglib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: jpeglib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: jpeglib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: jpeglib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: jpeglib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: jpeglib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: jpeglib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for jpeglib.h" >&5 echo $ECHO_N "checking for jpeglib.h... $ECHO_C" >&6 if test "${ac_cv_header_jpeglib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_jpeglib_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_jpeglib_h" >&5 echo "${ECHO_T}$ac_cv_header_jpeglib_h" >&6 fi if test $ac_cv_header_jpeglib_h = yes; then echo "$as_me:$LINENO: checking for jpeg_read_header in -ljpeg" >&5 echo $ECHO_N "checking for jpeg_read_header in -ljpeg... $ECHO_C" >&6 if test "${ac_cv_lib_jpeg_jpeg_read_header+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljpeg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char jpeg_read_header (); int main () { jpeg_read_header (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_jpeg_jpeg_read_header=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_jpeg_jpeg_read_header=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_jpeg_read_header" >&6 if test $ac_cv_lib_jpeg_jpeg_read_header = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_JPEG 1 _ACEOF LIBS="$LIBS -ljpeg" fi fi fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_config_files="$ac_config_files Makefile src/Makefile src/database/Makefile src/hdl/Makefile src/includes/Makefile src/input/Makefile src/parser/Makefile src/utility/Makefile src/spamprobe/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/database/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/database/Makefile" ;; "src/hdl/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/hdl/Makefile" ;; "src/includes/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/includes/Makefile" ;; "src/input/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/input/Makefile" ;; "src/parser/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/parser/Makefile" ;; "src/utility/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/utility/Makefile" ;; "src/spamprobe/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/spamprobe/Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@CYGPATH_W@,$CYGPATH_W,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@mkdir_p@,$mkdir_p,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t s,@AMTAR@,$AMTAR,;t t s,@am__tar@,$am__tar,;t t s,@am__untar@,$am__untar,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@CXXDEPMODE@,$CXXDEPMODE,;t t s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi spamprobe-1.4d/aclocal.m40000664000076400007640000011317610527227170012321 00000000000000# generated automatically by aclocal 1.9.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # -*- Autoconf -*- # Copyright (C) 2002, 2003 Free Software Foundation, Inc. # Generated from amversion.in; do not edit by hand. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.2])]) # AM_AUX_DIR_EXPAND # Copyright (C) 2001, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 6 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # serial 7 -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 11 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright (C) 2001, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # -*- Autoconf -*- # Copyright (C) 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # Copyright (C) 2003, 2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # AM_PROG_INSTALL_STRIP # Copyright (C) 2001, 2003 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) spamprobe-1.4d/configure.ac0000664000076400007640000001147510527227154012750 00000000000000AC_INIT AM_INIT_AUTOMAKE(spamprobe,1.4d) AC_PROG_CC AC_PROG_CXX AC_PROG_RANLIB AC_CHECK_HEADERS(unistd.h) AC_CHECK_HEADERS(dirent.h) AC_EGREP_HEADER([regcomp], [regex.h], AC_DEFINE(HAVE_REGEX_H), AC_MSG_ERROR([POSIX regcomp() function not available])) AC_ARG_ENABLE(default-8bit, [ --enable-default-8bit Changes the default character handling to store 8 bit chars ], AC_DEFINE(USE_8BIT)) AC_ARG_ENABLE(cdb, [ --enable-cdb Enables use of Berkeley DB concurrent data store ], AC_DEFINE(USE_CDB)) want_assert=0 AC_ARG_WITH(assert, [ --with-assert Enables assertions for testing ], [ if test "x$withval" != "xno" ; then want_assert=1 fi ] ) if test $want_assert != 1 ; then CPPFLAGS="-DNDEBUG $CPPFLAGS" fi AC_ARG_ENABLE(no-deprecated, [ --enable-no-deprecated Enables annoying deprecated warning ], [ CXXFLAGS="-Wno-deprecated $CXXFLAGS" ]) AC_ARG_ENABLE(big-endian, [ --enable-big-endian Causes all database reads and writes to use big-endian byte order ], AC_DEFINE(FORCE_NETWORK_ORDER)) have_database=0 AC_ARG_WITH(pbl, [ --with-pbl=PATH Specify path to PBL install ], [ if test "x$withval" != "xno" ; then if test -d "$withval/lib"; then LDFLAGS="-L${withval}/lib $LDFLAGS" else LDFLAGS="-L${withval} $LDFLAGS" fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include $CPPFLAGS" else CPPFLAGS="-I${withval} $CPPFLAGS" fi AC_CHECK_LIB(pbl, pblIsamCommit, LIBS="$LIBS -lpbl", AC_CHECK_LIB(pbl, pblIsamClose, LIBS="$LIBS -lpbl", AC_MSG_ERROR([No suitable PBL library found.]))) AC_TRY_LINK_FUNC(pblIsamOpen, AC_DEFINE([USE_PBL]) have_database=1) fi ] ) if test $have_database = 0 ; then AC_ARG_WITH(db, [ --with-db=PATH Specify path to BerkelyDB install directory ], [ if test "x$withval" != "xno" ; then if test -d "$withval/lib"; then LDFLAGS="-L${withval}/lib $LDFLAGS" else LDFLAGS="-L${withval} $LDFLAGS" fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include $CPPFLAGS" else CPPFLAGS="-I${withval} $CPPFLAGS" fi fi ], [ AC_EGREP_HEADER([DB_VERSION_MAJOR *3|4], [db.h],, AC_MSG_ERROR([No suitable BerkeleyDB db.h header file found. Use --with-db=PATH to specify the path to a version 3 or later install directory. You can download BerkeleyDB from http://www.sleepycat.com]) ) ] ) DAC_SEARCH_LIBS(BerkeleyDB, AC_LANG_PROGRAM([[#include ]], [[DB *db; DB_ENV *dbEnv; db_create(&db, dbEnv, 0);]]), [db db4 db-4 db3 db-3], AC_DEFINE([USE_DB]) have_database=1, [],[]) fi if test $have_database = 0 ; then AC_ARG_WITH(gdbm, [ --with-gdbm=PATH Specify path to GDBM install directory - not a good idea ], [ if test "x$withval" != "xno" ; then if test -d "$withval/lib"; then LDFLAGS="-L${withval}/lib $LDFLAGS" else LDFLAGS="-L${withval} $LDFLAGS" fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include $CPPFLAGS" else CPPFLAGS="-I${withval} $CPPFLAGS" fi AC_SEARCH_LIBS(dbm_store,[gdbm ndbm], AC_DEFINE([USE_DBM]) have_database=1) fi ] ) fi AC_TRY_LINK_FUNC(mmap,AC_DEFINE([USE_MMAP]) have_database=1) if test $have_database = 0 ; then AC_MSG_ERROR([No suitable database library (PDL or BerkeleyDB version 3 or higher) found. Specify location of proper package location using --with-db=PATH]) fi want_gif=1 AC_ARG_WITH(gif, [ --with-gif Enables processing of gif images (default) ], [ if test "x$withval" = "xno" ; then want_gif=0 fi ] ) if test $want_gif = 1 ; then AC_CHECK_HEADER([gif_lib.h],AC_CHECK_LIB(ungif, DGifOpen, AC_DEFINE([HAVE_UNGIF]) LIBS="$LIBS -lungif",AC_CHECK_LIB(gif, DGifOpen, AC_DEFINE([HAVE_UNGIF]) LIBS="$LIBS -lgif"))) fi want_png=1 AC_ARG_WITH(png, [ --with-png Enables processing of png images (default) ], [ if test "x$withval" = "xno" ; then want_png=0 fi ] ) if test $want_png = 1 ; then AC_CHECK_HEADER([png.h],AC_CHECK_LIB(png, png_set_progressive_read_fn, AC_DEFINE([HAVE_PNG]) LIBS="$LIBS -lpng")) fi want_jpeg=1 AC_ARG_WITH(jpeg, [ --with-jpeg Enables processing of jpeg images (default) ], [ if test "x$withval" = "xno" ; then want_jpeg=0 fi ] ) if test $want_jpeg = 1 ; then AC_CHECK_HEADER([jpeglib.h],AC_CHECK_LIB(jpeg, jpeg_read_header, AC_DEFINE([HAVE_JPEG]) LIBS="$LIBS -ljpeg")) fi AC_PROG_INSTALL AC_OUTPUT(Makefile src/Makefile src/database/Makefile src/hdl/Makefile src/includes/Makefile src/input/Makefile src/parser/Makefile src/utility/Makefile src/spamprobe/Makefile) spamprobe-1.4d/contrib/0000777000076400007640000000000010527262426012175 500000000000000spamprobe-1.4d/contrib/README-maildrop.txt0000664000076400007640000000353310526706576015432 00000000000000HOWTO use SpamProbe with maildrop. 0. INTRODUCTION maildrop is a mail-filtering package, somewhat similar to procmail, but more robust and with a clearer syntax. It is available as part of the "Courier" mail package or standalone from http://www.flounder.net/~mrsam/maildrop/README.html This document shows two examples for your ~/.mailfilter that make use of SpamProbe. 1. LICENSE Copyright (c) 2002 Matthias Andree Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LICENSE, with no Front-Cover Texts and no Back-Cover Texts. A copy of the license can be obtained from http://www.gnu.org/licenses/fdl.html 2.1. THE SIMPLE SETUP Put this into your ~/.mailfilter file: ============================================================================= # save mail to the "saved" mbox, better safe than sorry cc saved # score the mail and tag it SCORE=`spamprobe -8 receive` xfilter "reformail -I \"X-SpamProbe: $SCORE\"" # if it's spam, reroute it to the spamprobe mbox if (/^X-SpamProbe: SPAM/) to "spamprobe" ============================================================================= 2.2. USING SPAMASSASSIN AS TEACHER This assumes that spamd is running (for performance reasons, you should do this). Use the ~/.mailfilter setup from secton 2.1 above, and add these lines below the `to "spamprobe"' line: ============================================================================= xfilter "/usr/bin/spamc" if (/^X-Spam-Flag: YES/) { cc "|spamassassin -d -L|spamprobe -8 spam" to "spamassassin" } ============================================================================= spamprobe-1.4d/contrib/spamprobe.el0000664000076400007640000001042410526706576014436 00000000000000;;; spamprobe.el - spamprobe utils for emacs. ;; Copyright 2002 by Dave Pearson ;; Revision: 1.6 ;; spamprobe.el is free software distributed under the terms of the GNU ;; General Public Licence, version 2. For details see the file COPYING. ;;; Commentary: ;; I use spamprobe to help me manage ;; my incoming mail and, because of this, I wrote spamprobe.el to provide me ;; with a small set of emacs based spamprobe tools. ;; ;; This code might only be useful to you if you handle UCE in a similar way ;; to how I do. I (attempt to) deliver all UCE to an mbox mail folder called ;; ~/Mail/Junk. All mail in there should contain a "X-SpamProbe:" header ;; (added to each email by a procmail rule). I then retain all that UCE so I ;; can see how well spamprobe is doing. ;; ;; The latest version of spamprobe.el can be found at: ;; ;; ;;; Code: ;; (Not yet)Customize options. (defvar spamprobe-spam-folder "~/Mail/Junk" "*Folder that holds known \"spam\".") (defvar spamprobe-regexp "^X-SpamProbe: " "*Regular expression for a spamprobe result header.") (defvar spamprobe-good-regexp (concat spamprobe-regexp "GOOD") "*Regular expression for a spamprobe \"good\" result header.") (defvar spamprobe-spam-regexp (concat spamprobe-regexp "SPAM") "*Regular expression for a spamprobe \"spam\" result header.") (defvar spamprobe-score-command "spamprobe score" "*Command used to score a file.") ;; Global variables. (defvar spamprobe-checks 0) (defvar spamprobe-hits 0) (defvar spamprobe-misses 0) (defvar spamprobe-last-file-info nil) ;; Main code: (defun spamprobe-file-info () "Get the file info for the spam folder" (let ((info (file-attributes spamprobe-spam-folder))) (list (nth 5 info) (nth 7 info)))) (defun spamprobe-grep-junk (re) "Grep the \"spam\" folder." (car (read-from-string (shell-command-to-string (format "grep -c \"%s\" %s" re spamprobe-spam-folder))))) (defun spamprobe-calc () "Do the junk folder calculations." (unless (equal spamprobe-last-file-info (spamprobe-file-info)) (message "Calculating spam stats...") (setq spamprobe-last-file-info (spamprobe-file-info) spamprobe-hits (spamprobe-grep-junk spamprobe-spam-regexp) spamprobe-misses (spamprobe-grep-junk spamprobe-good-regexp) spamprobe-checks (+ spamprobe-hits spamprobe-misses)))) (defun spamprobe-calc-checks () "How many emails in the junk folder has spamprobe checked?" (spamprobe-calc) spamprobe-checks) (defun spamprobe-calc-hits () "How many emails did spamprobe correctly guess as junk?" (spamprobe-calc) spamprobe-hits) (defun spamprobe-calc-misses () "How many emails did spamprobe incorectly guess as ok?" (spamprobe-calc) spamprobe-misses) (defun spamprobe-calc-effectiveness () "How effective has spamprobe been so far?" (* (/ 100.0 (spamprobe-calc-checks)) (spamprobe-calc-hits))) ;;;###autoload (defun spamprobe-stats () "Display spamprobe stats." (interactive) (message "Checked: %d, Hits: %d, Missed: %d" (spamprobe-calc-checks) (spamprobe-calc-hits) (spamprobe-calc-misses))) ;;;###autoload (defun spamprobe-effectiveness () "How effective has spamprobe been at capturing junk mail?" (interactive) (message "spamprobe has caught %.2f%% of my junk email" (spamprobe-calc-effectiveness))) (defun spamprobe-region-score (start end) "Get the spamprobe score for region START to END. A `cons' is returned. The `car' is a string that says if the region is GOOD or SPAM, the `cdr' is the score of the region." (let ((temp (make-temp-file "spamprobe-region"))) (unwind-protect (progn (write-region start end temp) (message "Scoring region...") (let ((score (split-string (shell-command-to-string (format "%s %s" spamprobe-score-command temp))))) (cons (car score) (string-to-number (cadr score))))) (delete-file temp)))) ;;;###autoload (defun spamprobe-score-region (start end) "Display the spamprobe score for text in region START to END." (interactive "r") (let ((score (spamprobe-region-score start end))) (message "Score: %s (%f)" (car score) (cdr score)))) (provide 'spamprobe) ;;; spamprobe.el ends here spamprobe-1.4d/contrib/README-mta-mda-mua.txt0000664000076400007640000001401410526706576015717 00000000000000filename: README-mta-mda-mua.txt author: Anto Veldre ver 002, section 1.5 completely rewritten, minor clean-ups. ==================================================== What follows is some background information on MUAs, MDAs and MTAs (mail user, delivery and transfer agents) See also what opinion wiki has about the matter: http://twiki.org/cgi-bin/view/Wikilearn/EmailServerTerminology ------------------------------------------------------ 1.1 Admin domain versus user domain =================================== The good news is that unlike with some virus scanners, spamprobe installation avoids fiddling with sophisticated system toys (like mail queues, MTA configurations files and similar), which traditionally belong to UNIX administrator domain. All what spamprobe needs to attempt, is done in user space. This means you could implement spamprobe without neccessarily consulting your system administrator (which could be a problem at universities and other over-managed sites). But ... procmail is a prerequisite nevertheless. 1.2 sendmail + procmail ======================= Chances are that procmail is already installed on your system, because of sendmail needs it for local delivery. Historically, sendmail is the King of MTAs (http://www.sendmail.org). Provided your system is sufficiently modern, both sendmail and procmail should be installed. Sendmail decides whether or not should the message be delivered to a _local_ user and if the answer is YES, it hands the message over to procmail, which is responsible for the actual delivery (appending the message to the users mailbox somewhere at /var/spool/$user). Commanding "grep procmail /etc/sendmail.conf" is usually sufficient to estimate whether you have sendmail+procmail preinstalled. You also can check the precence of procmail by directly launching "procmail" (CTRL-D helps you out of there) or checking the precence by "which procmail". Another good news is that once procmail is installed (and somehow implemented into your mail delivery process), you do not have to configure it otherwise than via normal rc (run-command) file which is ~/.procmailrc . Visit http://www.procmail.org. "Interesting and Useful Links" is the most valuable section there. 1.3 Other MTA's =============== What to do if your system isn't sendmail based? To use spamprobe, you have to work out some method how MTA hands mail over to procmail. Other MTAs are compatible with procmail to lesser or greater extent. For Qmail (http://www.qmail.org), procmail is a normal satellite. For Postfix (http://www.postix.org), procmail should be specifically described as the local delivery agent (in /etc/postfic/mai.cf). For Exim (http://www.exim.org), a user only could pipe messages to procmail via ~/.forward file (if not prohibited by admin). But expect trouble with outdated smail or an old MMDF (SCO UNIX leftover). I hope no such bestia left on the planet but nevertheless... Any actual used experience is welcome to this section. 1.4 Bypassing the system-wide mail delivery system ================================================== Generally, an admin-controlled MTA could be easily substituted or bypassed by user space tools. This fact itself is not good or bad, it simply is an option for the user. Various POP3 or IMAP clients allow you to collect your messages from remote. Moreover - you could IMAP or POP3 to _localhost_, this way the retrieved messages (by default) are automatically erased from your system mailbox. Programs like fetchmail (http://www.tuxedo.org/~esr/fetchmail/) could be used to fully automate the mail collection process. Mail readers generally are widely configurable, so you could point to your actual mailbox. But be beware - graphical mail clients may distort (sorry, enrich) the classical mailbox structure used by mail, mailx, elm and pine. Once read into, it isn't easy way out of an proprietary mailbox. 1.5 My personal setup ===================== The ~/.procmailrc file I use looks like: MAILDIR=/home/$me/INCOMING-MAIL :0 c saved :0 SCORE=| /usr/local/bin/spamprobe receive :0 wf | formail -I "X-SpamProbe: $SCORE" :0 a: *^X-SpamProbe: SPAM dirty :0 a: *^X-SpamProbe: GOOD cleaned Now all incoming mail is stored at $MAILDIR/saved. In addition to this, spamprobe will use two self-explainingly named mailboxes as $MAILDIR/cleaned and $MAILDIR/dirty. The result is that my previous incoming mailbox at /var/spool/mail/me will no more be used by the procmail. Why? Because of after applying two mutually excluding rules (store SPAM at dirty and GOOD at goodies) no messages will be left for procmail to store at my previous inbox (at /var/spool/mail/$me). In excellent setups, $MAILDIR/saved file should be linked to an NFS share (probability two HD's will synchronously fail outweights NFS reliability problems). In excellent setups some cron script should periodically archive what is stored in saved file (e.g. my-mail-pre-2002-12-27.gz). Oh yeah, I almost forgot it - I am an elm addict for 10 years. Graphical MUAs may use a different paradigm and accordingly these may prefer fetching mail directly by POP3/IMAP. 1.6 Bayesian technology ======================= Seems like famous article by Paul Grahams inspired many spam-fighters and a lot of more than 1 programmer started to konqueror evil's territory with statistical methods. Searching for "bayesian" at http://www.freshmeat.net or http://www.sourceforge.net will indicate the popularity of the technology. 1.7 Security topics =================== Generally, be cautious when playing with .procmailrc. It is rather easy to create systemwide security blackholes via "vacation" program (http://www.ayradyss.org/programs/current.html#vacation) or piping the messages to programs (via ~/.forward file) 1.8 Cartago delenda est ======================= I still think MUAs should obtain a "SPAM" button beside "DELETE" one. Junk will be deleted in both cases, the difference is that "SPAM" knob will first analyse it and only then delete. Spamprobe is a good candidate to do the dirty work behind "SPAM" button. anto@xyz.ee ES1LAU spamprobe-1.4d/LICENSE.txt0000664000076400007640000001071410526706577012312 00000000000000The Q Public License Version 1.0 Copyright (C) 1999 Trolltech AS, Norway. Everyone is permitted to copy and distribute this license document. The intent of this license is to establish freedom to share and change the software regulated by this license under the open source model. This license applies to any software containing a notice placed by the copyright holder saying that it may be distributed under the terms of the Q Public License version 1.0. Such software is herein referred to as the Software. This license covers modification and distribution of the Software, use of third-party application programs based on the Software, and development of free software which uses the Software. Granted Rights -------------- 1. You are granted the non-exclusive rights set forth in this license provided you agree to and comply with any and all conditions in this license. Whole or partial distribution of the Software, or software items that link with the Software, in any form signifies acceptance of this license. 2. You may copy and distribute the Software in unmodified form provided that the entire package, including - but not restricted to - copyright, trademark notices and disclaimers, as released by the initial developer of the Software, is distributed. 3. You may make modifications to the Software and distribute your modifications, in a form that is separate from the Software, such as patches. The following restrictions apply to modifications: a. Modifications must not alter or remove any copyright notices in the Software. b. When modifications to the Software are released under this license, a non-exclusive royalty-free right is granted to the initial developer of the Software to distribute your modification in future versions of the Software provided such versions remain available under these terms in addition to any other license(s) of the initial developer. 4. You may distribute machine-executable forms of the Software or machine-executable forms of modified versions of the Software, provided that you meet these restrictions: a. You must include this license document in the distribution. b. You must ensure that all recipients of the machine-executable forms are also able to receive the complete machine-readable source code to the distributed Software, including all modifications, without any charge beyond the costs of data transfer, and place prominent notices in the distribution explaining this. c. You must ensure that all modifications included in the machine-executable forms are available under the terms of this license. 5. You may use the original or modified versions of the Software to compile, link and run application programs legally developed by you or by others. 6. You may develop application programs, reusable components and other software items that link with the original or modified versions of the Software. These items, when distributed, are subject to the following requirements: a. You must ensure that all recipients of machine-executable forms of these items are also able to receive and use the complete machine-readable source code to the items without any charge beyond the costs of data transfer. b. You must explicitly license all recipients of your items to use and re-distribute original and modified versions of the items in both machine-executable and source code forms. The recipients must be able to do so without any charges whatsoever, and they must be able to re-distribute to anyone they choose. c. If the items are not available to the general public, and the initial developer of the Software requests a copy of the items, then you must supply one. Limitations of Liability ------------------------ In no event shall the initial developers or copyright holders be liable for any damages whatsoever, including - but not restricted to - lost revenue or profits or other direct, indirect, special, incidental or consequential damages, even if they have been advised of the possibility of such damages, except to the extent invariable law, if any, provides otherwise. No Warranty ----------- The Software and this license document are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Choice of Law ------------- This license is governed by the Laws of the state of Maryland. Disputes shall be settled by a court selected by Burton Computer Corporation. spamprobe-1.4d/README.txt0000664000076400007640000013674210527231123012154 00000000000000SpamProbe v1.4 README LEGALESE Burton Computer Corporation http://www.burton-computer.com Copyright (C) 2002,2003,2004,2005,2006 Burton Computer Corporation ALL RIGHTS RESERVED This program is open source software; you can redistribute it and/or modify it under the terms of the Q Public License (QPL) version 1.0. Use of this software in whole or in part, including linking it (modified or unmodified) into other programs is subject to the terms of the QPL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Q Public License for more details. You should have received a copy of the Q Public License along with this program; see the file LICENSE.txt. If not, visit the Burton Computer Corporation or CoolDevTools web site QPL pages at: http://www.burton-computer.com/qpl.html INTRODUCTION Welcome to SpamProbe! Are you tired of the constant bombardment of your inbox by unwanted email pushing everything from porn to get rich quick schemes? Have you tried other spam filters but become disenchanted with them when you realized that their manually generated rule sets weren't updated fast enough to keep up with spammers wording changes? Or that they generated unwanted false positive scores? SpamProbe operates on a different basis entirely. Instead of using pattern matching and a set of human generated rules SpamProbe relies on a Bayesian analysis of the frequency of words used in spam and non-spam emails received by an individual person. The process is completely automatic and tailors itself to the kinds of emails that each person receives. My work on SpamProbe was inspired by an excellent article by Paul Graham. He describes the basic idea and his results. You can read his article here: http://www.paulgraham.com/spam.html I highly recommend reading the article and the other spam related links on his site for excellent insights into why spam is a problem and how you can defeat it. Of course running SpamProbe is an excellent step! :-) FEATURES * Spam detection using Bayesian analysis of terms contained in each email. Words used often in spams but not in good email tend to indicate that a message is spam. * Written in C++ for good performance. Database access using PBL or BerkeleyDB for quick startup and fast term count retrieval. * Recognition and decoding of MIME attachments in quoted-printable and base64 encoding. Automatically skips non-text attachments. MIME decoding enables SpamProbe to make decisions based on words in the emails rather than base64 gobbledigook. * Counts two word phrases as well as single words for higher precision. * Counts words in from, to, cc, received, and subject headers separately for improved accuracy since some words are better indicators of spam when they appear in the subject than in the body. Received headers after the first are counted separately from first Received header since they are likely to be forged in spams. * Ignores HTML tags in emails for scoring purposes unless the -h command line option is used. Many spams use HTML and few humans do so HTML tends to become a powerful recognizer of spams. However in the author's opinion this also substantially increases the likelihood of false positives if someone does send a non-spam email containing HTML tags. SpamProbe does pull urls from inside of html tags however since those tend to be spammer specific. * Supports MBOX, MBX and Maildir mailbox formats. * Analyzes image attachments to extract useful terms for scoring. This catches the majority of spams with only images and no words. * Locks mboxes and databases using fcntl file locking to avoid problems when multiple emails arrive simultaneously. Can optionally be compiled to use Berkeley DB's environment functions to provide better interaction with db_dump, db_verify, etc. * Scores only the Received, Subject, To, From, and Cc headers. All other headers are ignored to make it hard for spammers to hide non-spammy words in X- headers to fool the filter. The -H command line option can be used to override this. * Supports Content-Length: field in mbox headers. This can be disabled using -Y option to use only From_ to recognize new messages. * Uses MD5 digest of emails to recognize reclassification of an already classified spam to avoid distortion of the word counts if emails are reclassified. This way emails can be kept in an mbox that is repeatedly scanned by spamprobe without counting them more than once. Digest printed along with score can be stored in emails so that binary attachments can be removed by MUA after scoring without breaking SpamProbe's ability to reclassify the email later. * Provides a time stamp based database cleanup command to remove terms from the database if their counts never rise above a certain threshold value (normally 2). Tends to limit the otherwise unbounded growth of the database as each message adds some unique terms. Also provides a purge command to remove all terms with counts below a specified minimum no matter what their age. * The -X option uses a more aggressive scoring algorithm which uses all significantly good or spammy terms when scoring a message and also gives more weight to within message frequency of terms. This method improves recall and works best when the database contains a few thousand messages. * edit-term command allows users to directly modify the counts of individual terms. For example to force a particular term to be considered spammy or good. * train mode can be used in place of receive to minimize database writes by only updating database for difficult to classify messages. * auto-train mode can be used to build a database efficiently from a collection of email stored in multiple files. * Multiple database options including BerkeleyDB, PBL, and fixed size hash file. INSTALLATION SpamProbe is distributed in source code form. The current version uses autoconf to handle generating an appropriate Makefile for your system. Generally you should be able to install SpamProbe like this: ./configure make make install The configure script accepts some useful command line options including: --prefix=/path/to/install Use this to specify a directory tree to install SpamProbe and its man page into. The default is /usr/local. --with-pbl=/path/to/pbl Use this to specify the directory where you installed PBL (Peter Graf's Program Base Library) if the configure script is not able to find it on its own. See notes below for more information about the relative merits of PBL and Berkeley DB. --with-db=/path/to/db If you would rather use Berkeley DB than PBL use this to specify the directory where you installed Berkeley DB if the configure script is not able to find it on its own. --enable-cdb Use this to enable use of Berkeley DB's CDB mode. In this mode SP will create and use a Berkeley DB "environment" and take advantage of the "concurrent data store" feature of Berkeley DB. Theoretically this allows better interaction with Berkeley DB's utilities (db_verify, db_recover, etc) but some people have reported problems with this mode so it is now optional. --enable-default-8bit Use this if you want to change SP's default handling of eight bit characters. Normally 8 bit characters are converted to the letter z in the database to save space (this can be changed at runtime using the -8 command line option). If you normally receive 8 bit characters in email then you might want to compile with this flag to avoid the need to remember to type -8 all of the time. --enable-assert Use this if you want to enable the assertions in the source code for debugging purposes. Generally this is not desirable for production use since the assertions reduce performance. --enable-big-endian Causes all database reads and writes to use big-endian byte order even on little-endian platforms. Use this if you need to copy a database across different platforms and want to guarantee byte level data portability. This option slows down database I/O on little endian systems. If you want to statically link the BerkeleyDB library run configure with the appropriate command line option in the LDFLAGS variable. For gcc you do could something like this: LDFLAGS=-static ./configure make make install If you want to use Berkeley DB and configure does not find your BerkeleyDB library and you know it is installed but has a non-standard name then you can explicitly define the library to use. For example some RedHat 6.2 systems might require: CPPFLAGS=-I/usr/include/db3 ./configure You need GNU G++ or some other C++ compiler to compile SpamProbe. You also need either PBL or Berkeley DB installed on your system. PBL uses more disk space and may require you to download and install it on your system (see below) but is preferred because it supports transactions and is faster under heavy loads. Berkeley DB comes preinstalled on some operating systems so using it may be easier. It also creates smaller data files than PBL. However some users have reported data corruption issues with Berkeley DB in the past so use of PBL is recommended. That having been said the author of SpamProbe used Berkeley DB for almost a year without any problems in production so the reported issues seem to be OS or system specific. BUILD NOTES USING PBL To obtain PBL download it from Peter Graf's web site: http://mission.base.com/peter/source/ PBL does not use configure for its build process however its makefile seems to be appropriate out of the box for Red Hat Linux systems and may work without changes on other posix-like systems as well. To compile SpamProbe with PBL I did the following: tar xzvf pbl_1_03.tar.gz cd pbl_1_03 make cd .. tar xzvf spamprobe-1.0.tar.gz cd spamprobe-1.0 ./configure --with-pbl=../pbl_1_03 make make install BUILD NOTES USING BERKELEY DB To obtain BerkeleyDB if you do not already have it installed (many Linux distributions come with DB preinstalled) visit the SleepCat website to download a copy. BerkeleyDB is open source and you can use it for free. http://www.sleepycat.com Installation instructions for BerkeleyDB can be found here: http://www.sleepycat.com/docs/ref/build_unix/intro.html NOTES USING HASH DATABASE SpamProbe can use a simple, fixed size hash data file as an alternative to PBL or BDB. There are two advantages to the hash format. The first is speed. In my experiments the hash file format is around 2x the speed of PBL (ranged from 1.8x to 3.5x). The second advantage is that the hash data file size is fixed. You choose a size when you create the file and it never changes. File size can be anywhere from 1-100 MB. You need to choose a size large enough to hold your terms with room to spare. More on that later. The hash file format also has significant disadvantages. Becuase the file size is fixed you must monitor the file to ensure that it does not become overly full. When the file becomes more than half full performance will suffer. Also the hash format does not store original terms so you cannot use the dump command to learn what terms are spammy or hammy in your database. Finally, the hash format is imprecise. Hash collisions can cause the counts from different terms to be mixed together which can reduce accuracy. To create a hash data file you add a prefix to the directory name in the -d command line option. You can specify just the directory like this: spamprobe -d hash:$HOME/.spamprobe or you can add a size in megabytes for the file like this: spamprobe -d hash:42:$HOME/.spamprobe The size is only used when a file is first created. SP auto detects the size of an existing hash file. You need to allow enough space for twice as many terms as you are likely to have in your file. In my database I have 2.2 million terms. That required a database of are 53 MB. SP uses 12 bytes per term in the hash file so you can estimate the file size you'll need by multiplying the number of terms by 24. The hash format does not store the original terms. Instead it stores the 32 bit hash code for each term. You can do just about anything with a hash file that you could with a PBL file including import/export, edit-term, cleanup, purge, etc. You can use export your PBL database and import it to build a hash file (note that you cannot go the other direction) and you can export one hash file and import into a new one to enlarge your file. SETUP OF SPAMPROBE FOR USERS Once you have a spamprobe executable copy it to someplace in your PATH so that procmail can find it. Then create a directory for SpamProbe to store its databases in. By default SpamProbe wants to use the directory ~/.spamprobe. You must create this directory manually in order to run SpamProbe or else specify some other directory using the -d option. Something like this should suffice: spamprobe create-db or to use a different directory add the -d command line option: spamprobe -d somedirectory create-db SpamProbe can use either the PBL or Berkeley DB library for its databases. Both are fast on local file systems but very slow over NFS. Please ensure that your spamprobe directory is on a local file system to ensure good performance. MAILDIR FORMAT SpamProbe will accept a maildir directory name anywhere that an Mbox or MBX file name can be specified. When SpamProbe encounters a Maildir mailbox (directory) name it will automatically process all of the non-hidden files in the cur and new subdirectories of the mailbox. There is no need to individually specify these subdirectories. GETTING STARTED SpamProbe is not a stand alone mail filter. It doesn't sort your mail or split it into different mailboxes. Instead it relies on some other program such as procmail to actually file your mail for you. What SpamProbe does do is track the word counts in good and spam emails and generate a score for each email that indicates whether or not it is likely to be spam. Scores range from 0 to 1 with any score of 0.9 or higher indicating a probable spam. Personally I use SpamProbe with procmail to filter my incoming email into mail boxes. I have procmail score each inbound email using SpamProbe and insert a special header into each email containing its score. Then I have procmail move spams into a special mailbox. No spam filter is perfect and SpamProbe sometimes makes mistakes. To correct those mistakes I have a special mailbox that I put undetected spams into. I run SpamProbe periodically and have it reclassify any emails in that mailbox as spam so that it will make a better guess the next time around. This is not a procmail primer. You will need to ensure that you have procmail and formail installed before you can use this technique. Also I recommend that you read the procmail documentation so that you can fully understand this example and adapt it to your own needs. That having been said, my .procmailrc file looks like this: MAILDIR=$HOME/IMAP :0 c saved :0 SCORE=| /home/brian/bin/spamprobe train :0 wf | formail -I "X-SpamProbe: $SCORE" :0 a: *^X-SpamProbe: SPAM spamprobe I use IMAP to fetch my email so my mailboxes all live in a directory named IMAP on my mail server. NOTE: The first stanza copies all incoming emails into a special mbox called saved. SpamProbe IS OPEN SOURCE SOFTWARE and though it works well for me it is possible that it could somehow lose emails. Caution is always a good idea. That having been said, with the procmailrc file as shown above the worst that could happen if SpamProbe crashes is that the email would not be scored properly and procmail would deliver it to your inbox. Of course if procmail crashes all bets are off. The second stanza runs spamprobe in "train" mode to score the email, classify it as either spam or good, and possibly update the database. The train command tries to minimize the number of database updates by only updating the database with terms from an incoming message if there was insufficient confidence in the message's score. The train command always updates the database on the first 1500 of each type received. This ensures that sufficient email is classified to allow the filter to operate reliably. The next stanza runs formail to add a custom header to the email containing the SpamProbe score. The final stanza uses the contents of the custom header to file detected spams into a special mbox named spamprobe. As an alternative to using the train command, you can run spamprobe in "receive" mode. In that mode SpamProbe scores the email and then classifies it as either spam or good based on the score. It always automatically adds the word counts for the email to the appropriate database. This is essentially like running in score mode followed immediately by either spam or good mode. It produces more database I/O and a bigger database but ensures that every message has its terms reflected in the database. Personally I use train mode. A sample procmailrc file using the receive command looks like this: MAILDIR=$HOME/IMAP :0 c saved :0 SCORE=| /home/brian/bin/spamprobe receive :0 wf | formail -I "X-SpamProbe: $SCORE" :0 a: *^X-SpamProbe: SPAM spamprobe If you need to have a locale set when spamprobe is run by procmail you may need to use a script inside of the procmailrc file rather than running spamprobe directly. The script can set up any command line options or environment variables before running spamprobe. The most common use of this technique is to set the LANG environment variable. MAKING CORRECTIONS SpamProbe is not perfect. It is able to detect over 99% of the spams that I receive but some still slip through. To correct these missed emails I run SpamProbe periodically and have it scan a special mbox. Since I use IMAP to retrieve my emails I can simply drop undetected spams into this mbox from my mail client. If you use POP or some other system then you will need to find a way get the undetected spams into a mbox that spamprobe can see. Periodically I run a script that scans three special mboxes to correct errors in judgment: #!/bin/sh IMAPDIR=$HOME/IMAP spamprobe remove $IMAPDIR/remove spamprobe good $IMAPDIR/nonspam spamprobe spam $IMAPDIR/spam spamprobe train-spam $IMAPDIR/spamprobe From this example you can see that I use three special mboxes to make corrections. I copy emails that I don't want spamprobe to store into the remove mbox. This is useful if you receive email from a friend or colleague that looks like spam and you don't want it to dilute the effectiveness of the terms it contains. Undetected spams go into the spam mbox. SpamProbe will reclassify those emails as spam and correct its database accordingly. Note that doing this does not guarantee that the spam will always be scored as spam in the future. Some spams are too bland to detect perfectly. Fortunately those are very rare. The nonspam mbox is for any false positives. These are always possible and it is important to have a way to reclassify them when they do occur. If you are using receive mode rather than train mode then the above script can be modified to remove the train-spam line. For example: #!/bin/sh IMAPDIR=$HOME/IMAP spamprobe remove $IMAPDIR/remove spamprobe good $IMAPDIR/nonspam spamprobe spam $IMAPDIR/spam Finally you'll need to build a starting database. Since SpamProbe relies on word counts from past emails it requires a decent sized database to be accurate. To build the database select some of your mboxes containing past emails. Ideally you should have one mbox of spams and one or more of non-spams. If you don't have any spams handy then don't worry, SpamProbe will gradually become more accurate as you receive more spams. Expect a fairly high false negative (i.e. missed spams) rate as you first start using SpamProbe. To import your starting messages use commands such as these. The example assumes that you have non-spams stored in a file named mbox in your home directory and some spams stored in a file named nasty-spams. Replace these names with real ones. spamprobe good ~/mbox spamprobe spam ~/nasty-spams COMMAND LINE USAGE SpamProbe accepts a small set of commands and a growing set of options on the command line in addition to zero or more file names of mboxes. The general usage is: spamprobe [options] [filename...] You can obtain a full list of all available command line options by running the "help" command. For example: spamprobe help The recognized options are: -a char By default SpamProbe converts non-ascii characters (characters with the most significant bit set to 1) into the letter 'z'. This is useful for lumping all Asian characters into a single word for easy recognition. The -a option allows you to change the character to something else if you don't like the letter 'z' for some reason. -c Tells spamprobe to create the database directory if it does not already exist. Normally spamprobe exits with a usage error if the database directory does not already exist. -C number Tells SpamProbe to assign a default, somewhat neutral, probability to any term that does not have a weighted (good count doubled) count of at least number in the database. This prevents terms which have been seen only a few times from having an unreasonable influence on the score of an email containing them. The default value is 5. For example if number is 5 then in order for a term to use its calculated probability it must have been seen 3 times in good mails, or 2 times in good mails and once in spam, or 5 times in spam, or some other combination adding up to at least 5. -d directory By default SpamProbe stores its database in a directory named .spamprobe under your home directory. The -d option allows you to specify a different directory to use. This is necessary if your home directory is NFS mounted for example. The directory name can be prefixed with a special code to force SpamProbe to use a particular type of data file format. The type codes depend on how your copy of SpamProbe was compiled. Defined types include: Example Description -d pbl:path Forces the use of PBL data file. -d hash:path Forces the use of an mmapped hash file. -d split:path Forces the use of a hash file and ISAM file (may provide better precision than plain hash in some cases). The hash: option can also specify a desired file size in megabytes before the path. For example -d hash:19:path would cause SpamProbe to use a 19 MB hash file. The size must be in the range of 1-100. The default hash file size is 16 MB. Because hash files have a fixed size and capacity they should be cleaned relatively often using the cleanup command (see below) to prevent them from becoming full or being slowed by too many hash key collisions. Hash files provide better performance than either of the ISAM options (PBL or Berkeley DB). However hash files do not store the original terms. Only a 32 bit hash key is stored with each term. This prevents a user from exploring the terms in the database using the dump command to see what words are particularly spammy or hammy. -D directory Tells SpamProbe to use the database in the specified directory (must be different than the one specified with the -d option) as a shared database from which to draw terms that are not defined in the user's own database. This can be used to provide a baseline database shared by all users on a system (in the -D directory) and a private database unique to each user of the system ($HOME/.spamprobe or -d directory). -g field_name Tells SpamProbe what header to look for previous score and message digest in. Default is X-SpamProbe. Field name is not case sensitive. Used by all commands except receive. -h By default SpamProbe removes HTML markup from the text in emails to help avoid false positives. The -h option allows you to override this behavior and force SpamProbe to include words from within HTML tags in its word counts. Note that SpamProbe always counts any URLs in hrefs within tags whether -h is used or not. Use of this option is discouraged. It can increase the rate of spam detection slightly but unless the user receives a significant amount of HTML emails it also tends to increase the number of false positives. -H option By default SpamProbe only scans a meaningful subset of headers from the email message when searching for words to score. The -H option allows the user to specify additional headers to scan. Legal values are "all", "nox", "none", or "normal". "all" scans all headers, "nox" scans all headers except those starting with X-, "none" does not scan headers, and "normal" scans the normal set of headers. In addition to those values you can also explicitly add a header to the list of headers to process by adding the header name in lower case preceded by a plus sign. Multiple headers can be specified by using multiple -H options. For example, to include only the From and Received headers in your train command you could run spamprobe as follows: spamprobe -Hnone -H+from -H+received train You can also selectively ignore headers that would otherwise be processed by using -H-headername. For example to process all headers except for Subject you could run spamprobe as follows: spamprobe -Hall -H-subject train To process the normal set of headers but also add the SpamAssassin header X-SpamStatus you could run spamprobe as follows: spamprobe -H+x-spam-status train -l number Changes the spam probability threshold for emails from the default (0.7) to number. The number must be a between 0 and 1. Generally the value should be above 0.5 to avoid a high false positive rate. Lower numbers tend to produce more false positives while higher numbers tend to reduce accuracy. -m Forces SpamProbe to use mbox format for reading emails in receive mode. Normally SpamProbe assumes that the input to receive mode contains a single message so it doesn't look for message breaks. -M Forces SpamProbe to treat the entire input as a single message. This ignores From lines and Content-Length headers in the input. -o option_name Enables special options by name. Currently the only special options are: -o graham Causes SpamProbe to emulate the filtering algorithm originally outlined in A Plan For Spam. -o honor-status-header Causes SpamProbe to ignore messages if they have a Status: header containing a capital D. Some mail servers use this status to indicate a message that has been flagged for deletion but has not yet been purged from the file. DO NOT use this option with the receive or train command in your procmailrc file! Doing so could allow spammers to bypass the filter. This option is meant to be used with the train-spam and train-good commands in scripts that periodically update the database. -o honor-xstatus-header Causes SpamProbe to ignore messages if they have a X-Status: header containing a capital D. Some mail servers use this status to indicate a message that has been flagged for deletion but has not yet been purged from the file. DO NOT use this option with the receive or train command in your procmailrc file! Doing so could allow spammers to bypass the filter. This option is meant to be used with the train-spam and train-good commands in scripts that periodically update the database. -o ignore-body Causes SpamProbe to ignore terms from the message body when computing a score. This is not normally recommended but might be useful in conjunction with some other filter. For example, the whitelist option (see below) implicitly ignores the message body. -o orig-score Causes SpamProbe to use its original scoring algorithm that produces excellent results but tends to generate scores of either 0 or 1 for all messages. -o suspicious-tags Causes SpamProbe to scan the contents of "suspicious" tags for tokens rather than simply throwing them out. Currently only font tags are scanned but other tags may be added to this list in later versions. -o tokenized Causes SpamProbe to read tokens one per line rather than processing the input as mbox format. This allows users to completely replace the standard spamprobe tokenizer if they wish and instead use some external program as a tokenizer. For example in your procmailrc file you could use: SCORE=| tokenize.pl | /bin/spamprobe -o tokenized train In this mode SpamProbe considers a blank line to indicate the end of one message's tokens and the start of a new message's tokens. SpamProbe computes a message digest based on the lines of text containing the tokens. -o whitelist Causes SpamProbe to use information from the email's headers to identify whether or not the email is from a legitimate correspondent. The message body is ignored as are any never before seen terms and phrases in the headers. This option can be used with the score command in a procmailrc file to use a bayesian white list in conjunction with some other filter or rule external to SpamProbe. The -o option can be used multiple times and all requested options will be applied. Note that some options might conflict with each other in which case the last option would take precedence. -p number Changes the maximum number of words per phrase. Default value is two. Increasing the limit improves accuracy somewhat but increases database size. Experiments indicate that increasing beyond two is not worth the extra cost in space. -P number Causes spamprobe to perform a purge of all terms with junk count less than or equal 2 after every number messages are processed. Using this option when classifying a large collection of spam can prevent the database from growing overly large at the cost of more processing time and possible loss of precision. -r number Changes the number of times that a single word/phrase can occur in the top words array used to calculate the score for each message. Allowing repeats reduces the number of words overall (since a single word occupies more than one slot) but allows words which occur frequently in the message to have a higher weight. Generally this is changed only for optimization purposes. -R Causes spamprobe to treat the input as a single message and to base its exit code on whether or not that message was spam. The exit code will be 0 if the message was spam or 1 if the message was good. -s number SpamProbe maintains an in memory cache of the words it has seen in previous messages to reduce disk I/O and improve performance. By default the cache will contain the most recently accessed 2,500 terms. This number can be changed using the -s option. Using a larger the cache size will cause SpamProbe to use more memory and, potentially, to perform less database I/O. A value of zero causes SpamProbe to use 100,000 as the limit which effectively means that the cache will only be flushed at program exit (unless you have really enormous mailbox files). The cache doesn't affect receive, dump, or export but has a significant impact on the others. -T Causes SpamProbe to write out the top terms associated with each message in addition to its normal output. Works with find-good, find-spam, and score. -v When it appears once on the command line this option tells SpamProbe to write verbose information during processing. When it appears twice on the command line this option tells SpamProbe to write debugging information to stderr. This can be useful for debugging or for seeing which terms SpamProbe used to score each email. -V Prints version and copyright information and then exits. -w number Changes the number of most significant words/phrases used by SpamProbe to calculate the score for each message. Generally this is changed only for optimization purposes. -x Normally SpamProbe uses only a fixed number of top terms (as set by the -w command line option) when scoring emails. The -x option can be used to allow the array to be extended past the max size if more terms are available with probabilities <= 0.1 or >= 0.9. -X An interesting variation on the scoring settings. Equivalent to using "-w5 -r5 -x" so that generally only words with probabilites <= 0.1 or >= 0.9 are used and word frequencies in the email count heavily towards the score. Tests have shown that this setting tends to be safer (fewer false positives) and have higher recall (proper classification of spams previously scored as spam) although its predictive power isn't quite as good as the default settings. WARNING: This setting might work best with a fairly large corpus, it has not been tested with a small corpus so it might be very inaccurate with fewer than 1000 total messages. -Y Assume traditional Berkeley mailbox format, ignoring any Content-Length: fields. -7 Tells SpamProbe to ignore any characters with the most significant bit set to 1 instead of mapping them to the letter 'z'. -8 Tells SpamProbe to store all characters even if their most significant bit is set to 1. SpamProbe recognizes the following commands: spamprobe help [command] With no arguments spamprobe lists all of the valid commands. If one or more commands are specified after the word help, spamprobe will print a more verbose description of each command. spamprobe create-db If no database currently exists spamprobe will attempt to create one and then exit. This can be used to bootstrap a new installation. Strictly speaking this command is not necessary since the train-spam, train-good, and auto-train commands will also create a database if none already exists but some users like to create a database as a separate installation step. spamprobe create-config Writes a new configuration file named spamprobe.hdl into the database directory (normally $HOME/.spamprobe). Any existing configuration file will be overwritten so be sure to make a copy before invoking this command. spamprobe receive [filename...] Tells SpamProbe to read its standard input (or a file specified after the receive command) and score it using the current databases. Once the message has been scored the message is classified as either spam or non-spam and its word counts are written to the appropriate database. The message's score is written to stdout along with a single word. For example: SPAM 0.9999999 595f0150587edd7b395691964069d7af or GOOD 0.0200000 595f0150587edd7b395691964069d7af The string of numbers and letters after the score is the message's "digest", a 32 character number which uniquely identifies the message. The digest is used by SpamProbe to recognize messages that it has processed previously so that it can keep its word counts consistent if the message is reclassified. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe train [filename...] Functionally identical to receive except that the database is only modified if the message was "difficult" to classify. In practice this can reduce the number of database updates to as little as 10% of messages received. spamprobe score [filename...] Similar to receive except that the database is not modified in any way. spamprobe summarize [filename...] Similar to score except that it prints a short summary and score for each message. This can be useful when testing. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe find-spam [filename...] Similar to score except that it prints a short summary and score for each message that is determined to be spam. This can be useful when testing. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe find-good [filename...] Similar to score except that it prints a short summary and score for each message that is determined to be good. This can be useful when testing. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe auto-train {SPAM|GOOD filename...}... Attempts to efficiently build a database from all of the named files. You may specify one or more file of each type. Prior to each set of file names you must include the word SPAM or GOOD to indicate what type of mail is contained in the files which follow on the command line. The case of the SPAM and GOOD keywords is important. Any number of file names can be specified between the keywords. The command line format is very flexible. You can even use a find command in backticks to process whole directory trees of files. For example: spamprobe auto-train SPAM spams/* GOOD `find hams -type f` SpamProbe pre-scans the files to determine how many emails of each type exist and then trains on hams and spams in a random sequence that balances the inflow of each type so that the train command can work most effectively. For example if you had 400 hams and 400 spams, auto-train will generally process one spam, then one ham, etc. If you had 4000 spams and 400 hams then auto-train will generally process 10 spams, then one ham, etc. Since this command will likely take a long time to run it is often desireable to use it with the -v option to see progress information as the messages are processed. spamprobe -v auto-train SPAM spams/* GOOD hams/* spamprobe good [filename...] Scans each file (or stdin if no file is specified) and reclassifies every email in the file as non-spam. The databases are updated appropriately. Messages previously classified as good (recognized using their MD5 digest or message ids) are ignored. Messages previously classified as spam are reclassified as good. spamprobe train-good [filename...] Functionally identical to "good" command except that it only updates the database for messages that are either incorrectly classified (i.e. classified as spam) or are "difficult" to classify. In practice this can reduce amount of database updates to as little as 10% of messages. spamprobe spam [filename...] Scans each file (or stdin if no file is specified) and reclassifies every email in the file as spam. The databases are updated appropriately. Messages previously classified as spam (recognized using their MD5 digest of message ids) are ignored. Messages previously classified as good are reclassified as spam. spamprobe train-spam [filename...] Functionally identical to "spam" command except that it only updates the database for messages that are either incorrectly classified (i.e. classified as good) or are "difficult" to classify. In practice this can reduce amount of database updates to as little as 10% of messages. spamprobe remove [filename...] Scans each file (or stdin if no file is specified) and removes its term counts from the database. Messages which are not in the database (recognized using their MD5 digest) are ignored. spamprobe cleanup [ junk_count [ max_age ] ] Scans the database and removes all terms with junk_count or less (default 2) which have not had their counts modified in at least max_age days (default 7). You can specify multiple count/age pairs on a single command line but must specify both a count and an age for all but the last count. This should be run periodically to keep the database from growing endlessly. For my own email I use cron to run the cleanup command every day and delete all terms with count of 2 or less that have not been modified in the last two weeks. Here is the excerpt from my crontab: 3 0 * * * /home/brian/bin/spamprobe cleanup 2 14 Alternatively you might want to use a much higher count (1000 in this example) for terms that have not been seen in roughly six months: 3 0 * * * /home/brian/bin/spamprobe cleanup 1000 180 2 14 Because of the way that PBL and BerkeleyDB work the database file will not actually shrink, but newly added terms will be able to use the space previously occupied by any removed terms so that the file's growth should be significantly slower if this command is used. To actually shrink the database you can build a new one using the BerkeleyDB utility programs db_dump and db_load (Berkeley DB only) or the spamprobe import and export commands (either database library). For example: cd ~ mkdir new.spamprobe spamprobe export | spamprobe -d new.spamprobe import mv .spamprobe old.spamprobe mv new.spamprobe .spamprobe The -P option can also be used to limit the rate of growth of the database when importing a large number of emails. For example if you want to classify 1000 emails and want SP to purge rare terms every 100 messages use a command such as: spamprobe -P 100 good goodmailboxname Using -P slows down the classification but can avoid the need to use the db_dump trick. Using -P only makes sense when classifying a large number of messages. spamprobe purge [ junk_count ] Similar to cleanup but forces the immediate deletion of all terms with total count less than junk_count (default is 2) no matter how long it has been since they were modified (i.e. even if they were just added today). This could be handy immediately after classifying a large mailbox of historical spam or good email to make room for the next batch. spamprobe purge-terms regex Similar to purge except that it removes from the database all terms which match the specified regular expression. Be careful with this command because it could remove many more terms than you expect. Use dump with the same regex before running this command to see exactly what will be deleted. spamprobe edit-term term good_count spam_count Can be used to specifically set the good and spam counts of a term. Whether this is truly useful is doubtful but it is provided for completeness sake. For example it could be used to force a particular word to be very spammy or very good: spamprobe edit-term nigeria 0 1000000 spamprobe edit-term burton 10000000 0 spamprobe dump [ regex ] Prints the contents of the word counts database one word per line in human readable format with spam probability, good count, spam count, flags, and word in columns separated by whitespace. PBL and Berkeley DB sort terms alphabetically. The standard unix sort command can be used to sort the terms as desired. For example to list all words from "most good" to "least good" use this command: spamprobe dump | sort -k 1nr -k 3nr To list all words from "most spammy" to "least spammy" use this command: spamprobe dump | sort -k 1n -k 2nr Optionally you can specify a regular expression. If specified SpamProbe will only dump terms matching the regular expression. For example: spamprobe dump 'finance' spamprobe dump '\bfinance\b' spamprobe dump 'HSubject_.*finance' spamprobe tokenize [ filename ] Prints the tokens found in the file one word per line in human readable format with spam probability, good count, spam count, message count, and word in columns separated by whitespace. Terms are listed in the order in which they were encountered in the message. The standard unix sort command can be used to sort the terms as desired. For example to list all words from "most good" to "least good" use this command: spamprobe tokenize filename | sort -k 1nr -k 3nr To list all words from "most spammy" to "least spammy" use this command: spamprobe tokenize filename | sort -k 1n -k 2nr spamprobe export Similar to the dump command but prints the counts and words in a comma separated format with the words surrounded by double quotes. This can be more useful for importing into some databases. spamprobe import Reads the specified files which must contain export data written by the export command. The terms and counts from this file are added to the database. This can be used to convert a database from a prior version. spamprobe exec command Obtains an exclusive lock on the database and then executes the command using system(3). If multiple arguments are given after "exec" they are combined to form the command to be executed. This command can be used when you want to perform some operation on the database without interference from incoming mail. For example, to back up your .spamprobe directory using tar you could do something like this: cd spamprobe exec tar cf spamprobe-data.tar.gz .spamprobe If you simply want to hold the lock while interactively running commands in a different xterm you could use "spamprobe exec read". The linux read program simply reads a line of text from your terminal so the lock would effectively be held until you pressed the enter key. Another option would be to use a shell as the command and type the commands into that shell: spamprobe /bin/bash ls date exit Be careful not to run spamprobe in the shell though since the spamprobe in the shell will wind up deadlocked waiting for the spamprobe running the exec command to release its lock. spamprobe exec-shared command Same as exec except that a shared lock is used. This may be more appropriate if you are backing up your database since operations like score (but not train or receive) could still be performed on the database while the backup was running. SUPPORT AND WARRANTY SpamProbe works well for me. However please keep in mind that there is NO WARRANTY at all with this software. Read the QPL (LICENSE.txt) for details. YOU ASSUME ALL RISK when using this software. Be sure to visit the project page on sourceforge. There you can submit bug reports or feature requests, read and post messages on the forums, and download the latest version. http://sourceforge.net/projects/spamprobe/ You can also join the spamprobe mailing list to discuss issues with other SpamProbe users. http://lists.sourceforge.net/lists/listinfo/spamprobe-users Also feel free to contact me at bburton@users.sourceforge.net with any suggestions for improvements that you don't want to post to the forums. Enjoy! Brian Burton spamprobe-1.4d/acinclude.m40000664000076400007640000001003010526706577012647 00000000000000# $Id: 10_configure.in_db4.2.dpatch 8 2004-04-02 09:11:24Z bsb $ # # Written for the Debian spamprobe package by # # Bernd S. Brentrup # # Copyright (c) 2004 Software in the Public Interest # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception, the Free Software Foundation gives unlimited # permission to copy, distribute and modify the configure scripts that # are the output of Autoconf. You need not follow the terms of the GNU # General Public License when using or distributing such scripts, even # though portions of the text of Autoconf appear in them. The GNU # General Public License (GPL) does govern all other use of the material # that constitutes the Autoconf program. # # Certain portions of the Autoconf source text are designed to be copied # (in certain cases, depending on the input) into the output of # Autoconf. We call these the "data" portions. The rest of the Autoconf # source text consists of comments plus executable code that decides which # of the data portions to output in any given case. We call these # comments and executable code the "non-data" portions. Autoconf never # copies any of the non-data portions into its output. # # This special exception to the GPL applies to versions of Autoconf # released by the Free Software Foundation. When you make and # distribute a modified version of Autoconf, you may extend this special # exception to the GPL to apply to your modified version as well, *unless* # your modified version has the potential to copy into its output some # of the text that was the non-data portion of the version that you started # with. (In other words, unless your change moves or copies text from # the non-data portions to the data portions.) If your modification has # such potential, you must delete any notice of this special exception # to the GPL from your modified version. #-------------------------------------------------------------------------- # DAC_SEARCH_LIBS(NAME, PROGRAM, LIBRARIES, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [MORE-LIBS]) # # This macro has been trivially adopted from the AC_SEARCH_LIBS macro # distibuted with GNU autoconf, providing a more flexible and robust # method to select a needed library from a list of candidate # libraries. # # DAC_SEARCH_LIBS tries to link the user-supplied PROGRAM against each # library listed in the LIBRARIES argument (only base portions of # library names, i.e. for libXYZ.{a,so} use XYZ. # ACTION-IF-FOUND is invoked when PROGRAM can be linked, either # without using any entry from LIBRARIES or for the first successful # one, in the latter case -lXYZ is prepended to the global LIBS # variable. The MORE-LIBS argument can be used to provide additional # libraries needed to link PROGRAM. # The NAME argument is used to differentiate between multiple invocations # of DAC_SEARCH_LIBS AC_DEFUN([DAC_SEARCH_LIBS], [AC_CACHE_CHECK([for $1 library], [dac_cv_search_$1], [dac_save_LIBS=$LIBS dac_cv_search_$1=no AC_LANG_CONFTEST($2) AC_LINK_IFELSE([],dac_cv_search_$1="present") if test "$dac_cv_search_$1" = no; then for dac_lib in $3 ; do LIBS="-l$dac_lib $6 $dac_save_LIBS" AC_LINK_IFELSE([],dac_cv_search_$1="-l$dac_lib" break) done fi LIBS=$dac_save_LIBS]) AS_IF([test "$dac_cv_search_$1" != no], [test "$dac_cv_search_$1" = "present" || LIBS="$dac_cv_search_$1 $LIBS" ; $4], [$5])dnl ]) spamprobe-1.4d/spamprobe.10000664000076400007640000011022710527226671012532 00000000000000.TH spamprobe 1 "December 2005" "Version 1.4" SpamProbe .SH NAME spamprobe \- a bayesian spam filter .SH SYNOPSIS .B spamprobe [options] [filename...] .SH INTRODUCTION SpamProbe can be used in conjunction with procmail or similar program to filter email. SpamProbe uses a statistical algorithm to identify the key words and phrases in email and determine which emails are legitimate and which are spam. The algorithm used by SpamProbe is based on an excellent article by Paul Graham. He describes the basic idea and his results. You can read his article here: http://www.paulgraham.com/spam.html .SH COMMAND LINE USAGE SpamProbe accepts a small set of commands and a growing set of options on the command line in addition to zero or more file names of mboxes. The general usage is: spamprobe [options] [filename...] The recognized options are: -a char By default SpamProbe converts non-ascii characters (characters with the most significant bit set to 1) into the letter 'z'. This is useful for lumping all Asian characters into a single word for easy recognition. The -a option allows you to change the character to something else if you don't like the letter 'z' for some reason. -c Tells spamprobe to create the database directory if it does not already exist. Normally spamprobe exits with a usage error if the database directory does not already exist. -C number Tells SpamProbe to assign a default, somewhat neutral, probability to any term that does not have a weighted (good count doubled) count of at least number in the database. This prevents terms which have been seen only a few times from having an unreasonable influence on the score of an email containing them. The default value is 5. For example if number is 5 then in order for a term to use its calculated probability it must have been seen 3 times in good mails, or 2 times in good mails and once in spam, or 5 times in spam, or some other combination adding up to at least 5. -d directory By default SpamProbe stores its database in a directory named .spamprobe under your home directory. The -d option allows you to specify a different directory to use. This is necessary if your home directory is NFS mounted for example. The directory name can be prefixed with a special code to force SpamProbe to use a particular type of data file format. The type codes depend on how your copy of SpamProbe was compiled. Defined types include: Example Description -d pbl:path Forces the use of PBL data file. -d hash:path Forces the use of an mmapped hash file. -d split:path Forces the use of a hash file and ISAM file (may provide better precision than plain hash in some cases). The hash: option can also specify a desired file size in megabytes before the path. For example -d hash:19:path would cause SpamProbe to use a 19 MB hash file. The size must be in the range of 1-100. The default hash file size is 16 MB. Because hash files have a fixed size and capacity they should be cleaned relatively often using the cleanup command (see below) to prevent them from becoming full or being slowed by too many hash key collisions. Hash files provide better performance than either of the ISAM options (PBL or Berkeley DB). However hash files do not store the original terms. Only a 32 bit hash key is stored with each term. This prevents a user from exploring the terms in the database using the dump command to see what words are particularly spammy or hammy. -D directory Tells SpamProbe to use the database in the specified directory (must be different than the one specified with the -d option) as a shared database from which to draw terms that are not defined in the user's own database. This can be used to provide a baseline database shared by all users on a system (in the -D directory) and a private database unique to each user of the system ($HOME/.spamprobe or -d directory). -g field_name Tells SpamProbe what header to look for previous score and message digest in. Default is X-SpamProbe. Field name is not case sensitive. Used by all commands except receive. -h By default SpamProbe removes HTML markup from the text in emails to help avoid false positives. The -h option allows you to override this behavior and force SpamProbe to include words from within HTML tags in its word counts. Note that SpamProbe always counts any URLs in hrefs within tags whether -h is used or not. Use of this option is discouraged. It can increase the rate of spam detection slightly but unless the user receives a significant amount of HTML emails it also tends to increase the number of false positives. -H option By default SpamProbe only scans a meaningful subset of headers from the email message when searching for words to score. The -H option allows the user to specify additional headers to scan. Legal values are "all", "nox", "none", or "normal". "all" scans all headers, "nox" scans all headers except those starting with X-, "none" does not scan headers, and "normal" scans the normal set of headers. In addition to those values you can also explicitly add a header to the list of headers to process by adding the header name in lower case preceded by a plus sign. Multiple headers can be specified by using multiple -H options. For example, to include only the From and Received headers in your train command you could run spamprobe as follows: spamprobe -Hnone -H+from -H+received train You can also selectively ignore headers that would otherwise be processed by using -H-headername. For example to process all headers except for Subject you could run spamprobe as follows: spamprobe -Hall -H-subject train To process the normal set of headers but also add the SpamAssassin header X-SpamStatus you could run spamprobe as follows: spamprobe -H+x-spam-status train -l number Changes the spam probability threshold for emails from the default (0.7) to number. The number must be a between 0 and 1. Generally the value should be above 0.5 to avoid a high false positive rate. Lower numbers tend to produce more false positives while higher numbers tend to reduce accuracy. -m Forces SpamProbe to use mbox format for reading emails in receive mode. Normally SpamProbe assumes that the input to receive mode contains a single message so it doesn't look for message breaks. -M Forces SpamProbe to treat the entire input as a single message. This ignores From lines and Content-Length headers in the input. -o option_name Enables special options by name. Currently the only special options are: -o graham Causes SpamProbe to emulate the filtering algorithm originally outlined in A Plan For Spam. -o honor-status-header Causes SpamProbe to ignore messages if they have a Status: header containing a capital D. Some mail servers use this status to indicate a message that has been flagged for deletion but has not yet been purged from the file. DO NOT use this option with the receive or train command in your procmailrc file! Doing so could allow spammers to bypass the filter. This option is meant to be used with the train-spam and train-good commands in scripts that periodically update the database. -o honor-xstatus-header Causes SpamProbe to ignore messages if they have a X-Status: header containing a capital D. Some mail servers use this status to indicate a message that has been flagged for deletion but has not yet been purged from the file. DO NOT use this option with the receive or train command in your procmailrc file! Doing so could allow spammers to bypass the filter. This option is meant to be used with the train-spam and train-good commands in scripts that periodically update the database. -o ignore-body Causes SpamProbe to ignore terms from the message body when computing a score. This is not normally recommended but might be useful in conjunction with some other filter. For example, the whitelist option (see below) implicitly ignores the message body. -o orig-score Causes SpamProbe to use its original scoring algorithm that produces excellent results but tends to generate scores of either 0 or 1 for all messages. -o suspicious-tags Causes SpamProbe to scan the contents of "suspicious" tags for tokens rather than simply throwing them out. Currently only font tags are scanned but other tags may be added to this list in later versions. -o tokenized Causes SpamProbe to read tokens one per line rather than processing the input as mbox format. This allows users to completely replace the standard spamprobe tokenizer if they wish and instead use some external program as a tokenizer. For example in your procmailrc file you could use: SCORE=| tokenize.pl | /bin/spamprobe -o tokenized train In this mode SpamProbe considers a blank line to indicate the end of one message's tokens and the start of a new message's tokens. SpamProbe computes a message digest based on the lines of text containing the tokens. -o whitelist Causes SpamProbe to use information from the email's headers to identify whether or not the email is from a legitimate correspondent. The message body is ignored as are any never before seen terms and phrases in the headers. This option can be used with the score command in a procmailrc file to use a bayesian white list in conjunction with some other filter or rule external to SpamProbe. The -o option can be used multiple times and all requested options will be applied. Note that some options might conflict with each other in which case the last option would take precedence. -p number Changes the maximum number of words per phrase. Default value is two. Increasing the limit improves accuracy somewhat but increases database size. Experiments indicate that increasing beyond two is not worth the extra cost in space. -P number Causes spamprobe to perform a purge of all terms with junk count less than or equal 2 after every number messages are processed. Using this option when classifying a large collection of spam can prevent the database from growing overly large at the cost of more processing time and possible loss of precision. -r number Changes the number of times that a single word/phrase can occur in the top words array used to calculate the score for each message. Allowing repeats reduces the number of words overall (since a single word occupies more than one slot) but allows words which occur frequently in the message to have a higher weight. Generally this is changed only for optimization purposes. -R Causes spamprobe to treat the input as a single message and to base its exit code on whether or not that message was spam. The exit code will be 0 if the message was spam or 1 if the message was good. -s number SpamProbe maintains an in memory cache of the words it has seen in previous messages to reduce disk I/O and improve performance. By default the cache will contain the most recently accessed 2,500 terms. This number can be changed using the -s option. Using a larger the cache size will cause SpamProbe to use more memory and, potentially, to perform less database I/O. A value of zero causes SpamProbe to use 100,000 as the limit which effectively means that the cache will only be flushed at program exit (unless you have really enormous mailbox files). The cache doesn't affect receive, dump, or export but has a significant impact on the others. -T Causes SpamProbe to write out the top terms associated with each message in addition to its normal output. Works with find-good, find-spam, and score. -v Tells SpamProbe to write debugging information to stderr. This can be useful for debugging or for seeing which terms SpamProbe used to score each email. -V Prints version and copyright information and then exits. -w number Changes the number of most significant words/phrases used by SpamProbe to calculate the score for each message. Generally this is changed only for optimization purposes. -x Normally SpamProbe uses only a fixed number of top terms (as set by the -w command line option) when scoring emails. The -x option can be used to allow the array to be extended past the max size if more terms are available with probabilities <= 0.1 or >= 0.9. -X An interesting variation on the scoring settings. Equivalent to using "-w5 -r5 -x" so that generally only words with probabilites <= 0.1 or >= 0.9 are used and word frequencies in the email count heavily towards the score. Tests have shown that this setting tends to be safer (fewer false positives) and have higher recall (proper classification of spams previously scored as spam) although its predictive power isn't quite as good as the default settings. WARNING: This setting might work best with a fairly large corpus, it has not been tested with a small corpus so it might be very inaccurate with fewer than 1000 total messages. -Y Assume traditional Berkeley mailbox format, ignoring any Content-Length: fields. -7 Tells SpamProbe to ignore any characters with the most significant bit set to 1 instead of mapping them to the letter 'z'. -8 Tells SpamProbe to store all characters even if their most significant bit is set to 1. SpamProbe recognizes the following commands: spamprobe help [command] With no arguments spamprobe lists all of the valid commands. If one or more commands are specified after the word help, spamprobe will print a more verbose description of each command. spamprobe create-db If no database currently exists spamprobe will attempt to create one and then exit. This can be used to bootstrap a new installation. Strictly speaking this command is not necessary since the train-spam, train-good, and auto-train commands will also create a database if none already exists but some users like to create a database as a separate installation step. spamprobe create-config Writes a new configuration file named spamprobe.hdl into the database directory (normally $HOME/.spamprobe). Any existing configuration file will be overwritten so be sure to make a copy before invoking this command. spamprobe receive [filename...] Tells SpamProbe to read its standard input (or a file specified after the receive command) and score it using the current databases. Once the message has been scored the message is classified as either spam or non-spam and its word counts are written to the appropriate database. The message's score is written to stdout along with a single word. For example: SPAM 0.9999999 595f0150587edd7b395691964069d7af or GOOD 0.0200000 595f0150587edd7b395691964069d7af The string of numbers and letters after the score is the message's "digest", a 32 character number which uniquely identifies the message. The digest is used by SpamProbe to recognize messages that it has processed previously so that it can keep its word counts consistent if the message is reclassified. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe train [filename...] Functionally identical to receive except that the database is only modified if the message was "difficult" to classify. In practice this can reduce the number of database updates to as little as 10% of messages received. spamprobe score [filename...] Similar to receive except that the database is not modified in any way. spamprobe summarize [filename...] Similar to score except that it prints a short summary and score for each message. This can be useful when testing. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe find-spam [filename...] Similar to score except that it prints a short summary and score for each message that is determined to be spam. This can be useful when testing. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe find-good [filename...] Similar to score except that it prints a short summary and score for each message that is determined to be good. This can be useful when testing. Using the -T option additionally lists the terms used to produce the score along with their counts (number of times they were found in the message). spamprobe auto-train {SPAM|GOOD filename...}... Attempts to efficiently build a database from all of the named files. You may specify one or more file of each type. Prior to each set of file names you must include the word SPAM or GOOD to indicate what type of mail is contained in the files which follow on the command line. The case of the SPAM and GOOD keywords is important. Any number of file names can be specified between the keywords. The command line format is very flexible. You can even use a find command in backticks to process whole directory trees of files. For example: spamprobe auto-train SPAM spams/* GOOD `find hams -type f` SpamProbe pre-scans the files to determine how many emails of each type exist and then trains on hams and spams in a random sequence that balances the inflow of each type so that the train command can work most effectively. For example if you had 400 hams and 400 spams, auto-train will generally process one spam, then one ham, etc. If you had 4000 spams and 400 hams then auto-train will generally process 10 spams, then one ham, etc. Since this command will likely take a long time to run it is often desireable to use it with the -v option to see progress information as the messages are processed. spamprobe -v auto-train SPAM spams/* GOOD hams/* spamprobe good [filename...] Scans each file (or stdin if no file is specified) and reclassifies every email in the file as non-spam. The databases are updated appropriately. Messages previously classified as good (recognized using their MD5 digest or message ids) are ignored. Messages previously classified as spam are reclassified as good. spamprobe train-good [filename...] Functionally identical to "good" command except that it only updates the database for messages that are either incorrectly classified (i.e. classified as spam) or are "difficult" to classify. In practice this can reduce amount of database updates to as little as 10% of messages. spamprobe spam [filename...] Scans each file (or stdin if no file is specified) and reclassifies every email in the file as spam. The databases are updated appropriately. Messages previously classified as spam (recognized using their MD5 digest of message ids) are ignored. Messages previously classified as good are reclassified as spam. spamprobe train-spam [filename...] Functionally identical to "spam" command except that it only updates the database for messages that are either incorrectly classified (i.e. classified as good) or are "difficult" to classify. In practice this can reduce amount of database updates to as little as 10% of messages. spamprobe remove [filename...] Scans each file (or stdin if no file is specified) and removes its term counts from the database. Messages which are not in the database (recognized using their MD5 digest of message ids) are ignored. spamprobe cleanup [ junk_count [ max_age ] ]... Scans the database and removes all terms with junk_count or less (default 2) which have not had their counts modified in at least max_age days (default 7). You can specify multiple count/age pairs on a single command line but must specify both a count and an age for all but the last count. This should be run periodically to keep the database from growing endlessly. For my own email I use cron to run the cleanup command every day and delete all terms with count of 2 or less that have not been modified in the last two weeks. Here is the excerpt from my crontab: 3 0 * * * /home/brian/bin/spamprobe cleanup 2 14 Alternatively you might want to use a much higher count (1000 in this example) for terms that have not been seen in roughly six months: 3 0 * * * /home/brian/bin/spamprobe cleanup 1000 180 2 14 Because of the way that PBL and BerkeleyDB work the database file will not actually shrink, but newly added terms will be able to use the space previously occupied by any removed terms so that the file's growth should be significantly slower if this command is used. To actually shrink the database you can build a new one using the BerkeleyDB utility programs db_dump and db_load (Berkeley DB only) or the spamprobe import and export commands (either database library). For example: cd ~ mkdir new.spamprobe spamprobe export | spamprobe -d new.spamprobe import mv .spamprobe old.spamprobe mv new.spamprobe .spamprobe The -P option can also be used to limit the rate of growth of the database when importing a large number of emails. For example if you want to classify 1000 emails and want SP to purge rare terms every 100 messages use a command such as: spamprobe -P 100 good goodmailboxname Using -P slows down the classification but can avoid the need to use the db_dump trick. Using -P only makes sense when classifying a large number of messages. spamprobe purge [ junk_count ] Similar to cleanup but forces the immediate deletion of all terms with total count less than junk_count (default is 2) no matter how long it has been since they were modified (i.e. even if they were just added today). This could be handy immediately after classifying a large mailbox of historical spam or good email to make room for the next batch. spamprobe purge-terms regex Similar to purge except that it removes from the database all terms which match the specified regular expression. Be careful with this command because it could remove many more terms than you expect. Use dump with the same regex before running this command to see exactly what will be deleted. spamprobe edit-term term good_count spam_count Can be used to specifically set the good and spam counts of a term. Whether this is truly useful is doubtful but it is provided for completeness sake. For example it could be used to force a particular word to be very spammy or very good: spamprobe edit-term nigeria 0 1000000 spamprobe edit-term burton 10000000 0 spamprobe dump [ regex ] Prints the contents of the word counts database one word per line in human readable format with spam probability, good count, spam count, flags, and word in columns separated by whitespace. PBL and Berkeley DB sort terms alphabetically. The standard unix sort command can be used to sort the terms as desired. For example to list all words from "most good" to "least good" use this command: spamprobe dump | sort -k 1nr -k 3nr To list all words from "most spammy" to "least spammy" use this command: spamprobe dump | sort -k 1n -k 2nr Optionally you can specify a regular expression. If specified SpamProbe will only dump terms matching the regular expression. For example: spamprobe dump 'finance' spamprobe dump '\bfinance\b' spamprobe dump 'HSubject_.*finance' spamprobe tokenize [ filename ] Prints the tokens found in the file one word per line in human readable format with spam probability, good count, spam count, message count, and word in columns separated by whitespace. Terms are listed in the order in which they were encountered in the message. The standard unix sort command can be used to sort the terms as desired. For example to list all words from "most good" to "least good" use this command: spamprobe tokenize filename | sort -k 1nr -k 3nr To list all words from "most spammy" to "least spammy" use this command: spamprobe tokenize filename | sort -k 1n -k 2nr spamprobe export Similar to the dump command but prints the counts and words in a comma separated format with the words surrounded by double quotes. This can be more useful for importing into some databases. spamprobe import Reads the specified files which must contain export data written by the export command. The terms and counts from this file are added to the database. This can be used to convert a database from a prior version. spamprobe exec command Obtains an exclusive lock on the database and then executes the command using system(3). If multiple arguments are given after "exec" they are combined to form the command to be executed. This command can be used when you want to perform some operation on the database without interference from incoming mail. For example, to back up your .spamprobe directory using tar you could do something like this: cd spamprobe exec tar cf spamprobe-data.tar.gz .spamprobe If you simply want to hold the lock while interactively running commands in a different xterm you could use "spamprobe exec read". The linux read program simply reads a line of text from your terminal so the lock would effectively be held until you pressed the enter key. Another option would be to use a shell as the command and type the commands into that shell: spamprobe /bin/bash ls date exit Be careful not to run spamprobe in the shell though since the spamprobe in the shell will wind up deadlocked waiting for the spamprobe running the exec command to release its lock. spamprobe exec-shared command Same as exec except that a shared lock is used. This may be more appropriate if you are backing up your database since operations like score (but not train or receive) could still be performed on the database while the backup was running. .SH SETUP OF SPAMPROBE FOR USERS Once you have a spamprobe executable copy it to someplace in your PATH so that procmail can find it. Then create a directory for SpamProbe to store its databases in. By default SpamProbe wants to use the directory ~/.spamprobe. You must create this directory manually in order to run SpamProbe or else specify some other directory using the -d option. Something like this should suffice: mkdir ~/.spamprobe SpamProbe can use either the PBL or Berkeley DB library for its databases. Both are fast on local file systems but very slow over NFS. Please ensure that your spamprobe directory is on a local file system to ensure good performance. .SH NOTES USING HASH DATABASE SpamProbe can use a simple, fixed size hash data file as an alternative to PBL or BDB. There are two advantages to the hash format. The first is speed. In my experiments the hash file format is around 2x the speed of PBL (ranged from 1.8x to 3.5x). The second advantage is that the hash data file size is fixed. You choose a size when you create the file and it never changes. File size can be anywhere from 1-100 MB. You need to choose a size large enough to hold your terms with room to spare. More on that later. The hash file format also has significant disadvantages. Becuase the file size is fixed you must monitor the file to ensure that it does not become overly full. When the file becomes more than half full performance will suffer. Also the hash format does not store original terms so you cannot use the dump command to learn what terms are spammy or hammy in your database. Finally, the hash format is imprecise. Hash collisions can cause the counts from different terms to be mixed together which can reduce accuracy. To create a hash data file you add a prefix to the directory name in the -d command line option. You can specify just the directory like this: spamprobe -d hash:$HOME/.spamprobe or you can add a size in megabytes for the file like this: spamprobe -d hash:42:$HOME/.spamprobe The size is only used when a file is first created. SP auto detects the size of an existing hash file. You need to allow enough space for twice as many terms as you are likely to have in your file. In my database I have 2.2 million terms. That required a database of are 53 MB. SP uses 12 bytes per term in the hash file so you can estimate the file size you'll need by multiplying the number of terms by 24. The hash format does not store the original terms. Instead it stores the 32 bit hash code for each term. You can do just about anything with a hash file that you could with a PBL file including import/export, edit-term, cleanup, purge, etc. You can use export your PBL database and import it to build a hash file (note that you cannot go the other direction) and you can export one hash file and import into a new one to enlarge your file. .SH MAILDIR FORMAT SpamProbe will accept a maildir directory name anywhere that an Mbox or MBX file name can be specified. When SpamProbe encounters a Maildir mailbox (directory) name it will automatically process all of the non-hidden files in the cur and new subdirectories of the mailbox. There is no need to individually specify these subdirectories. .SH GETTING STARTED SpamProbe is not a stand alone mail filter. It doesn't sort your mail or split it into different mailboxes. Instead it relies on some other program such as procmail to actually file your mail for you. What SpamProbe does do is track the word counts in good and spam emails and generate a score for each email that indicates whether or not it is likely to be spam. Scores range from 0 to 1 with any score of 0.9 or higher indicating a probable spam. Personally I use SpamProbe with procmail to filter my incoming email into mail boxes. I have procmail score each inbound email using SpamProbe and insert a special header into each email containing its score. Then I have procmail move spams into a special mailbox. No spam filter is perfect and SpamProbe sometimes makes mistakes. To correct those mistakes I have a special mailbox that I put undetected spams into. I run SpamProbe periodically and have it reclassify any emails in that mailbox as spam so that it will make a better guess the next time around. This is not a procmail primer. You will need to ensure that you have procmail and formail installed before you can use this technique. Also I recommend that you read the procmail documentation so that you can fully understand this example and adapt it to your own needs. That having been said, my .procmailrc file looks like this: MAILDIR=$HOME/IMAP :0 c saved :0 SCORE=| /home/brian/bin/spamprobe train :0 wf | formail -I "X-SpamProbe: $SCORE" :0 a: *^X-SpamProbe: SPAM spamprobe I use IMAP to fetch my email so my mailboxes all live in a directory named IMAP on my mail server. NOTE: The first stanza copies all incoming emails into a special mbox called saved. SpamProbe IS BETA SOFTWARE and though it works well for me it is possible that it could somehow lose emails. Caution is always a good idea. That having been said, with the procmailrc file as shown above the worst that could happen if SpamProbe crashes is that the email would not be scored properly and procmail would deliver it to your inbox. Of course if procmail crashes all bets are off. The second stanza runs spamprobe in "train" mode to score the email, classify it as either spam or good, and possibly update the database. The train command tries to minimize the number of database updates by only updating the database with terms from an incoming message if there was insufficient confidence in the message's score. The train command always updates the database on the first 1500 of each type received. This ensures that sufficient email is classified to allow the filter to operate reliably. The next stanza runs formail to add a custom header to the email containing the SpamProbe score. The final stanza uses the contents of the custom header to file detected spams into a special mbox named spamprobe. As an alternative to using the train command, you can run spamprobe in "receive" mode. In that mode SpamProbe scores the email and then classifies it as either spam or good based on the score. It always automatically adds the word counts for the email to the appropriate database. This is essentially like running in score mode followed immediately by either spam or good mode. It produces more database I/O and a bigger database but ensures that every message has its terms reflected in the database. Personally I use train mode. A sample procmailrc file using the receive command looks like this: MAILDIR=$HOME/IMAP :0 c saved :0 SCORE=| /home/brian/bin/spamprobe receive :0 wf | formail -I "X-SpamProbe: $SCORE" :0 a: *^X-SpamProbe: SPAM spamprobe .SH MAKING CORRECTIONS SpamProbe is not perfect. It is able to detect over 99% of the spams that I receive but some still slip through. To correct these missed emails I run SpamProbe periodically and have it scan a special mbox. Since I use IMAP to retrieve my emails I can simply drop undetected spams into this mbox from my mail client. If you use POP or some other system then you will need to find a way get the undetected spams into a mbox that spamprobe can see. Periodically I run a script that scans three special mboxes to correct errors in judgment: #!/bin/sh IMAPDIR=$HOME/IMAP spamprobe remove $IMAPDIR/remove spamprobe good $IMAPDIR/nonspam spamprobe spam $IMAPDIR/spam spamprobe train-spam $IMAPDIR/spamprobe From this example you can see that I use three special mboxes to make corrections. I copy emails that I don't want spamprobe to store into the remove mbox. This is useful if you receive email from a friend or colleague that looks like spam and you don't want it to dilute the effectiveness of the terms it contains. Undetected spams go into the spam mbox. SpamProbe will reclassify those emails as spam and correct its database accordingly. Note that doing this does not guarantee that the spam will always be scored as spam in the future. Some spams are too bland to detect perfectly. Fortunately those are very rare. The nonspam mbox is for any false positives. These are always possible and it is important to have a way to reclassify them when they do occur. If you are using receive mode rather than train mode then the above script can be modified to remove the train-spam line. For example: #!/bin/sh IMAPDIR=$HOME/IMAP spamprobe remove $IMAPDIR/remove spamprobe good $IMAPDIR/nonspam spamprobe spam $IMAPDIR/spam Finally you'll need to build a starting database. Since SpamProbe relies on word counts from past emails it requires a decent sized database to be accurate. To build the database select some of your mboxes containing past emails. Ideally you should have one mbox of spams and one or more of non-spams. If you don't have any spams handy then don't worry, SpamProbe will gradually become more accurate as you receive more spams. Expect a fairly high false negative (i.e. missed spams) rate as you first start using SpamProbe. To import your starting messages use commands such as these. The example assumes that you have non-spams stored in a file named mbox in your home directory and some spams stored in a file named nasty-spams. Replace these names with real ones. spamprobe good ~/mbox spamprobe spam ~/nasty-spams .SH SEE ALSO procmail(1) spamprobe-1.4d/src/0000777000076400007640000000000010527262440011320 500000000000000spamprobe-1.4d/src/database/0000777000076400007640000000000010527262430013063 500000000000000spamprobe-1.4d/src/database/FrequencyDBImpl_pbl.cc0000664000076400007640000002142110527261700017135 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_pbl.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifdef USE_PBL #include #include #include #include #include "CleanupManager.h" #include "LockFile.h" #include "WordData.h" #include "FrequencyDBImpl_pbl.h" static const int BUFFER_SIZE = 1024; static const int CLEANUP_RECORDS_PER_TRANSACTION = 10; const char *FrequencyDBImpl_pbl::SEARCH_SUFFIX("pkey"); inline int throw_on_error(const char *function_name, int rc) { if (rc >= 0) { return rc; } if (pbl_errno == PBL_ERROR_NOT_FOUND) { return PBL_ERROR_NOT_FOUND; } static char buffer[4096]; ostrstream msg(buffer, sizeof(buffer)); msg << function_name << ": " << pbl_errstr << " (" << pbl_errno << ")" << ends; throw runtime_error(buffer); } inline int warn_on_error(const char *function_name, int rc) { if (rc >= 0) { return rc; } if (pbl_errno == PBL_ERROR_NOT_FOUND) { return PBL_ERROR_NOT_FOUND; } cerr << "warning: pbl reported error: " << function_name << ": " << pbl_errstr << " (" << pbl_errno << ")" << endl; return rc; } FrequencyDBImpl *FrequencyDBImpl_pbl::factory(const DatabaseConfig *config) { return new FrequencyDBImpl_pbl(); } FrequencyDBImpl_pbl::FrequencyDBImpl_pbl() : m_kf(0), m_isReadOnly(false), m_inTransaction(false) { } FrequencyDBImpl_pbl::~FrequencyDBImpl_pbl() { close(); } inline int copy_key(const string &str, unsigned char *ptr) { int len = str.size(); if (len >= 254) { len = 254; } memcpy(ptr, str.c_str(), len); ptr[len] = (unsigned char)0; return len + 1; } bool FrequencyDBImpl_pbl::open(const string &arg_filename, bool read_only, int open_mode) { close(); assert(m_kf == 0); File db_file(arg_filename); db_file.setSuffix(SEARCH_SUFFIX); string filename(db_file.getPath()); char *filename_ptr = const_cast(filename.c_str()); if (!read_only) { m_kf = pblKfCreate(filename_ptr, 0); } if (!m_kf) { m_kf = pblKfOpen(filename_ptr, read_only ? 0 : 1, 0); } m_isReadOnly = read_only; m_inTransaction = false; if (is_debug) { cerr << "DATABASE OPENED " << db_file.getPath() << endl; } return m_kf != 0; } void FrequencyDBImpl_pbl::close() { if (m_kf) { quietAbortTransaction(); warn_on_error("pblKfFlush", pblKfFlush(m_kf)); warn_on_error("pblKfClose", pblKfClose(m_kf)); m_kf = 0; } } void FrequencyDBImpl_pbl::flush() { if (m_kf) { throw_on_error("pblKfFlush", pblKfFlush(m_kf)); } } void FrequencyDBImpl_pbl::quietAbortTransaction() { assert(m_kf); if (m_inTransaction) { warn_on_error("pblKfCommit", pblKfCommit(m_kf, 1)); m_inTransaction = false; } } void FrequencyDBImpl_pbl::beginTransaction() { assert(m_kf); assert(!m_inTransaction); if (!m_inTransaction) { if (is_debug) { cerr << "starting transaction" << endl; } throw_on_error("pblKfStartTransaction", pblKfStartTransaction(m_kf)); m_inTransaction = true; } } void FrequencyDBImpl_pbl::endTransaction(bool commit) { assert(m_kf); assert(m_inTransaction); if (m_inTransaction) { if (is_debug) { cerr << "ending transaction: " << commit << endl; } throw_on_error("pblKfCommit", pblKfCommit(m_kf, commit ? 0 : 1)); m_inTransaction = false; } } void FrequencyDBImpl_pbl::writeWord(const string &word, const WordData &counts) { assert(m_kf); assert(!m_isReadOnly); bool delete_word = counts.totalCount() <= 0; unsigned char key[BUFFER_SIZE]; int keylen = copy_key(word, key); WordData db_counts(counts); db_counts.toDatabaseOrder(); int rc = throw_on_error("pblKfFind", pblKfFind(m_kf, PBLEQ, key, keylen, 0, 0)); if (rc == PBL_ERROR_NOT_FOUND) { if (!delete_word) { if (is_debug) { cerr << "inserting word " << word << ": keylen " << keylen << endl; } throw_on_error("pblKfInsert", pblKfInsert(m_kf, key, keylen, (unsigned char *)&db_counts, sizeof(db_counts))); } else { if (is_debug) { cerr << "ignoring zero count word " << word << ": keylen " << keylen << endl; } } } else { assert(rc >= 0); if (delete_word) { if (is_debug) { cerr << "deleting word " << word << ": keylen " << keylen << endl; } throw_on_error("pblKfDelete", pblKfDelete(m_kf)); } else { if (is_debug) { cerr << "updating word " << word << ": keylen " << keylen << endl; } throw_on_error("pblKfUpdateData", pblKfUpdate(m_kf, (unsigned char *)&db_counts, sizeof(db_counts))); } } } bool FrequencyDBImpl_pbl::readWord(const string &word, WordData &counts) { assert(m_kf); unsigned char key[BUFFER_SIZE]; int keylen = copy_key(word, key); int rc = throw_on_error("pblKfFind", pblKfFind(m_kf, PBLEQ, key, keylen, 0, 0)); if (rc == PBL_ERROR_NOT_FOUND) { return false; } assert(rc == sizeof(counts)); throw_on_error("pblKfRead", pblKfRead(m_kf, (unsigned char *)&counts, sizeof(counts))); counts.toHostOrder(); return true; } bool FrequencyDBImpl_pbl::getWord(int pbl_code, string &word, WordData &counts) { char key[BUFFER_SIZE]; int keylen = 0; int rc = 0; switch (pbl_code) { case PBLFIRST: rc = throw_on_error("pblKfGetAbs", pblKfGetAbs(m_kf, 0, key, &keylen)); break; case PBLTHIS: rc = throw_on_error("pblKfThis", pblKfThis(m_kf, key, &keylen)); break; default: assert(pbl_code == PBLNEXT); rc = throw_on_error("pblKfNext", pblKfNext(m_kf, key, &keylen)); break; } if (rc == PBL_ERROR_NOT_FOUND) { return false; } word.assign(key); throw_on_error("pblKfRead", pblKfRead(m_kf, (unsigned char *)&counts, sizeof(counts))); counts.toHostOrder(); return true; } bool FrequencyDBImpl_pbl::firstWord(string &word, WordData &counts) { return getWord(PBLFIRST, word, counts); } bool FrequencyDBImpl_pbl::nextWord(string &word, WordData &counts) { return getWord(PBLNEXT, word, counts); } string FrequencyDBImpl_pbl::getDatabaseType() const { return "DBM-pbl"; } void FrequencyDBImpl_pbl::sweepOutOldTerms(const CleanupManager &cleanman) { string word; WordData counts; assert(!m_isReadOnly); assert(!m_inTransaction); beginTransaction(); try { int records_processed = 0; bool again = firstWord(word, counts); while (again) { bool delete_word = false; if (word.length() >= 3 && word[0] == '_' && word[1] == '_') { if (starts_with(word, "__MD5") && counts.totalCount() == 0) { // go ahead and remove digests that have a count of zero delete_word = true; } else { // ignore special words like __MD5 and __COUNT__ } } else { delete_word = cleanman.shouldDelete(counts); } if (delete_word) { if (is_debug) { cerr << "sweepOutJunk: removing term " << word << " with total count " << counts.totalCount() << " and age " << counts.age() << endl; } throw_on_error("pblKfDelete", pblKfDelete(m_kf)); again = getWord(PBLTHIS, word, counts); ++records_processed; } else { again = nextWord(word, counts); } if (records_processed >= CLEANUP_RECORDS_PER_TRANSACTION) { endTransaction(true); beginTransaction(); records_processed = 0; } } } catch (runtime_error &ex) { quietAbortTransaction(); throw; } endTransaction(true); flush(); } #endif // USE_PBL spamprobe-1.4d/src/database/FrequencyDBImpl_bdb.h0000664000076400007640000000551310527261700016755 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_bdb.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_bdb_h #define _FrequencyDBImpl_bdb_h #ifdef USE_DB #include #include "FrequencyDBImpl.h" class File; class LockFile; class FrequencyDBImpl_bdb : public FrequencyDBImpl { public: FrequencyDBImpl_bdb(); ~FrequencyDBImpl_bdb(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); static FrequencyDBImpl *factory(const DatabaseConfig *); private: bool firstWord(string &word, WordData &counts, bool read_only); bool loadKey(DBT &key, string &word, WordData &counts) const; bool loadKey(DBT &key, WordData &counts) const; bool openDatabase(const File &db_file, bool read_only, int create_mode); bool openEnvironment(const File &db_file, bool read_only, int create_mode); void closeCursor(); void closeDatabase(); void closeEnvironment(); private: /// Not implemented. FrequencyDBImpl_bdb(const FrequencyDBImpl_bdb &); /// Not implemented. FrequencyDBImpl_bdb& operator=(const FrequencyDBImpl_bdb &); private: bool m_isReadOnly; DB_ENV *m_env; DB *m_file; DBC *m_cursor; }; #endif // USE_DB #endif // _FrequencyDBImpl_bdb_h spamprobe-1.4d/src/database/HashDataFile.cc0000664000076400007640000002323210527261700015566 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HashDataFile.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifdef USE_MMAP #include #include #include #include #include #include #include "File.h" #include "WordData.h" #include "HashDataFile.h" enum { SIZE_MULTIPLE = 1024, DEBUG_HASH = 1, }; // table of primes indexed roughy by megabyte from 1 to 100 megs static const int primes_by_meg[] = { // assumes 12 bytes per entry 87359, 174761, 262139, 349519, 436889, // 1 - 5 megs 524287, 611657, 699037, 786431, 873787, // 6 - 10 megs 961189, 1048573, 1135951, 1223329, 1310719, // 11 - 15 megs 1398091, 1485479, 1572853, 1660231, 1747619, // 16 - 20 megs 1835003, 1922387, 2009759, 2097143, 2184509, // 21 - 25 megs 2271901, 2359267, 2446673, 2534057, 2621431, // 26 - 30 megs 2708821, 2796181, 2883577, 2970959, 3058343, // 31 - 35 megs 3145721, 3233093, 3320477, 3407857, 3495253, // 36 - 40 megs 3582629, 3670013, 3757393, 3844777, 3932153, // 41 - 45 megs 4019527, 4106897, 4194301, 4281679, 4369061, // 46 - 50 megs 4456433, 4543823, 4631203, 4718579, 4805959, // 51 - 55 megs 4893341, 4980727, 5068111, 5155489, 5242877, // 56 - 60 megs 5330251, 5417597, 5505023, 5592373, 5679769, // 61 - 65 megs 5767129, 5854543, 5941921, 6029299, 6116687, // 66 - 70 megs 6204071, 6291449, 6378787, 6466193, 6553577, // 71 - 75 megs 6640979, 6728347, 6815741, 6903121, 6990493, // 76 - 80 megs 7077883, 7165267, 7252649, 7340009, 7427353, // 81 - 85 megs 7514791, 7602151, 7689557, 7776931, 7864301, // 86 - 90 megs 7951693, 8039081, 8126453, 8213819, 8301217, // 91 - 95 megs 8388593, 8475947, 8563351, 8650727, 8738129, // 96 - 100 megs }; #define PRIMES_ARRAY_SIZE (sizeof(primes_by_meg) / sizeof(primes_by_meg[0])) static int compute_divisor_for_max_elements(int max_elements) { for (int i = PRIMES_ARRAY_SIZE - 1; i >= 0; --i) { int divisor = primes_by_meg[i]; if (divisor <= max_elements) { return divisor; } } return primes_by_meg[0]; } HashDataFile::HashDataFile(int num_headers, HashDataFile::ulong_t size_in_bytes) : m_base(0) { initialize(num_headers, size_in_bytes); } HashDataFile::~HashDataFile() { close(); } void HashDataFile::initialize(int num_headers, HashDataFile::ulong_t size_in_bytes) { m_numHeaders = num_headers; int max_elements = (size_in_bytes / WordArray::ENTRY_SIZE) - m_numHeaders; m_divisor = compute_divisor_for_max_elements(max_elements); m_indexLimit = m_divisor + m_numHeaders; m_size = WordArray::ENTRY_SIZE * m_indexLimit; if (is_debug) { cerr << "HASH_DIVISOR " << m_divisor << " (0x" << hex << m_divisor << ")" << " INDEX_LIMIT " << dec << m_indexLimit << " SIZE " << m_size << endl; } } void HashDataFile::populateEmptyFile(int fd) { if (is_debug) { cerr << "INITIALIZING NEW HASHFILE" << endl; } const int SIZE_MULTIPLE = 1024; unsigned char zeros[SIZE_MULTIPLE * WordArray::ENTRY_SIZE]; WordArray::fillNullBuffer(zeros, SIZE_MULTIPLE); for (int i = 0; i < m_indexLimit; i += SIZE_MULTIPLE) { ::write(fd, &zeros, min(m_indexLimit - i, (HashDataFile::ulong_t)SIZE_MULTIPLE) * WordArray::ENTRY_SIZE); } } bool HashDataFile::open(const string &filename, bool read_only, int create_mode) { close(); if (is_debug) { cerr << "OPEN HASHFILE " << filename << endl; } m_isReadOnly = read_only; m_createMode = create_mode; File data_file(filename); bool exists = data_file.isFile(); m_isNewFile = !exists; if (read_only && !exists) { cerr << "error: hash file " << filename << " does not exist and cannot be created in read-only mode" << endl; return false; } if (exists) { unsigned long file_size = data_file.getSize(); if ((file_size % WordArray::ENTRY_SIZE) != 0) { cerr << "error: hash file " << filename << " size not a multiple of " << WordArray::ENTRY_SIZE << " bytes" << endl; return false; } initialize(m_numHeaders, file_size); if (m_size != file_size) { cerr << "error: hash file " << filename << " size invalid " << file_size << " != " << m_size << endl; return false; } } if (is_debug) { cerr << "HASHFILE " << filename << " SIZE " << m_size << endl; } int flags = (read_only) ? O_RDONLY : O_RDWR; if (!exists) { flags |= O_CREAT; } int fd = ::open(filename.c_str(), flags, create_mode); if (fd < 0) { cerr << "error: unable to open database " << filename << ": " << strerror(errno) << endl; return false; } if (!exists) { populateEmptyFile(fd); } if (!mmapFile(fd, read_only)) { cerr << "error: unable to mmap file " << filename << ": " << strerror(errno) << endl; close(); return false; } m_filename = filename; return true; } bool HashDataFile::mmapFile(int fd, bool read_only) { if (is_debug) { cerr << "MMAPPING HASHFILE" << endl; } int flags = (read_only) ? PROT_READ : (PROT_READ | PROT_WRITE); m_base = (char *)mmap(0, m_size, flags, MAP_SHARED, fd, 0); if (m_base == (char *)-1) { m_base = 0; return false; } m_array.reset(m_base, m_indexLimit); return true; } void HashDataFile::close() { if (m_base) { ::munmap(m_base, m_size); m_array.reset(0, 0); m_base = 0; m_filename.erase(); } } bool HashDataFile::isOpen() { return m_base != 0; } void HashDataFile::writeRecord(int record_number, HashDataFile::ulong_t key, const WordData &word_data) { assert(m_base); assert(record_number >= 0); assert(record_number < m_indexLimit); m_array.writeWord(record_number, key, word_data); } void HashDataFile::readRecord(int record_number, HashDataFile::ulong_t &key, WordData &word_data) { assert(m_base); assert(record_number >= 0); assert(record_number < m_indexLimit); m_array.readWord(record_number, key, word_data); } bool HashDataFile::write(ulong_t key, const WordData &word_data) { assert(m_base); int index = computeIndexForKey(key); for (int i = 0; i < m_divisor; ++i) { ulong_t old_key = m_array.readKey(index); if (old_key == key || old_key == 0) { m_array.writeWord(index, key, word_data); return true; } if (m_autoCleaner.isNotNull()) { WordData old_data; m_array.readWord(index, old_key, old_data); if (m_autoCleaner->shouldDelete(old_data)) { m_array.writeWord(index, key, word_data); if (is_debug) { cerr << "HashDataFile: overwriting old word for new one: " << " index " << index << " new_key " << key << " old_key " << old_key << " total " << old_data.totalCount() << " good " << old_data.goodCount() << " spam " << old_data.spamCount() << " age " << old_data.age() << endl; } return true; } } // skip this slot since it contains a collision index = m_numHeaders + ((index - m_numHeaders + 1) % m_divisor); } return false; } bool HashDataFile::read(ulong_t key, WordData &word_data) { assert(m_base); ulong_t old_key = 0; int index = computeIndexForKey(key); for (int i = 0; i < m_divisor; ++i) { m_array.readWord(index, old_key, word_data); if (old_key == key) { // slot matches our key so return it's value return true; } if (old_key == 0) { // slot is empty - this key is not in file return false; } // skip this slot since it contains a collision index = m_numHeaders + ((index - m_numHeaders + 1) % m_divisor); } return false; } void HashDataFile::copyHeadersToFile(HashDataFile &file) { ulong_t key = 0; WordData word_data; for (int i = 0; i < m_numHeaders; ++i) { readRecord(i, key, word_data); file.writeRecord(i, key, word_data); } } void HashDataFile::copyContentsToFile(HashDataFile &file) { ulong_t key = 0; WordData word_data; for (int i = m_numHeaders; i < m_indexLimit; ++i) { readRecord(i, key, word_data); if (key != 0) { file.write(key, word_data); } } } #endif // USE_MMAP spamprobe-1.4d/src/database/FrequencyDBImpl_hash.h0000664000076400007640000000547010527261700017153 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_hash.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_hash_h #define _FrequencyDBImpl_hash_h #ifdef USE_MMAP #include "FrequencyDBImpl.h" #include "HashDataFile.h" class ifstream; class LockFD; class FrequencyDBImpl_hash : public FrequencyDBImpl { public: FrequencyDBImpl_hash(int _size = 32); ~FrequencyDBImpl_hash(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); static FrequencyDBImpl *factory(const DatabaseConfig *); static const char *SEARCH_SUFFIX; private: HashDataFile::ulong_t computeKeyForWord(const string &word); string getWordForIndex(int index, HashDataFile::ulong_t key); void initializeHeaderRecords(); bool validateHeaderRecords(); void copyToNewDataFile(const CleanupManager &cleanman, const string &rehash_filename); void swapDataFilesAndReopen(const string &live_filename, const string &rehash_filename, const string &temp_filename); private: /// Not implemented. FrequencyDBImpl_hash(const FrequencyDBImpl_hash &); /// Not implemented. FrequencyDBImpl_hash& operator=(const FrequencyDBImpl_hash &); private: HashDataFile::ulong_t m_cursor; HashDataFile m_dataFile; }; #endif // USE_MMAP #endif // _FrequencyDBImpl_hash_h spamprobe-1.4d/src/database/FrequencyDBImpl_cache.h0000664000076400007640000000522110527261700017265 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_cache.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_cache_h #define _FrequencyDBImpl_cache_h #include "LRUCache.h" #include "FrequencyDBImpl.h" class FrequencyDBImpl_cache : public FrequencyDBImpl { public: FrequencyDBImpl_cache(FrequencyDBImpl *db, int max_size); ~FrequencyDBImpl_cache(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void clear(); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); private: /// Not implemented. FrequencyDBImpl_cache(const FrequencyDBImpl_cache &); /// Not implemented. FrequencyDBImpl_cache& operator=(const FrequencyDBImpl_cache &); private: struct CacheEntry { CacheEntry(bool _is_shared, const WordData &_counts) : is_shared(_is_shared), counts(_counts) { } bool is_shared; WordData counts; }; void addWordData(const string &word, bool is_dirty, bool is_shared, const WordData &counts); private: typedef LRUCache > CacheType; typedef LRUCache >::iterator IteratorType; Ptr m_db; CacheType m_cache; }; #endif // _FrequencyDBImpl_cache_h spamprobe-1.4d/src/database/FrequencyDBImpl_dbm.h0000664000076400007640000000461410527261700016771 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_dbm.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_dbm_h #define _FrequencyDBImpl_dbm_h #ifdef USE_DBM extern "C" { #include } #include "FrequencyDBImpl.h" class LockFile; class FrequencyDBImpl_dbm : public FrequencyDBImpl { public: FrequencyDBImpl_dbm(); ~FrequencyDBImpl_dbm(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); static FrequencyDBImpl *factory(const DatabaseConfig *); private: bool loadKey(const datum &key, string &word, WordData &counts) const; bool loadKey(const datum &key, WordData &counts) const; private: /// Not implemented. FrequencyDBImpl_dbm(const FrequencyDBImpl_dbm &); /// Not implemented. FrequencyDBImpl_dbm& operator=(const FrequencyDBImpl_dbm &); private: DBM *m_file; }; #endif // USE_DBM #endif // _FrequencyDBImpl_dbm_h spamprobe-1.4d/src/database/WordArray.h0000664000076400007640000000434010527261700015064 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: WordArray.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _WordArray_h #define _WordArray_h class WordData; class WordArray { public: WordArray(char *buffer = 0, int num_words = 0); ~WordArray(); enum { ENTRY_SIZE = 12, KEY_SIZE = 4, COUNT_SIZE = 3, FLAGS_SIZE = 2, }; typedef unsigned long key_t; void reset(char *buffer, int num_words); key_t readKey(int index); void readWord(int index, key_t &key, WordData &word); void writeWord(int index, key_t key, const WordData &word); static void fillNullBuffer(unsigned char *buffer, int num_entries); private: /// Not implemented. WordArray(const WordArray &); /// Not implemented. WordArray& operator=(const WordArray &); private: static void copyToArray(unsigned char *&data, int length, int number); static void copyFromArray(const unsigned char *&data, int length, int &number); private: unsigned char *m_buffer; int m_numWords; }; #endif // _WordArray_h spamprobe-1.4d/src/database/WordArray.cc0000664000076400007640000000657610527261700015237 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: WordArray.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "WordData.h" #include "WordArray.h" WordArray::WordArray(char *buffer, int num_words) : m_buffer((unsigned char *)buffer), m_numWords(num_words) { } WordArray::~WordArray() { } void WordArray::reset(char *buffer, int num_words) { m_buffer = (unsigned char *)buffer; m_numWords = num_words; } WordArray::key_t WordArray:: readKey(int index) { assert(index >= 0); assert(index < m_numWords); int key_int = 0; const unsigned char *data = m_buffer + ENTRY_SIZE * index; copyFromArray(data, KEY_SIZE, key_int); return (key_t)key_int; } void WordArray::readWord(int index, WordArray::key_t &key, WordData &word) { assert(index >= 0); assert(index < m_numWords); const unsigned char *data = m_buffer + ENTRY_SIZE * index; int good_count, spam_count, flags, key_int; copyFromArray(data, KEY_SIZE, key_int); copyFromArray(data, COUNT_SIZE, good_count); copyFromArray(data, COUNT_SIZE, spam_count); copyFromArray(data, FLAGS_SIZE, flags); word.reset(good_count, spam_count, flags); key = key_int; } void WordArray::writeWord(int index, WordArray::key_t key, const WordData &word) { assert(index >= 0); assert(index < m_numWords); unsigned char *data = m_buffer + ENTRY_SIZE * index; copyToArray(data, KEY_SIZE, key); copyToArray(data, COUNT_SIZE, word.goodCount()); copyToArray(data, COUNT_SIZE, word.spamCount()); copyToArray(data, FLAGS_SIZE, word.flags()); } void WordArray::copyToArray(unsigned char *&data, int length, int number) { for (int i = 0; i < length; ++i) { *data = (unsigned char)(number & 0xff); number = number >> 8; ++data; } } void WordArray::copyFromArray(const unsigned char *&data, int length, int &number) { number = 0; data += length; for (int i = 0; i < length; ++i) { --data; number = number << 8; number = number | (unsigned int)*data; } data += length; } void WordArray::fillNullBuffer(unsigned char *buffer, int num_entries) { memset(buffer, 0, num_entries * ENTRY_SIZE); } spamprobe-1.4d/src/database/HashDataFile.h0000664000076400007640000000625110527261700015432 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HashDataFile.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HashDataFile_h #define _HashDataFile_h #ifdef USE_MMAP #include "FrequencyDBImpl.h" #include "WordArray.h" #include "CleanupManager.h" class HashDataFile { public: typedef WordArray::key_t ulong_t; HashDataFile(int num_headers, ulong_t size_in_bytes); ~HashDataFile(); void initialize(int num_headers, ulong_t size_in_bytes); ulong_t firstIndex() const { return m_numHeaders; } ulong_t indexLimit() const { return m_indexLimit; } ulong_t size() const { return m_size; } const string &filename() const { return m_filename; } bool open(const string &filename, bool read_only, int create_mode); void close(); bool isOpen(); void writeRecord(int header_number, ulong_t key, const WordData &word_data); void readRecord(int header_number, ulong_t &key, WordData &word_data); bool write(ulong_t key, const WordData &word_data); bool read(ulong_t key, WordData &word_data); bool isReadOnly() const { m_isReadOnly; } int createMode() const { return m_createMode; } bool isNewFile() const { return m_isNewFile; } void setAutoClean(OWNED CleanupManager *cleaner) { m_autoCleaner.set(cleaner); } void copyHeadersToFile(HashDataFile &file); void copyContentsToFile(HashDataFile &file); private: /// Not implemented. HashDataFile(const HashDataFile &); /// Not implemented. HashDataFile& operator=(const HashDataFile &); void populateEmptyFile(int fd); bool mmapFile(int fd, bool read_only); ulong_t computeIndexForKey(ulong_t key) { return m_numHeaders + (key % m_divisor); } private: string m_filename; bool m_isReadOnly; int m_createMode; bool m_isNewFile; char *m_base; WordArray m_array; ulong_t m_numHeaders; ulong_t m_size; ulong_t m_divisor; ulong_t m_indexLimit; Ptr m_autoCleaner; }; #endif // USE_MMAP #endif // _HashDataFile_h spamprobe-1.4d/src/database/CleanupManager.cc0000664000076400007640000000417010527261700016173 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: CleanupManager.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CleanupManager.h" CleanupManager::CleanupManager() { } CleanupManager::CleanupManager(int junk_count, int max_age) { addLimit(junk_count, max_age); } CleanupManager::~CleanupManager() { } void CleanupManager::addLimit(int junk_count, int max_age) { m_nodes.push_back(CleanupNode(junk_count, max_age)); if (is_debug) { cerr << "CleanupManager added limit: count " << junk_count << " age " << max_age << endl; } } bool CleanupManager::shouldDelete(const WordData &word_data) const { for (NodeIter_t i = m_nodes.begin(); i != m_nodes.end(); ++i) { if (word_data.totalCount() <= i->junk_count && word_data.age() > i->max_age) { if (is_debug) { cerr << "CleanupManager triggered limit:" << " count " << word_data.totalCount() << " <= " << i->junk_count << " age " << word_data.age() << " > " << i->max_age << endl; } return true; } } return false; } spamprobe-1.4d/src/database/FrequencyDBImpl_null.cc0000664000076400007640000000440310527261700017333 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_null.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "FrequencyDBImpl_null.h" static const string DATABASE_TYPE("null"); FrequencyDBImpl_null::FrequencyDBImpl_null() { } FrequencyDBImpl_null::~FrequencyDBImpl_null() { } bool FrequencyDBImpl_null::open(const string &filename, bool read_only, int create_mode) { return true; } void FrequencyDBImpl_null::close() { } void FrequencyDBImpl_null::flush() { } void FrequencyDBImpl_null::clear() { } void FrequencyDBImpl_null::writeWord(const string &word, const WordData &counts) { } bool FrequencyDBImpl_null::readWord(const string &word, WordData &counts) { return false; } bool FrequencyDBImpl_null::firstWord(string &word, WordData &counts) { return false; } bool FrequencyDBImpl_null::nextWord(string &word, WordData &counts) { return false; } string FrequencyDBImpl_null::getDatabaseType() const { return DATABASE_TYPE; } void FrequencyDBImpl_null::sweepOutOldTerms(const CleanupManager &cleanman) { } spamprobe-1.4d/src/database/FrequencyDBImpl_dual.cc0000664000076400007640000000675110527261700017316 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_dual.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include "WordData.h" #include "FrequencyDBImpl_dual.h" static const string DATABASE_TYPE("-dual"); FrequencyDBImpl_dual::FrequencyDBImpl_dual(FrequencyDBImpl *shared_db, FrequencyDBImpl *private_db, const string &shared_filename) : m_sharedDB(shared_db), m_privateDB(private_db), m_sharedFilename(shared_filename) { assert(shared_db); assert(private_db); } FrequencyDBImpl_dual::~FrequencyDBImpl_dual() { close(); } bool FrequencyDBImpl_dual::open(const string &filename, bool read_only, int create_mode) { close(); return m_sharedDB->open(m_sharedFilename, true, SHARED_DB_MODE) && m_privateDB->open(filename, read_only, PRIVATE_DB_MODE); } void FrequencyDBImpl_dual::close() { m_privateDB->close(); m_sharedDB->close(); } void FrequencyDBImpl_dual::flush() { m_sharedDB->flush(); m_privateDB->flush(); } void FrequencyDBImpl_dual::writeWord(const string &word, const WordData &counts) { m_privateDB->writeWord(word, counts); } bool FrequencyDBImpl_dual::readWord(const string &word, WordData &counts) { return m_privateDB->readWord(word, counts) || m_sharedDB->readWord(word, counts); } bool FrequencyDBImpl_dual::readWord(const string &word, WordData &counts, bool &is_shared) { if (m_privateDB->readWord(word, counts)) { is_shared = false; return true; } if (m_sharedDB->readWord(word, counts)) { is_shared = true; return true; } return false; } bool FrequencyDBImpl_dual::firstWord(string &word, WordData &counts) { return m_privateDB->firstWord(word, counts); } bool FrequencyDBImpl_dual::nextWord(string &word, WordData &counts) { return m_privateDB->nextWord(word, counts); } string FrequencyDBImpl_dual::getDatabaseType() const { return m_sharedDB->getDatabaseType() + DATABASE_TYPE; } void FrequencyDBImpl_dual::sweepOutOldTerms(const CleanupManager &cleanman) { m_privateDB->sweepOutOldTerms(cleanman); } bool FrequencyDBImpl_dual::canCacheTerm(const string &word) { return m_sharedDB->canCacheTerm(word) || m_privateDB->canCacheTerm(word); } spamprobe-1.4d/src/database/FrequencyDBImpl_split.cc0000664000076400007640000001117210527261700017515 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_split.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifdef USE_MMAP #include #include "LockFD.h" #include "WordData.h" #include "DatabaseConfig.h" #include "FrequencyDBImpl_hash.h" #include "FrequencyDBImpl_split.h" FrequencyDBImpl *FrequencyDBImpl_split::factory(const DatabaseConfig *config) { return new FrequencyDBImpl_split(config); } FrequencyDBImpl_split::FrequencyDBImpl_split(const DatabaseConfig *config) : m_config(config), m_cursor(0) { } FrequencyDBImpl_split::~FrequencyDBImpl_split() { close(); } bool FrequencyDBImpl_split::open(const string &filename, bool read_only, int create_mode) { close(); string db_filename(filename); m_db.set(m_config->createDatabaseImplUsingDefaultType(db_filename)); if (!m_db->open(db_filename, read_only, create_mode)) { m_db.clear(); return false; } db_filename = filename; m_hash.set(new FrequencyDBImpl_hash(m_config->targetSizeMB())); if (!m_hash->open(db_filename, read_only, create_mode)) { m_db.clear(); m_hash.clear(); return false; } return true; } void FrequencyDBImpl_split::close() { m_db.clear(); m_hash.clear(); } void FrequencyDBImpl_split::flush() { if (m_db.get()) { m_db->flush(); } if (m_hash.get()) { m_hash->flush(); } } void FrequencyDBImpl_split::beginTransaction() { if (m_db.get()) { m_db->beginTransaction(); } if (m_hash.get()) { m_hash->beginTransaction(); } } void FrequencyDBImpl_split::endTransaction(bool commit) { if (m_db.get()) { m_db->endTransaction(commit); } if (m_hash.get()) { m_hash->endTransaction(commit); } } void FrequencyDBImpl_split::writeWord(const string &word, const WordData &counts) { assert(m_db.get()); assert(m_hash.get()); if (word.length() > 0 && word[0] == '_' && word != FrequencyDB::COUNT_WORD) { m_db->writeWord(word, counts); } else { m_hash->writeWord(word, counts); } } bool FrequencyDBImpl_split::readWord(const string &word, WordData &counts) { assert(m_db.get()); assert(m_hash.get()); bool ret = false; if (word.length() > 0 && word[0] == '_' && word != FrequencyDB::COUNT_WORD) { ret = m_db->readWord(word, counts); } else { ret = m_hash->readWord(word, counts); } return ret; } bool FrequencyDBImpl_split::firstWord(string &word, WordData &counts) { assert(m_db.get()); assert(m_hash.get()); if (m_db->firstWord(word, counts)) { m_cursor = 0; return true; } if (m_hash->firstWord(word, counts)) { m_cursor = 1; return true; } m_cursor = 2; return false; } bool FrequencyDBImpl_split::nextWord(string &word, WordData &counts) { assert(m_db.get()); assert(m_hash.get()); if (m_cursor == 0) { if (m_db->nextWord(word, counts)) { return true; } m_cursor = 1; } if (m_cursor == 1) { if (m_hash->nextWord(word, counts)) { return true; } m_cursor = 2; } return false; } string FrequencyDBImpl_split::getDatabaseType() const { return "BerkeleyDB-Hashed"; } void FrequencyDBImpl_split::sweepOutOldTerms(const CleanupManager &cleanman) { assert(m_db.get()); assert(m_hash.get()); m_db->sweepOutOldTerms(cleanman); m_hash->sweepOutOldTerms(cleanman); } bool FrequencyDBImpl_split::canCacheTerm(const string &word) { return (word.length() == 0) || (word[0] == '_' && word != FrequencyDB::COUNT_WORD); } #endif // USE_DBM spamprobe-1.4d/src/database/FrequencyDBImpl_hash.cc0000664000076400007640000002277510527261700017320 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_hash.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifdef USE_MMAP #include #include #include #include #include #include #include "hash.h" #include "CleanupManager.h" #include "DatabaseConfig.h" #include "LockFD.h" #include "WordData.h" #include "FrequencyDBImpl_hash.h" const char *FrequencyDBImpl_hash::SEARCH_SUFFIX("hash"); static const string TEMP_SUFFIX("rehash"); static const string RENAME_SUFFIX("bak"); enum { INDEX_OFFSET = 5, FILE_TYPE_INDEX = 0, COUNT_INDEX = 1, DEBUG_HASH = 0, HASH32_FILE_KEY = 0x0bcc0001, }; HashDataFile::ulong_t hash_string(const string &str) { return jenkins_hash((ub1*)str.c_str(), (ub4)str.length(), 0); } FrequencyDBImpl *FrequencyDBImpl_hash::factory(const DatabaseConfig *config) { return new FrequencyDBImpl_hash(config->targetSizeMB()); } FrequencyDBImpl_hash::FrequencyDBImpl_hash(int _size) : m_cursor(0), m_dataFile(INDEX_OFFSET, _size * 1024 * 1024) { #ifdef USE_HASH_AUTO_CLEAN Ptr cleaner(new CleanupManager); cleaner->addLimit(2, 14); cleaner->addLimit(100, 30); cleaner->addLimit(10000, 180); cleaner->addLimit(100000, 360); m_dataFile.setAutoClean(cleaner.release()); #endif } FrequencyDBImpl_hash::~FrequencyDBImpl_hash() { close(); } bool FrequencyDBImpl_hash::open(const string &arg_filename, bool read_only, int create_mode) { close(); if (is_debug) { cerr << "OPEN DATABASE " << arg_filename << endl; } File db_file(arg_filename); db_file.setSuffix(SEARCH_SUFFIX); if (!m_dataFile.open(db_file.getPath(), read_only, create_mode)) { return false; } if (m_dataFile.isNewFile()) { initializeHeaderRecords(); } else if (!validateHeaderRecords()) { m_dataFile.close(); cerr << "ERROR: Unexpected header record" << endl; return false; } if (is_debug) { cerr << "DATABASE OPENED " << db_file.getPath() << endl; } return true; } void FrequencyDBImpl_hash::initializeHeaderRecords() { HashDataFile::ulong_t key = HASH32_FILE_KEY; WordData word_data; word_data.reset(HASH32_FILE_KEY, 0, 0); m_dataFile.writeRecord(FILE_TYPE_INDEX, key, word_data); } bool FrequencyDBImpl_hash::validateHeaderRecords() { HashDataFile::ulong_t key = 0; WordData word_data; m_dataFile.readRecord(FILE_TYPE_INDEX, key, word_data); return key == HASH32_FILE_KEY; } void FrequencyDBImpl_hash::close() { m_cursor = 0; m_dataFile.close(); } void FrequencyDBImpl_hash::flush() { } void FrequencyDBImpl_hash::writeWord(const string &word, const WordData &counts) { assert(m_dataFile.isOpen()); if (word == FrequencyDB::COUNT_WORD) { m_dataFile.writeRecord(COUNT_INDEX, 0, counts); } else { HashDataFile::ulong_t key = computeKeyForWord(word); if (!m_dataFile.write(key, counts)) { throw runtime_error(string("no room in hash file for term ") + word); } } if (is_debug) { cerr << "wrote word " << word << " good " << counts.goodCount() << " spam " << counts.spamCount() << " total " << counts.totalCount() << endl; } } bool FrequencyDBImpl_hash::readWord(const string &word, WordData &counts) { assert(m_dataFile.isOpen()); bool answer = false; if (word == FrequencyDB::COUNT_WORD) { HashDataFile::ulong_t ignored; m_dataFile.readRecord(COUNT_INDEX, ignored, counts); answer = true; } else { HashDataFile::ulong_t key = computeKeyForWord(word); answer = m_dataFile.read(key, counts); } if (is_debug) { cerr << "read word " << word << " found? " << (answer ? "yes" : "no") << " good " << counts.goodCount() << " spam " << counts.spamCount() << " total " << counts.totalCount() << endl; } return answer; } string FrequencyDBImpl_hash::getWordForIndex(int index, HashDataFile::ulong_t key) { if (index == COUNT_INDEX) { return FrequencyDB::COUNT_WORD; } else { char buffer[128]; sprintf(buffer, "I0x%08x", key); return buffer; } } HashDataFile::ulong_t FrequencyDBImpl_hash::computeKeyForWord(const string &word) { HashDataFile::ulong_t key = 0; if (word == FrequencyDB::COUNT_WORD) { // key not used for count } else if (starts_with(word, "I0x")) { sscanf(word.c_str() + 3, "%x", &key); } else { key = hash_string(word); } if (DEBUG_HASH && is_debug) { cerr << " KEY 0x" << hex << key << " WORD " << word << endl; } return key; } bool FrequencyDBImpl_hash::firstWord(string &word, WordData &counts) { assert(m_dataFile.isOpen()); HashDataFile::ulong_t key = 0; word = FrequencyDB::COUNT_WORD; m_dataFile.readRecord(COUNT_INDEX, key, counts); m_cursor = INDEX_OFFSET; return true; } bool FrequencyDBImpl_hash::nextWord(string &word, WordData &counts) { assert(m_dataFile.isOpen()); HashDataFile::ulong_t key = 0; for (; m_cursor < m_dataFile.indexLimit(); ++m_cursor) { m_dataFile.readRecord(m_cursor, key, counts); if (counts.totalCount() > 0) { word = getWordForIndex(m_cursor, key); ++m_cursor; return true; } } return false; } string FrequencyDBImpl_hash::getDatabaseType() const { return "Hashed-array"; } void FrequencyDBImpl_hash::sweepOutOldTerms(const CleanupManager &cleanman) { assert(m_dataFile.isOpen()); assert(!m_dataFile.isReadOnly()); File live_file(m_dataFile.filename()); File rehash_file(live_file); rehash_file.setSuffix(TEMP_SUFFIX); File temp_file(live_file); temp_file.setSuffix(RENAME_SUFFIX); copyToNewDataFile(cleanman, rehash_file.getPath()); swapDataFilesAndReopen(live_file.getPath(), rehash_file.getPath(), temp_file.getPath()); assert(m_dataFile.isOpen()); } void FrequencyDBImpl_hash::copyToNewDataFile(const CleanupManager &cleanman, const string &rehash_filename) { assert(m_dataFile.isOpen()); File rehash_file(rehash_filename); if (rehash_file.isFile()) { if (is_debug) { cerr << "sweepOutJunk: removing existing rehash file " << rehash_filename << endl; } rehash_file.remove(); } HashDataFile temp_file(INDEX_OFFSET, m_dataFile.size()); temp_file.open(rehash_filename, false, m_dataFile.createMode()); m_dataFile.copyHeadersToFile(temp_file); HashDataFile::ulong_t key; WordData counts; // now copy all non-empty keys with acceptable junk_count and max_age for (HashDataFile::ulong_t i = INDEX_OFFSET; i < m_dataFile.indexLimit(); ++i) { m_dataFile.readRecord(i, key, counts); if (key != 0) { if (counts.totalCount() == 0 || cleanman.shouldDelete(counts)) { if (is_debug) { cerr << "sweepOutJunk: removing term " << getWordForIndex(i, key) << " with total count " << counts.totalCount() << " and age " << counts.age() << endl; } } else { temp_file.write(key, counts); } } } temp_file.close(); } void FrequencyDBImpl_hash::swapDataFilesAndReopen(const string &live_filename, const string &rehash_filename, const string &temp_filename) { assert(m_dataFile.isOpen()); bool read_only = m_dataFile.isReadOnly(); int create_mode = m_dataFile.createMode(); m_dataFile.close(); if (is_debug) { cerr << "renaming " << live_filename << " to " << temp_filename << endl; } File renamer; renamer.setPath(live_filename); renamer.rename(temp_filename); try { if (is_debug) { cerr << "renaming " << rehash_filename << " to " << live_filename << endl; } renamer.setPath(rehash_filename); renamer.rename(live_filename); } catch (...) { if (is_debug) { cerr << "recovery: renaming " << temp_filename << " to " << live_filename << endl; } renamer.setPath(temp_filename); renamer.rename(live_filename); throw; } if (is_debug) { cerr << "opening new hash file" << endl; } if (!m_dataFile.open(live_filename, read_only, create_mode)) { throw runtime_error("unable to open new file"); } if (is_debug) { cerr << "deleting original hash file " << temp_filename << endl; } renamer.setPath(temp_filename); renamer.remove(); assert(m_dataFile.isOpen()); } #endif // USE_MMAP spamprobe-1.4d/src/database/FrequencyDB.cc0000664000076400007640000002336710527261700015471 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDB.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include "DatabaseConfig.h" #include "File.h" #include "InterruptedException.h" #include "WordData.h" #include "DatabaseConfig.h" #include "FrequencyDBImpl.h" #include "FrequencyDBImpl_null.h" #include "FrequencyDB.h" /// defined here to avoid having an otherwise empty WordData.cc file - yeah I know unsigned long WordData::s_today = 0; static const string DIGEST_PREFIX("__MD5__"); const string FrequencyDB::COUNT_WORD("__COUNT__"); const int FrequencyDBImpl::SHARED_DB_MODE = 0666; const int FrequencyDBImpl::PRIVATE_DB_MODE = 0600; class InterruptTest { public: InterruptTest(FrequencyDB *db) : m_db(db) { m_db->setBusy(true); } ~InterruptTest() { m_db->setBusy(false); m_db->throwOnInterrupt(); } private: FrequencyDB *m_db; }; FrequencyDB::FrequencyDB(const DatabaseConfig *config) : m_config(config), m_isInterrupted(false), m_isBusy(false), m_db(new FrequencyDBImpl_null) { } FrequencyDB::~FrequencyDB() { close(); } bool FrequencyDB::requestInterrupt() { if (m_isInterrupted || !m_isBusy) { return true; } m_isInterrupted = true; cerr << "INTERRUPT SCHEDULED: TRY AGAIN AFTER SEVERAL SECONDS IF SHUTDOWN FAILS" << endl; return false; } void FrequencyDB::throwOnInterrupt() { if (m_isInterrupted) { m_isInterrupted = false; throw InterruptedException(); } } bool FrequencyDB::open(bool read_only) { close(); WordData::setTodayDate(); m_db.set(m_config->createDatabaseImpl(read_only)); if (m_db.isNull()) { m_db.set(new FrequencyDBImpl_null); return false; } else { return true; } } void FrequencyDB::close() { // don't want to cause a loop in the int_test destructor m_isInterrupted = false; InterruptTest int_test(this); m_db.set(new FrequencyDBImpl_null); } void FrequencyDB::flush() { assert(m_db.get()); InterruptTest int_test(this); m_db->flush(); } void FrequencyDB::beginTransaction() { assert(m_db.get()); InterruptTest int_test(this); m_db->beginTransaction(); } void FrequencyDB::endTransaction(bool commit) { assert(m_db.get()); InterruptTest int_test(this); m_db->endTransaction(commit); } void FrequencyDB::setWordCounts(const string &word, int good_count, int spam_count) { assert(m_db.get()); assert(good_count >= 0 && spam_count >= 0); WordData counts(good_count, spam_count); counts.adjustDate(); InterruptTest int_test(this); m_db->writeWord(word, counts); } void FrequencyDB::touchWord(const string &word) { assert(m_db.get()); InterruptTest int_test(this); WordData counts; if (m_db->readWord(word, counts)) { counts.adjustDate(); m_db->writeWord(word, counts); } } void FrequencyDB::addWord(const string &word, int good_count, int spam_count) { assert(m_db.get()); InterruptTest int_test(this); WordData counts; m_db->readWord(word, counts); counts.adjustGoodCount(good_count); counts.adjustSpamCount(spam_count); counts.adjustDate(); m_db->writeWord(word, counts); } void FrequencyDB::addWord(const string &word, int good_count, int spam_count, unsigned long flags) { assert(m_db.get()); InterruptTest int_test(this); WordData counts; bool exists = m_db->readWord(word, counts); counts.adjustGoodCount(good_count); counts.adjustSpamCount(spam_count); if (exists) { counts.adjustDate(); } else { counts.setFlags(flags); } m_db->writeWord(word, counts); } bool FrequencyDB::readWord(const string &word, WordData &counts) { assert(m_db.get()); InterruptTest int_test(this); return m_db->readWord(word, counts); } void FrequencyDB::removeWord(const string &word, int good_count, int spam_count) { assert(m_db.get()); InterruptTest int_test(this); addWord(word, -good_count, -spam_count); } void FrequencyDB::getWordCounts(const string &word, int &good_count, int &spam_count) { WordData counts; readWord(word, counts); good_count = counts.goodCount(); spam_count = counts.spamCount(); } void FrequencyDB::getMessageCounts(int &good_message_count, int &spam_message_count) { getWordCounts(COUNT_WORD, good_message_count, spam_message_count); } int FrequencyDB::getTotalMessageCount() { InterruptTest int_test(this); int good_message_count, spam_message_count; getWordCounts(COUNT_WORD, good_message_count, spam_message_count); return good_message_count + spam_message_count; } int FrequencyDB::getMessageCount(const Message &msg, bool &is_spam) { assert(m_db.get()); InterruptTest int_test(this); WordData counts; if (!m_db->readWord(DIGEST_PREFIX + msg.getDigest(), counts)) { is_spam = false; return 0; } assert(counts.goodCount() >= 0 && counts.spamCount() >= 0); assert(!(counts.goodCount() > 0 && counts.spamCount() > 0)); is_spam = (counts.spamCount() > 0); return is_spam ? counts.spamCount() : counts.goodCount(); } bool FrequencyDB::containsMessage(const Message &msg, bool &is_spam) { return getMessageCount(msg, is_spam) > 0; } void FrequencyDB::adjustWordCounts(const string &word, int delta, bool is_spam) { assert(m_db.get()); if (is_spam) { addWord(word, 0, delta); } else { addWord(word, delta, 0); } } void FrequencyDB::touchMessage(const Message &msg) { assert(m_db.get()); assert(msg.getDigest().length() > 0); for (int i = 0; i < msg.getTokenCount(); ++i) { const Token *tok = msg.getToken(i); touchWord(tok->getWord()); } if (is_debug) { string msg_id; cerr << "Updated terms from message " << msg.getID(msg_id) << "/" << msg.getDigest() << " in database" << endl; } } void FrequencyDB::addMessage(const Message &msg, bool new_is_spam, bool force_update) { assert(m_db.get()); assert(msg.getDigest().length() > 0); bool already_is_spam = false; bool already_exists = containsMessage(msg, already_is_spam); assert(!already_exists || (!new_is_spam == !already_is_spam)); if (already_exists) { assert(!already_is_spam == !new_is_spam); if (!force_update) { // message already counted, do nothing return; } // force_update causes us to pretend it doesn't already exist so // we wind up adding its terms again even though they are already counted } for (int i = 0; i < msg.getTokenCount(); ++i) { const Token *tok = msg.getToken(i); adjustWordCounts(tok->getWord(), tok->getCount(), new_is_spam); } adjustWordCounts(DIGEST_PREFIX + msg.getDigest(), 1, new_is_spam); if (!already_exists) { adjustWordCounts(COUNT_WORD, 1, new_is_spam); } if (is_debug) { string msg_id; cerr << "Updated message " << msg.getID(msg_id) << "/" << msg.getDigest() << " in database as " << (new_is_spam ? "spam." : "good.") << endl; } } void FrequencyDB::removeMessage(const Message &msg) { assert(m_db.get()); assert(msg.getDigest().length() > 0); bool is_spam = false; int message_count = getMessageCount(msg, is_spam); if (message_count == 0) { // not in database return; } for (int i = 0; i < msg.getTokenCount(); ++i) { const Token *tok = msg.getToken(i); adjustWordCounts(tok->getWord(), -message_count * tok->getCount(), is_spam); } adjustWordCounts(DIGEST_PREFIX + msg.getDigest(), -message_count, is_spam); adjustWordCounts(COUNT_WORD, -1, is_spam); assert(getMessageCount(msg, is_spam) == 0); if (is_debug) { string msg_id; cerr << "Removed message " << msg.getID(msg_id) << "/" << msg.getDigest() << " from database." << endl; } } bool FrequencyDB::firstWord(string &word, WordData &counts) { assert(m_db.get()); InterruptTest int_test(this); return m_db->firstWord(word, counts); } bool FrequencyDB::nextWord(string &word, WordData &counts) { assert(m_db.get()); InterruptTest int_test(this); return m_db->nextWord(word, counts); } string FrequencyDB::getDatabaseType() { InterruptTest int_test(this); return m_db.get() ? m_db->getDatabaseType() : "unknown"; } void FrequencyDB::sweepOutOldTerms(const CleanupManager &cleanman) { assert(m_db.get()); InterruptTest int_test(this); return m_db->sweepOutOldTerms(cleanman); } spamprobe-1.4d/src/database/FrequencyDBImpl_dbm.cc0000664000076400007640000000736110527261700017131 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_dbm.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifdef USE_DBM #include #include #include "LockFile.h" #include "WordData.h" #include "FrequencyDBImpl_dbm.h" static const string LOCK_FILENAME("lock"); FrequencyDBImpl *FrequencyDBImpl_dbm::factory() { return new FrequencyDBImpl_dbm(); } FrequencyDBImpl_dbm::FrequencyDBImpl_dbm() : m_file(0) { } FrequencyDBImpl_dbm::~FrequencyDBImpl_dbm() { close(); } bool FrequencyDBImpl_dbm::open(const string &filename, bool read_only) { close(); int flags; if (read_only) { flags = O_RDONLY; } else { flags = O_RDWR | O_CREAT; } m_file = dbm_open(filename.c_str(), flags, 0600); return m_file != 0; } void FrequencyDBImpl_dbm::close() { if (m_file) { dbm_close(m_file); m_file = 0; } m_lock.clear(); } void FrequencyDBImpl_dbm::flush() { } void FrequencyDBImpl_dbm::writeWord(const string &word, const WordData &counts) { assert(m_file); datum key; key.dptr = (char *)word.c_str(); key.dsize = word.length() + 1; datum value; value.dptr = (char *)&counts; value.dsize = sizeof(counts); dbm_store(m_file, key, value, DBM_REPLACE); } bool FrequencyDBImpl_dbm::readWord(const string &word, WordData &counts) { assert(m_file); datum key; key.dptr = (char *)word.c_str(); key.dsize = word.length() + 1; return loadKey(key, counts); } bool FrequencyDBImpl_dbm::firstWord(string &word, WordData &counts) { datum key = dbm_firstkey(m_file); return loadKey(key, word, counts); } bool FrequencyDBImpl_dbm::nextWord(string &word, WordData &counts) { datum key = dbm_nextkey(m_file); return loadKey(key, word, counts); } bool FrequencyDBImpl_dbm::loadKey(const datum &key, string &word, WordData &counts) const { if (key.dptr == NULL) { word.erase(); counts.clear(); return false; } word.assign(key.dptr, max(0, key.dsize - 1)); return loadKey(key, counts); } bool FrequencyDBImpl_dbm::loadKey(const datum &key, WordData &counts) const { if (key.dptr == NULL) { counts.clear(); return false; } datum value = dbm_fetch(m_file, key); if (!value.dptr || value.dsize != sizeof(WordData)) { counts.clear(); return false; } counts = *((WordData *)value.dptr); return true; } string FrequencyDBImpl_dbm::getDatabaseType() const { return "DBM-hash"; } void FrequencyDBImpl_dbm::sweepOutJunk(const CleanupManager &cleanman) { } #endif // USE_DBM spamprobe-1.4d/src/database/Message.cc0000664000076400007640000000721710527261700014702 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Message.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MessageHeaderList.h" #include "Message.h" typedef vector::size_type vtokindex_t; typedef vector::const_iterator vtokiter_t; typedef map::const_iterator mtokiter_t; enum { RESERVE_TOKENS_SIZE = 1000 }; Message::Message() { m_tokensByIndex.reserve(RESERVE_TOKENS_SIZE); m_tokensInOrder.reserve(RESERVE_TOKENS_SIZE); m_topTokens.reserve(RESERVE_TOKENS_SIZE); } Message::~Message() { clear(); } void Message::clear() { for (mtokiter_t i = m_tokensByName.begin(); i != m_tokensByName.end(); ++i) { delete i->second; } m_id.erase(); m_tokensByIndex.clear(); m_tokensByName.clear(); m_tokensInOrder.clear(); } int Message::getAllTokensCount() const { int total = 0; for (vtokiter_t i = m_tokensByIndex.begin(); i != m_tokensByIndex.end(); ++i) { total += (*i)->getCount(); } return total; } Token *Message::getToken(int index) const { assert(index >= 0); assert((vtokindex_t)index < m_tokensByIndex.size()); return m_tokensByIndex[index]; } Token *Message::getInOrderToken(int index) const { assert(index >= 0); assert((vtokindex_t)index < m_tokensInOrder.size()); return m_tokensInOrder[index]; } Token *Message::getToken(const string &word) const { assert(m_tokensByName.size() == m_tokensByIndex.size()); mtokiter_t i = m_tokensByName.find(word); return (i != m_tokensByName.end()) ? i->second : 0; } void Message::addToken(const string &word, const string &prefix, int flags) { assert(word.length() > 0); if (prefix.length() > 0) { addToken(prefix + word, flags); } else { addToken(word, flags); } } void Message::addToken(const string &word, int flags) { assert(word.length() > 0); Token *tok = getToken(word); if (tok) { tok->incrementCount(); m_tokensInOrder.push_back(tok); } else if (m_maxTokenCount <= 0 || m_tokensByName.size() < m_maxTokenCount) { tok = new Token(word, flags); m_tokensByIndex.push_back(tok); m_tokensByName.insert(make_pair(word, tok)); m_tokensInOrder.push_back(tok); } if (is_debug) { cerr << "ADD TOKEN " << word << endl; } } Token *Message::getTopToken(int i) { assert(i >= 0); assert(i < (int)m_topTokens.size()); return m_topTokens[i]; } const string &Message::getHeader(const string &name, string &buffer) const { if (m_source.isNull()) { buffer = EMPTY_STRING; return buffer; } return m_source->head()->getHeaderString(name, EMPTY_STRING, buffer); } spamprobe-1.4d/src/database/FrequencyDBImpl_split.h0000664000076400007640000000463510527261700017365 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_split.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_split_h #define _FrequencyDBImpl_split_h #ifdef USE_MMAP #include "FrequencyDBImpl.h" class FrequencyDBImpl_split : public FrequencyDBImpl { public: FrequencyDBImpl_split(const DatabaseConfig *config); ~FrequencyDBImpl_split(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void beginTransaction(); void endTransaction(bool commit); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); bool canCacheTerm(const string &word); static FrequencyDBImpl *factory(const DatabaseConfig *); private: /// Not implemented. FrequencyDBImpl_split(const FrequencyDBImpl_split &); /// Not implemented. FrequencyDBImpl_split& operator=(const FrequencyDBImpl_split &); private: const DatabaseConfig *m_config; int m_cursor; Ptr m_db; Ptr m_hash; }; #endif // USE_MMAP #endif // _FrequencyDBImpl_split_h spamprobe-1.4d/src/database/DatabaseConfig.cc0000664000076400007640000001364410527261700016151 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: DatabaseConfig.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "File.h" #include "WordData.h" #include "FrequencyDBImpl.h" #include "FrequencyDBImpl_split.h" #include "FrequencyDBImpl_hash.h" #include "FrequencyDBImpl_cache.h" #include "FrequencyDBImpl_dual.h" #include "FrequencyDBImpl_dbm.h" #include "FrequencyDBImpl_bdb.h" #include "FrequencyDBImpl_pbl.h" #include "FrequencyDBImpl_null.h" #include "DatabaseConfig.h" struct DBType { const string prefix; const char *suffix; FrequencyDBImplFactory factory; }; static DBType DBTYPES[] = { #ifdef USE_MMAP { "split", 0, FrequencyDBImpl_split::factory }, { "hash", FrequencyDBImpl_hash::SEARCH_SUFFIX, FrequencyDBImpl_hash::factory }, #endif #ifdef USE_PBL { "pbl", FrequencyDBImpl_pbl::SEARCH_SUFFIX, FrequencyDBImpl_pbl::factory }, #endif #ifdef USE_DB { "bdb", 0, FrequencyDBImpl_bdb::factory }, #endif #ifdef USE_DBM { "gdbm", 0, FrequencyDBImpl_dbm::factory }, #endif #ifdef USE_PBL { "", FrequencyDBImpl_pbl::SEARCH_SUFFIX, FrequencyDBImpl_pbl::factory }, #endif #ifdef USE_DB { "", 0, FrequencyDBImpl_bdb::factory }, #endif #ifdef USE_DBM { "", 0, FrequencyDBImpl_dbm::factory }, #endif #ifdef USE_MMAP { "", FrequencyDBImpl_hash::SEARCH_SUFFIX, FrequencyDBImpl_hash::factory }, #endif { "", 0 } }; DatabaseConfig::DatabaseConfig() : m_targetSizeMB(32), m_maxCacheTerms(15000) { File basedir(File::getHomeDir(), ".spamprobe"); File sp_dir(basedir, "sp_words"); m_privateFilename = sp_dir.getPath(); } DatabaseConfig::~DatabaseConfig() { } void DatabaseConfig::parseCommandLineArg(string &arg, string &database_type, int &target_size_mb) { database_type = ""; target_size_mb = m_targetSizeMB; string::size_type first_colon = arg.find(":"); if (first_colon == string::npos) { return; } database_type = arg.substr(0, first_colon); string::size_type last_colon = arg.find(":", first_colon + 1); if (last_colon == string::npos) { arg.erase(0, first_colon + 1); } else { target_size_mb = atoi(arg.substr(first_colon + 1, last_colon - first_colon - 1).c_str()); arg.erase(0, last_colon + 1); } } OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImpl(bool read_only) const { string private_filename(m_privateFilename); Ptr private_db(createDatabaseImplUsingBestFit(m_databaseType, private_filename)); Ptr db; if (m_sharedFilename.length() == 0) { db.set(private_db.release()); } else { string shared_filename(m_sharedFilename); Ptr shared_db(createDatabaseImplUsingBestFit("", shared_filename)); db.set(new FrequencyDBImpl_dual(shared_db.release(), private_db.release(), shared_filename)); } if (m_maxCacheTerms > 0) { db.set(new FrequencyDBImpl_cache(db.release(), m_maxCacheTerms)); } return db->open(private_filename, read_only, FrequencyDBImpl::PRIVATE_DB_MODE) ? db.release() : 0; } OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplUsingBestFit(const string &type, string &filename) const { Ptr db; if (db.isNull() && type.length() > 0) { db.set(createDatabaseImplForType(type, filename)); } if (db.isNull()) { db.set(createDatabaseImplUsingExistingFile(filename)); } if (db.isNull()) { db.set(createDatabaseImplUsingDefaultType(filename)); } if (db.isNull()) { throw runtime_error(string("no database type known for filename: ") + filename); } return db.release(); } OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplForType(const string &type, string &filename) const { File search_file(filename); for (DBType *dbt = DBTYPES; dbt->factory; ++dbt) { if (dbt->prefix == type) { if (dbt->suffix) { search_file.setSuffix(dbt->suffix); } if (is_debug) { cerr << "USING REQUESTED DATABASE TYPE '" << dbt->prefix << "' PATH " << search_file.getPath() << endl; } filename = search_file.getPath(); return (dbt->factory)(this); } } return 0; } OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplUsingDefaultType(string &filename) const { return createDatabaseImplForType("", filename); } OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplUsingExistingFile(string &filename) const { File search_file(filename); for (DBType *dbt = DBTYPES; dbt->factory; ++dbt) { if (dbt->suffix) { search_file.setSuffix(dbt->suffix); if (search_file.isFile()) { if (is_debug) { cerr << "USING DISCOVERED DATABASE TYPE '" << dbt->prefix << "' PATH " << search_file.getPath() << endl; } filename = search_file.getPath(); return (dbt->factory)(this); } } } return 0; } spamprobe-1.4d/src/database/FrequencyDBImpl_cache.cc0000664000076400007640000001255510527261700017433 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_cache.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include "WordData.h" #include "FrequencyDBImpl_cache.h" static const string DATABASE_TYPE("-cached"); FrequencyDBImpl_cache::FrequencyDBImpl_cache(FrequencyDBImpl *db, int max_size) : m_db(db), m_cache(max_size) { assert(db); } FrequencyDBImpl_cache::~FrequencyDBImpl_cache() { close(); } bool FrequencyDBImpl_cache::open(const string &filename, bool read_only, int create_mode) { close(); return m_db->open(filename, read_only, create_mode); } void FrequencyDBImpl_cache::close() { m_db->close(); clear(); } void FrequencyDBImpl_cache::flush() { // PBL performance poor for large transactions on large databases // 100 seems to be a good limit for records per transaction const int MAX_RECORDS_PER_TRANSACTION = 100; int num_writes = 0; m_db->beginTransaction(); for (IteratorType i = m_cache.begin(), limit = m_cache.end(); i != limit; ++i) { if (i.isLocked()) { m_db->writeWord(i.key(), i.value()->counts); m_cache.unlock(i.key()); if (++num_writes >= MAX_RECORDS_PER_TRANSACTION) { m_db->endTransaction(true); m_db->beginTransaction(); num_writes = 0; } } } m_db->endTransaction(true); m_db->flush(); } void FrequencyDBImpl_cache::addWordData(const string &word, bool is_dirty, bool is_shared, const WordData &counts) { m_cache.put(word, make_ref(new CacheEntry(is_shared, counts)), is_dirty); } void FrequencyDBImpl_cache::clear() { m_cache.clear(); } void FrequencyDBImpl_cache::writeWord(const string &word, const WordData &counts) { if (m_cache.lockedCount() >= m_cache.maxSize()) { if (is_debug) { cerr << "MAX CACHE TERMS EXCEEDED - FLUSHING CACHE" << endl; } flush(); } if (!m_db->canCacheTerm(word)) { if (is_debug) { cerr << "UNCACHED TERM " << word << endl; } m_db->writeWord(word, counts); } else { Ref entry; if (!m_cache.get(word, entry)) { addWordData(word, true, false, counts); if (is_debug) { cerr << "CACHED TERM INSERTED " << word << endl; } } else if ((entry->counts).equals(counts)) { if (is_debug) { cerr << "CACHED TERM UNCHANGED " << word << endl; } } else if (entry->is_shared && entry->counts.hasSameCounts(counts)) { // Do nothing because we don't want terms migrating from shared to // private database if only the timestamp changed. if (is_debug) { cerr << "CACHED TERM FROM SHARED " << word << endl; } } else { entry->is_shared = false; entry->counts = counts; m_cache.lock(word); if (is_debug) { cerr << "CACHED TERM UPDATED " << word << endl; } } } if (is_debug) { cerr << "CACHE SIZE LOCKED: " << m_cache.lockedCount() << " TOTAL " << m_cache.size() << " MAX " << m_cache.maxSize() << endl; } } bool FrequencyDBImpl_cache::readWord(const string &word, WordData &counts) { Ref entry; if (m_cache.get(word, entry)) { if (is_debug) { cerr << "READ CACHED TERM " << word << endl; } counts = entry->counts; return true; } bool is_shared = false; if (m_db->readWord(word, counts, is_shared)) { if (m_db->canCacheTerm(word)) { addWordData(word, false, is_shared, counts); if (is_debug) { cerr << "CACHED UNMODIFIED TERM " << word << endl; } } return true; } return false; } bool FrequencyDBImpl_cache::firstWord(string &word, WordData &counts) { flush(); clear(); return m_db->firstWord(word, counts); } bool FrequencyDBImpl_cache::nextWord(string &word, WordData &counts) { return m_db->nextWord(word, counts); } string FrequencyDBImpl_cache::getDatabaseType() const { return m_db->getDatabaseType() + DATABASE_TYPE; } void FrequencyDBImpl_cache::sweepOutOldTerms(const CleanupManager &cleanman) { flush(); clear(); m_db->sweepOutOldTerms(cleanman); } spamprobe-1.4d/src/database/FrequencyDBImpl_null.h0000664000076400007640000000410310527261700017172 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_null.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_null_h #define _FrequencyDBImpl_null_h #include "FrequencyDBImpl.h" class FrequencyDBImpl_null : public FrequencyDBImpl { public: FrequencyDBImpl_null(); ~FrequencyDBImpl_null(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void clear(); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); private: /// Not implemented. FrequencyDBImpl_null(const FrequencyDBImpl_null &); /// Not implemented. FrequencyDBImpl_null& operator=(const FrequencyDBImpl_null &); }; #endif // _FrequencyDBImpl_null_h spamprobe-1.4d/src/database/FrequencyDBImpl.h0000664000076400007640000000501410527261700016142 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_h #define _FrequencyDBImpl_h #include "FrequencyDB.h" class CleanupManager; class DatabaseConfig; class WordData; class FrequencyDBImpl { public: virtual ~FrequencyDBImpl() { } virtual bool open(const string &filename, bool read_only, int create_mode) = 0; virtual void close() = 0; virtual void flush() = 0; virtual void beginTransaction() { } virtual void endTransaction(bool commit) { } virtual void writeWord(const string &word, const WordData &word_data) = 0; virtual bool readWord(const string &word, WordData &word_data) = 0; virtual bool readWord(const string &word, WordData &word_data, bool &is_shared) { is_shared = false; return readWord(word, word_data); } virtual bool firstWord(string &word, WordData &counts) = 0; virtual bool nextWord(string &word, WordData &counts) = 0; virtual string getDatabaseType() const = 0; virtual void sweepOutOldTerms(const CleanupManager &cleanman) = 0; virtual bool canCacheTerm(const string &word) { return true; } static const int SHARED_DB_MODE; static const int PRIVATE_DB_MODE; }; typedef FrequencyDBImpl *(*FrequencyDBImplFactory)(const DatabaseConfig *config); #endif // _FrequencyDBImpl_h spamprobe-1.4d/src/database/Makefile.am0000664000076400007640000000124510526706576015054 00000000000000AUTOMAKE_OPTIONS=foreign INCLUDES= -I@top_srcdir@/src/includes noinst_LIBRARIES=libdatabase.a libdatabase_a_SOURCES=\ CleanupManager.cc\ DatabaseConfig.cc\ FrequencyDB.cc\ FrequencyDBImpl.h\ FrequencyDBImpl_bdb.cc\ FrequencyDBImpl_bdb.h\ FrequencyDBImpl_cache.cc\ FrequencyDBImpl_cache.h\ FrequencyDBImpl_dbm.cc\ FrequencyDBImpl_dbm.h\ FrequencyDBImpl_dual.cc\ FrequencyDBImpl_dual.h\ FrequencyDBImpl_hash.cc\ FrequencyDBImpl_hash.h\ FrequencyDBImpl_null.cc\ FrequencyDBImpl_null.h\ FrequencyDBImpl_pbl.cc\ FrequencyDBImpl_pbl.h\ FrequencyDBImpl_split.cc\ FrequencyDBImpl_split.h\ HashDataFile.cc\ HashDataFile.h\ Message.cc\ WordArray.cc\ WordArray.h spamprobe-1.4d/src/database/FrequencyDBImpl_pbl.h0000664000076400007640000000475610527261700017013 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_pbl.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_pbl_h #define _FrequencyDBImpl_pbl_h #ifdef USE_PBL #include #include "FrequencyDBImpl.h" class File; class LockFile; class FrequencyDBImpl_pbl : public FrequencyDBImpl { public: FrequencyDBImpl_pbl(); ~FrequencyDBImpl_pbl(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void beginTransaction(); void endTransaction(bool commit); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); static FrequencyDBImpl *factory(const DatabaseConfig *); static const char *SEARCH_SUFFIX; private: void quietAbortTransaction(); bool getWord(int pbl_code, string &word, WordData &counts); private: /// Not implemented. FrequencyDBImpl_pbl(const FrequencyDBImpl_pbl &); /// Not implemented. FrequencyDBImpl_pbl& operator=(const FrequencyDBImpl_pbl &); private: pblKeyFile_t *m_kf; bool m_isReadOnly; bool m_inTransaction; }; #endif // USE_PBL #endif // _FrequencyDBImpl_pbl_h spamprobe-1.4d/src/database/FrequencyDBImpl_dual.h0000664000076400007640000000466610527261700017163 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_dual.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDBImpl_dual_h #define _FrequencyDBImpl_dual_h #include "FrequencyDBImpl.h" class FrequencyDBImpl_dual : public FrequencyDBImpl { public: FrequencyDBImpl_dual(FrequencyDBImpl *shared_db, FrequencyDBImpl *private_db, const string &shared_db_filename); ~FrequencyDBImpl_dual(); bool open(const string &filename, bool read_only, int create_mode); void close(); void flush(); void writeWord(const string &word, const WordData &word_data); bool readWord(const string &word, WordData &word_data); bool readWord(const string &word, WordData &word_data, bool &is_shared); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType() const; void sweepOutOldTerms(const CleanupManager &cleanman); bool canCacheTerm(const string &word); private: /// Not implemented. FrequencyDBImpl_dual(const FrequencyDBImpl_dual &); /// Not implemented. FrequencyDBImpl_dual& operator=(const FrequencyDBImpl_dual &); private: Ptr m_sharedDB; Ptr m_privateDB; string m_sharedFilename; }; #endif // _FrequencyDBImpl_dual_h spamprobe-1.4d/src/database/FrequencyDBImpl_bdb.cc0000664000076400007640000002476110527261700017121 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDBImpl_bdb.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifdef USE_DB #include #include #include #include "CleanupManager.h" #include "LockFile.h" #include "WordData.h" #include "FrequencyDBImpl_bdb.h" struct MyDBT : public DBT { MyDBT() { memset(this, 0, sizeof(*this)); } MyDBT(const string &word) { memset(this, 0, sizeof(*this)); size = word.length() + 1; data = (char *)word.c_str(); } MyDBT(const WordData &counts) { memset(this, 0, sizeof(*this)); size = sizeof(WordData); data = (char *)&counts; } }; inline int throw_on_error(const char *function_name, int rc) { if (rc == DB_NOTFOUND) { return rc; } if (rc != 0) { static char buffer[4096]; ostrstream msg(buffer, sizeof(buffer)); msg << function_name << ": " << db_strerror(rc) << " (" << rc << ")" << ends; throw runtime_error(buffer); } return rc; } inline int warn_on_error(const char *function_name, int rc) { if (rc == DB_NOTFOUND) { return rc; } if (rc != 0) { cerr << "warning: berkeley db reported error: " << function_name << ": " << db_strerror(rc) << " (" << rc << ")" << endl; } return rc; } FrequencyDBImpl *FrequencyDBImpl_bdb::factory(const DatabaseConfig *config) { return new FrequencyDBImpl_bdb(); } FrequencyDBImpl_bdb::FrequencyDBImpl_bdb() : m_env(0), m_file(0), m_cursor(0) { } FrequencyDBImpl_bdb::~FrequencyDBImpl_bdb() { close(); } bool FrequencyDBImpl_bdb::open(const string &arg_filename, bool read_only, int create_mode) { close(); m_isReadOnly = read_only; File db_file(arg_filename); if (!openEnvironment(db_file, read_only, create_mode)) { return false; } if (!openDatabase(db_file, read_only, create_mode)) { closeEnvironment(); return false; } if (is_debug) { cerr << "DATABASE OPENED " << db_file.getPath() << endl; } return true; } bool FrequencyDBImpl_bdb::openDatabase(const File &db_file, bool read_only, int create_mode) { if (is_debug) { cerr << "OPENING DATABASE " << db_file.getPath() << endl; } int ret = db_create(&m_file, m_env, 0); if (ret != 0) { cerr << "error: unable to create database " << db_file.getPath() << ": " << db_strerror(ret) << endl; return false; } // SleepyCat in their infinite wisdom decided to change the open // function's signature in the 4.1 release. Gee thanks for breaking // my code guys. That was real smart and so much better than // introducing a second open function rather than force me to embed // hideous ifdefs into my code. string filename(m_env ? db_file.getName() : db_file.getPath()); int flags = read_only ? DB_RDONLY : DB_CREATE; #if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 ret = m_file->open(m_file, NULL, filename.c_str(), NULL, DB_BTREE, flags, create_mode); #else ret = m_file->open(m_file, filename.c_str(), NULL, DB_BTREE, flags, create_mode); #endif if (ret != 0) { cerr << "error: unable to open database " << db_file.getPath() << ": " << db_strerror(ret) << endl; m_file = 0; return false; } if (is_debug) { cerr << "OPENED DATABASE " << db_file.getPath() << endl; } return true; } bool FrequencyDBImpl_bdb::openEnvironment(const File &db_file, bool read_only, int create_mode) { #if USE_CDB File env_dir(db_file.parent()); if (is_debug) { cerr << "OPENING ENVIRONMENT " << env_dir.getPath() << endl; } int ret = db_env_create(&m_env, 0); if (ret != 0) { cerr << "error: unable to create environment " << db_file.getPath() << ": " << db_strerror(ret) << endl; m_env = 0; return false; } int env_flags = DB_INIT_CDB | DB_INIT_MPOOL | DB_CREATE; ret = m_env->open(m_env, db_file.parent().getPath().c_str(), env_flags, create_mode); if (ret != 0) { if (read_only) { // we can still operate without the environment if we're in read-only mode m_env = 0; } else { cerr << "error: unable to open environment " << env_dir.getPath() << ": " << db_strerror(ret) << endl; m_env = 0; return false; } } #else m_env = 0; #endif return true; } void FrequencyDBImpl_bdb::closeCursor() { if (m_cursor) { warn_on_error("c_close", m_cursor->c_close(m_cursor)); m_cursor = 0; } } void FrequencyDBImpl_bdb::closeDatabase() { if (m_file) { warn_on_error("db sync", m_file->sync(m_file, 0)); warn_on_error("db close", m_file->close(m_file, 0)); m_file = 0; } } void FrequencyDBImpl_bdb::closeEnvironment() { #ifdef USE_CDB if (m_env) { warn_on_error("env close", m_env->close(m_env, 0)); m_env = 0; } #endif } void FrequencyDBImpl_bdb::close() { closeCursor(); closeDatabase(); closeEnvironment(); } void FrequencyDBImpl_bdb::flush() { if (is_debug) { cerr << "flushing database..." << endl; } throw_on_error("sync", m_file->sync(m_file, 0)); } void FrequencyDBImpl_bdb::writeWord(const string &word, const WordData &counts) { assert(m_file); MyDBT key(word); bool delete_word = counts.totalCount() <= 0; if (is_debug) { WordData old_counts; bool exists = loadKey(key, old_counts); if (delete_word) { cerr << "writeWord: deleting '" << word << "'" << endl; } else if (exists) { cerr << "writeWord: updating '" << word << "'" << " old (" << old_counts.goodCount() << "," << old_counts.spamCount() << ")" << " new (" << counts.goodCount() << "," << counts.spamCount() << ")" << endl; } else { cerr << "writeWord: inserting '" << word << "'" << " new (" << counts.goodCount() << "," << counts.spamCount() << ")" << endl; } } if (delete_word) { throw_on_error("del", m_file->del(m_file, NULL, &key, 0)); } else { MyDBT value(counts); throw_on_error("put", m_file->put(m_file, NULL, &key, &value, 0)); } } bool FrequencyDBImpl_bdb::readWord(const string &word, WordData &counts) { assert(m_file); MyDBT key(word); return loadKey(key, counts); } bool FrequencyDBImpl_bdb::firstWord(string &word, WordData &counts) { return firstWord(word, counts, true); } bool FrequencyDBImpl_bdb::firstWord(string &word, WordData &counts, bool read_only) { closeCursor(); assert(read_only || !m_isReadOnly); int cursor_flags = 0; #ifdef USE_CDB if (!read_only) { cursor_flags |= DB_WRITECURSOR; } #endif int ret = warn_on_error("cursor", m_file->cursor(m_file, NULL, &m_cursor, cursor_flags)); if (ret != 0) { return false; } assert(m_cursor); return nextWord(word, counts); } bool FrequencyDBImpl_bdb::nextWord(string &word, WordData &counts) { if (!m_cursor) { return false; } MyDBT key; MyDBT value; int ret = warn_on_error("c_get", m_cursor->c_get(m_cursor, &key, &value, DB_NEXT)); if (ret != 0) { word.erase(); counts.clear(); closeCursor(); return false; } if (!value.data || value.size != sizeof(WordData)) { word.erase(); counts.clear(); return false; } word.assign((const char *)key.data, max((u_int32_t)0, key.size - 1)); counts = *((WordData *)value.data); return true; } bool FrequencyDBImpl_bdb::loadKey(DBT &key, string &word, WordData &counts) const { if (key.data == NULL) { word.erase(); counts.clear(); return false; } if (key.size == 0) { word.erase(); } else { word.assign((const char *)key.data, key.size - 1); } return loadKey(key, counts); } bool FrequencyDBImpl_bdb::loadKey(DBT &key, WordData &counts) const { if (key.data == NULL) { counts.clear(); return false; } MyDBT value; int ret = throw_on_error("get", m_file->get(m_file, NULL, &key, &value, 0)); if (ret != 0) { counts.clear(); return false; } if (!value.data || value.size != sizeof(WordData)) { counts.clear(); return false; } counts = *((WordData *)value.data); return true; } string FrequencyDBImpl_bdb::getDatabaseType() const { return "BerkeleyDB-btree"; } void FrequencyDBImpl_bdb::sweepOutOldTerms(const CleanupManager &cleanman) { string word; WordData counts; assert(!m_isReadOnly); bool again = firstWord(word, counts, false); while (again) { bool delete_word = false; if (word.length() >= 3 && word[0] == '_' && word[1] == '_') { if (starts_with(word, "__MD5") && counts.totalCount() == 0) { // go ahead and remove digests that have a count of zero delete_word = true; } else { // ignore special words like __MD5 and __COUNT__ } } else { delete_word = cleanman.shouldDelete(counts); } if (delete_word) { if (is_debug) { cerr << "sweepOutJunk: removing term " << word << " with total count " << counts.totalCount() << " and age " << counts.age() << endl; } warn_on_error("c_del", m_cursor->c_del(m_cursor, 0)); } again = nextWord(word, counts); } flush(); } #endif // USE_DBM spamprobe-1.4d/src/database/Makefile.in0000664000076400007640000003307510527227176015066 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(libdatabase_a_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/database DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libdatabase_a_AR = $(AR) $(ARFLAGS) libdatabase_a_LIBADD = am_libdatabase_a_OBJECTS = CleanupManager.$(OBJEXT) \ DatabaseConfig.$(OBJEXT) FrequencyDB.$(OBJEXT) \ FrequencyDBImpl_bdb.$(OBJEXT) FrequencyDBImpl_cache.$(OBJEXT) \ FrequencyDBImpl_dbm.$(OBJEXT) FrequencyDBImpl_dual.$(OBJEXT) \ FrequencyDBImpl_hash.$(OBJEXT) FrequencyDBImpl_null.$(OBJEXT) \ FrequencyDBImpl_pbl.$(OBJEXT) FrequencyDBImpl_split.$(OBJEXT) \ HashDataFile.$(OBJEXT) Message.$(OBJEXT) WordArray.$(OBJEXT) libdatabase_a_OBJECTS = $(am_libdatabase_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libdatabase_a_SOURCES) DIST_SOURCES = $(libdatabase_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I@top_srcdir@/src/includes noinst_LIBRARIES = libdatabase.a libdatabase_a_SOURCES = \ CleanupManager.cc\ DatabaseConfig.cc\ FrequencyDB.cc\ FrequencyDBImpl.h\ FrequencyDBImpl_bdb.cc\ FrequencyDBImpl_bdb.h\ FrequencyDBImpl_cache.cc\ FrequencyDBImpl_cache.h\ FrequencyDBImpl_dbm.cc\ FrequencyDBImpl_dbm.h\ FrequencyDBImpl_dual.cc\ FrequencyDBImpl_dual.h\ FrequencyDBImpl_hash.cc\ FrequencyDBImpl_hash.h\ FrequencyDBImpl_null.cc\ FrequencyDBImpl_null.h\ FrequencyDBImpl_pbl.cc\ FrequencyDBImpl_pbl.h\ FrequencyDBImpl_split.cc\ FrequencyDBImpl_split.h\ HashDataFile.cc\ HashDataFile.h\ Message.cc\ WordArray.cc\ WordArray.h all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/database/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/database/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libdatabase.a: $(libdatabase_a_OBJECTS) $(libdatabase_a_DEPENDENCIES) -rm -f libdatabase.a $(libdatabase_a_AR) libdatabase.a $(libdatabase_a_OBJECTS) $(libdatabase_a_LIBADD) $(RANLIB) libdatabase.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CleanupManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DatabaseConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDB.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_bdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_dbm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_dual.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_null.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_pbl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrequencyDBImpl_split.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HashDataFile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WordArray.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/hdl/0000777000076400007640000000000010527262440012067 500000000000000spamprobe-1.4d/src/hdl/HdlParser.cc0000664000076400007640000001045010527261700014176 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlParser.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "IstreamCharReader.h" #include "StringReader.h" #include "HdlError.h" #include "HdlToken.h" #include "HdlTokenizer.h" #include "HdlStatement.h" #include "HdlParser.h" const Ref HdlParser::parseString(const string &src) { StringReader reader(src); m_tokenizer = make_ref(new HdlTokenizer("", &reader)); return parse(); } const Ref HdlParser::parseFile(const File &file) { ifstream fin(file.getPath().c_str()); IstreamCharReader reader(&fin); m_tokenizer = make_ref(new HdlTokenizer(file.getPath(), &reader)); return parse(); } const Ref HdlParser::parse() { Ref stmt; Ref id(skipAndEnsureIdentifier()); if (id->isBegin()) { stmt = parseBlock(); } else { stmt = parseStatement(id, false); } m_tokenizer.clear(); return stmt; } const Ref HdlParser::parseBlock() { Ref id(skipAndEnsureIdentifier()); Ref stmt(parseStatement(id, true)); for (;;) { id = skipAndEnsureIdentifier(); if (id->isBegin()) { Ref child(parseBlock()); stmt->addChild(child); } else if (id->isEnd()) { skipAndEnsureSemiColon(); return stmt; } else { Ref child(parseStatement(id, false)); stmt->addChild(child); } } } void HdlParser::skipAndEnsureSemiColon() { if (!m_tokenizer->nextToken()) { throw HdlError("unexpected eof", m_tokenizer->filename(), m_tokenizer->lineNumber()); } if (!m_tokenizer->isSemiColon()) { throw HdlError("expected semi-colon", m_tokenizer->filename(), m_tokenizer->lineNumber()); } } const Ref HdlParser::skipAndEnsureIdentifier() { if (!m_tokenizer->nextToken()) { throw HdlError("unexpected eof", m_tokenizer->filename(), m_tokenizer->lineNumber()); } if (!m_tokenizer->hasToken() || m_tokenizer->token().isNull() || !m_tokenizer->token()->isIdentifier()) { throw HdlError("expected identifier", m_tokenizer->filename(), m_tokenizer->lineNumber()); } return m_tokenizer->takeToken(); } const Ref HdlParser::parseStatement(const Ref &id, bool is_block) { if (id->isBegin() || id->isEnd()) { throw HdlError(string("invalid statement name: ") + id->strValue(), m_tokenizer->filename(), m_tokenizer->lineNumber()); } Ref stmt(new HdlStatement(id, is_block)); parseArgumentsForStatement(stmt); return stmt; } void HdlParser::parseArgumentsForStatement(const Ref &stmt) { for (;;) { if (!m_tokenizer->nextToken()) { throw HdlError("unexpected eof", m_tokenizer->filename(), m_tokenizer->lineNumber()); } if (m_tokenizer->isSemiColon()) { break; } if (!m_tokenizer->hasToken()) { // this probably can't happen but just being safe throw HdlError("token expected", m_tokenizer->filename(), m_tokenizer->lineNumber()); } Ref id(m_tokenizer->takeToken()); if (id->isBegin() || id->isEnd()) { throw HdlError("invalid use of begin/end", m_tokenizer->filename(), m_tokenizer->lineNumber()); } stmt->addArgument(id); } } spamprobe-1.4d/src/hdl/HdlStandardStatementConstraint.cc0000664000076400007640000000755310527261700020446 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlStandardStatementConstraint.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlError.h" #include "HdlToken.h" #include "HdlStatement.h" #include "HdlArgumentConstraint.h" #include "HdlStandardStatementConstraint.h" void HdlStandardStatementConstraint::validateStatement(const HdlStatement *stmt) const { if (stmt->isBlock() != m_isBlock) { throw HdlError(m_isBlock ? "block expected" : "statement expected", stmt->name()); } if (stmt->numArguments() < m_minArgCount) { string msg("expected at least "); msg += num_to_string(m_minArgCount); msg += " arguments but found "; msg += num_to_string(stmt->numArguments()); throw HdlError(msg, stmt->name()); } if (stmt->numArguments() > m_maxArgCount) { string msg("expected at most "); msg += num_to_string(m_maxArgCount); msg += " arguments but found "; msg += num_to_string(stmt->numArguments()); throw HdlError(msg, stmt->name()); } int i = 0; for (; i < m_minArgCount; ++i) { const CRef &constraint = m_arguments[i]; constraint->validateArgument(stmt->argument(i)); } if (stmt->numArguments() > m_minArgCount) { if (m_minArgCount > 0 && m_minArgCount >= m_arguments.size()) { cerr << "m_minArgCount: " << m_minArgCount << endl; cerr << "num_args " << m_arguments.size() << endl; throw HdlError("internal error: insufficient argument definitions", stmt->name()); } for (; i < stmt->numArguments(); ++i) { const CRef &constraint = m_arguments[m_minArgCount]; constraint->validateArgument(stmt->argument(i)); } } if (m_isBlock) { for (i = 0; i < stmt->numChildren(); ++i) { const CRef &child = stmt->child(i); const CRef &constraint = childConstraint(child->name()->strValue()); if (constraint.isNotNull()) { constraint->validateStatement(child); } else { throwInvalidStatement(child->name()); } } } } void HdlStandardStatementConstraint::throwInvalidStatement(const CRef &token) const { string msg("invalid statement, expected"); for (ChildVector::const_iterator i = m_children.begin(); i != m_children.end(); ++i) { const CRef &constraint = *i; msg += " '"; msg += constraint->name(); msg += "'"; } msg += " but found '"; msg += token->strValue(); msg += "'"; throw HdlError(msg, token); } const CRef HdlStandardStatementConstraint::childConstraint(const string &id) const { for (ChildVector::const_iterator i = m_children.begin(); i != m_children.end(); ++i) { const CRef &constraint = *i; if (constraint->name() == id) { return constraint; } } return CRef(); } spamprobe-1.4d/src/hdl/HdlStatementConstraint.h0000664000076400007640000000337410527261700016624 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlStatementConstraint.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlStatementConstraint_h #define _HdlStatementConstraint_h #include "util.h" class HdlStatementConstraint { public: HdlStatementConstraint(const string &name) : m_name(name) { } virtual ~HdlStatementConstraint() { } virtual void validateStatement(const CRef &stmt) const; const string &name() const { return m_name; } private: /// Not implemented. HdlStatementConstraint(const HdlStatementConstraint &); /// Not implemented. HdlStatementConstraint& operator=(const HdlStatementConstraint &); private: string m_name; }; #endif // _HdlStatementConstraint_h spamprobe-1.4d/src/hdl/HdlStatementConstraint.cc0000664000076400007640000000256310527261700016761 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlStatementConstraint.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlError.h" #include "HdlToken.h" #include "HdlStatement.h" #include "HdlArgumentConstraint.h" #include "HdlStatementConstraint.h" void HdlStatementConstraint::validateStatement(const CRef &stmt) const { } spamprobe-1.4d/src/hdl/HdlToken.cc0000664000076400007640000000616310527261700014030 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlToken.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "HdlToken.h" static string IDENTIFIER_NAME("identifier"); static string INTEGER_NAME("integer"); static string DOUBLE_NAME("double"); static string STRING_NAME("string"); HdlToken::HdlToken(TokenType type, const string &str_value, double num_value, const string &filename, int line) : m_type(type), m_string(str_value), m_double(num_value), m_filename(filename), m_line(line) { } bool HdlToken::equals(const CRef &other) const { assert(other.isNotNull()); if (m_type != other->m_type) { return false; } switch (m_type) { case IDENTIFIER: case STRING: return m_string == other->m_string; case DOUBLE: case INTEGER: return m_double == other->m_double; default: throw runtime_error("invalid token type encountered"); } } bool HdlToken::operator==(const HdlToken &other) const { if (m_type != other.m_type) { return false; } switch (m_type) { case IDENTIFIER: case STRING: return m_string == other.m_string; case DOUBLE: case INTEGER: return m_double == other.m_double; default: throw runtime_error("invalid token type encountered"); } } const string &HdlToken::asString(string &answer) const { switch (m_type) { case IDENTIFIER: answer += m_string; break; case STRING: answer += '"'; answer += m_string; answer += '"'; break; case DOUBLE: case INTEGER: answer += num_to_string(m_double); break; default: throw runtime_error("invalid token type encountered"); } return answer; } const string &HdlToken::typeName(TokenType type) { switch (type) { case IDENTIFIER: return IDENTIFIER_NAME; case STRING: return STRING_NAME; case INTEGER: return INTEGER_NAME; case DOUBLE: return DOUBLE_NAME; default: throw runtime_error("invalid token type encountered"); } } const string &HdlToken::typeName() const { return typeName(m_type); } spamprobe-1.4d/src/hdl/HdlRecursiveStatementConstraint.h0000664000076400007640000000373410527261700020514 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlRecursiveStatementConstraint.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlRecursiveStatementConstraint_h #define _HdlRecursiveStatementConstraint_h #include "HdlStatementConstraint.h" class HdlRecursiveStatementConstraint : public HdlStatementConstraint { public: HdlRecursiveStatementConstraint(const HdlStatementConstraint *other) : HdlStatementConstraint(other->name()), m_other(other) { } ~HdlRecursiveStatementConstraint() { } virtual void validateStatement(const CRef &stmt) const { return m_other->validateStatement(stmt); } private: /// Not implemented. HdlRecursiveStatementConstraint(const HdlRecursiveStatementConstraint &); /// Not implemented. HdlRecursiveStatementConstraint& operator=(const HdlRecursiveStatementConstraint &); private: const HdlStatementConstraint *m_other; }; #endif // _HdlRecursiveStatementConstraint_h spamprobe-1.4d/src/hdl/HdlError.cc0000664000076400007640000000264210527261700014037 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlError.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlToken.h" #include "HdlError.h" HdlError::HdlError(const string &msg, const CRef &token) : runtime_error(token->filename() + ": " + num_to_string(token->line()) + ": " + msg), m_filename(token->filename()), m_lineNumber(token->line()) { } spamprobe-1.4d/src/hdl/HdlStatement.cc0000664000076400007640000000407710527261700014716 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlStatement.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlToken.h" #include "HdlStatement.h" HdlStatement::HdlStatement(const Ref &name, bool is_block) : m_name(name), m_isBlock(is_block) { } HdlStatement::~HdlStatement() { } const CRef HdlStatement::child(const CRef &token) const { typedef ChildVector::const_iterator i_iter; for (i_iter i = m_children.begin(); i != m_children.end(); ++i) { const CRef &child = *i; const CRef &child_token = child->name(); if (*child_token == *token) { return child; } } return CRef(); } const CRef HdlStatement::child(const string &name) const { typedef ChildVector::const_iterator i_iter; for (i_iter i = m_children.begin(); i != m_children.end(); ++i) { const CRef &child = *i; if (child->name()->strValue() == name) { return child; } } return CRef(); } spamprobe-1.4d/src/hdl/HdlStandardStatementConstraint.h0000664000076400007640000000525510527261700020305 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlStandardStatementConstraint.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlStandardStatementConstraint_h #define _HdlStandardStatementConstraint_h #include "HdlStatementConstraint.h" class HdlArgumentConstraint; class HdlStandardStatementConstraint : public HdlStatementConstraint { public: HdlStandardStatementConstraint(const string &name, bool is_block) : HdlStatementConstraint(name), m_isBlock(is_block), m_minArgCount(0), m_maxArgCount(0) { } virtual ~HdlStandardStatementConstraint() { } virtual void validateStatement(const HdlStatement *stmt) const; void addArgument(const Ref &arg) { m_arguments.push_back(arg); } void addChild(const Ref &child) { m_children.push_back(child); } void setArgCounts(int min_args, int max_args) { m_minArgCount = min_args; m_maxArgCount = max_args; } private: const CRef childConstraint(const string &id) const; void throwInvalidStatement(const CRef &token) const; private: /// Not implemented. HdlStandardStatementConstraint(const HdlStandardStatementConstraint &); /// Not implemented. HdlStandardStatementConstraint& operator=(const HdlStandardStatementConstraint &); private: typedef vector > ArgVector; typedef vector > ChildVector; bool m_isBlock; int m_minArgCount; int m_maxArgCount; ArgVector m_arguments; ChildVector m_children; }; #endif // _HdlStandardStandardStatementConstraint_h spamprobe-1.4d/src/hdl/HdlTokenizer.cc0000664000076400007640000001212710527261700014717 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlTokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractCharReader.h" #include "HdlError.h" #include "HdlToken.h" #include "HdlTokenizer.h" static const string invalid_char_message(const string base_msg, char ch) { return base_msg + ": '" + ch + "'"; } HdlTokenizer::HdlTokenizer(const string &filename, AbstractCharReader *reader) : m_filename(filename), m_lineNumber(1), m_haveToken(false), m_isSemiColon(false), m_reader(reader) { m_reader->forward(); } HdlTokenizer::~HdlTokenizer() { } bool HdlTokenizer::nextToken() { m_haveToken = false; m_isSemiColon = false; for (;;) { if (m_reader->atEnd()) { return false; } char ch = m_reader->currentChar(); if (ch == ';') { m_haveToken = true; m_isSemiColon = true; m_reader->forward(); return true; } if (is_digit(ch)) { return readNumber(); } if (ch == '"' || ch == '\'') { return readString(ch); } if (is_alpha(ch)) { return readIdentifier(); } if (ch == '#') { skipToEOL(); ch = m_reader->currentChar(); } if (!is_space(ch)) { throw HdlError(invalid_char_message("unexpected character", ch), m_filename, m_lineNumber); } if (ch == '\n') { m_lineNumber += 1; } m_reader->forward(); } } void HdlTokenizer::skipToEOL() { while (m_reader->hasChar() && m_reader->currentChar() != '\n') { m_reader->forward(); } } bool HdlTokenizer::onInvalidInterTokenCharacter() { if (!m_reader->hasChar()) { return false; } char ch = m_reader->currentChar(); if (ch == ';' || is_space(ch)) { return false; } return true; } bool HdlTokenizer::readNumber() { bool have_decimal = false; string digits; while (m_reader->hasChar() && is_digit(m_reader->currentChar())) { digits += m_reader->currentChar(); m_reader->forward(); } if (m_reader->hasChar() && m_reader->currentChar() == '.') { digits += '.'; have_decimal = true; m_reader->forward(); while (m_reader->hasChar() && is_digit(m_reader->currentChar())) { digits += m_reader->currentChar(); m_reader->forward(); } } if (onInvalidInterTokenCharacter()) { throw HdlError(invalid_char_message("invalid character after number", m_reader->currentChar()), m_filename, m_lineNumber); } m_haveToken = true; if (have_decimal) { m_token = HdlToken::doubleToken(atof(digits.c_str()), m_filename, m_lineNumber); } else { m_token = HdlToken::intToken(atoi(digits.c_str()), m_filename, m_lineNumber); } return true; } bool HdlTokenizer::readIdentifier() { string chars; while (m_reader->hasChar() && (is_alnum(m_reader->currentChar()) || m_reader->currentChar() == '_')) { chars += m_reader->currentChar(); m_reader->forward(); } if (onInvalidInterTokenCharacter()) { throw HdlError(invalid_char_message("invalid character after identifier", m_reader->currentChar()), m_filename, m_lineNumber); } m_haveToken = true; m_token = HdlToken::idToken(chars, m_filename, m_lineNumber); return true; } bool HdlTokenizer::readString(char end_quote) { string chars; m_reader->forward(); // skip open quote for (;;) { if (!m_reader->hasChar()) { throw HdlError("unterminated string", m_filename, m_lineNumber); } if (m_reader->currentChar() == end_quote) { break; } chars += m_reader->currentChar(); m_reader->forward(); } m_reader->forward(); // skip past the quote if (onInvalidInterTokenCharacter()) { throw HdlError(invalid_char_message("invalid character after string", m_reader->currentChar()), m_filename, m_lineNumber); } m_haveToken = true; m_token = HdlToken::strToken(chars, m_filename, m_lineNumber); return true; } bool HdlTokenizer::isSemiColon() { return m_haveToken && m_isSemiColon; } const CRef &HdlTokenizer::token() const { return m_token; } const Ref HdlTokenizer::takeToken() { return m_token.transfer(); } spamprobe-1.4d/src/hdl/HdlPrinter.cc0000664000076400007640000001177710527261700014402 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlPrinter.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlToken.h" #include "HdlStatement.h" #include "HdlPrinter.h" HdlPrinter::HdlPrinter() : m_increment(" "), m_depth(0), m_atNewLine(true) { } HdlPrinter::HdlPrinter(const string &indent, const string &increment) : m_indent(indent), m_increment(increment), m_depth(0), m_atNewLine(true) { } HdlPrinter::~HdlPrinter() { } void HdlPrinter::beginBlock(ostream &out) { printIndent(out); out << "begin "; m_depth += 1; } void HdlPrinter::endBlock(ostream &out) { m_depth -= 1; printIndent(out); out << "end;\n"; m_atNewLine = true; } void HdlPrinter::beginStatement(ostream &out, const string &name) { printIndent(out); out << name; } void HdlPrinter::endStatement(ostream &out) { out << ";\n"; m_atNewLine = true; } void HdlPrinter::addArgument(ostream &out, const string &str) { out << ' ' << str; } void HdlPrinter::addID(ostream &out, const string &str) { out << ' ' << str; } void HdlPrinter::addString(ostream &out, const string &str) { if (str.find('"') != string::npos) { out << " '" << str << '\''; } else { out << " \"" << str << '"'; } } void HdlPrinter::addInteger(ostream &out, int value) { out << ' ' << value; } void HdlPrinter::addDouble(ostream &out, double value) { out << ' ' << value; } void HdlPrinter::reset() { m_depth = 0; m_atNewLine = true; } void HdlPrinter::printToken(ostream &out, const CRef &token) { if (token->isInteger()) { addInteger(out, token->intValue()); } else if (token->isIdentifier()) { addID(out, token->strValue()); } else { addString(out, token->strValue()); } } void HdlPrinter::printStatement(ostream &out, const CRef &stmt) { if (stmt->isBlock()) { beginBlock(out); } beginStatement(out, stmt->name()->strValue()); for (int i = 0; i < stmt->numArguments(); ++i) { printToken(out, stmt->argument(i)); } endStatement(out); for (int i = 0; i < stmt->numChildren(); ++i) { printStatement(out, stmt->child(i)); } if (stmt->isBlock()) { endBlock(out); } } void HdlPrinter::printIndent(ostream &out) { if (m_atNewLine) { out << m_indent; for (int i = 0; i < m_depth; ++i) { out << m_increment; } m_atNewLine = false; } } void HdlPrinter::printBoolStatement(ostream &out, const string &name, bool value) { beginStatement(out, name); addID(out, value ? "true" : "false"); endStatement(out); } void HdlPrinter::printIDStatement(ostream &out, const string &name, const string &value) { beginStatement(out, name); addID(out, value); endStatement(out); } void HdlPrinter::printStringStatement(ostream &out, const string &name, const string &value) { beginStatement(out, name); addString(out, value); endStatement(out); } void HdlPrinter::printStringStatement(ostream &out, const string &name, char ch_value) { string value; value += ch_value; printStringStatement(out, name, value); } void HdlPrinter::printIntStatement(ostream &out, const string &name, int value) { beginStatement(out, name); addInteger(out, value); endStatement(out); } void HdlPrinter::printDoubleStatement(ostream &out, const string &name, double value) { beginStatement(out, name); addDouble(out, value); endStatement(out); } spamprobe-1.4d/src/hdl/Makefile.am0000664000076400007640000000110210526706576014047 00000000000000AUTOMAKE_OPTIONS=foreign INCLUDES= -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES=libhdl.a libhdl_a_SOURCES=\ HdlArgumentConstraint.cc\ HdlArgumentConstraint.h\ HdlError.cc\ HdlParser.cc\ HdlPrinter.cc\ HdlStatement.cc\ HdlStatementConstraint.cc\ HdlStatementConstraint.h\ HdlStandardStatementConstraint.cc\ HdlStandardStatementConstraint.h\ HdlRecursiveStatementConstraint.h\ HdlSyntaxChecker.cc\ HdlToken.cc\ HdlTokenizer.cc LDADD = libhdl.a ../input/libinput.a ../utility/libutility.a #noinst_PROGRAMS=testhdl #testhdl_SOURCES=\ # testhdl.cc spamprobe-1.4d/src/hdl/HdlSyntaxChecker.cc0000664000076400007640000002340710527261700015523 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlSyntaxChecker.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlArgumentConstraint.h" #include "HdlError.h" #include "HdlToken.h" #include "HdlStatement.h" #include "HdlRecursiveStatementConstraint.h" #include "HdlStandardStatementConstraint.h" #include "HdlSyntaxChecker.h" static void validate_token_name(const CRef &stmt, const string &name) { if (stmt->name()->strValue() != name) { throw HdlError(string("expected ") + name, stmt->name()); } } HdlSyntaxChecker::HdlSyntaxChecker(const CRef &syntax_tree) { initFromSyntaxTree(syntax_tree); } HdlSyntaxChecker::~HdlSyntaxChecker() { } void HdlSyntaxChecker::checkSyntax(const CRef &stmt) { m_constraint->validateStatement(stmt); } void HdlSyntaxChecker::initFromSyntaxTree(const CRef &stmt) { validate_token_name(stmt, "language"); verifyArgCount(stmt, 1); verifyArgType(stmt, 0, HdlToken::IDENTIFIER); Ref syntax(new HdlStandardStatementConstraint(stmt->argument(0)->strValue(), true)); for (int i = 0; i < stmt->numChildren(); ++i) { const CRef &child = stmt->child(i); string name = child->name()->strValue(); if (name == "statement") { parseStatement(syntax, child); } else if (name == "block") { parseBlock(syntax, child); } else if (name == "unchecked") { parseUnchecked(syntax, child); } else { throw HdlError("expected unchecked, block, or statement", child->name()); } } m_constraint = syntax; } int HdlSyntaxChecker::parseArgs(const Ref &stmt_constraint, const CRef &stmt, int index) { if (stmt->numChildren() < 1) { throw HdlError("expected args statement", stmt->name()); } const CRef &args = stmt->child(0); validate_token_name(args, "args"); if (args->numArguments() < 2) { throw HdlError("expected at least 2 arguments", args->name()); } verifyArgType(args, 0, HdlToken::INTEGER); verifyArgType(args, 1, HdlToken::INTEGER); int min_args = args->argument(0)->intValue(); int max_args = args->argument(1)->intValue(); stmt_constraint->setArgCounts(min_args, max_args); int expected = min_args; if (max_args > min_args) { expected += 1; } if (args->numArguments() < (expected + 2)) { throw HdlError("not enough arguments to args statement", args->name()); } vector > tables; for (int i = 2; expected > 0; ++i) { const CRef &arg = args->argument(i); Ref arg_constraint(new HdlArgumentConstraint); if (arg->strValue() == "string") { arg_constraint->acceptString(); } else if (arg->strValue() == "int") { arg_constraint->acceptInteger(); } else if (arg->strValue() == "double") { arg_constraint->acceptDouble(); } else if (arg->strValue() == "anyid") { arg_constraint->acceptID(); } else if (arg->strValue() == "id") { i += 1; if (i >= args->numArguments()) { throw HdlError("identifier expected after id", args->name()); } verifyArgType(args, i, HdlToken::IDENTIFIER); arg_constraint->acceptID(args->argument(i)); } else if (arg->strValue() == "table") { tables.push_back(arg_constraint); } else { throw HdlError("expected string, int, anyid, id, or table", arg); } stmt_constraint->addArgument(arg_constraint); expected -= 1; } int expected_children = 1 + tables.size(); if (stmt->numChildren() < expected_children) { throw HdlError("insufficient children for specified number of tables", stmt->name()); } for (int i = 1; i < expected_children; ++i) { Ref &table = tables[i - 1]; const CRef &child = stmt->child(i); if (child->name()->strValue() != "table") { throw HdlError("expected table", child->name()); } parseTable(table, child); } return expected_children; } void HdlSyntaxChecker::parseTable(const Ref &table, const CRef &stmt) { int id_index = 0; for (int i = 0; i < stmt->numArguments(); ++i) { const CRef &token = stmt->argument(i); if (token->strValue() == "string") { table->acceptString(); } else if (token->strValue() == "int") { table->acceptInteger(); } else if (token->strValue() == "double") { table->acceptDouble(); } else if (token->strValue() == "anyid") { table->acceptID(); } else if (token->strValue() == "id") { i += 1; if (i >= stmt->numArguments()) { throw HdlError("expected identifier after id", stmt->name()); } verifyArgType(stmt, i, HdlToken::IDENTIFIER); table->acceptID(stmt->argument(i)); } else { throw HdlError("expected string, int, anyid, or id", token); } } } void HdlSyntaxChecker::parseBlock(const Ref &stmt_constraint, const CRef &stmt) { verifyIsBlock(stmt, true); if (stmt->numArguments() == 0) { throw HdlError("at least one argument expected", stmt->name()); } verifyArgType(stmt, 0, HdlToken::IDENTIFIER); Ref block(new HdlStandardStatementConstraint(stmt->argument(0)->strValue(), true)); for (int i = 1; i < stmt->numArguments(); ++i) { const CRef &arg = stmt->argument(i); if (arg->strValue() == "recursive") { block->addChild(Ref(new HdlRecursiveStatementConstraint(block.ptr()))); } else { throw HdlError("unknown flag for block declaration", arg); } } for (int next_child = parseArgs(block, stmt, 0); next_child < stmt->numChildren(); ++next_child) { const CRef &child = stmt->child(next_child); string name = child->name()->strValue(); if (name == "statement") { parseStatement(block, child); } else if (name == "block") { parseBlock(block, child); } else if (name == "unchecked") { parseUnchecked(block, child); } else { throw HdlError("expected unchecked, block, or statement", child->name()); } } stmt_constraint->addChild(block); } void HdlSyntaxChecker::parseStatement(const Ref &stmt_constraint, const CRef &stmt) { verifyIsBlock(stmt, true); verifyArgCount(stmt, 1); verifyArgType(stmt, 0, HdlToken::IDENTIFIER); Ref block(new HdlStandardStatementConstraint(stmt->argument(0)->strValue(), false)); int next_child = parseArgs(block, stmt, 0); if (next_child != stmt->numChildren()) { throw HdlError("statement declarations can only contain arg and table statements", stmt->name()); } stmt_constraint->addChild(block); } void HdlSyntaxChecker::parseUnchecked(const Ref &stmt_constraint, const CRef &stmt) { verifyIsBlock(stmt, false); verifyArgCount(stmt, 1); verifyArgType(stmt, 0, HdlToken::IDENTIFIER); stmt_constraint->addChild(Ref(new HdlStatementConstraint(stmt->argument(0)->strValue()))); } void HdlSyntaxChecker::verifyArgCount(const CRef &stmt, int count) { if (stmt->numArguments() != count) { throw HdlError(string("statement requires ") + num_to_string(count) + " arguments but has " + num_to_string(stmt->numArguments()), stmt->name()); } } void HdlSyntaxChecker::verifyArgEquals(const CRef &stmt, int index, const CRef &token) { if (!stmt->argument(index)->equals(token)) { throw HdlError(string("arg ") + num_to_string(index + 1) + " expected '" + token->strValue() + "'", stmt->argument(index)); } } void HdlSyntaxChecker::verifyArgType(const CRef &stmt, int index, HdlToken::TokenType type) { if (stmt->argument(index)->tokenType() != type) { throw HdlError(string("arg ") + num_to_string(index + 1) + " expected '" + HdlToken::typeName(type) + " found " + stmt->argument(index)->typeName(), stmt->argument(index)); } } void HdlSyntaxChecker::verifyIsBlock(const CRef &stmt, bool is_block) { if (is_block != stmt->isBlock()) { throw HdlError(string("statement must") + (is_block ? " " : " not ") + "be a block", stmt->name()); } } spamprobe-1.4d/src/hdl/HdlArgumentConstraint.h0000664000076400007640000000423510527261700016437 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlArgumentConstraint.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlArgumentConstraint_h #define _HdlArgumentConstraint_h #include #include "util.h" class HdlToken; class HdlArgumentConstraint { public: HdlArgumentConstraint() : m_intOK(false), m_doubleOK(false), m_stringOK(false), m_idOK(false) { } ~HdlArgumentConstraint() { } void acceptID() { m_idOK = true; } void acceptID(const CRef &id); void acceptInteger() { m_intOK = true; } void acceptDouble() { m_intOK = true; m_doubleOK = true; } void acceptString() { m_stringOK = true; } void validateArgument(const CRef &arg) const; private: void throwInvalidArgument(const CRef &arg) const; private: /// Not implemented. HdlArgumentConstraint(const HdlArgumentConstraint &); /// Not implemented. HdlArgumentConstraint& operator=(const HdlArgumentConstraint &); private: bool m_intOK; bool m_doubleOK; bool m_stringOK; bool m_idOK; set m_validIDs; }; #endif // _HdlArgumentConstraint_h spamprobe-1.4d/src/hdl/HdlArgumentConstraint.cc0000664000076400007640000000450010527261700016570 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlArgumentConstraint.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HdlError.h" #include "HdlToken.h" #include "HdlArgumentConstraint.h" void HdlArgumentConstraint::acceptID(const CRef &id) { m_validIDs.insert(id->strValue()); } void HdlArgumentConstraint::validateArgument(const CRef &token) const { if (token->isInteger() && m_intOK) { return; } if (token->isDouble() && m_doubleOK) { return; } if (token->isString() && m_stringOK) { return; } if (token->isIdentifier()) { if (m_idOK || m_validIDs.find(token->strValue()) != m_validIDs.end()) { return; } } throwInvalidArgument(token); } void HdlArgumentConstraint::throwInvalidArgument(const CRef &token) const { string msg("invalid argument, expected"); if (m_intOK) { msg += " integer"; } if (m_doubleOK) { msg += " double"; } if (m_stringOK) { msg += " string"; } if (m_idOK) { msg += " identifier"; } else if (m_validIDs.size() > 0) { if (m_intOK || m_stringOK) { msg += " or one of "; } for (set::const_iterator i = m_validIDs.begin(); i != m_validIDs.end(); ++i) { msg += " '"; msg += *i; msg += "'"; } } throw HdlError(msg, token); } spamprobe-1.4d/src/hdl/Makefile.in0000664000076400007640000003165210527227176014070 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(libhdl_a_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/hdl DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libhdl_a_AR = $(AR) $(ARFLAGS) libhdl_a_LIBADD = am_libhdl_a_OBJECTS = HdlArgumentConstraint.$(OBJEXT) \ HdlError.$(OBJEXT) HdlParser.$(OBJEXT) HdlPrinter.$(OBJEXT) \ HdlStatement.$(OBJEXT) HdlStatementConstraint.$(OBJEXT) \ HdlStandardStatementConstraint.$(OBJEXT) \ HdlSyntaxChecker.$(OBJEXT) HdlToken.$(OBJEXT) \ HdlTokenizer.$(OBJEXT) libhdl_a_OBJECTS = $(am_libhdl_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libhdl_a_SOURCES) DIST_SOURCES = $(libhdl_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES = libhdl.a libhdl_a_SOURCES = \ HdlArgumentConstraint.cc\ HdlArgumentConstraint.h\ HdlError.cc\ HdlParser.cc\ HdlPrinter.cc\ HdlStatement.cc\ HdlStatementConstraint.cc\ HdlStatementConstraint.h\ HdlStandardStatementConstraint.cc\ HdlStandardStatementConstraint.h\ HdlRecursiveStatementConstraint.h\ HdlSyntaxChecker.cc\ HdlToken.cc\ HdlTokenizer.cc LDADD = libhdl.a ../input/libinput.a ../utility/libutility.a all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/hdl/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/hdl/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libhdl.a: $(libhdl_a_OBJECTS) $(libhdl_a_DEPENDENCIES) -rm -f libhdl.a $(libhdl_a_AR) libhdl.a $(libhdl_a_OBJECTS) $(libhdl_a_LIBADD) $(RANLIB) libhdl.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlArgumentConstraint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlError.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlPrinter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlStandardStatementConstraint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlStatement.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlStatementConstraint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlSyntaxChecker.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlToken.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HdlTokenizer.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am #noinst_PROGRAMS=testhdl #testhdl_SOURCES=\ # testhdl.cc # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/includes/0000777000076400007640000000000010527262433013130 500000000000000spamprobe-1.4d/src/includes/MailMessage.h0000664000076400007640000000457210527261700015412 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessage.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MailMessage_h #define _MailMessage_h #include "util.h" #include "Buffer.h" class AbstractMultiLineString; class MessageHeaderList; class MailMessageList; class MailMessage { public: MailMessage(const CRef &full_text); MailMessage(const CRef &head_text, const CRef &body_text, const CRef &full_text); ~MailMessage(); CRef &headText() { return m_headText; } CRef &bodyText() { return m_bodyText; } CRef &fullText() { return m_fullText; } const MessageHeaderList *head(); const MailMessageList *body(); bool isMultiPart(); bool hasParts(); const AbstractMultiLineString *asText(bool &is_html); bool asData(Buffer &buffer); private: bool isMultiPartType(); bool isHtml(const AbstractMultiLineString *text); private: CRef m_headText; CRef m_bodyText; CRef m_fullText; Ref m_head; Ref m_body; CRef m_decodedText; bool m_isHtml; }; #endif spamprobe-1.4d/src/includes/util.h0000664000076400007640000000754510527261701014204 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: util.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _util_h #define _util_h #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include "Ptr.h" #include "Ref.h" using namespace std; #define OWNED extern bool is_debug; extern bool is_verbose; inline unsigned to_8bits(char ch) { return((unsigned)ch) & 0xff; } extern string to_7bits(const string &str); extern string to_lower(const string &str); extern string to_upper(const string &str); extern bool is_lower(const string &str); extern string trim_copy(const string &str, string::size_type start_offset); extern string trim(const string &str); inline bool is_nan(double value) { #ifdef isnan return isnan(value); #else return !(value == value); #endif } inline bool starts_with(const string &str, const char *prefix) { return strncmp(str.c_str(), prefix, strlen(prefix)) == 0; } inline bool starts_with(const string &str, const string &prefix) { return strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0; } inline bool ends_with(const string &str, const string &suffix) { return str.length() >= suffix.length() && strcmp(str.c_str() + str.length() - suffix.length(), suffix.c_str()) == 0; } extern bool is_digits(const string &str); // work around for unsafe ctype functions on solaris inline bool is_lower(char ch) { return islower(to_8bits(ch)); } // work around for unsafe ctype functions on solaris inline bool is_upper(char ch) { return isupper(to_8bits(ch)); } inline bool is_space(char ch) { return isspace(to_8bits(ch)); } inline bool is_alpha(char ch) { return isalpha(to_8bits(ch)); } inline bool is_alnum(char ch) { return isalnum(to_8bits(ch)); } inline bool is_digit(char ch) { return isdigit(to_8bits(ch)); } inline char to_lower(char ch) { return tolower(to_8bits(ch)); } inline char to_upper(char ch) { return toupper(to_8bits(ch)); } inline bool is_cntrl(char ch) { return iscntrl(to_8bits(ch)); } inline bool is_xdigit(char ch) { return isxdigit(to_8bits(ch)); } char hex_digit(unsigned ch); int hex_to_int(char ch); int hex_to_int(const string &s); inline char safe_char(unsigned ch) { ch = (ch & 0xff); if (iscntrl(ch) && !isspace(ch)) { ch = ' '; } return static_cast(ch); } // // Simple escape sequence encoding and decoding of string data. // void encode_string(const string &src, string &dst); void decode_string(const string &src, string &dst); const char *num_to_string(int num); const char *num_to_string(double num); const char *num_to_string3(int num); extern const string EMPTY_STRING; #endif // _util_h spamprobe-1.4d/src/includes/AbstractTokenizer.h0000664000076400007640000000300210527261700016644 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractTokenizer_h #define _AbstractTokenizer_h #include "util.h" class AbstractCharReader; class AbstractTokenReceiver; class AbstractTokenizer { public: virtual ~AbstractTokenizer() { } virtual void tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix) = 0; }; #endif spamprobe-1.4d/src/includes/Token.h0000664000076400007640000000570410527261700014301 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Token.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Token_h #define _Token_h #include "util.h" class Token { public: Token(const string &word, int flags) : m_word(word), m_count(1), m_dbGoodCount(0), m_dbSpamCount(0), m_score(0.0), m_tieBreakCount(0), m_flags(flags) { } ~Token() { } const string &getWord() const { return m_word; } int getCount() const { return m_count; } void incrementCount(int delta = 1) { m_count += delta; } double getScore() const { return m_score; } void setScore(double value) { m_score = value; } double getDistanceFromMean() const { double diff = 0.5 - m_score; return (diff >= 0.0) ? diff : -diff; } int getDBTotalCount() const { return m_dbGoodCount + m_dbSpamCount; } int getDBGoodCount() const { return m_dbGoodCount; } void setDBGoodCount(int value) { m_dbGoodCount = value; } int getDBSpamCount() const { return m_dbSpamCount; } void setDBSpamCount(int value) { m_dbSpamCount = value; } void setSortCount(long value) { m_sortCount = value; } long getSortCount() const { return m_sortCount; } void setTieBreakCount(long value) { m_tieBreakCount = value; } long getTieBreakCount() const { return m_tieBreakCount; } enum { FLAG_NORMAL = 1 << 0, FLAG_DERIVED = 1 << 1, FLAG_PHRASE = 1 << 2, FLAG_ANY = 0xff, }; int getFlags() const { return m_flags; } void setFlags(int value) { m_flags = value; } private: /// Not implemented. Token(const Token &); /// Not implemented. Token& operator=(const Token &); private: string m_word; int m_count; int m_dbGoodCount; int m_dbSpamCount; double m_score; long m_tieBreakCount; long m_sortCount; int m_flags; }; #endif // _Token_h spamprobe-1.4d/src/includes/IstreamCharReader.h0000664000076400007640000000333510527261700016544 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: IstreamCharReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _IstreamCharReader_h #define _IstreamCharReader_h #include #include "AbstractCharReader.h" class IstreamCharReader : public AbstractCharReader { public: IstreamCharReader(istream *stream, bool can_seek = false); virtual ~IstreamCharReader(); virtual bool forward(); virtual bool hasChar(); virtual bool atEnd(); virtual bool skip(int nchars); virtual OWNED AbstractCharReaderPosition *createMark(); virtual void returnToMark(AbstractCharReaderPosition *pos); private: istream *m_stream; streambuf *m_rdbuf; bool m_canSeek; }; #endif spamprobe-1.4d/src/includes/TempPtr.h0000664000076400007640000000344110527260123014606 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _TempPtr_h #define _TempPtr_h #include /** * Manages a temporary pointer to an object. Nulls the pointer in its destructor. * Note that this is not intended for resource management but simply to ensure * that a pointer is cleared once it is no longer needed (to avoid it being reused * accidentally to refer to an already deleted object). */ template class TempPtr { public: TempPtr(T *&ptr, T *value) : m_ptr(ptr) { assert(m_ptr == 0); m_ptr = value; } ~TempPtr() { m_ptr = 0; } private: /// Not implemented. TempPtr(const TempPtr &); /// Not implemented. TempPtr& operator=(const TempPtr &); private: T *&m_ptr; }; #endif // _TempPtr_h spamprobe-1.4d/src/includes/HdlToken.h0000664000076400007640000001070610527261700014727 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlToken.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlToken_h #define _HdlToken_h #include "util.h" class HdlToken { public: typedef enum { STRING = 1, IDENTIFIER, INTEGER, DOUBLE } TokenType; static inline const Ref intToken(int value) { return make_ref(new HdlToken(INTEGER, "", value, "", 0)); } static inline const Ref intToken(int value, const string &filename, int line) { return make_ref(new HdlToken(INTEGER, "", value, filename, line)); } static inline const Ref doubleToken(double value) { return make_ref(new HdlToken(DOUBLE, "", value, "", 0)); } static inline const Ref doubleToken(double value, const string &filename, int line) { return make_ref(new HdlToken(DOUBLE, "", value, filename, line)); } static inline const Ref idToken(const string &value) { return make_ref(new HdlToken(IDENTIFIER, value, 0, "", 0)); } static inline const Ref idToken(const string &value, const string &filename, int line) { return make_ref(new HdlToken(IDENTIFIER, value, 0, filename, line)); } static inline const Ref strToken(const string &value) { return make_ref(new HdlToken(STRING, value, 0, "", 0)); } static inline const Ref strToken(const string &value, const string &filename, int line) { return make_ref(new HdlToken(STRING, value, 0, filename, line)); } TokenType tokenType() const { return m_type; } int intValue() const { return (int)m_double; } double doubleValue() const { return m_double; } const string &strValue() const { return m_string; } const string &filename() const { return m_filename; } int line() const { return m_line; } bool equals(const CRef &other) const; bool operator==(const HdlToken &other) const; const string &asString(string &answer) const; static const string &typeName(TokenType type); const string &typeName() const; bool isDouble() const { return m_type == DOUBLE; } bool isInteger() const { return m_type == INTEGER; } bool isNumber() const { return isDouble() || isInteger(); } bool isIdentifier() const { return m_type == IDENTIFIER; } bool isString() const { return m_type == STRING; } bool isBegin() const { return m_type == IDENTIFIER && m_string == "begin"; } bool isEnd() const { return m_type == IDENTIFIER && m_string == "end"; } bool isTrueValue() const { return (m_type == IDENTIFIER && m_string != "false") || (isNumber() && m_double != 0);; } private: HdlToken(TokenType type, const string &str_value, double num_value, const string &filename, int line); private: /// Not implemented. HdlToken(const HdlToken &); /// Not implemented. HdlToken& operator=(const HdlToken &); private: TokenType m_type; string m_string; double m_double; string m_filename; int m_line; }; #endif // _HdlToken_h spamprobe-1.4d/src/includes/HdlError.h0000664000076400007640000000347010527261700014740 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlError.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlError_h #define _HdlError_h #include #include "util.h" class HdlToken; class HdlError : public runtime_error { public: HdlError(const string &msg, const string &filename, int line_number) : runtime_error(filename + ": " + num_to_string(line_number) + ": " + msg), m_filename(filename), m_lineNumber(line_number) { } HdlError(const string &msg, const CRef &token); virtual ~HdlError() throw() { } const string &filename() const { return m_filename; } int lineNumber() const { return m_lineNumber; } private: string m_filename; int m_lineNumber; }; #endif // _HdlError_h spamprobe-1.4d/src/includes/hash.h0000664000076400007640000000141110527260526014140 00000000000000/* By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this code any way you wish, private, educational, or commercial. It's free. See http://burtleburtle.net/bob/hash/evahash.html Use for hash table lookup, or anything where one collision in 2^^32 is acceptable. Do NOT use for cryptographic purposes. */ #ifndef _jenkinshash_h #define _jenkinshash_h #ifdef __cplusplus extern "C" { #endif typedef unsigned long int ub4; /* unsigned 4-byte quantities */ typedef unsigned char ub1; /* unsigned 1-byte quantities */ #define hashsize(n) ((ub4)1<<(n)) #define hashmask(n) (hashsize(n)-1) ub4 jenkins_hash(const ub1 *k, ub4 length, ub4 initval); #ifdef __cplusplus } #endif #endif // _jenkinshash_h spamprobe-1.4d/src/includes/HdlTokenizer.h0000664000076400007640000000416710527261700015625 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlTokenizer_h #define _HdlTokenizer_h #include "util.h" class AbstractCharReader; class HdlToken; class HdlTokenizer { public: HdlTokenizer(const string &filename, AbstractCharReader *reader); ~HdlTokenizer(); bool nextToken(); bool isSemiColon(); const CRef &token() const; const Ref takeToken(); bool hasToken() const { return m_haveToken; } const string &filename() const { return m_filename; } int lineNumber() const { return m_lineNumber; } private: bool readNumber(); bool readIdentifier(); bool readString(char end_quote); bool onInvalidInterTokenCharacter(); void skipToEOL(); private: /// Not implemented. HdlTokenizer(const HdlTokenizer &); /// Not implemented. HdlTokenizer& operator=(const HdlTokenizer &); private: string m_filename; int m_lineNumber; bool m_haveToken; bool m_isSemiColon; Ref m_token; AbstractCharReader *m_reader; }; #endif // _HdlTokenizer_h spamprobe-1.4d/src/includes/CleanupManager.h0000664000076400007640000000363210527261700016101 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: CleanupManager.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _CleanupManager_h #define _CleanupManager_h #include #include "WordData.h" class CleanupManager { public: CleanupManager(); CleanupManager(int junk_count, int max_age); ~CleanupManager(); void addLimit(int junk_count, int max_age); bool shouldDelete(const WordData &word_data) const; private: /// Not implemented. CleanupManager(const CleanupManager &); /// Not implemented. CleanupManager& operator=(const CleanupManager &); private: struct CleanupNode { CleanupNode(int _junk_count, int _max_age) : junk_count(_junk_count), max_age(_max_age) {} int junk_count; int max_age; }; typedef vector::const_iterator NodeIter_t; vector m_nodes; }; #endif // _CleanupManager_h spamprobe-1.4d/src/includes/Message.h0000664000076400007640000000566710527261700014615 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Message.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Message_h #define _Message_h #include #include #include "Token.h" #include "MailMessage.h" class Message { public: Message(); ~Message(); void clear(); int getTokenCount() const { return m_tokensByName.size(); } int getInOrderTokenCount() const { return m_tokensInOrder.size(); } Token *getInOrderToken(int index) const; int getAllTokensCount() const; Token *getToken(int index) const; Token *getToken(const string &word) const; const string &getID(string &buffer) const { return getHeader("message-id", buffer); } void setDigest(const string &value) { m_digest = value; } string getDigest() const { return m_digest; } void addToken(const string &word, const string &prefix, int flags); void addToken(const string &word, int flags); bool isEmpty() const { return m_tokensByName.size() == 0; } void clearTopTokens() { m_topTokens.clear(); } void addTopToken(Token *tok) { m_topTokens.push_back(tok); } int getTopTokenCount() { return m_topTokens.size(); } Token *getTopToken(int index); void setSource(OWNED MailMessage *source) { m_source.set(source); } void setMaxTokenCount(int value) { m_maxTokenCount = value; } MailMessage *source() { return m_source.get(); } const string &getHeader(const string &name, string &buffer) const; private: /// Not implemented. Message(const Message &); /// Not implemented. Message& operator=(const Message &); private: string m_id; string m_digest; vector m_tokensByIndex; vector m_tokensInOrder; map m_tokensByName; vector m_topTokens; Ptr m_source; int m_maxTokenCount; }; #endif // _Message_h spamprobe-1.4d/src/includes/SimpleTokenizer.h0000664000076400007640000000414310527261700016341 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SimpleTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _SimpleTokenizer_h #define _SimpleTokenizer_h #include "AbstractTokenizer.h" class SimpleTokenizer : public AbstractTokenizer { public: explicit SimpleTokenizer(char non_ascii_char); virtual ~SimpleTokenizer(); virtual void tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix); private: void reset(); bool isLetterChar(char ch); bool isSpecialChar(char ch); char currentChar(AbstractCharReader *reader); void appendChar(string &s, char ch); bool processStart(char ch); bool processWaiting(char ch); bool processInWord(char ch); bool processPending(char ch); bool processCharForState(char ch); void sendToken(const string &prefix, string &token); private: AbstractTokenReceiver *m_receiver; enum { START, WAITING, IN_WORD, PENDING } m_state; string m_token; string m_pending; char m_nonAsciiCharReplacement; }; #endif spamprobe-1.4d/src/includes/Tokenizer.h0000664000076400007640000000322110527261701015164 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Tokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Tokenizer_h #define _Tokenizer_h #include "util.h" class Tokenizer { public: Tokenizer(); ~Tokenizer(); void start(); bool addChar(char ch); bool stop(); const string &getWord() { return m_word; } private: /// Not implemented. Tokenizer(const Tokenizer &); /// Not implemented. Tokenizer& operator=(const Tokenizer &); private: string m_word; string m_pending; enum { STATE_START, STATE_WAITING, STATE_IN_WORD, STATE_PENDING } m_state; }; #endif // _Tokenizer_h spamprobe-1.4d/src/includes/UrlOnlyHtmlTokenizer.h0000664000076400007640000000323210527261701017340 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: UrlOnlyHtmlTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _UrlOnlyHtmlTokenizer_h #define _UrlOnlyHtmlTokenizer_h #include "HtmlTokenizer.h" #include "RegularExpression.h" class UrlOnlyHtmlTokenizer : public HtmlTokenizer { public: UrlOnlyHtmlTokenizer(AbstractTokenizer *textTokenizer, AbstractTokenizer *htmlTokenizer, int maxTagLength, bool keep_suspicious_tags); ~UrlOnlyHtmlTokenizer(); protected: virtual void processTagBody(const string &tag); private: bool m_keepSuspiciousTags; }; #endif spamprobe-1.4d/src/includes/AbstractCharReader.h0000664000076400007640000000361610527261700016705 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractCharReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractCharReader_h #define _AbstractCharReader_h #include "util.h" class AbstractCharReaderPosition { public: virtual ~AbstractCharReaderPosition() { } }; class AbstractCharReader { public: virtual ~AbstractCharReader() {} virtual bool forward() = 0; virtual bool skip(int nchars) = 0; virtual bool hasChar() = 0; virtual bool atEnd() = 0; bool matchChar(char ch) { return forward() && ch == currentChar(); } char currentChar() { return m_currentChar; } virtual OWNED AbstractCharReaderPosition *createMark() { return 0; } virtual void returnToMark(AbstractCharReaderPosition *pos) { } protected: void setCurrentChar(char ch) { m_currentChar = ch; } private: char m_currentChar; }; #endif spamprobe-1.4d/src/includes/AbstractMailMessageParser.h0000664000076400007640000000267210527261700020252 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractMailMessageParser.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractMailMessageParser_h #define _AbstractMailMessageParser_h #include "Message.h" #include "MailMessage.h" class AbstractMailMessageParser { public: virtual ~AbstractMailMessageParser() { } virtual OWNED Message *parseMailMessage(MailMessage *source) = 0; }; #endif spamprobe-1.4d/src/includes/AbstractTokenReceiver.h0000664000076400007640000000274610527261700017455 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractTokenReceiver.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractTokenReceiver_h #define _AbstractTokenReceiver_h #include "util.h" class AbstractTokenReceiver { public: virtual ~AbstractTokenReceiver() { } /// Called by an AbstractTokenizer for each token it produces. virtual void receiveToken(const string &prefix, const string &token) = 0; }; #endif spamprobe-1.4d/src/includes/MultiLineJoinedString.h0000664000076400007640000000320410527261700017434 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MultiLineJoinedString.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MultiLineJoinedString_h #define _MultiLineJoinedString_h #include #include "AbstractMultiLineString.h" typedef vector > MultiLineStringList; class MultiLineJoinedString : public AbstractMultiLineString { public: MultiLineJoinedString(const MultiLineStringList &targets); virtual ~MultiLineJoinedString(); virtual int lineCount() const; virtual const string &line(int index) const; private: MultiLineStringList m_targets; }; #endif spamprobe-1.4d/src/includes/MD5Digester.h0000664000076400007640000000343310527261700015272 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MD5Digester.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MD5Digester_h #define _MD5Digester_h #include "util.h" struct md5_state_s; class MD5Digester { public: MD5Digester(); ~MD5Digester(); void start(); void add(const string &value); void add(const unsigned char *bytes, int num_bytes); void stop(); const bool isRunning() const { return m_running; } const string &asString() const { assert(!m_running); return m_digest; } private: /// Not implemented. MD5Digester(const MD5Digester &); /// Not implemented. MD5Digester& operator=(const MD5Digester &); private: string m_digest; Ptr m_state; bool m_running; }; #endif // _MD5Digester_h spamprobe-1.4d/src/includes/InterruptedException.h0000664000076400007640000000260610527261700017403 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: InterruptedException.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _InterruptedException_h #define _InterruptedException_h #include #include "util.h" class InterruptedException : public runtime_error { public: InterruptedException() : runtime_error("interrupted by user") { } }; #endif spamprobe-1.4d/src/includes/WordData.h0000664000076400007640000001072310527261701014724 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: WordData.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _WordData_h #define _WordData_h #if defined(FORCE_NETWORK_ORDER) #include #define to_database_order(x) htonl(x) #define to_host_order(x) ntohl(x) #endif #include #include "util.h" class WordData { public: WordData() : m_goodCount(0), m_spamCount(0), m_flags(0) { } WordData(int _good_count, int _spam_count) : m_goodCount(_good_count), m_spamCount(_spam_count), m_flags(0) { } WordData(const WordData &other) : m_goodCount(other.m_goodCount), m_spamCount(other.m_spamCount), m_flags(other.m_flags) { } bool equals(const WordData &other) { return m_goodCount == other.m_goodCount && m_spamCount == other.m_spamCount && m_flags == other.m_flags; } bool hasSameCounts(const WordData &other) { return m_spamCount == other.m_spamCount && m_goodCount == other.m_goodCount; } int spamCount() const { return m_spamCount; } int goodCount() const { return m_goodCount; } int totalCount() const { return m_goodCount + m_spamCount; } void setFlags(unsigned long flags) { m_flags = flags; } unsigned long flags() const { return m_flags; } void adjustGoodCount(int delta) { m_goodCount += delta; if (m_goodCount < 0) { m_goodCount = 0; } } void adjustSpamCount(int delta) { m_spamCount += delta; if (m_spamCount < 0) { m_spamCount = 0; } } void clear() { m_goodCount = 0; m_spamCount = 0; m_flags = 0; } void reset(int good_count, int spam_count, int flags) { m_goodCount = good_count; m_spamCount = spam_count; m_flags = flags; } void adjustDate() { assert(s_today > 0); m_flags = (m_flags & ~TIME_STAMP_MASK) | s_today; } /// Returns day the record was last modified (days since epoch) int timeStamp() const { return (int)(m_flags & TIME_STAMP_MASK); } /** returns age of the record in days using the current s_today value as the base value */ int age() const { assert(timeStamp() <= (int)s_today); return (int)s_today - timeStamp(); } /** Initializes the current day number for use by adjust*Count(). Must be called before either of them are called. */ static void setTodayDate(time_t date_offset = 0) { const time_t base_time = 1029124800; // August 12, 2002 const time_t seconds_per_day = 60 * 60 * 24; time_t now = time(0) - base_time; now -= date_offset * seconds_per_day; s_today = (unsigned long)(0xffff & (now / seconds_per_day)); if (is_debug) { cerr << "WordData::setTodayDate: set date to " << s_today << endl; } } void toDatabaseOrder() { #if defined(FORCE_NETWORK_ORDER) m_goodCount = to_database_order(m_goodCount); m_spamCount = to_database_order(m_spamCount); m_flags = to_database_order(m_flags); #endif } void toHostOrder() { #if defined(FORCE_NETWORK_ORDER) m_goodCount = to_host_order(m_goodCount); m_spamCount = to_host_order(m_spamCount); m_flags = to_host_order(m_flags); #endif } private: enum { // low 16 bits of flags hold days since epoch TIME_STAMP_MASK = 0xffff }; int m_goodCount; int m_spamCount; unsigned long m_flags; static unsigned long s_today; }; #endif // _WordData_h spamprobe-1.4d/src/includes/StringReader.h0000664000076400007640000000324310527261700015606 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: StringReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _StringReader_h #define _StringReader_h #include "AbstractCharReader.h" class StringReaderPosition; class StringReader : public AbstractCharReader { public: StringReader(const string &source); virtual ~StringReader(); virtual bool forward(); virtual bool hasChar(); virtual bool skip(int nchars); virtual bool atEnd(); virtual OWNED AbstractCharReaderPosition *createMark(); virtual void returnToMark(AbstractCharReaderPosition *pos); private: const string &m_source; int m_index; }; #endif spamprobe-1.4d/src/includes/LockFile.h0000664000076400007640000000312710527261700014706 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: LockFile.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _LockFile_h #define _LockFile_h #include "File.h" #include "LockFD.h" class LockFile { public: LockFile(const File &file); ~LockFile(); typedef LockFD::LockType_t LockType_t; void lock(LockType_t lock_type, int lock_mode = 0600); void release(); private: /// Not implemented. LockFile(const LockFile &); /// Not implemented. LockFile& operator=(const LockFile &); private: File m_file; Ptr m_lock; }; #endif // _LockFile_h spamprobe-1.4d/src/includes/File.h0000664000076400007640000000437110527261700014077 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: File.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _File_h #define _File_h #include #include "util.h" class File { public: explicit File(); explicit File(const string &path); explicit File(const File &parent, const string &filename); File(const File &); File& operator=(const File &); ~File(); operator const char *() const { return m_path.c_str(); } void addComponent(const string &name); void setPath(const string &path); string getPath() const { return m_path; } string getName() const; bool exists() const; bool isFile() const; bool isDirectory() const; bool isSelfOrParent() const; bool isHidden() const; bool hasChild(const string &path) const; File parent() const; unsigned long getSize() const; void makeDirectory(int mode) const; void rename(const string &new_path); void remove(); bool hasSuffix(const string &suffix) const; void setSuffix(const string &suffix); void children(vector &files); static File getHomeDir(); static const string DOT; static const string DOT_DOT; private: string m_path; }; bool operator<(const File &a, const File &b); #endif // _File_h spamprobe-1.4d/src/includes/AbstractMultiLineString.h0000664000076400007640000000362010527261700017771 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractMultiLineString.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractMultiLineString_h #define _AbstractMultiLineString_h #include "util.h" class AbstractCharReader; class AbstractMultiLineString { public: virtual ~AbstractMultiLineString(); /// returns number of lines in string virtual int lineCount() const = 0; /// returns the specified line virtual const string &line(int index) const = 0; virtual const string &join(string &buffer) const; virtual const string &join(string &buffer, const string &terminator) const; /// creates a new char reader owned by the caller virtual Ref createCharReader() const; /// creates a new char reader owned by the caller virtual Ref createCharReader(const string &terminator) const; }; #endif spamprobe-1.4d/src/includes/LineReader.h0000664000076400007640000000340010527261700015222 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: LineReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _LineReader_h #define _LineReader_h #include "Buffer.h" #include "AbstractCharReader.h" class LineReader { public: LineReader(AbstractCharReader *reader); ~LineReader(); bool forward(); bool forward(int &chars_remaining); bool hasLine(); const string ¤tLine() { return m_line; } void skipChars(int count) { m_reader->skip(count); } private: bool isLineTerminator(char ch, int &chars_remaining); bool forwardChar(int &remaining); private: AbstractCharReader *m_reader; Buffer m_buffer; string m_line; bool m_needsStart; bool m_hasLine; }; #endif spamprobe-1.4d/src/includes/Ptr.h0000664000076400007640000000416210527261700013763 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Ptr.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Ptr_h #define _Ptr_h #include /// Older versions of g++ shipped with incomplete auto_ptr implementations. /// This class is similar to auto_ptr but does not support implicit transfer /// of ownership since that can be confusing and error prone. template class Ptr { public: explicit Ptr(T *p = 0) : m_ptr(p) { } ~Ptr() { delete release(); } T *operator->() const { assert(m_ptr); return m_ptr; } T &operator*() const { assert(m_ptr); return *m_ptr; } T *release() { T *ptr = m_ptr; m_ptr = 0; return ptr; } T *get() const { return m_ptr; } void set(T *p = 0) { delete m_ptr; m_ptr = p; } void clear() { delete release(); } bool isNull() const { return m_ptr == 0; } bool isNotNull() const { return m_ptr != 0; } private: /// Not implemented. Ptr(const Ptr &); /// Not implemented. Ptr& operator=(const Ptr &); T *m_ptr; }; #endif // _Ptr_h spamprobe-1.4d/src/includes/HtmlTokenizer.h0000664000076400007640000000535410527261700016021 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HtmlTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HtmlTokenizer_h #define _HtmlTokenizer_h #include "AbstractCharReader.h" #include "AbstractTokenizer.h" #include "AbstractTokenReceiver.h" class AbstractCharReader; class HtmlTokenizer : public AbstractTokenizer, AbstractCharReader { public: HtmlTokenizer(AbstractTokenizer *textTokenizer, AbstractTokenizer *htmlTokenizer, int maxTagLength); virtual ~HtmlTokenizer(); virtual void tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix); virtual bool forward(); virtual bool hasChar(); virtual bool atEnd(); virtual bool skip(int nchars); protected: virtual void processTagUrls(const string &tag); virtual void processTagBody(const string &tag); virtual bool isCommentTag(const string &tag); virtual bool isInvisibleTag(const string &tag); virtual bool isOpenCommentTag(const string &tag); virtual bool isIncompleteCommentTag(const string &tag); virtual bool processedTag(string &tag); char parseEntityInteger(const string &entity); bool processEntity(const string &entity); virtual bool processedEntity(); const string &decodeUrl(const string &url, string &buffer); private: // configuration options initialized during construction // lifetime of these objects must exceed this object's lifetime AbstractTokenizer *m_textTokenizer; AbstractTokenizer *m_tagTokenizer; int m_maxTagLength; // temporary variables used during tokenizing string m_prefix; AbstractCharReader *m_reader; AbstractTokenReceiver *m_receiver; }; #endif spamprobe-1.4d/src/includes/MultiLineString.h0000664000076400007640000000332010527261700016302 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MultiLineString.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MultiLineString_h #define _MultiLineString_h #include #include "AbstractMultiLineString.h" class AbstractCharReader; class MultiLineString : public AbstractMultiLineString { public: MultiLineString(); virtual ~MultiLineString(); virtual int lineCount() const; virtual const string &line(int index) const; virtual void appendToLastLine(const string &line); virtual void addLine(const string &line); virtual void parseText(const string &text); static Ref fromText(const string &text); private: vector m_lines; }; #endif spamprobe-1.4d/src/includes/HdlParser.h0000664000076400007640000000365710527261700015112 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlParser.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlParser_h #define _HdlParser_h #include "File.h" #include "HdlTokenizer.h" class HdlStatement; class HdlToken; class HdlParser { public: HdlParser() {} ~HdlParser() {} const Ref parseString(const string &src); const Ref parseFile(const File &file); private: /// Not implemented. HdlParser(const HdlParser &); /// Not implemented. HdlParser& operator=(const HdlParser &); private: const Ref parse(); const Ref parseBlock(); const Ref parseStatement(const Ref &id, bool is_block); void parseArgumentsForStatement(const Ref &stmt); void skipAndEnsureSemiColon(); const Ref skipAndEnsureIdentifier(); private: Ref m_tokenizer; }; #endif // _HdlParser_h spamprobe-1.4d/src/includes/MultiLineSubString.h0000664000076400007640000000323510527261700016761 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MultiLineSubString.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MultiLineSubString_h #define _MultiLineSubString_h #include "AbstractMultiLineString.h" class MultiLineSubString : public AbstractMultiLineString { public: MultiLineSubString(const CRef &target, int start_index, int limit_index = INT_MAX); virtual ~MultiLineSubString(); virtual int lineCount() const; virtual const string &line(int index) const; private: CRef m_target; int m_startIndex; int m_length; }; #endif spamprobe-1.4d/src/includes/LockFD.h0000664000076400007640000000311210527261700014312 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: LockFD.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _LockFD_h #define _LockFD_h #include "File.h" class LockFD { public: LockFD(int fd); ~LockFD(); enum LockType_t { SHARED_LOCK, EXCLUSIVE_LOCK }; void lock(LockType_t lock_type); void release(); int getFD() const { return m_lockFD; } private: /// Not implemented. LockFD(const LockFD &); /// Not implemented. LockFD& operator=(const LockFD &); private: int m_lockFD; bool m_locked; }; #endif // _LockFD_h spamprobe-1.4d/src/includes/AbstractMailMessageReader.h0000664000076400007640000000265010527261700020214 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractMailMessageReader_h #define _AbstractMailMessageReader_h #include "util.h" class MailMessage; class LineReader; class AbstractMailMessageReader { public: virtual ~AbstractMailMessageReader() { } virtual OWNED MailMessage *readMessage() = 0; }; #endif spamprobe-1.4d/src/includes/MessageHeader.h0000664000076400007640000000335510527261700015716 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MessageHeader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MessageHeader_h #define _MessageHeader_h #include "AbstractMultiLineString.h" class MessageHeader { public: MessageHeader(const string &name, const CRef &lines); ~MessageHeader(); const string &name() const { return m_name; } const string &lowerName() const { return m_lowerName; } bool hasName(const string &name) { return m_lowerName == name; } const CRef &lines() const { return m_lines; } private: string m_name; string m_lowerName; CRef m_lines; }; #endif spamprobe-1.4d/src/includes/AutoTrainMailMessageReader.h0000664000076400007640000000527310527261700020363 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AutoTrainMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AutoTrainMessageReader_h #define _AutoTrainMessageReader_h #include #include #include "File.h" #include "AbstractMailMessageReader.h" #include "MailMessageReaderFactory.h" class AutoTrainMailMessageReader : public AbstractMailMessageReader { public: AutoTrainMailMessageReader(); ~AutoTrainMailMessageReader(); void addMailboxFile(bool is_spam, const string &path); OWNED MailMessage *readMessage(); bool messageWasSpam() { return m_messageWasSpam; } const File &messageFile() { return m_messageFile; } private: /// Not implemented. AutoTrainMailMessageReader(const AutoTrainMailMessageReader &); /// Not implemented. AutoTrainMailMessageReader& operator=(const AutoTrainMailMessageReader &); private: bool shouldUseSpam(); long countMessagesInFile(const string &path); void openFile(const string &path, Ptr &reader); bool readMessage(deque &paths, string &path, Ptr &reader, Ptr &message); bool readMessage(bool is_spam, Ptr &message); private: long m_spamCount; long m_totalCount; deque m_spamPaths; deque m_goodPaths; MailMessageReaderFactory m_readerFactory; bool m_messageWasSpam; File m_messageFile; string m_spamPath; string m_goodPath; Ptr m_spamReader; Ptr m_goodReader; }; #endif // _AutoTrainMailMessageReader_h spamprobe-1.4d/src/includes/ParserConfig.h0000664000076400007640000000747010527261700015605 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: ParserConfig.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _ParserConfig_h #define _ParserConfig_h #include "HeaderPrefixList.h" class ParserConfig { public: ParserConfig(); ~ParserConfig(); void setReplaceNonAsciiChars(int value) { if (value > 0) { m_replaceNonAsciiChars = true; m_nonAsciiChar = tolower((char)value); } else { m_replaceNonAsciiChars = false; m_nonAsciiChar = 0; } } bool getReplaceNonAsciiChars() const { return m_replaceNonAsciiChars; } char getNonAsciiCharReplacement() const { return m_nonAsciiChar; } string::size_type getMinTermLength() const { return m_minTermLength; } string::size_type getMaxTermLength() const { return m_maxTermLength; } bool getRemoveHTML() const { return m_removeHTML; } void setMinTermLength(string::size_type value) { m_minTermLength = value; } void setMaxTermLength(string::size_type value) { m_maxTermLength = value; } void setRemoveHTML(bool value) { m_removeHTML = value; } void setMinPhraseTerms(int length) { m_minPhraseTerms = length; } void setMaxPhraseTerms(int length) { m_maxPhraseTerms = length; } void setMinPhraseChars(int length) { m_minPhraseChars = length; } void setMaxPhraseChars(int length) { m_maxPhraseChars = length; } int getMinPhraseTerms() const { return m_minPhraseTerms; } int getMaxPhraseTerms() const { return m_maxPhraseTerms; } int getMinPhraseChars() const { return m_minPhraseChars; } int getMaxPhraseChars() const { return m_maxPhraseChars; } void setSpamProbeFieldName(const string &value) { m_spamprobeFieldName = value; } const string &spamprobeFieldName() const { return m_spamprobeFieldName; } HeaderPrefixList *headers() { return &m_prefixedHeaders; } void setKeepSuspiciousTags(bool value) { m_keepSuspiciousTags = value; } bool getKeepSuspiciousTags() const { return m_keepSuspiciousTags; } void setIgnoreBody(bool value) { m_ignoreBody = value; } bool getIgnoreBody() const { return m_ignoreBody; } void setMaxTermsPerMessage(int value) { m_maxTermsPerMessage = value; } int getMaxTermsPerMessage() const { return m_maxTermsPerMessage; } private: string::size_type m_minTermLength; string::size_type m_maxTermLength; bool m_replaceNonAsciiChars; char m_nonAsciiChar; bool m_removeHTML; bool m_keepSuspiciousTags; bool m_ignoreBody; string m_spamprobeFieldName; HeaderPrefixList m_prefixedHeaders; int m_minPhraseTerms; int m_maxPhraseTerms; int m_minPhraseChars; int m_maxPhraseChars; int m_maxTermsPerMessage; }; #endif // _ParserConfig_h spamprobe-1.4d/src/includes/MailMessageDigester.h0000664000076400007640000000406110527261700017072 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageDigester.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MailMessageDigester_h #define _MailMessageDigester_h #include "Message.h" #include "MailMessageList.h" class MD5Digester; class MessageHeaderList; class MailMessageDigester { public: void assignDigestToMessage(Message *parsed_message, MailMessage *mail_message, const string &existing_digest_header); const string &digestMessage(MailMessage *messge, string &buffer); private: void digestLines(MD5Digester &md5, const CRef lines); void digestHeaderLines(MD5Digester &md5, const MessageHeaderList *header, const string &header_name); bool getExistingDigest(const MessageHeaderList *message_headers, const string &header_name, string &buffer); }; #endif spamprobe-1.4d/src/includes/SimpleMultiLineStringCharReader.h0000664000076400007640000000422310527261700021400 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SimpleMultiLineStringCharReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _SimpleMultiLineStringCharReader_h #define _SimpleMultiLineStringCharReader_h #include "AbstractCharReader.h" class AbstractMultiLineString; class SimpleMultiLineStringCharReaderPosition; class SimpleMultiLineStringCharReader : public AbstractCharReader { public: SimpleMultiLineStringCharReader(const AbstractMultiLineString *target); SimpleMultiLineStringCharReader(const AbstractMultiLineString *target, const string &terminator); virtual ~SimpleMultiLineStringCharReader(); virtual bool forward(); virtual bool skip(int nchars); virtual bool hasChar(); virtual bool atEnd(); virtual OWNED AbstractCharReaderPosition *createMark(); virtual void returnToMark(AbstractCharReaderPosition *pos); private: void reset(); const string *getCurrentLine(); bool ensureCharReady(); private: const AbstractMultiLineString *m_target; string m_terminator; Ptr m_position; }; #endif spamprobe-1.4d/src/includes/RegularExpression.h0000664000076400007640000000553710527261700016706 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: RegularExpression.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _RegularExpression_h #define _RegularExpression_h #include #include "util.h" class RegularExpressionImpl; /** Simple shell class encapsulating a regex API. Currently uses the POSIX regular expression functions. */ class RegularExpression { public: RegularExpression(); explicit RegularExpression(const string &expr, int num_subs = 1, bool ignore_case = false, bool ignore_newline = true); ~RegularExpression(); bool isValid(); bool setExpression(const string &expr, int num_subs = 1, bool ignore_case = false, bool ignore_newline = true); bool match(const string &str); int matchCount() const; const string &getMatch(int match_index, string &matched_string); const string &getMatch(int match_index, string &matched_string, const string &default_value); ostream &dumpMatches(ostream &out); struct MatchData { string::size_type start_pos; string::size_type end_pos; }; void getMatch(int match_index, MatchData &match_data); void removeMatch(int match_index, string &text); void replaceMatch(int match_index, string &text, const string &replace_with); private: /// Not implemented. RegularExpression(const RegularExpression &); /// Not implemented. RegularExpression& operator=(const RegularExpression &); private: friend class RegularExpressionImpl; Ptr m_expr; string m_text; vector m_matches; }; #endif // _RegularExpression_h spamprobe-1.4d/src/includes/Ref.h0000664000076400007640000001132010527261700013724 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Ref.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Ref_h #define _Ref_h #include template class RefBase { public: void clear() { release(); m_count = 0; m_ptr = 0; } bool equals(const RefBase &other) const { return m_ptr == other.m_ptr; } bool isNull() const { return m_ptr == 0; } bool isNotNull() const { return m_ptr != 0; } int *count() const { return m_count; } T *ptr() const { return m_ptr; } protected: RefBase() : m_ptr(0), m_count(0) { } RefBase(T *ptr); RefBase(const RefBase &other) : m_count(other.m_count), m_ptr(other.m_ptr) { if (m_count) { ++*m_count; } } template RefBase(const RefBase &other) : m_count(other.count()), m_ptr(other.ptr()) { if (m_count) { ++*m_count; } } ~RefBase() { release(); } void assign(const RefBase &other); private: // not implemented RefBase &operator=(const RefBase &); void acquire(const RefBase &other); void release(); int *m_count; T *m_ptr; }; template RefBase::RefBase(T *ptr) { if (ptr) { try { m_count = new int(1); } catch (...) { delete ptr; throw; } } else { m_count = 0; } m_ptr = ptr; } template void RefBase::acquire(const RefBase &other) { m_count = other.m_count; m_ptr = other.m_ptr; if (m_count) { ++*m_count; } } template void RefBase::release() { assert(!m_count || *m_count >= 1); assert(!m_count == !m_ptr); if (m_count && --*m_count == 0) { delete m_count; delete m_ptr; } } template void RefBase::assign(const RefBase &other) { if (m_count != other.m_count) { release(); acquire(other); } } template class Ref; template class CRef : public RefBase { public: CRef() { } explicit CRef(T *ptr) : RefBase(ptr) { } CRef(const CRef &other) : RefBase(other) { } template CRef(const Ref &other) : RefBase(other) { } template CRef(const CRef &other) : RefBase(other) { } CRef &operator=(const CRef &other) { assign(other); return *this; } const T *operator->() const { return RefBase::ptr(); } const T &operator*() const { return *RefBase::ptr(); } const T *ptr() const { return RefBase::ptr(); } const CRef transfer() { CRef tmp(*this); RefBase::clear(); return tmp; } }; template class Ref : public CRef { public: Ref() { } explicit Ref(T *ptr) : CRef(ptr) { } template explicit Ref(Z *ptr) : CRef(ptr) { } Ref(const Ref &other) : CRef(other) { } template Ref(const Ref &other) : CRef(other) { } Ref &operator=(const Ref &other) { assign(other); return *this; } T *operator->() const { return RefBase::ptr(); } T &operator*() const { return *RefBase::ptr(); } T *ptr() const { return RefBase::ptr(); } const Ref transfer() { Ref tmp(*this); RefBase::clear(); return tmp; } }; template Ref make_ref(T *ptr) { return Ref(ptr); } template bool operator==(const RefBase &a, const RefBase &b) { return a.equals(b); } template bool operator!=(const RefBase &a, const RefBase &b) { return !a.equals(b); } #endif // _Ref_h spamprobe-1.4d/src/includes/LRUCache.h0000664000076400007640000002130710527260121014600 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _LRUCache_h #define _LRUCache_h #include #include #include "util.h" template class LRUCache { public: struct LRUCacheNode; typedef LRUCacheNode NodeType; typedef Ref RefType; typedef list ListType; typedef typename list::iterator IterType; class LRUCacheNodeKeyCompare; typedef map MapType; typedef typename MapType::iterator MapIterType; struct LRUCacheNode { KeyType key; ValueType value; bool isLocked; IterType currentPosition; }; class LRUCacheNodeKeyCompare : public binary_function { public: bool operator()(const NodeType *a, const NodeType *b) { return a->key < b->key; } }; class iterator { friend class LRUCache; iterator(MapType *index, MapIterType iter) : m_index(index), m_iterator(iter) { } public: bool operator==(const iterator &other) { return m_iterator == other.m_iterator; } bool operator!=(const iterator &other) { return m_iterator != other.m_iterator; } iterator &operator++() { ++m_iterator; return *this; } iterator operator++(int) { iterator old_value(m_index, m_iterator); ++m_iterator; return old_value; } const KeyType &key() { assert(m_iterator != m_index->end()); return m_iterator->second->key; } const ValueType &value() { assert(m_iterator != m_index->end()); return m_iterator->second->value; } bool isLocked() { assert(m_iterator != m_index->end()); return m_iterator->second->isLocked; } private: MapType *m_index; MapIterType m_iterator; }; public: LRUCache(int max_size) : m_maxSize(max_size), m_normalCount(0), m_lockedCount(0) { } ~LRUCache() { } bool get(const KeyType &key, ValueType &value); void put(const KeyType &key, ValueType value, bool is_locked); void dump(); void clear(); iterator begin() { return iterator(&m_index, m_index.begin()); } iterator end() { return iterator(&m_index, m_index.end()); } iterator find(const KeyType &key); void unlock(const KeyType &key) { setLocked(findNode(key), false); } void lock(const KeyType &key) { setLocked(findNode(key), true); } int size() { return m_normalCount + m_lockedCount; } int maxSize() { return m_maxSize; } int lockedCount() { return m_lockedCount; } int unlockedCount() { return m_normalCount; } private: void addNewNode(const KeyType &key, ValueType value, bool is_locked); NodeType *findNode(const KeyType &key); void setLocked(NodeType *node, bool is_locked); void removeNode(NodeType *node); void eliminateOldObjects(); void dump(ListType &nodes); void dump(NodeType *node); void setLocked(const KeyType &key, bool is_locked) { setLocked(findNode(key), is_locked); } private: int m_maxSize; int m_lockedCount; int m_normalCount; ListType m_normalList; ListType m_lockedList; MapType m_index; }; template bool LRUCache::get(const KeyType &key, ValueType &value) { NodeType *node = findNode(key); if (node == 0) { return false; } if (!node->isLocked) { m_normalList.splice(m_normalList.begin(), m_normalList, node->currentPosition); node->currentPosition = m_normalList.begin(); assert((*node->currentPosition).ptr() == node); } value = node->value; return true; } template void LRUCache::put(const KeyType &key, ValueType value, bool is_locked) { NodeType key_node; key_node.key = key; MapIterType i = m_index.find(&key_node); if (i == m_index.end()) { addNewNode(key, value, is_locked); } else { NodeType *node = i->second; setLocked(node, is_locked); node->value = value; } } template void LRUCache::dump() { cerr << "locked: " << lockedCount() << ": "; cerr << "locked: "; dump(m_lockedList); cerr << "normal: " << unlockedCount() << ": "; dump(m_normalList); } template void LRUCache::clear() { m_index.clear(); m_normalList.clear(); m_lockedList.clear(); m_normalCount = 0; m_lockedCount = 0; } template typename LRUCache::iterator LRUCache::find(const KeyType &key) { NodeType key_node; key_node.key = key; return iterator(&m_index, m_index.find(&key_node)); } template void LRUCache::addNewNode(const KeyType &key, ValueType value, bool is_locked) { eliminateOldObjects(); RefType node(new NodeType); node->key = key; node->value = value; node->isLocked = is_locked; if (is_locked) { node->currentPosition = m_lockedList.insert(m_lockedList.begin(), node); m_lockedCount += 1; } else { node->currentPosition = m_normalList.insert(m_normalList.begin(), node); m_normalCount += 1; } m_index.insert(make_pair(node.ptr(), node.ptr())); } template typename LRUCache::NodeType *LRUCache::findNode(const KeyType &key) { NodeType key_node; key_node.key = key; MapIterType map_iter = m_index.find(&key_node); return (map_iter == m_index.end()) ? 0 : map_iter->second; } template void LRUCache::setLocked(NodeType *node, bool is_locked) { if (node) { if (is_locked) { if (!node->isLocked) { m_normalCount -= 1; m_lockedCount += 1; node->isLocked = true; m_lockedList.splice(m_lockedList.begin(), m_normalList, node->currentPosition); node->currentPosition = m_lockedList.begin(); assert((*node->currentPosition).ptr() == node); } } else { if (node->isLocked) { m_normalCount += 1; m_lockedCount -= 1; node->isLocked = false; m_normalList.splice(m_normalList.begin(), m_lockedList, node->currentPosition); node->currentPosition = m_normalList.begin(); assert((*node->currentPosition).ptr() == node); } } } } template void LRUCache::removeNode(NodeType *node) { if (node->isLocked) { m_lockedCount -= 1; m_index.erase(node); m_lockedList.erase(node->currentPosition); } else { m_normalCount -= 1; m_index.erase(node); m_normalList.erase(node->currentPosition); } } template void LRUCache::eliminateOldObjects() { while (size() >= m_maxSize && m_normalCount > 0) { RefType nr(m_normalList.back()); removeNode(nr.ptr()); } } template void LRUCache::dump(ListType &nodes) { for (IterType i = nodes.begin(); i != nodes.end(); ++i) { dump((*i).ptr()); } cerr << endl; } template void LRUCache::dump(NodeType *node) { cerr << "Node(" << node->key << "," << node->value << "," << node->isLocked << ")"; } #endif spamprobe-1.4d/src/includes/TraditionalMailMessageParser.h0000664000076400007640000000551710527261701020763 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TraditionalMailMessageParser.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _TraditionalMailMessageParser_h #define _TraditionalMailMessageParser_h #include "Message.h" #include "MailMessage.h" #include "RegularExpression.h" #include "AbstractTokenReceiver.h" #include "AbstractMailMessageParser.h" class AbstractTokenizer; class ParserConfig; class MessageHeader; class MimeDecoder; class TraditionalMailMessageParser : public AbstractMailMessageParser, public AbstractTokenReceiver { public: TraditionalMailMessageParser(ParserConfig *config); virtual ~TraditionalMailMessageParser(); virtual OWNED Message *parseMailMessage(MailMessage *source); void receiveToken(const string &prefix, const string &token); protected: virtual void addDerivedTerms(const string &prefix, const string &token); virtual void addTokenParts(const string &prefix, const string &token); private: void addTerm(const string &prefix, const string &term, int flags); bool isPhrase(const string &token); void parseHeader(const MessageHeader *header, MimeDecoder *decoder); void parseHtmlBodyText(const AbstractMultiLineString *text); void parsePlainBodyText(const AbstractMultiLineString *text); void parseBodyText(MailMessage *source); void parseCharset(MailMessage *source, const string &prefix); virtual void parseHeaders(MailMessage *source); virtual void parseBody(MailMessage *source); virtual OWNED AbstractTokenizer *createTokenizer(); private: string m_prefix; Ptr m_message; Ptr m_textTokenizer; Ptr m_htmlTokenizer; RegularExpression m_ipRegex; ParserConfig *m_config; }; #endif spamprobe-1.4d/src/includes/Makefile.am0000664000076400007640000000217710526706576015123 00000000000000AUTOMAKE_OPTIONS=foreign EXTRA_DIST=\ AbstractCharReader.h\ AbstractMailMessageParser.h\ AbstractMailMessageReader.h\ AbstractMultiLineString.h\ AbstractTokenizer.h\ AbstractTokenReceiver.h\ Array.h\ AutoTrainMailMessageReader.h\ Buffer.h\ CleanupManager.h\ config.h\ DatabaseConfig.h\ File.h\ FrequencyDB.h\ hash.h\ HeaderPrefixList.h\ HdlError.h\ HdlParser.h\ HdlPrinter.h\ HdlStatement.h\ HdlSyntaxChecker.h\ HdlToken.h\ HdlTokenizer.h\ HtmlTokenizer.h\ InterruptedException.h\ IstreamCharReader.h\ LineReader.h\ LockFD.h\ LockFile.h\ LRUCache.h\ MailMessage.h\ MailMessageDigester.h\ MailMessageList.h\ MailMessageReaderFactory.h\ MD5Digester.h\ Message.h\ MessageHeader.h\ MessageHeaderList.h\ MultiLineJoinedString.h\ MultiLineString.h\ MultiLineSubString.h\ ParserConfig.h\ Ptr.h\ Ref.h\ RegularExpression.h\ SimpleMultiLineStringCharReader.h\ SimpleTokenizer.h\ StringReader.h\ TempPtr.h\ TokenCollector.h\ TokenFilteringTokenizer.h\ Token.h\ Tokenizer.h\ TraditionalMailMessageParser.h\ UrlOnlyHtmlTokenizer.h\ util.h\ WordData.h #noinst_PROGRAMS=testrc #testrc_SOURCES=\ # testrc.cc spamprobe-1.4d/src/includes/TokenCollector.h0000664000076400007640000000365610527261700016154 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TokenCollector.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _TokenCollector_h #define _TokenCollector_h #include #include #include "util.h" #include "AbstractTokenReceiver.h" class TokenCollector : public AbstractTokenReceiver { public: virtual ~TokenCollector(); virtual void receiveToken(const string &token); int tokenCount(const string &token) { MapType::const_iterator i = m_tokens.find(token); return (i == m_tokens.end()) ? 0 : i->second; } void clear() { m_tokens.clear(); } bool hasToken(const string &token) { MapType::const_iterator i = m_tokens.find(token); return i != m_tokens.end(); } typedef vector ListType; void getTokens(ListType &tokens); private: typedef map MapType; MapType m_tokens; }; #endif spamprobe-1.4d/src/includes/HeaderPrefixList.h0000664000076400007640000000723010527261700016417 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HeaderPrefixList.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HeaderPrefixList_h #define _HeaderPrefixList_h #include #include "util.h" class HeaderPrefixList { private: struct HeaderData { string first_prefix; string other_prefix; int visit_count; }; typedef map MapType; typedef MapType::iterator IteratorType; public: HeaderPrefixList(); ~HeaderPrefixList(); /// Resets the counts kept by shouldProcessHeader() void resetHeaderCounts(); /// Determines if the header should be processed and what prefix to use. /// Remembers the number of times the header has been seen already. bool shouldProcessHeader(const string &name, string &prefix); void removePrefixedHeaders(); void setBlankPrefixesMode(); void setDefaultHeadersMode(); void setNonXHeadersMode(); void setAllHeadersMode(); void setNoHeadersMode(); bool getBlankPrefixesMode() { return m_forceBlankPrefixes; } bool getNonXHeadersMode() { return m_visitAllHeaders && m_ignoreXHeaders; } bool getAllHeadersMode() { return m_visitAllHeaders; } bool getNoHeadersMode() { return m_visitAllHeaders == false && m_values.size() == 0; } void addSimpleHeaderPrefix(const string &name); void addHeaderPrefix(const string &name, const string &first_prefix, const string &other_prefix); void removeHeaderPrefix(const string &name); class const_iterator { friend class HeaderPrefixList; public: bool operator!=(const const_iterator &other) { return m_iter != other.m_iter; } const_iterator &operator++() { ++m_iter++; return *this; } const string &name() { return (*m_iter).first; } string firstPrefix() { return getPrefixBody((*m_iter).second.first_prefix); } string otherPrefix() { return getPrefixBody((*m_iter).second.other_prefix); } private: const_iterator(MapType::const_iterator iter) : m_iter(iter) {} string getPrefixBody(const string &prefix); MapType::const_iterator m_iter; }; const_iterator begin() { return const_iterator(m_values.begin()); } const_iterator end() { return const_iterator(m_values.end()); } private: /// Not implemented. HeaderPrefixList(const HeaderPrefixList &); /// Not implemented. HeaderPrefixList& operator=(const HeaderPrefixList &); private: bool m_visitAllHeaders; bool m_ignoreXHeaders; bool m_forceBlankPrefixes; MapType m_values; }; #endif // _HeaderPrefixList_h spamprobe-1.4d/src/includes/HdlStatement.h0000664000076400007640000000516010527261700015611 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlStatement.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlStatement_h #define _HdlStatement_h #include #include "util.h" class HdlToken; class HdlStatement { public: HdlStatement(const Ref &name, bool is_block); ~HdlStatement(); bool isBlock() const { return m_isBlock; } const CRef &name() const { return m_name; } int numArguments() const { return (int)m_arguments.size(); } const CRef &argument(int index) const { assert(index >= 0); assert(index < numArguments()); return m_arguments[index]; } void addArgument(const Ref &arg) { assert(arg.isNotNull()); m_arguments.push_back(arg); } int numChildren() const { return (int)m_children.size(); } const CRef &child(int index) const { assert(index >= 0); assert(index < numChildren()); return m_children[index]; } const CRef child(const CRef &token) const; const CRef child(const string &name) const; void addChild(const Ref &stmt) { assert(stmt.isNotNull()); m_children.push_back(stmt); } private: /// Not implemented. HdlStatement(const HdlStatement &); /// Not implemented. HdlStatement& operator=(const HdlStatement &); private: typedef vector > ArgVector; typedef vector > ChildVector; Ref m_name; bool m_isBlock; ArgVector m_arguments; ChildVector m_children; }; #endif // _HdlStatement_h spamprobe-1.4d/src/includes/config.h0000664000076400007640000000217310527260652014470 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: config.h 193 2005-12-14 00:35:25Z brian $ // // Copyright (C) 2000 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // spamprobe-1.4d/src/includes/Array.h0000664000076400007640000000405410527261700014274 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Array.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Array_h #define _Array_h #include /// Manages lifetime of a dynamically allocated, fixed sized, array. /// Array is automatically delete[]ed in constructor. template class Array { public: Array(T *p = 0) : m_ptr(p) { } ~Array() { delete[] release(); } T &operator*() const { assert(m_ptr); return *m_ptr; } T &operator[](int index) const { assert(m_ptr); return m_ptr[index]; } T *release() { T *ptr = m_ptr; m_ptr = 0; return ptr; } T *get() const { return m_ptr; } void set(T *p = 0) { delete[] m_ptr; m_ptr = p; } void clear() { delete[] release(); } bool isNull() { return m_ptr == 0; } bool isNotNull() { return m_ptr != 0; } private: /// Not implemented. Array(const Array &); /// Not implemented. Array& operator=(const Array &); T *m_ptr; }; #endif // _Array_h spamprobe-1.4d/src/includes/MailMessageReaderFactory.h0000664000076400007640000000341610527261700020061 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageReaderFactory.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MailMessageReaderFactory_h #define _MailMessageReaderFactory_h #include "util.h" class AbstractMailMessageReader; class File; class MailMessageReaderFactory { public: MailMessageReaderFactory(); static bool isAcceptableFile(const File &file); OWNED AbstractMailMessageReader *createReader(const File &file); OWNED AbstractMailMessageReader *createStdinReader(); void setIgnoreFrom(bool value) { m_ignoreFrom = value; } void setIgnoreContentLength(bool value) { m_ignoreContentLength = value; } private: bool m_ignoreFrom; bool m_ignoreContentLength; }; #endif // _MailMessageReaderFactory_h spamprobe-1.4d/src/includes/TokenFilteringTokenizer.h0000664000076400007640000000375110527261701020041 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TokenFilteringTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _TokenFilteringTokenizer_h #define _TokenFilteringTokenizer_h #include "AbstractTokenizer.h" class TokenFilteringTokenizer : public AbstractTokenizer, AbstractTokenReceiver { public: TokenFilteringTokenizer(OWNED AbstractTokenizer *tokenizer, int min_length, int max_length, bool allow_numbers); ~TokenFilteringTokenizer(); virtual void tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix); virtual void receiveToken(const string &prefix, const string &token); private: int m_minLength; int m_maxLength; bool m_allowNumbers; AbstractTokenReceiver *m_receiver; Ptr m_tokenizer; }; #endif spamprobe-1.4d/src/includes/FrequencyDB.h0000664000076400007640000001026010527261700015361 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FrequencyDB.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FrequencyDB_h #define _FrequencyDB_h #include "Message.h" class CleanupManager; class DatabaseConfig; class FrequencyDBImpl; class WordData; class FrequencyDB { public: FrequencyDB(const DatabaseConfig *config); ~FrequencyDB(); bool open(bool read_only); void close(); void flush(); bool isOpen() { return m_db.get() != 0; } void beginTransaction(); void endTransaction(bool commit); void setWordCounts(const string &word, int good_count, int spam_count); void addWord(const string &word, int good_count, int spam_count); void addWord(const string &word, int good_count, int spam_count, unsigned long flags); bool readWord(const string &word, WordData &counts); void removeWord(const string &word, int good_count, int spam_count); void touchWord(const string &word); void getWordCounts(const string &word, int &good_count, int &spam_count); void getMessageCounts(int &good_message_count, int &spam_message_count); int getTotalMessageCount(); bool containsMessage(const Message &msg, bool &is_spam); int getMessageCount(const Message &msg, bool &is_spam); void addMessage(const Message &msg, bool is_spam, bool force_update); /** Decrement the counts on all terms of this message that are in the database. The message must already be in the database or else nothing is done. */ void removeMessage(const Message &msg); /** Update the timestamp of all terms in this message that are already in the database. Any terms not already in the database are ignored. */ void touchMessage(const Message &msg); bool firstWord(string &word, WordData &counts); bool nextWord(string &word, WordData &counts); string getDatabaseType(); void sweepOutOldTerms(const CleanupManager &cleanman); int getMessageCount(bool is_spam) { int good_count, spam_count; getMessageCounts(good_count, spam_count); return is_spam ? spam_count : good_count; } int getMessageCount() { int good_count, spam_count; getMessageCounts(good_count, spam_count); return good_count + spam_count; } bool requestInterrupt(); bool isInterrupted() { return m_isInterrupted; } void throwOnInterrupt(); void setBusy(bool value) { m_isBusy = value; } static const string COUNT_WORD; private: /// Not implemented. FrequencyDB(const FrequencyDB &); /// Not implemented. FrequencyDB& operator=(const FrequencyDB &); private: void adjustWordCounts(const string &word, int delta, bool is_spam); OWNED FrequencyDBImpl *createDB(string &filename); private: const DatabaseConfig *m_config; Ptr m_db; bool m_isInterrupted; bool m_isBusy; }; #endif // _FrequencyDB_h spamprobe-1.4d/src/includes/HdlSyntaxChecker.h0000664000076400007640000000562510527261700016426 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlSyntaxChecker.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlSyntaxChecker_h #define _HdlSyntaxChecker_h #include "HdlToken.h" class HdlArgumentConstraint; class HdlStatement; class HdlStatementConstraint; class HdlStandardStatementConstraint; class HdlSyntaxChecker { public: HdlSyntaxChecker(const CRef &syntax_tree); ~HdlSyntaxChecker(); void checkSyntax(const CRef &stmt); private: void initFromSyntaxTree(const CRef &syntax_tree); int parseArgs(const Ref &stmt_constraint, const CRef &stmt, int index); void parseTable(const Ref &table, const CRef &stmt); void parseBlock(const Ref &stmt_constraint, const CRef &stmt); void parseStatement(const Ref &stmt_constraint, const CRef &stmt); void parseUnchecked(const Ref &stmt_constraint, const CRef &stmt); void verifyArgCount(const CRef &stmt, int count); void verifyArgEquals(const CRef &stmt, int index, const CRef &token); void verifyArgType(const CRef &stmt, int index, HdlToken::TokenType type); void verifyIsBlock(const CRef &stmt, bool is_block); private: /// Not implemented. HdlSyntaxChecker(const HdlSyntaxChecker &); /// Not implemented. HdlSyntaxChecker& operator=(const HdlSyntaxChecker &); private: Ref m_constraint; }; #endif // _HdlSyntaxChecker_h spamprobe-1.4d/src/includes/HdlPrinter.h0000664000076400007640000000611110527261700015265 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HdlPrinter.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HdlPrinter_h #define _HdlPrinter_h #include "util.h" class HdlPrinter { public: HdlPrinter(); HdlPrinter(const string &indent, const string &increment); ~HdlPrinter(); void beginBlock(ostream &out); void endBlock(ostream &out); void beginStatement(ostream &out, const string &name); void endStatement(ostream &out); void addArgument(ostream &out, const string &str); void addID(ostream &out, const string &str); void addString(ostream &out, const string &str); void addInteger(ostream &out, int value); void addDouble(ostream &out, double value); void reset(); void printBoolStatement(ostream &out, const string &stmt_id, bool value); void printIntStatement(ostream &out, const string &stmt_id, int value); void printDoubleStatement(ostream &out, const string &stmt_id, double value); void printIDStatement(ostream &out, const string &stmt_id, const string &value); void printStringStatement(ostream &out, const string &stmt_id, const string &value); void printStringStatement(ostream &out, const string &stmt_id, char value); void printToken(ostream &out, const CRef &token); void printStatement(ostream &out, const CRef &stmt); private: void printIndent(ostream &out); private: /// Not implemented. HdlPrinter(const HdlPrinter &); /// Not implemented. HdlPrinter& operator=(const HdlPrinter &); private: string m_indent; string m_increment; int m_depth; bool m_atNewLine; }; #endif // _HdlPrinter_h spamprobe-1.4d/src/includes/Makefile.in0000664000076400007640000002140510527227176015122 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/includes DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign EXTRA_DIST = \ AbstractCharReader.h\ AbstractMailMessageParser.h\ AbstractMailMessageReader.h\ AbstractMultiLineString.h\ AbstractTokenizer.h\ AbstractTokenReceiver.h\ Array.h\ AutoTrainMailMessageReader.h\ Buffer.h\ CleanupManager.h\ config.h\ DatabaseConfig.h\ File.h\ FrequencyDB.h\ hash.h\ HeaderPrefixList.h\ HdlError.h\ HdlParser.h\ HdlPrinter.h\ HdlStatement.h\ HdlSyntaxChecker.h\ HdlToken.h\ HdlTokenizer.h\ HtmlTokenizer.h\ InterruptedException.h\ IstreamCharReader.h\ LineReader.h\ LockFD.h\ LockFile.h\ LRUCache.h\ MailMessage.h\ MailMessageDigester.h\ MailMessageList.h\ MailMessageReaderFactory.h\ MD5Digester.h\ Message.h\ MessageHeader.h\ MessageHeaderList.h\ MultiLineJoinedString.h\ MultiLineString.h\ MultiLineSubString.h\ ParserConfig.h\ Ptr.h\ Ref.h\ RegularExpression.h\ SimpleMultiLineStringCharReader.h\ SimpleTokenizer.h\ StringReader.h\ TempPtr.h\ TokenCollector.h\ TokenFilteringTokenizer.h\ Token.h\ Tokenizer.h\ TraditionalMailMessageParser.h\ UrlOnlyHtmlTokenizer.h\ util.h\ WordData.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/includes/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/includes/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am #noinst_PROGRAMS=testrc #testrc_SOURCES=\ # testrc.cc # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/includes/Buffer.h0000664000076400007640000000540510527261700014430 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Buffer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Buffer_h #define _Buffer_h #include "Array.h" // // Similar to Array but handles variable length. // template class Buffer { public: explicit Buffer(int capacity) : m_length(0), m_capacity(capacity), m_ptr(new T[capacity]) { assert(capacity > 0); } T &operator[](int index) const { assert(index >= 0); assert(index < m_length); return m_ptr[index]; } T *get() const { return m_ptr.get(); } void clear() { m_length = 0; } void append(const T &value) { assert(m_length <= m_capacity); if (m_length >= m_capacity) { resize(m_capacity + ((m_capacity < 128) ? 32 : m_capacity / 2)); } assert(m_length < m_capacity); m_ptr[m_length++] = value; } int length() const { return m_length; } int capacity() const { return m_capacity; } void reset(int new_capacity) { assert(new_capacity > 0); Array tmp(new T[new_capacity]); m_length = 0; m_capacity = new_capacity; m_ptr.set(tmp.release()); } void resize(int new_capacity) { assert(new_capacity > 0); Array tmp(new T[new_capacity]); int new_length = (m_length < new_capacity) ? m_length : new_capacity; if (m_ptr.isNotNull() && new_length > 0) { copy(m_ptr.get(), m_ptr.get() + new_length, tmp.get()); } m_capacity = new_capacity; m_length = new_length; m_ptr.set(tmp.release()); assert(m_capacity >= m_length); } private: /// Not implemented. Buffer(const Buffer &); /// Not implemented. Buffer& operator=(const Buffer &); Array m_ptr; int m_length; int m_capacity; }; #endif // _Buffer_h spamprobe-1.4d/src/includes/DatabaseConfig.h0000664000076400007640000000603010527261700016044 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: DatabaseConfig.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _DatabaseConfig_h #define _DatabaseConfig_h #include "util.h" class FrequencyDBImpl; class DatabaseConfig { public: DatabaseConfig(); ~DatabaseConfig(); void setDatabaseType(const string &value) { m_databaseType = value; } const string &databaseType() const { return m_databaseType; } void setPrivateFilename(const string &filename) { m_privateFilename = filename; } const string &privateFilename() const { return m_privateFilename; } void setSharedFilename(const string &filename) { m_sharedFilename = filename; } const string &sharedFilename() const { return m_sharedFilename; } void setTargetSizeMB(int value) { m_targetSizeMB = value; } int targetSizeMB() const { return m_targetSizeMB; } void setMaxCacheTerms(int value) { m_maxCacheTerms = value; } int maxCacheTerms() const { return m_maxCacheTerms; } void parseCommandLineArg(string &arg, string &database_type, int &target_size_mb); OWNED FrequencyDBImpl *createDatabaseImpl(bool read_only) const; OWNED FrequencyDBImpl *createDatabaseImplUsingDefaultType(string &filename) const; private: /// Not implemented. DatabaseConfig(const DatabaseConfig &); /// Not implemented. DatabaseConfig& operator=(const DatabaseConfig &); OWNED FrequencyDBImpl *createDatabaseImplUsingBestFit(const string &type, string &filename) const; OWNED FrequencyDBImpl *createDatabaseImplForType(const string &type, string &filename) const; OWNED FrequencyDBImpl *createDatabaseImplUsingExistingFile(string &filename) const; private: string m_databaseType; string m_privateFilename; string m_sharedFilename; int m_targetSizeMB; int m_maxCacheTerms; }; #endif // _DatabaseConfig_h spamprobe-1.4d/src/includes/MailMessageList.h0000664000076400007640000000331510527261700016240 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageList.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MailMessageList_h #define _MailMessageList_h #include #include "util.h" class MailMessage; class MailMessageList { public: ~MailMessageList() { } void addMessage(OWNED MailMessage *message) { m_messages.push_back(make_ref(message)); } int messageCount() const { return m_messages.size(); } MailMessage *message(int index) const { assert(index >= 0); assert(index < messageCount()); return m_messages[index].ptr(); } private: typedef vector > MessageVector; MessageVector m_messages; }; #endif spamprobe-1.4d/src/includes/MessageHeaderList.h0000664000076400007640000000474610527261700016557 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MessageHeaderList.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MessageHeaderList_h #define _MessageHeaderList_h #include #include "MessageHeader.h" class MessageHeaderList { public: MessageHeaderList() { } ~MessageHeaderList() { } const MessageHeader *header(int index) const { assert(index >= 0); assert(index < headerCount()); return m_headers[index].ptr(); } int headerCount() const { return m_headers.size(); } void addHeader(OWNED MessageHeader *header) { m_headers.push_back(make_ref(header)); } CRef header(const string &name) const; const string &getContentTypeString(string &buffer) const; const string &getBoundaryString(string &buffer) const; const string &getCharsetString(string &buffer) const; bool isTextType() const; bool hasType(const string &type_name) const; bool isMessageType() const; bool hasBoundaryString() const; const string &getHeaderString(const string &header_name, const string &default_value, string &buffer) const; private: const string &findParam(const string &header, const string ¶m, const string &defaultValue, string &buffer) const; private: typedef vector > HeaderVector; HeaderVector m_headers; }; #endif spamprobe-1.4d/src/input/0000777000076400007640000000000010527262434012462 500000000000000spamprobe-1.4d/src/input/IstreamCharReader.cc0000664000076400007640000000460310527261701016233 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: IstreamCharReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "IstreamCharReader.h" class IstreamReaderPosition : public AbstractCharReaderPosition { public: IstreamReaderPosition(streampos _position) : position(_position) { } virtual ~IstreamReaderPosition() { } streampos position; }; IstreamCharReader::IstreamCharReader(istream *stream, bool can_seek) : m_stream(stream), m_rdbuf(stream->rdbuf()), m_canSeek(can_seek) { } IstreamCharReader::~IstreamCharReader() { } bool IstreamCharReader::forward() { int ichr = m_rdbuf->sbumpc(); if (ichr == EOF) { return false; } setCurrentChar(safe_char(ichr)); return true; } bool IstreamCharReader::hasChar() { return m_rdbuf->sgetc() != EOF; } bool IstreamCharReader::atEnd() { return m_rdbuf->sgetc() == EOF; } bool IstreamCharReader::skip(int nchars) { while (nchars-- > 0) { if (!forward()) { return false; } } return true; } OWNED AbstractCharReaderPosition *IstreamCharReader::createMark() { return m_canSeek ? new IstreamReaderPosition(m_rdbuf->pubseekoff(0,ios::cur,ios::in)) : 0; } void IstreamCharReader::returnToMark(AbstractCharReaderPosition *pos) { if (m_canSeek && pos) { m_rdbuf->pubseekpos(dynamic_cast(pos)->position); } } spamprobe-1.4d/src/input/StringReader.cc0000664000076400007640000000421210527261701015273 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: StringReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "StringReader.h" class StringReaderPosition : public AbstractCharReaderPosition { public: StringReaderPosition(int _index) : index(_index) { } virtual ~StringReaderPosition() { } int index; }; StringReader::StringReader(const string &source) : m_source(source), m_index(-1) { } StringReader::~StringReader() { } bool StringReader::forward() { return skip(1); } bool StringReader::hasChar() { return m_index >= 0 && m_index < m_source.length(); } bool StringReader::skip(int nchars) { m_index += nchars; if (m_index >= m_source.length()) { return false; } setCurrentChar(m_source[m_index]); return m_index < m_source.length(); } bool StringReader::atEnd() { return m_index >= m_source.length(); } OWNED AbstractCharReaderPosition *StringReader::createMark() { return new StringReaderPosition(m_index); } void StringReader::returnToMark(AbstractCharReaderPosition *pos) { m_index = dynamic_cast(pos)->index; } spamprobe-1.4d/src/input/SimpleMultiLineStringCharReader.cc0000664000076400007640000001331210527261701021067 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SimpleMultiLineStringCharReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractMultiLineString.h" #include "SimpleMultiLineStringCharReader.h" class SimpleMultiLineStringCharReaderPosition : public AbstractCharReaderPosition { public: SimpleMultiLineStringCharReaderPosition(const string *terminator, const AbstractMultiLineString *target) : m_terminator(terminator), m_target(target) { assert(m_terminator); assert(m_target); m_haveTerminator = m_terminator->size() > 0; reset(); } ~SimpleMultiLineStringCharReaderPosition() { } void copyPosition(const SimpleMultiLineStringCharReaderPosition *other) { assert(other); m_terminator = other->m_terminator; m_target = other->m_target; m_lineIndex = other->m_lineIndex; m_charIndex = other->m_charIndex; m_inTerminator = other->m_inTerminator; m_haveTerminator = other->m_haveTerminator; m_atEnd = other->m_atEnd; m_currentChar = other->m_currentChar; m_currentLine = other->m_currentLine; m_currentLineLength = other->m_currentLineLength; } void reset() { m_lineIndex = 0; m_charIndex = -1; m_inTerminator = false; m_atEnd = m_lineIndex >= m_target->lineCount(); m_currentChar = ' '; m_currentLine = 0; m_currentLineLength = 0; } bool skip(int nchars) { m_charIndex += nchars; return ensureCharReady(); } const string *currentLine() { if (!m_currentLine) { m_currentLine = m_inTerminator ? m_terminator : &m_target->line(m_lineIndex); m_currentLineLength = (int)m_currentLine->size(); } return m_currentLine; } bool hasChar() { return m_lineIndex >= 0 && !m_atEnd; } bool atEnd() const { return m_atEnd; } char currentChar() const { return m_currentChar; } bool ensureCharReady(); int currentLineLength() const { assert(m_currentLine); return m_currentLineLength; } private: const AbstractMultiLineString *m_target; const string *m_terminator; int m_lineIndex; int m_charIndex; bool m_inTerminator; bool m_haveTerminator; bool m_atEnd; char m_currentChar; const string *m_currentLine; int m_currentLineLength; }; bool SimpleMultiLineStringCharReaderPosition::ensureCharReady() { if (m_atEnd) { return false; } assert(m_lineIndex < m_target->lineCount()); for (;;) { const string *line = currentLine(); if (m_charIndex < m_currentLineLength) { m_currentChar = (*line)[m_charIndex]; return true; } m_charIndex -= m_currentLineLength; m_currentLine = 0; if (m_inTerminator || !m_haveTerminator) { m_inTerminator = false; ++m_lineIndex; if (m_lineIndex >= m_target->lineCount()) { break; } } else { m_inTerminator = true; } } m_atEnd = true; return false; } SimpleMultiLineStringCharReader::SimpleMultiLineStringCharReader(const AbstractMultiLineString *target) : m_target(target), m_position(new SimpleMultiLineStringCharReaderPosition(&m_terminator, target)) { reset(); } SimpleMultiLineStringCharReader::SimpleMultiLineStringCharReader(const AbstractMultiLineString *target, const string &terminator) : m_target(target), m_terminator(terminator), m_position(new SimpleMultiLineStringCharReaderPosition(&m_terminator, target)) { reset(); } SimpleMultiLineStringCharReader::~SimpleMultiLineStringCharReader() { } bool SimpleMultiLineStringCharReader::forward() { return skip(1); } bool SimpleMultiLineStringCharReader::skip(int nchars) { bool answer = m_position->skip(nchars); if (answer) { setCurrentChar(m_position->currentChar()); } return answer; } bool SimpleMultiLineStringCharReader::hasChar() { return m_position->hasChar(); } bool SimpleMultiLineStringCharReader::atEnd() { return m_position->atEnd(); } void SimpleMultiLineStringCharReader::reset() { m_position->reset(); } AbstractCharReaderPosition *SimpleMultiLineStringCharReader::createMark() { return new SimpleMultiLineStringCharReaderPosition(*m_position.get()); } void SimpleMultiLineStringCharReader::returnToMark(AbstractCharReaderPosition *position) { m_position->copyPosition(dynamic_cast(position)); setCurrentChar(m_position->currentChar()); } const string *SimpleMultiLineStringCharReader::getCurrentLine() { return m_position->currentLine(); } bool SimpleMultiLineStringCharReader::ensureCharReady() { bool answer = m_position->ensureCharReady(); if (answer) { setCurrentChar(m_position->currentChar()); } return answer; } spamprobe-1.4d/src/input/LineReader.cc0000664000076400007640000000514610527261701014723 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: LineReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "AbstractCharReader.h" #include "LineReader.h" static const char CR = '\r'; static const char LF = '\n'; LineReader::LineReader(AbstractCharReader *reader) : m_reader(reader), m_buffer(40960), m_needsStart(true), m_hasLine(false) { } LineReader::~LineReader() { } bool LineReader::forward() { int remaining = INT_MAX; return forward(remaining); } bool LineReader::forwardChar(int &remaining) { if (remaining <= 0) { return false; } --remaining; return m_reader->forward(); } bool LineReader::forward(int &chars_remaining) { if (m_needsStart) { forwardChar(chars_remaining); m_needsStart = false; } if (chars_remaining <= 0 || m_reader->atEnd()) { m_line.erase(); m_hasLine = false; return false; } m_buffer.clear(); while (chars_remaining >= 0 && m_reader->hasChar()) { char ch = m_reader->currentChar(); forwardChar(chars_remaining); if (isLineTerminator(ch, chars_remaining)) { break; } m_buffer.append(ch); if (chars_remaining == 0) { break; } } m_line.assign(m_buffer.get(), m_buffer.get() + m_buffer.length()); m_hasLine = true; return true; } bool LineReader::isLineTerminator(char ch, int &chars_remaining) { if (ch == CR) { if (m_reader->hasChar() && m_reader->currentChar() == LF) { forwardChar(chars_remaining); } return true; } return ch == LF; } bool LineReader::hasLine() { return m_hasLine; } spamprobe-1.4d/src/input/Makefile.am0000664000076400007640000000034010526706576014442 00000000000000AUTOMAKE_OPTIONS=foreign INCLUDES= -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES=libinput.a libinput_a_SOURCES=\ IstreamCharReader.cc\ LineReader.cc\ SimpleMultiLineStringCharReader.cc\ StringReader.cc spamprobe-1.4d/src/input/Makefile.in0000664000076400007640000002751310527227177014462 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(libinput_a_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/input DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libinput_a_AR = $(AR) $(ARFLAGS) libinput_a_LIBADD = am_libinput_a_OBJECTS = IstreamCharReader.$(OBJEXT) \ LineReader.$(OBJEXT) SimpleMultiLineStringCharReader.$(OBJEXT) \ StringReader.$(OBJEXT) libinput_a_OBJECTS = $(am_libinput_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libinput_a_SOURCES) DIST_SOURCES = $(libinput_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES = libinput.a libinput_a_SOURCES = \ IstreamCharReader.cc\ LineReader.cc\ SimpleMultiLineStringCharReader.cc\ StringReader.cc all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/input/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/input/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libinput.a: $(libinput_a_OBJECTS) $(libinput_a_DEPENDENCIES) -rm -f libinput.a $(libinput_a_AR) libinput.a $(libinput_a_OBJECTS) $(libinput_a_LIBADD) $(RANLIB) libinput.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IstreamCharReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LineReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleMultiLineStringCharReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringReader.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/utility/0000777000076400007640000000000010527262437013031 500000000000000spamprobe-1.4d/src/utility/MD5Digester.cc0000664000076400007640000000425110527261701015325 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MD5Digester.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "md5.h" #include "MD5Digester.h" MD5Digester::MD5Digester() : m_running(false), m_state(new md5_state_s) { } MD5Digester::~MD5Digester() { if (m_running) { md5_byte_t raw_digest[32]; md5_finish(m_state.get(), raw_digest); } } void MD5Digester::start() { assert(!m_running); m_digest.erase(); md5_init(m_state.get()); m_running = true; } void MD5Digester::add(const string &value) { assert(m_running); if (value.length() > 0) { md5_append(m_state.get(), (md5_byte_t *)value.data(), value.length()); } } void MD5Digester::add(const unsigned char *bytes, int num_bytes) { assert(m_running); if (num_bytes > 0) { md5_append(m_state.get(), (md5_byte_t *)bytes, num_bytes); } } void MD5Digester::stop() { assert(m_running); md5_byte_t raw_digest[32]; md5_finish(m_state.get(), raw_digest); m_digest.erase(); for (int i = 0; i < 16; ++i) { m_digest += hex_digit((raw_digest[i] >> 4) & 0x0f); m_digest += hex_digit(raw_digest[i] & 0x0f); } m_running = false; } spamprobe-1.4d/src/utility/MultiLineString.cc0000664000076400007640000000471410527261701016346 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MultiLineString.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MultiLineString.h" MultiLineString::MultiLineString() { } MultiLineString::~MultiLineString() { } int MultiLineString::lineCount() const { return m_lines.size(); } const string &MultiLineString::line(int index) const { assert(index >= 0); assert(index < m_lines.size()); return m_lines[index]; } void MultiLineString::addLine(const string &line) { m_lines.push_back(line); } void MultiLineString::appendToLastLine(const string &line) { if (m_lines.size() == 0) { m_lines.push_back(line); } else { m_lines[m_lines.size() - 1] += line; } } void MultiLineString::parseText(const string &text) { const char *start = text.c_str(); for (const char *s = start; *s; ++s) { assert(start <= s); switch (*s) { case '\r': { string line(start, s); addLine(line); if (s[1] == '\n') { s += 1; } start = s + 1; } break; case '\n': { string line(start, s); addLine(line); start = s + 1; } break; default: break; } } assert(start <= (text.c_str() + text.length())); if (*start) { addLine(start); } } Ref MultiLineString::fromText(const string &text) { Ref answer(new MultiLineString()); answer->parseText(text); return answer; } spamprobe-1.4d/src/utility/hash.c0000664000076400007640000001100210526706576014036 00000000000000/* By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this code any way you wish, private, educational, or commercial. It's free. See http://burtleburtle.net/bob/hash/evahash.html Use for hash table lookup, or anything where one collision in 2^^32 is acceptable. Do NOT use for cryptographic purposes. */ #include "hash.h" /* -------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. For every delta with one or two bits set, and the deltas of all three high bits or all three low bits, whether the original value of a,b,c is almost all zero or is uniformly distributed, * If mix() is run forward or backward, at least 32 bits in a,b,c have at least 1/4 probability of changing. * If mix() is run forward, every bit of c will change between 1/3 and 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) mix() was built out of 36 single-cycle latency instructions in a structure that could supported 2x parallelism, like so: a -= b; a -= c; x = (c>>13); b -= c; a ^= x; b -= a; x = (a<<8); c -= a; b ^= x; c -= b; x = (b>>13); ... Unfortunately, superscalar Pentiums and Sparcs can't take advantage of that parallelism. They've also turned some of those single-cycle latency instructions into multi-cycle latency instructions. Still, this is the fastest good hash I could find. There were about 2^^68 to choose from. I only looked at a billion or so. -------------------------------------------------------------------- */ #define mix(a,b,c) \ { \ a -= b; a -= c; a ^= (c>>13); \ b -= c; b -= a; b ^= (a<<8); \ c -= a; c -= b; c ^= (b>>13); \ a -= b; a -= c; a ^= (c>>12); \ b -= c; b -= a; b ^= (a<<16); \ c -= a; c -= b; c ^= (b>>5); \ a -= b; a -= c; a ^= (c>>3); \ b -= c; b -= a; b ^= (a<<10); \ c -= a; c -= b; c ^= (b>>15); \ } /* -------------------------------------------------------------------- hash() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) len : the length of the key, counting by bytes initval : can be any 4-byte value Returns a 32-bit value. Every bit of the key affects every bit of the return value. Every 1-bit and 2-bit delta achieves avalanche. About 6*len+35 instructions. The best hash table sizes are powers of 2. There is no need to do mod a prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. For example, if you need only 10 bits, do h = (h & hashmask(10)); In which case, the hash table should have hashsize(10) elements. If you are hashing n strings (ub1 **)k, do it like this: for (i=0, h=0; i= 12) { a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24)); b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24)); c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24)); mix(a,b,c); k += 12; len -= 12; } /*------------------------------------- handle the last 11 bytes */ c += length; switch(len) /* all the case statements fall through */ { case 11: c+=((ub4)k[10]<<24); case 10: c+=((ub4)k[9]<<16); case 9 : c+=((ub4)k[8]<<8); /* the first byte of c is reserved for the length */ case 8 : b+=((ub4)k[7]<<24); case 7 : b+=((ub4)k[6]<<16); case 6 : b+=((ub4)k[5]<<8); case 5 : b+=k[4]; case 4 : a+=((ub4)k[3]<<24); case 3 : a+=((ub4)k[2]<<16); case 2 : a+=((ub4)k[1]<<8); case 1 : a+=k[0]; /* case 0: nothing left to add */ } mix(a,b,c); /*-------------------------------------------- report the result */ return c; } spamprobe-1.4d/src/utility/LockFD.cc0000664000076400007640000000376510527261701014364 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: LockFD.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include #include #include #include "LockFD.h" LockFD::LockFD(int fd) : m_lockFD(fd), m_locked(false) { } LockFD::~LockFD() { try { release(); } catch (...) { } } void LockFD::lock(LockType_t lock_type) { release(); struct flock buf; buf.l_type = (lock_type == SHARED_LOCK) ? F_RDLCK : F_WRLCK; buf.l_whence = SEEK_SET; buf.l_start = 0; buf.l_len = 0; int rc = fcntl(m_lockFD, F_SETLKW, &buf); if (rc < 0) { throw runtime_error(strerror(errno)); } m_locked = true; } void LockFD::release() { if (m_locked) { struct flock buf; buf.l_type = F_UNLCK; buf.l_whence = SEEK_SET; buf.l_start = 0; buf.l_len = 0; int rc = fcntl(m_lockFD, F_SETLK, &buf); if (rc < 0) { throw runtime_error(strerror(errno)); } m_locked = false; } } spamprobe-1.4d/src/utility/util.cc0000664000076400007640000001151210527261701014224 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: util.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "util.h" const string EMPTY_STRING; static const char HEX_CHARS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; bool is_debug = false; bool is_verbose = false; string to_7bits(const string &str) { string answer(str); for (string::size_type pos = 0, limit = str.length(); pos < limit; ++pos) { unsigned char ch = str[pos]; if (ch & 0x80) { answer[pos] = (char)(ch & 0x7f); } } return answer; } string trim_copy(const string &str, string::size_type offset) { string answer; const char *s = str.c_str() + offset; while (*s && is_space(*s)) { ++s; } while (*s) { answer += *s; ++s; } return answer; } string trim(const string &str) { const char *start = str.c_str(); while (*start && is_space(*start)) { ++start; } string answer; if (*start) { const char *last = start; for (const char *s = start; *s; ++s) { if (!is_space(*s)) { last = s; } } answer.assign(start, last - start + 1); } return answer; } string to_lower(const string &str) { string answer; answer.reserve(str.length() + 1); for (const char *s = str.c_str(); *s; ++s) { answer += to_lower(*s); } return answer; } string to_upper(const string &str) { string answer; for (const char *s = str.c_str(); *s; ++s) { answer += to_upper(*s); } return answer; } bool is_digits(const string &str) { for (const char *s = str.c_str(); *s; ++s) { if (!is_digit(*s)) { return false; } } return true; } bool is_lower(const string &str) { for (const char *s = str.c_str(); *s; ++s) { if (is_alpha(*s) && !is_lower(*s)) { return false; } } return true; } void encode_string(const string &src, string &dst) { const unsigned char *s = (const unsigned char *)src.data(); const unsigned char *end = s + src.size(); for ( ; s != end; ++s) { if (*s == '\\') { dst += "\\\\"; } else if (isprint(*s) && (*s != '\"')) { dst += *s; } else { dst += '\\'; dst += ('0' + ((*s & 0xd0) >> 6)); dst += ('0' + ((*s & 0x38) >> 3)); dst += ('0' + (*s & 0x07)); } } } void decode_string(const string &src, string &dst) { const char *s = src.c_str(); while (*s) { if (*s != '\\') { dst += *s; ++s; } else { ++s; if (*s == '\\') { dst += *s; ++s; } else { assert(is_digit(s[0]) && is_digit(s[1]) && is_digit(s[2])); unsigned char ch = ((s[0] - '0') << 6) | ((s[1] - '0') << 3) | (s[2] - '0'); dst += ch; s += 3; } } } } char hex_digit(unsigned ch) { assert(ch <= 15); return HEX_CHARS[ch & 0x0f]; } int hex_to_int(char ch) { if (is_digit(ch)) { return ch - '0'; } else { return 10 + to_lower(ch) - 'a'; } } int hex_to_int(const string &str) { int answer = 0; for (const char *s = str.c_str(); *s; ++s) { answer = (answer << 4) | hex_to_int(*s); } return answer; } const char *num_to_string(int num) { static char buffer[32]; sprintf(buffer, "%d", num); return buffer; } const char *num_to_string(double num) { static char buffer[128]; sprintf(buffer, "%f", num); return buffer; } const char *num_to_string3(int num) { static char buffer[32]; sprintf(buffer, "%03d", num); return buffer; } spamprobe-1.4d/src/utility/RegularExpression.cc0000664000076400007640000001371110527261701016733 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: RegularExpression.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef HAVE_REGEX_H #error This module requires POSIX regular expressions #endif #include "RegularExpression.h" #include #define MAX_MATCHES 25 void dumpstr(const string &str) { cout << "dump: len " << dec << str.length() << ": " << str << endl; for (string::size_type pos = 0; pos < str.length(); ++pos) { if (pos % 20 == 0 && pos != 0) { cout << endl; } cout << str[pos] << " " << hex << (unsigned)(str[pos] & 0xff) << " "; } cout << endl; } class RegularExpressionImpl { public: RegularExpressionImpl() : m_haveExpr(false) { } ~RegularExpressionImpl() { if (m_haveExpr) { regfree(&m_expr); } } void release() { if (m_haveExpr) { regfree(&m_expr); m_numSubs = 0; m_haveExpr = false; } } bool compile(const string &expr, int num_subs, bool ignore_case, bool ignore_newline) { assert(num_subs < MAX_MATCHES); release(); int flags = REG_EXTENDED; if (ignore_case) { flags |= REG_ICASE; } if (ignore_newline) { flags |= REG_NEWLINE; } if (num_subs == 0) { flags |= REG_NOSUB; } if (regcomp(&m_expr, expr.c_str(), flags)) { return false; } m_numSubs = num_subs; m_haveExpr = true; return true; } bool match(const string &text, vector &match_vec) { assert(m_haveExpr); match_vec.clear(); regmatch_t matches[MAX_MATCHES + 1]; int rc = regexec(&m_expr, to_7bits(text).c_str(), m_numSubs + 1, matches, 0); if (rc != 0) { return false; } for (int i = 0; i <= m_numSubs; ++i) { RegularExpression::MatchData md; if (matches[i].rm_so == -1) { md.start_pos = 0; md.end_pos = 0; } else { md.start_pos = matches[i].rm_so; md.end_pos = matches[i].rm_eo; } match_vec.push_back(md); } return true; } private: bool m_haveExpr; int m_numSubs; regex_t m_expr; }; RegularExpression::RegularExpression() { } RegularExpression::RegularExpression(const string &expr, int num_subs, bool ignore_case, bool ignore_newline) { setExpression(expr, num_subs, ignore_case, ignore_newline); } RegularExpression::~RegularExpression() { } bool RegularExpression::isValid() { return m_expr.get() != 0; } bool RegularExpression::setExpression(const string &expr, int num_subs, bool ignore_case, bool ignore_newline) { Ptr new_expr(new RegularExpressionImpl); if (!new_expr->compile(expr, num_subs, ignore_case, ignore_newline)) { return false; } m_expr.set(new_expr.release()); return true; } bool RegularExpression::match(const string &text) { assert(isValid()); m_text = text; return m_expr->match(m_text, m_matches); } int RegularExpression::matchCount() const { return (int)m_matches.size(); } void RegularExpression::removeMatch(int match_index, string &text) { assert(match_index < matchCount()); MatchData *match_data = &m_matches[match_index]; text.erase(match_data->start_pos, match_data->end_pos - match_data->start_pos + 1); } void RegularExpression::replaceMatch(int match_index, string &text, const string &replace_with) { assert(match_index < matchCount()); MatchData *match_data = &m_matches[match_index]; text.replace(match_data->start_pos, match_data->end_pos - match_data->start_pos + 1, replace_with); } void RegularExpression::getMatch(int match_index, MatchData &match_data) { assert(match_index < matchCount()); match_data = m_matches[match_index]; } const string &RegularExpression::getMatch(int match_index, string &matched_string) { assert(match_index < matchCount()); MatchData &md(m_matches[match_index]); matched_string = m_text.substr(md.start_pos, md.end_pos - md.start_pos); return matched_string; } const string &RegularExpression::getMatch(int match_index, string &matched_string, const string &default_value) { if (match_index < matchCount()) { MatchData &md(m_matches[match_index]); matched_string = m_text.substr(md.start_pos, md.end_pos - md.start_pos); } else { matched_string = default_value; } return matched_string; } ostream &RegularExpression::dumpMatches(ostream &out) { string buffer; for (int i = 0; i < matchCount(); ++i) { out << " " << i << ": " << getMatch(i, buffer) << endl; } return out; } spamprobe-1.4d/src/utility/LockFile.cc0000664000076400007640000000351210527261701014740 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: LockFile.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include #include #include #include "LockFile.h" LockFile::LockFile(const File &file) : m_file(file) { } LockFile::~LockFile() { try { release(); } catch (...) { } } void LockFile::lock(LockType_t lock_type, int lock_mode) { release(); int open_flag = O_CREAT | ((lock_type == LockFD::SHARED_LOCK) ? O_RDONLY : O_RDWR); int fd = ::open(m_file, open_flag, lock_mode); if (fd < 0) { throw runtime_error(strerror(errno)); } m_lock.set(new LockFD(fd)); m_lock->lock(lock_type); } void LockFile::release() { if (m_lock.get()) { m_lock->release(); close(m_lock->getFD()); m_lock.clear(); } } spamprobe-1.4d/src/utility/MultiLineJoinedString.cc0000664000076400007640000000377610527261701017506 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MultiLineJoinedString.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "MultiLineJoinedString.h" MultiLineJoinedString::MultiLineJoinedString(const MultiLineStringList &targets) : m_targets(targets) { } MultiLineJoinedString::~MultiLineJoinedString() { } int MultiLineJoinedString::lineCount() const { int answer = 0; for (MultiLineStringList::const_iterator i = m_targets.begin(); i != m_targets.end(); ++i) { answer += (*i)->lineCount(); } return answer; } const string &MultiLineJoinedString::line(int index) const { assert(index >= 0); assert(index < lineCount()); for (MultiLineStringList::const_iterator i = m_targets.begin(); i != m_targets.end(); ++i) { if (index < (*i)->lineCount()) { return (*i)->line(index); } index -= (*i)->lineCount(); } assert(false); throw std::out_of_range("MultiLineJoinedString: range check"); } spamprobe-1.4d/src/utility/Makefile.am0000664000076400007640000000062710526706576015016 00000000000000AUTOMAKE_OPTIONS=foreign INCLUDES= -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES=libutility.a libutility_a_SOURCES=\ AbstractMultiLineString.cc\ File.cc\ hash.c\ LockFD.cc\ LockFile.cc\ MD5Digester.cc\ md5.c\ md5.h\ MultiLineJoinedString.cc\ MultiLineString.cc\ MultiLineSubString.cc\ RegularExpression.cc\ util.cc #noinst_PROGRAMS=test_lru #test_lru_SOURCES=\ # test_lru.cc spamprobe-1.4d/src/utility/md5.h0000664000076400007640000000647610527260276013621 00000000000000/* Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.h is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed references to Ghostscript; clarified derivation from RFC 1321; now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); added conditionalization for C++ compilation from Martin Purschke . 1999-05-03 lpd Original version. */ #ifndef md5_INCLUDED # define md5_INCLUDED /* * This package supports both compile-time and run-time determination of CPU * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is * defined as non-zero, the code will be compiled to run only on big-endian * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to * run on either big- or little-endian CPUs, but will run slightly less * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. */ typedef unsigned char md5_byte_t; /* 8-bit byte */ typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { md5_word_t count[2]; /* message length in bits, lsw first */ md5_word_t abcd[4]; /* digest buffer */ md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; #ifdef __cplusplus extern "C" { #endif /* Initialize the algorithm. */ void md5_init(md5_state_t *pms); /* Append a string to the message. */ void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); /* Finish the message and return the digest. */ void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ #endif #endif /* md5_INCLUDED */ spamprobe-1.4d/src/utility/AbstractMultiLineString.cc0000664000076400007640000000372410527261701020032 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractMultiLineString.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "SimpleMultiLineStringCharReader.h" #include "AbstractMultiLineString.h" AbstractMultiLineString::~AbstractMultiLineString() { } Ref AbstractMultiLineString::createCharReader() const { return Ref(new SimpleMultiLineStringCharReader(this, EMPTY_STRING)); } Ref AbstractMultiLineString::createCharReader(const string &terminator) const { return Ref(new SimpleMultiLineStringCharReader(this, terminator)); } const string &AbstractMultiLineString::join(string &buffer) const { return join(buffer, EMPTY_STRING); } const string &AbstractMultiLineString::join(string &buffer, const string &terminator) const { for (int i = 0; i < lineCount(); ++i) { buffer += line(i); buffer += terminator; } return buffer; } spamprobe-1.4d/src/utility/md5.c0000664000076400007640000003022010526706576013603 00000000000000/* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order either statically or dynamically; added missing #include in library. 2002-03-11 lpd Corrected argument list for main(), and added int return type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is unsigned in ANSI C, signed in traditional"; made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ #include "md5.h" #include #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) #else # define BYTE_ORDER 0 #endif #define T_MASK ((md5_word_t)~0) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) #define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) #define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) #define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) #define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) #define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) #define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) #define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) #define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) #define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) #define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) #define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) #define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) #define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) #define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) #define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) #define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) #define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) #define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ md5_word_t X[16]; #else /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; const md5_word_t *X; #endif { #if BYTE_ORDER == 0 /* * Determine dynamically whether this is a big-endian or * little-endian machine, since we can use a more efficient * algorithm on the latter. */ static const int w = 1; if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ #endif #if BYTE_ORDER <= 0 /* little-endian */ { /* * On little-endian machines, we can process properly aligned * data without copying it. */ if (!((data - (const md5_byte_t *)0) & 3)) { /* data are properly aligned */ X = (const md5_word_t *)data; } else { /* not aligned */ memcpy(xbuf, data, 64); X = xbuf; } } #endif #if BYTE_ORDER == 0 else /* dynamic big-endian */ #endif #if BYTE_ORDER >= 0 /* big-endian */ { /* * On big-endian machines, we must arrange the bytes in the * right order. */ const md5_byte_t *xp = data; int i; # if BYTE_ORDER == 0 X = xbuf; /* (dynamic only) */ # else # define xbuf X /* (static only) */ # endif for (i = 0; i < 16; ++i, xp += 4) xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); } #endif } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; pms->abcd[3] += d; } void md5_init(md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; pms->abcd[3] = 0x10325476; } void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) { const md5_byte_t *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; md5_word_t nbits = (md5_word_t)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } spamprobe-1.4d/src/utility/MultiLineSubString.cc0000664000076400007640000000443310527261701017016 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MultiLineSubString.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MultiLineSubString.h" MultiLineSubString::MultiLineSubString(const CRef &target, int start_index, int limit_index) : m_target(target) { assert(m_target.isNotNull()); assert(start_index >= 0); assert(limit_index >= 0); start_index = max(0, start_index); limit_index = max(0, min(limit_index, m_target->lineCount())); if (m_target->lineCount() == 0 || start_index >= m_target->lineCount() || start_index >= limit_index) { m_startIndex = m_target->lineCount(); // force out_of_range exception if ::line() called m_length = 0; } else { m_startIndex = start_index; m_length = limit_index - start_index; } assert(m_startIndex >= 0); assert(m_startIndex <= m_target->lineCount()); assert(m_length >= 0); assert(m_length <= m_target->lineCount()); } MultiLineSubString::~MultiLineSubString() { } int MultiLineSubString::lineCount() const { return m_length; } const string &MultiLineSubString::line(int index) const { assert(index >= 0); assert(index < m_length); return m_target->line(m_startIndex + index); } spamprobe-1.4d/src/utility/Makefile.in0000664000076400007640000003350110527227200015003 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(libutility_a_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/utility DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libutility_a_AR = $(AR) $(ARFLAGS) libutility_a_LIBADD = am_libutility_a_OBJECTS = AbstractMultiLineString.$(OBJEXT) \ File.$(OBJEXT) hash.$(OBJEXT) LockFD.$(OBJEXT) \ LockFile.$(OBJEXT) MD5Digester.$(OBJEXT) md5.$(OBJEXT) \ MultiLineJoinedString.$(OBJEXT) MultiLineString.$(OBJEXT) \ MultiLineSubString.$(OBJEXT) RegularExpression.$(OBJEXT) \ util.$(OBJEXT) libutility_a_OBJECTS = $(am_libutility_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libutility_a_SOURCES) DIST_SOURCES = $(libutility_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES = libutility.a libutility_a_SOURCES = \ AbstractMultiLineString.cc\ File.cc\ hash.c\ LockFD.cc\ LockFile.cc\ MD5Digester.cc\ md5.c\ md5.h\ MultiLineJoinedString.cc\ MultiLineString.cc\ MultiLineSubString.cc\ RegularExpression.cc\ util.cc all: all-am .SUFFIXES: .SUFFIXES: .c .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/utility/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/utility/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libutility.a: $(libutility_a_OBJECTS) $(libutility_a_DEPENDENCIES) -rm -f libutility.a $(libutility_a_AR) libutility.a $(libutility_a_OBJECTS) $(libutility_a_LIBADD) $(RANLIB) libutility.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractMultiLineString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LockFD.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LockFile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MD5Digester.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiLineJoinedString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiLineString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiLineSubString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RegularExpression.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .cc.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am #noinst_PROGRAMS=test_lru #test_lru_SOURCES=\ # test_lru.cc # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/utility/File.cc0000664000076400007640000001155710527261701014137 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: File.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include #include #include #ifdef HAVE_DIRENT_H #include #endif #include #include "File.h" const char SEPARATOR_CHAR('/'); const string SEPARATOR("/"); const string SUFFIX_START("."); const string File::DOT("."); const string File::DOT_DOT(".."); File::File() { } File::File(const string &path) { setPath(path); } File::File(const File &other) : m_path(other.m_path) { } File::File(const File &other, const string &name) : m_path(other.m_path) { addComponent(name); } File::~File() { } File &File::operator=(const File &other) { m_path = other.m_path; return *this; } void File::addComponent(const string &name) { if (m_path != SEPARATOR) { m_path += SEPARATOR; } string::size_type last = name.length() - 1; if (last >= 1 && name[last] == SEPARATOR_CHAR) { m_path.append(name, 0, last); } else { m_path += name; } } void File::setPath(const string &path) { string::size_type last = path.length() - 1; if (last >= 1 && path[last] == SEPARATOR_CHAR) { m_path.assign(path, 0, last); } else { m_path = path; } } bool File::exists() const { struct stat buf; return stat(m_path.c_str(), &buf) == 0; } bool File::isFile() const { struct stat buf; return stat(m_path.c_str(), &buf) == 0 && S_ISREG(buf.st_mode); } bool File::isDirectory() const { struct stat buf; return stat(m_path.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode); } bool File::isHidden() const { return starts_with(getName(), DOT); } bool File::isSelfOrParent() const { string name = getName(); return name == DOT || name == DOT_DOT; } bool File::hasChild(const string &path) const { return File(*this, path).exists(); } unsigned long File::getSize() const { struct stat buf; return stat(m_path.c_str(), &buf) == 0 ? buf.st_size : 0; } File File::parent() const { string::size_type pos = m_path.rfind(SEPARATOR); if (pos == string::npos) { return isDirectory() ? File(DOT_DOT) : File(DOT); } else { return File(m_path.substr(0, pos)); } } string File::getName() const { string::size_type pos = m_path.rfind(SEPARATOR); if (pos == string::npos) { return m_path; } else { return m_path.substr(pos + 1); } } void File::makeDirectory(int mode) const { if (mkdir(m_path.c_str(), (mode_t)mode) != 0) { throw runtime_error(strerror(errno)); } } void File::rename(const string &new_path) { if (::rename(m_path.c_str(), new_path.c_str()) != 0) { throw runtime_error(strerror(errno)); } m_path = new_path; } void File::remove() { if (unlink(m_path.c_str()) != 0) { throw runtime_error(strerror(errno)); } } File File::getHomeDir() { char *home = getenv("HOME"); if (home == NULL) { return File(); } else { return File(home); } } bool File::hasSuffix(const string &suffix) const { string::size_type pos = m_path.rfind(SUFFIX_START); return (pos != string::npos) && (strcmp(m_path.c_str() + pos + 1, suffix.c_str()) == 0); } void File::setSuffix(const string &suffix) { string::size_type pos = m_path.rfind(SUFFIX_START); if (pos != string::npos && m_path.find(SEPARATOR, pos + 1) == string::npos) { m_path.erase(pos, string::npos); } m_path += SUFFIX_START; m_path += suffix; } bool operator<(const File &a, const File &b) { return a.getPath() < b.getPath(); } #ifdef HAVE_DIRENT_H struct DirHelper { DirHelper(const char *path) : dir(opendir(path)) {} ~DirHelper() { if (dir) closedir(dir); } DIR *dir; }; #endif void File::children(vector &files) { #ifdef HAVE_DIRENT_H DirHelper d(m_path.c_str()); if (d.dir) { for (struct dirent *ent = readdir(d.dir); ent ; ent = readdir(d.dir)) { files.push_back(File(*this, ent->d_name)); } } #endif } spamprobe-1.4d/src/scripts/0000777000076400007640000000000010527262426013013 500000000000000spamprobe-1.4d/src/scripts/runtest.sh0000664000076400007640000000401210526706576014776 00000000000000#!/bin/bash # Script to run spamprobe on input files generated by splitmail.rb and # summarize the results. #DBPREFIX=hash:44: #DBDIR=$HOME/.spamprobe #DBDIR=$HOME/sptest2 DBPREFIX= DBDIR=$HOME/s2test DBARG=${DBPREFIX}${DBDIR} ulimit -c 100000 CACHE_ARG="-s 500" VERBOSE="" #SPEXEC="./spamprobe.old.2" SPEXEC="./spamprobe -cd $DBARG $CACHE_ARG" ( #for i in normal normal-ext all-sigs graham ; do #for i in normal all-sigs normal-5 all-sigs-5 ; do #for i in normal normal-3 normal-5 ; do #for i in normal normal-3 graham ; do #for i in phrases-2 phrases-3 phrases-4 phrases-5 ; do #for i in normal avg alt1 ; do #for i in normal all-phrases-5 all-phrases-3-5 ; do #for i in normal proximity-3 proximity-5 ; do for i in normal ; do echo `date` RUNNING TEST $i if [ -d $DBDIR ] ; then \rm $DBDIR/* 2>/dev/null fi #echo `date` Training #cat _spam.1 | formail -n 5 -s $SPEXEC train-spam & #cat _good.1 | formail -n 5 -s $SPEXEC train-good & #wait echo `date` Adding good emails $SPEXEC -t $i good _good.1 echo `date` Adding spam emails $SPEXEC -t $i spam _spam.1 echo Purging unique terms $SPEXEC -cd $DBARG purge 1 echo `date` Database directory ls -l $DBDIR/sp* echo `date` Number of messages in database $SPEXEC -t $i counts #echo `date` Number of terms in database #$SPEXEC -t $i dump | wc -l echo `date` Verifying good emails "(looking for false positives)" $SPEXEC $VERBOSE -t $i score _good.1 | ruby countscores.rb #echo `date` Finding false positives #$SPEXEC $VERBOSE -T -t $i find-spam _good.1 echo `date` Verifying spam emails $SPEXEC $VERBOSE -t $i score _spam.1 | ruby countscores.rb echo `date` Scoring good mails $SPEXEC $VERBOSE -t $i score _good.2 | ruby countscores.rb #echo `date` Finding false positives #$SPEXEC $VERBOSE -T -t $i find-spam _good.2 echo `date` Scoring spam mails $SPEXEC $VERBOSE -t $i score _spam.2 | ruby countscores.rb #echo `date` Finding false negatives #$SPEXEC $VERBOSE -T -t $i find-good _spam.2 echo done ) 2>&1 | tee _results spamprobe-1.4d/src/scripts/wordtests.sh0000664000076400007640000000232110526706576015331 00000000000000#!/bin/bash # Script to run spamprobe on input files generated by splitmail.rb and # summarize the results. DBDIR=$HOME/s3test SPEXEC=./spamprobe ( for h in min-0.25 ; do for w in 27 38 50 65; do for r in 2 3 4 ; do echo `date` RUNNING TEST with $h testcase $w words $r repeats cmd="$SPEXEC -t $h -r $r -w $w -cd $DBDIR" echo Building databases if [ -d $DBDIR ] ; then \rm $DBDIR/*.pag $DBDIR/*.dir $DBDIR/*.db $DBDIR/sp_words.* 2>/dev/null fi $cmd good _good.1 $cmd spam _spam.1 echo `date` Verifying good emails $cmd score _good.1 | ruby countscores.rb #$cmd find-spam _good.1 echo `date` Verifying spam emails $cmd score _spam.1 | ruby countscores.rb #$cmd find-good _spam.1 echo `date` Scoring good mails $cmd score _good.2 | ruby countscores.rb #$cmd find-spam _good.2 echo `date` Scoring spam mails $cmd score _spam.2 | ruby countscores.rb #$cmd find-good _spam.2 #echo Incrementally scoring good mails #ruby incrtest.rb _good.2 good "$cmd" #echo Incrementally scoring spam mails #ruby incrtest.rb _spam.2 spam "$cmd" echo `date` finished done done done ) 2>&1 | tee _results spamprobe-1.4d/src/scripts/incrtest.rb0000664000076400007640000000402010526706576015115 00000000000000#!/usr/bin/ruby # # A script to read an mbox of spams and perform a test on each to # see how well the filter can score spams as they arrive. After # each message is score it is classified as spam and the next # is scored. This is intended to simulate normal use of the # filter with incoming email. # if ARGV.length != 3 STDERR.printf("usage: incrtest filename mail_type spamprobe\n") exit 1 end class ScoreKeeper def initialize @goods = 0.to_f @spams = 0.to_f @classifies = 0 end def isWrongType(score, mailtype) if score >= 0.9 return mailtype == "good" else return mailtype == "spam" end end def addScore(score) if score >= 0.9 @spams += 1 else @goods += 1 end end def addGood @goods += 1 end def addSpam @spams += 1 end def total @goods + @spams end def percentage 100.0 * @spams / (@goods + @spams) end def printSummary printf("GOOD %10d SPAM %10d TOTAL %10d PCT %10.2f (%d errors)\n", @goods, @spams, total, percentage, @classifies) end def processMail(baseargs, mailtype, tmpname) score = 0 args = baseargs + " score " + tmpname IO.popen(args, "r") do |f| a = f.readlines addScore(a[0].to_f) end if isWrongType(score, mailtype) @classifies += 1 system(baseargs + " " + mailtype + " " + tmpname) end end end tmpname = '_temp' filename = ARGV.shift mailtype = ARGV.shift baseargs = ARGV.shift score_keeper = ScoreKeeper.new on_blank = true first = true tmp = File.open(tmpname, "w") File.open(filename).each do |line| if on_blank and line =~ /^From\s+\S+\s+\w\w\w\s+\w\w\w\s+\d\d?\s+\d\d\s*:\s*\d\d\s*:\s*\d\d\s+\d\d\d\d/ on_blank = false if first first = false else tmp.close score_keeper.processMail(baseargs, mailtype, tmpname) tmp = File.open(tmpname, "w") end elsif line.length == 1 on_blank = true end tmp.print(line) end tmp.close score_keeper.processMail(baseargs, mailtype, tmpname) score_keeper.printSummary spamprobe-1.4d/src/scripts/multitest.sh0000664000076400007640000000122010526706576015322 00000000000000#!/bin/bash GOOD_MAIL="$HOME/newton/IMAP/active $HOME/newton/IMAP/archive $HOME/newton/IMAP/saved/companies/other $HOME/newton/IMAP/saved/consult/GE/CMS $HOME/newton/IMAP/saved/Projects/OpenSource" SPAM_MAIL="$HOME/newton/IMAP/SpamArchive $HOME/newton/IMAP/TestSpam" #SPAM_MAIL="$HOME/newton/IMAP/SpamArchive" PERCENTAGE=75 DBDIR=$HOME/sptest VERBOSE="" SPEXEC="./spamprobe" ( #for i in 1 2 3 4 5 6 7 8 9 10 ; do for i in 1 2 3 4 5 ; do echo CREATING TEST CASE $i USING PERCENTAGE $PERCENTAGE ruby splitmail.rb $PERCENTAGE _good $GOOD_MAIL ruby splitmail.rb $PERCENTAGE _spam $SPAM_MAIL bash runtest.sh done ) 2>&1 | tee _multi_results spamprobe-1.4d/src/scripts/splitmail.rb0000664000076400007640000000444510526706576015273 00000000000000#!/usr/bin/ruby # # A script to split a mbox file into two files with a randomly # chosen set of emails in each file. Used to create test cases # for trying out different sets of filter parameters. # require 'md5' if ARGV.length < 2 STDERR.printf("usage: splitmail percentage outfileprefix [filename...]\n") exit 1 end max_messages = 8000 ignore_exp = /^Subject:\s+DON.T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA/ header_exp = /(^To:)|(^From:)|(^Date:)|(^Subject:)|(^Cc:)/ skip_pct = 5 + rand(10) pct = ARGV.shift.to_i prefix = ARGV.shift files = [ File.open(prefix + ".1", "w"), File.open(prefix + ".2", "w") ]; first = [ true, true ] digests = Hash.new ARGV.each do |filename| msg_count = 0 dup_count = 0 digester = MD5.new message = "" on_blank = true in_body = false ignore_it = false File.open(filename).each do |line| if on_blank && line =~ /^From\s+\S+\s+\w\w\w\s+\w\w\w\s+\d\d?\s+\d\d\s*:\s*\d\d\s*:\s*\d\d\s+\d\d\d\d/ if (message.length > 0) && (not digests.has_key?(digester.hexdigest) && (not ignore_it) && (rand(100) >= skip_pct)) filenum = (rand(100) <= pct) ? 0 : 1 if first[filenum] first[filenum] = false else files[filenum].print("\n") end files[filenum].print(message) digests.store(digester.hexdigest, 1) msg_count += 1 elsif message.length > 0 dup_count += 1 end message = "" on_blank = false in_body = false ignore_it = false digester = MD5.new if msg_count > max_messages break end elsif line.length == 1 on_blank = true in_body = true end if in_body if message.length < 4096 digester.update(line) end elsif header_exp =~ line digester.update(line) ignore_it = ignore_it || (ignore_exp =~ line) end message.concat(line) end if (message.length > 0) && (not digests.has_key?(digester.hexdigest) && (not ignore_it)) filenum = (rand(100) <= pct) ? 0 : 1 if first[filenum] first[filenum] = false else files[filenum].print("\n") end files[filenum].print(message) msg_count += 1 elsif message.length > 0 dup_count += 1 end printf("split file %s with %d unique messages and %d dups\n", filename, msg_count, dup_count) end spamprobe-1.4d/src/scripts/countscores.rb0000664000076400007640000000140010526706576015630 00000000000000#!/usr/bin/env ruby # Simple ruby script to count the number of scores in each # category (good/bad). Expects one floating point number # per line as output by spamprobe score. threshold = 0.9 if ARGV.size == 1 threshold = ARGV.shift.to_f end min_score = 2.0 max_score = -1.0 spams = 0 goods = 0 STDIN.each do |line| judgement,score_str,digest = line.split score = score_str.to_f if judgement == 'SPAM' spams += 1 else goods += 1 end if score > max_score max_score = score end if score < min_score min_score = score end end total = spams + goods pct = spams.to_f / (spams.to_f + goods.to_f) * 100.0 printf("GOOD %5d SPAM %5d TOTAL %5d PCT %6.2f MIN %8.6f MAX %8.6f\n", goods, spams, total, pct, min_score, max_score) spamprobe-1.4d/src/Makefile.am0000664000076400007640000000013210526706576013302 00000000000000AUTOMAKE_OPTIONS = foreign SUBDIRS = database includes input parser utility hdl spamprobe spamprobe-1.4d/src/parser/0000777000076400007640000000000010527262436012621 500000000000000spamprobe-1.4d/src/parser/UrlOnlyHtmlTokenizer.cc0000664000076400007640000000372110527261701017167 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: UrlOnlyHtmlTokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "UrlOnlyHtmlTokenizer.h" static bool is_suspicious_tag(const string &tag) { static RegularExpression suspicious_expr("^font|^img", 1, true, true); bool answer = suspicious_expr.match(tag); return answer; } UrlOnlyHtmlTokenizer::UrlOnlyHtmlTokenizer(AbstractTokenizer *textTokenizer, AbstractTokenizer *htmlTokenizer, int maxTagLength, bool keep_suspicious_tags) : HtmlTokenizer(textTokenizer, htmlTokenizer, maxTagLength), m_keepSuspiciousTags(keep_suspicious_tags) { } UrlOnlyHtmlTokenizer::~UrlOnlyHtmlTokenizer() { } void UrlOnlyHtmlTokenizer::processTagBody(const string &tag) { if (m_keepSuspiciousTags && is_suspicious_tag(tag)) { HtmlTokenizer::processTagBody(tag); } } spamprobe-1.4d/src/parser/SimpleTokenizer.cc0000664000076400007640000001062210527261701016165 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SimpleTokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractTokenReceiver.h" #include "AbstractCharReader.h" #include "SimpleTokenizer.h" SimpleTokenizer::SimpleTokenizer(char non_ascii_char) : m_nonAsciiCharReplacement(non_ascii_char) { reset(); } SimpleTokenizer::~SimpleTokenizer() { } char SimpleTokenizer::currentChar(AbstractCharReader *reader) { char ch = reader->currentChar(); if (m_nonAsciiCharReplacement && (ch & 0x80)) { ch = m_nonAsciiCharReplacement; } return ch; } void SimpleTokenizer::tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix) { reset(); m_receiver = receiver; while (reader->forward()) { if (processCharForState(currentChar(reader))) { if (is_debug) { cerr << "SEND TOKEN: " << m_token << endl; } sendToken(prefix, m_token); } } if (m_token.length() > 0){ sendToken(prefix, m_token); } } void SimpleTokenizer::reset() { m_state = START; m_token.erase(); m_pending.erase(); } bool SimpleTokenizer::isLetterChar(char ch) { return (ch & 0x80) || is_alnum(ch) || (ch == '%'); } bool SimpleTokenizer::isSpecialChar(char ch) { switch (ch) { case '.': case '-': case '+': case ',': case '_': case '$': return true; default: return false; } } void SimpleTokenizer::appendChar(string &s, char ch) { s += to_lower(ch); } bool SimpleTokenizer::processStart(char ch) { assert(m_state == START); m_token.erase(); m_pending.erase(); m_state = WAITING; return processWaiting(ch); } bool SimpleTokenizer::processWaiting(char ch) { assert(m_state == WAITING); if (ch == '$' || isLetterChar(ch)) { appendChar(m_token, ch); m_state = IN_WORD; } return false; } bool SimpleTokenizer::processInWord(char ch) { assert(m_state == IN_WORD); if (isLetterChar(ch)) { appendChar(m_token, ch); return false; } if (isSpecialChar(ch)) { m_state = PENDING; appendChar(m_pending, ch); return false; } m_state = START; return true; } bool SimpleTokenizer::processPending(char ch) { if (isLetterChar(ch)) { m_state = IN_WORD; m_token += m_pending; appendChar(m_token, ch); m_pending.erase(); return false; } if (isSpecialChar(ch)) { appendChar(m_pending, ch); return false; } m_state = START; m_pending.erase(); return true; } bool SimpleTokenizer::processCharForState(char ch) { //cerr << "PROCESS CHAR '" << ch << "' (" << (int)ch << ") STATE " << m_state // << " TOKEN '" << m_token << "' PENDING '" << m_pending << "'" << endl; switch (m_state) { case START: return processStart(ch); case WAITING: return processWaiting(ch); case IN_WORD: return processInWord(ch); case PENDING: return processPending(ch); default: assert(false); cerr << "INVALID STATE " << m_state << endl; return false; } } void SimpleTokenizer::sendToken(const string &prefix, string &token) { m_receiver->receiveToken(prefix, m_token); m_token.erase(); } spamprobe-1.4d/src/parser/GifParser.h0000664000076400007640000000374510527261701014575 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: GifParser.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #if defined(HAVE_UNGIF) #ifndef _GifParser_h #define _GifParser_h extern "C" { #include } #include "ImageParser.h" #include "Buffer.h" class GifParser : public ImageParser { public: GifParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes); ~GifParser(); virtual bool parseImage(); private: void openImage(); void parseImageRecords(); static int readFromBuffer(GifFileType *file, GifByteType *dst, int length); private: /// Not implemented. GifParser(const GifParser &); /// Not implemented. GifParser& operator=(const GifParser &); private: GifFileType *m_gif; int m_nextByteIndex; }; #endif // _GifParser_h #endif // HAVE_UNGIF spamprobe-1.4d/src/parser/MailMessageReader.h0000664000076400007640000000360110527261701016214 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MailMessageReader_h #define _MailMessageReader_h #include "AbstractLineMailMessageReader.h" class MailMessage; class LineReader; class MultiLineString; class MailMessageReader : public AbstractLineMailMessageReader { public: MailMessageReader(bool use_content_length = false); virtual ~MailMessageReader(); virtual OWNED MailMessage *readMessage(); protected: virtual bool isNewMessageBoundary(const string &line); private: void readMessageWithContentLength(MultiLineString *text); void readMessageWithBoundary(MultiLineString *text, bool append_to_last_line); bool findContentLength(MultiLineString *text, int &content_length); private: bool m_useContentLength; }; #endif spamprobe-1.4d/src/parser/HeaderParser.cc0000664000076400007640000000535310527261701015413 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HeaderParser.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractMultiLineString.h" #include "MultiLineString.h" #include "MessageHeader.h" #include "MessageHeaderList.h" #include "HeaderParser.h" Ref HeaderParser::parseHeader(const CRef &headerText) { m_headerText = headerText; m_headerList = make_ref(new MessageHeaderList()); m_currentName.erase(); m_currentLines.clear(); parse(); return m_headerList; } bool HeaderParser::isContinuationLine(const string &line) { return is_space(line[0]); } void HeaderParser::addHeader() { if (m_currentName.length() > 0 && m_currentLines.isNotNull()) { m_headerList->addHeader(new MessageHeader(m_currentName, m_currentLines)); } m_currentName.erase(); m_currentLines.clear(); } void HeaderParser::addLineToCurrent(const string &line) { if (m_currentLines.isNotNull()) { m_currentLines->addLine(line); } } void HeaderParser::startHeader(const string &line) { string::size_type colon_index = line.find(':'); if (colon_index == string::npos) { return; } m_currentName.assign(line, 0, colon_index); m_currentLines = make_ref(new MultiLineString()); m_currentLines->addLine(trim_copy(line, colon_index + 1)); } void HeaderParser::parse() { for (int i = 0; i < m_headerText->lineCount(); ++i) { const string &line(m_headerText->line(i)); if (line.length() > 0) { if (isContinuationLine(line)) { addLineToCurrent(line); } else { addHeader(); startHeader(line); } } } addHeader(); } spamprobe-1.4d/src/parser/MimeDecoder.cc0000664000076400007640000002553710527261701015231 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MimeDecoder.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractCharReader.h" #include "MultiLineString.h" #include "MultiLineSubString.h" #include "MessageHeader.h" #include "MessageHeaderList.h" #include "RegularExpression.h" #include "MimeDecoder.h" static unsigned char char_value(unsigned char ch) { if (ch >= '0' && ch <= '9') { return ch - '0'; } if (ch >= 'a' && ch <= 'f') { return 10 + ch - 'a'; } if (ch >= 'A' && ch <= 'F') { return 10 + ch - 'A'; } return 0; } static const int BASE64_CHARS[256] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }; static const int MAX_CHAR_INDEX = sizeof(BASE64_CHARS) / sizeof(BASE64_CHARS[0]); inline bool next_char64(AbstractCharReader *reader, char &ch, unsigned char &value) { while (!reader->atEnd()) { ch = reader->currentChar(); if (ch == '=') { value = 0; reader->forward(); return true; } unsigned int index = (unsigned)(ch & 0xff); if (index >= MAX_CHAR_INDEX) { assert(!"should not be possible but just to be safe"); break; } if (BASE64_CHARS[index] >= 0) { value = BASE64_CHARS[index]; reader->forward(); return true; } reader->forward(); } ch = ' '; value = 0; return false; } CRef MimeDecoder::decodeHeaderString(const CRef &header_value) { static const string token_expr("[^] \t()<>@,;:\"/[?.=]+"); static const string encoded_word_expr = string("=\\?(") + token_expr + ")\\?(" + token_expr + ")\\?([^\\?]+)\\?="; string text; header_value->join(text); if (is_debug) { cerr << "decodeHeader: before: " << text << endl; } bool changed = false; RegularExpression::MatchData whole_match; string whole_string, charset, method, encoded_word, decoded_text; RegularExpression encoded_word_regex(encoded_word_expr, 4, false, true); string::size_type offset = 0; while ((offset < text.length()) && encoded_word_regex.match(text.c_str() + offset)) { string::size_type replace_start = offset; encoded_word_regex.getMatch(0, whole_match); encoded_word_regex.getMatch(2, method); encoded_word_regex.getMatch(3, encoded_word); method = trim(to_lower(method)); bool valid_method = true; if (method == "q") { Ref word(new MultiLineString()); word->addLine(encoded_word); CRef decoded_lines(unquoteString(word, true)); decoded_lines->join(decoded_text); offset += decoded_text.length(); } else if (method == "b") { Ref word(new MultiLineString()); word->addLine(encoded_word); CRef decoded_lines(decodeString(word)); decoded_lines->join(decoded_text); offset += decoded_text.length(); } else { valid_method = false; offset += whole_match.end_pos; } if (valid_method) { text.replace(replace_start + whole_match.start_pos, whole_match.end_pos - whole_match.start_pos, decoded_text); changed = true; } } if (is_debug) { if (changed) { cerr << "decodeHeader: after: " << text << endl; } else { cerr << "decodeHeader: no change" << endl; } } if (changed) { return MultiLineString::fromText(text); } else { return header_value; } } bool MimeDecoder::isQuotedPrintable(const CRef &contentTransferEncoding) { if (contentTransferEncoding.isNull() || contentTransferEncoding->lineCount() < 1) { return false; } return starts_with(to_lower(contentTransferEncoding->line(0)), "quoted-printable"); } bool MimeDecoder::isBase64(const CRef &contentTransferEncoding) { if (contentTransferEncoding.isNull() || contentTransferEncoding->lineCount() < 1) { return false; } return starts_with(to_lower(contentTransferEncoding->line(0)), "base64"); } CRef MimeDecoder::decodeText(const MessageHeaderList *headers, const CRef &body) { if (!headers->isTextType()) { return body; } CRef transfer_encoding(headers->header("content-transfer-encoding")); if (isQuotedPrintable(transfer_encoding)) { if (is_debug) { cerr << "UNQUOTING BODY" << endl; } return unquoteString(body); } if (isBase64(transfer_encoding)) { if (is_debug) { cerr << "DECODING BODY" << endl; } return decodeString(body); } return body; } CRef MimeDecoder::unquoteString(const CRef &messageBody, bool convert_underscores) { Ref answer(new MultiLineString()); string buffer; bool no_changes = true; buffer.reserve(10240); for (int k = 0; k < messageBody->lineCount(); ++k) { bool add_new_line = true; const string &line(messageBody->line(k)); const char *line_chars = line.c_str(); const int line_length = line.length(); const int last_index = line_length - 1; const int hex_limit = line_length - 2; for (string::size_type i = 0; i < line_length; ++i) { char ch = line_chars[i]; if (ch == '=') { no_changes = false; if (i == last_index) { // soft line break - ignore newline add_new_line = false; } else if ((i < hex_limit) && is_xdigit(line_chars[i+1]) && is_xdigit(line_chars[i+2])) { char ch = (char)((char_value(line_chars[i+1]) << 4) | char_value(line_chars[i+2])); buffer += safe_char(ch); i += 2; } } else if (convert_underscores && ch == '_') { buffer += ' '; no_changes = false; } else { buffer += ch; } } if (add_new_line) { answer->addLine(buffer); buffer.erase(); } } answer->addLine(buffer); if (no_changes) { return messageBody; } else { return answer; } } CRef MimeDecoder::decodeString(const CRef &messageBody) { string buffer; Ref char_reader(messageBody->createCharReader()); decodeString(char_reader.ptr(), buffer); if (is_debug) { cerr << "DECODED TO " << buffer << endl; } return MultiLineString::fromText(buffer); } void MimeDecoder::decodeString(AbstractCharReader *reader, string &decoded_string) { char c1, c2, c3, c4; unsigned char u1, u2, u3, u4; reader->forward(); while (next_char64(reader, c1, u1) && next_char64(reader, c2, u2) && next_char64(reader, c3, u3) && next_char64(reader, c4, u4)) { if (c3 != '=' && c4 != '=') { // common case of 3 octets decoded_string += safe_char((u1 << 2) | (u2 >> 4)); // 6 + 2 decoded_string += safe_char(((u2 & 0x0f) << 4) | (u3 >> 2)); // 4 + 4 decoded_string += safe_char(((u3 & 0x03) << 6) | u4); // 2 + 6 } else if (c3 == '=') { // padded case with 1 octet decoded_string += safe_char((u1 << 2) | (u2 >> 4)); // 6 + 2 } else { // padded case with 2 octets decoded_string += safe_char((u1 << 2) | (u2 >> 4)); // 6 + 2 decoded_string += safe_char(((u2 & 0x0f) << 4) | (u3 >> 2)); // 4 + 4 } } } void MimeDecoder::decodeData(const CRef &messageBody, Buffer &decoded_data) { Ref char_reader(messageBody->createCharReader()); decodeData(char_reader.ptr(), decoded_data); } void MimeDecoder::decodeData(AbstractCharReader *reader, Buffer &decoded_data) { char c1, c2, c3, c4; unsigned char u1, u2, u3, u4; reader->forward(); while (next_char64(reader, c1, u1) && next_char64(reader, c2, u2) && next_char64(reader, c3, u3) && next_char64(reader, c4, u4)) { if (c3 != '=' && c4 != '=') { // common case of 3 octets decoded_data.append((u1 << 2) | (u2 >> 4)); // 6 + 2 decoded_data.append(((u2 & 0x0f) << 4) | (u3 >> 2)); // 4 + 4 decoded_data.append(((u3 & 0x03) << 6) | u4); // 2 + 6 } else if (c3 == '=') { // padded case with 1 octet decoded_data.append((u1 << 2) | (u2 >> 4)); // 6 + 2 } else { // padded case with 2 octets decoded_data.append((u1 << 2) | (u2 >> 4)); // 6 + 2 decoded_data.append(((u2 & 0x0f) << 4) | (u3 >> 2)); // 4 + 4 } } } spamprobe-1.4d/src/parser/MessageHeader.cc0000664000076400007640000000257610527261701015547 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MessageHeader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MessageHeader.h" MessageHeader::MessageHeader(const string &name, const CRef &lines) : m_name(name), m_lowerName(to_lower(name)), m_lines(lines) { } MessageHeader::~MessageHeader() { } spamprobe-1.4d/src/parser/StreamMailMessageReader.h0000664000076400007640000000377310527261701017402 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: StreamMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _StreamMailMessageReader_h #define _StreamMailMessageReader_h #include "AbstractLineMailMessageReader.h" class AbstractCharReader; class StreamMailMessageReader : public AbstractMailMessageReader { public: StreamMailMessageReader(); virtual ~StreamMailMessageReader(); void setStream(istream *in_stream, bool can_seek, bool ignore_from, bool ignore_content_length); void close(); virtual OWNED MailMessage *readMessage(); private: /// Not implemented. StreamMailMessageReader(const StreamMailMessageReader &); /// Not implemented. StreamMailMessageReader& operator=(const StreamMailMessageReader &); private: istream *m_stream; Ptr m_charReader; Ptr m_lineReader; Ptr m_mailReader; }; #endif // _StreamMailMessageReader_h spamprobe-1.4d/src/parser/TraditionalMailMessageParser.cc0000664000076400007640000002232610527261701020604 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TraditionalMailMessageParser.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "GifParser.h" #include "PngParser.h" #include "JpegParser.h" #include "ParserConfig.h" #include "AbstractMultiLineString.h" #include "AbstractTokenizer.h" #include "AbstractTokenReceiver.h" #include "MessageHeader.h" #include "MessageHeaderList.h" #include "MailMessage.h" #include "MailMessageList.h" #include "SimpleTokenizer.h" #include "PhrasingTokenizer.h" #include "UrlOnlyHtmlTokenizer.h" #include "TokenFilteringTokenizer.h" #include "SimpleMultiLineStringCharReader.h" #include "StringReader.h" #include "MimeDecoder.h" #include "TraditionalMailMessageParser.h" static const string URL_PREFIX("U_"); static const string IP_ADDRESS_REGEX("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"); static const string IP_ADDRESS_TERM("IP_ADDRESS"); static const string LINE_SEPARATOR(" "); TraditionalMailMessageParser::TraditionalMailMessageParser(ParserConfig *config) : m_config(config), m_ipRegex(IP_ADDRESS_REGEX) { } TraditionalMailMessageParser::~TraditionalMailMessageParser() { } OWNED AbstractTokenizer *TraditionalMailMessageParser::createTokenizer() { Ptr answer; answer.set(new SimpleTokenizer(m_config->getNonAsciiCharReplacement())); answer.set(new TokenFilteringTokenizer(answer.release(), m_config->getMinTermLength(), m_config->getMaxTermLength(), false)); answer.set(new PhrasingTokenizer(answer.release(), m_config->getMinPhraseTerms(), m_config->getMaxPhraseTerms(), m_config->getMinPhraseChars(), m_config->getMaxPhraseChars())); return answer.release(); } OWNED Message *TraditionalMailMessageParser::parseMailMessage(MailMessage *source) { m_message.set(new Message()); m_message->setMaxTokenCount(m_config->getMaxTermsPerMessage()); Ptr html_text_tokenizer(createTokenizer()); m_textTokenizer.set(createTokenizer()); if (m_config->getRemoveHTML()) { m_htmlTokenizer.set(new UrlOnlyHtmlTokenizer(m_textTokenizer.get(), html_text_tokenizer.get(), 256, m_config->getKeepSuspiciousTags())); } else { m_htmlTokenizer.set(new HtmlTokenizer(m_textTokenizer.get(), html_text_tokenizer.get(), 256)); } parseBody(source); return m_message.release(); } void TraditionalMailMessageParser::receiveToken(const string &prefix, const string &token) { if (prefix != m_prefix) { addTerm(prefix, token, Token::FLAG_NORMAL); addDerivedTerms(prefix, token); } addTerm(m_prefix, token, Token::FLAG_NORMAL); addDerivedTerms(m_prefix, token); } void TraditionalMailMessageParser::addDerivedTerms(const string &prefix, const string &token) { if (isPhrase(token)) { return; } if (m_ipRegex.match(token)) { addTerm(prefix, IP_ADDRESS_TERM, Token::FLAG_DERIVED); } addTokenParts(prefix, token); } void TraditionalMailMessageParser::addTokenParts(const string &prefix, const string &token) { const char *word_start = token.c_str(); const char *s = word_start; while (*s) { while (*s && !is_alnum(*s) && !(*s & 0x80)) { ++s; } bool all_digits = true; const char *start = s; while (*s && (is_alnum(*s) || (*s & 0x80))) { all_digits = all_digits && is_digit(*s); ++s; } const char *end = s; if (!all_digits) { if (start != word_start) { addTerm(prefix, start, Token::FLAG_DERIVED); } if (((end - start) > 1) && *end && !all_digits) { addTerm(prefix, string(start, end), Token::FLAG_DERIVED); } } } } void TraditionalMailMessageParser::addTerm(const string &prefix, const string &term, int flags) { m_message->addToken(term, prefix, flags); } bool TraditionalMailMessageParser::isPhrase(const string &token) { return token.find(' ') != string::npos; } void TraditionalMailMessageParser::parseHtmlBodyText(const AbstractMultiLineString *text) { if (is_debug) { cerr << "PARSING HTML BODY TEXT LINES: " << text->lineCount() << endl; } m_prefix.erase(); SimpleMultiLineStringCharReader reader(text, LINE_SEPARATOR); m_htmlTokenizer->tokenize(this, &reader, m_prefix); if (is_debug) { cerr << "FINISHED PARSING HTML BODY TEXT LINES: " << text->lineCount() << endl; } } void TraditionalMailMessageParser::parsePlainBodyText(const AbstractMultiLineString *text) { if (is_debug) { cerr << "PARSING PLAIN BODY TEXT LINES: " << text->lineCount() << endl; } m_prefix.erase(); SimpleMultiLineStringCharReader reader(text, LINE_SEPARATOR); m_textTokenizer->tokenize(this, &reader, m_prefix); if (is_debug) { cerr << "FINISHED PARSING PLAIN BODY TEXT LINES: " << text->lineCount() << endl; } } void TraditionalMailMessageParser::parseBodyText(MailMessage *source) { #if defined(HAVE_UNGIF) || defined(HAVE_PNG) || defined(HAVE_JPEG) Ptr image_parser; Buffer buffer(1024); #if defined(HAVE_UNGIF) if (source->head()->hasType("image/gif") && source->asData(buffer) && buffer.length() > 0) { image_parser.set(new GifParser(m_message.get(), m_textTokenizer.get(), this, "Igif_", buffer)); } #endif #if defined(HAVE_PNG) if (source->head()->hasType("image/png") && source->asData(buffer) && buffer.length() > 0) { image_parser.set(new PngParser(m_message.get(), m_textTokenizer.get(), this, "Ipng_", buffer)); } #endif #if defined(HAVE_JPEG) if (source->head()->hasType("image/jpeg") && source->asData(buffer) && buffer.length() > 0) { image_parser.set(new JpegParser(m_message.get(), m_textTokenizer.get(), this, "Ijpeg_", buffer)); } #endif if (image_parser.isNotNull()) { image_parser->parseImage(); return; } #endif // defined(HAVE_UNGIF) || defined(HAVE_PNG) || defined(HAVE_JPEG) bool is_html; const AbstractMultiLineString *text = source->asText(is_html); if (!text) { if (is_debug) { cerr << "IGNORING NON-TEXT PART" << endl; } return; } if (is_debug) { for (int i = 0; i < text->lineCount(); ++i) { cerr << "TEXT: " << i << ": " << text->line(i) << "\n"; } } if (is_html) { parseHtmlBodyText(text); } else { parsePlainBodyText(text); } } void TraditionalMailMessageParser::parseCharset(MailMessage *source, const string &prefix) { string charset; source->head()->getCharsetString(charset); if (charset.length() > 0) { m_prefix = prefix; StringReader reader(charset); m_textTokenizer->tokenize(this, &reader, m_prefix); } } void TraditionalMailMessageParser::parseHeader(const MessageHeader *header, MimeDecoder *decoder) { CRef lines(decoder->decodeHeaderString(header->lines())); SimpleMultiLineStringCharReader reader(lines.ptr()); m_textTokenizer->tokenize(this, &reader, m_prefix); } void TraditionalMailMessageParser::parseHeaders(MailMessage *source) { MimeDecoder decoder; m_config->headers()->resetHeaderCounts(); const MessageHeaderList *head = source->head(); for (int i = 0; i < head->headerCount(); ++i) { const MessageHeader *header = head->header(i); if (!starts_with(header->lowerName(), "from ")) { if (m_config->headers()->shouldProcessHeader(header->lowerName(), m_prefix)) { parseHeader(header, &decoder); } } } parseCharset(source, "CS_"); } void TraditionalMailMessageParser::parseBody(MailMessage *source) { if (is_debug) { cerr << "parseBody: begins " << source->bodyText()->line(0) << endl; } parseHeaders(source); if (source->bodyText()->lineCount() == 0) { if (is_debug) { cerr << "parseBody: ignoring empty body" << endl; } return; } if (!m_config->getIgnoreBody()) { if (source->hasParts()) { for (int i = 0; i < source->body()->messageCount(); ++i) { parseBody(source->body()->message(i)); } } else { parseBodyText(source); } } if (is_debug) { cerr << "parseBody: ends " << source->bodyText()->line(source->bodyText()->lineCount() - 1) << endl; } } spamprobe-1.4d/src/parser/BodyParser.cc0000664000076400007640000000774510527261701015127 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: BodyParser.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MessageHeader.h" #include "MessageHeaderList.h" #include "MultiLineString.h" #include "MultiLineSubString.h" #include "MailMessage.h" #include "MailMessageList.h" #include "BodyParser.h" Ref BodyParser::parseBody(const MessageHeaderList *headers, const CRef &body_text) { m_headers = headers; m_bodyText = body_text; m_bodyParts = make_ref(new MailMessageList()); parse(); m_bodyText.clear(); return m_bodyParts; } int BodyParser::skipToBlank(const CRef &lines, int &offset) { while (offset < lines->lineCount()) { if (lines->line(offset).length() == 0) { return offset; } ++offset; } return lines->lineCount(); } int BodyParser::skipToNonBlank(const CRef &lines, int &offset) { while (offset < lines->lineCount()) { if (lines->line(offset).length() > 0) { return offset; } ++offset; } return lines->lineCount(); } void BodyParser::addPart(const CRef &lines) { int offset = 0; int header_start = skipToNonBlank(lines, offset); int header_end = skipToBlank(lines, offset); int body_start = skipToNonBlank(lines, offset); int body_end = lines->lineCount(); CRef head(new MultiLineSubString(lines, header_start, header_end)); CRef body(new MultiLineSubString(lines, body_start, body_end)); Ptr message(new MailMessage(head, body, lines)); m_bodyParts->addMessage(message.release()); } void BodyParser::addPartsForBoundary(const CRef &lines, const string &boundary) { string part_boundary = "--" + boundary; string end_boundary = part_boundary + "--"; int offset = 0; offset = skipToNonBlank(lines, offset); int prev_offset = -1; while (offset < lines->lineCount()) { const string &line(lines->line(offset)); if (line == part_boundary || line == end_boundary) { if (prev_offset >= 0 && offset > prev_offset) { Ref part(new MultiLineSubString(lines, prev_offset, offset)); addPart(part); } if (line == end_boundary) { // ignore anything after end boundary return; } prev_offset = offset + 1; } ++offset; } // a safety net in case the loser mail client didn't include the end boundary if (prev_offset >= 0 && offset > prev_offset) { Ref part(new MultiLineSubString(lines, prev_offset, offset)); addPart(part); } } void BodyParser::parse() { string boundary; m_headers->getBoundaryString(boundary); if (boundary.length() > 0) { addPartsForBoundary(m_bodyText, boundary); } else { addPart(m_bodyText); } } spamprobe-1.4d/src/parser/MaildirMailMessageReader.h0000664000076400007640000000370010527261701017516 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MaildirMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MaildirMailMessageReader_h #define _MaildirMailMessageReader_h #include "File.h" #include "AbstractMailMessageReader.h" class MaildirMailMessageReader : public AbstractMailMessageReader { public: MaildirMailMessageReader(const File &maildir); ~MaildirMailMessageReader(); virtual OWNED MailMessage *readMessage(); static bool isMaildir(const File &maildir); private: /// Not implemented. MaildirMailMessageReader(const MaildirMailMessageReader &); /// Not implemented. MaildirMailMessageReader& operator=(const MaildirMailMessageReader &); typedef vector FileVec; typedef FileVec::const_iterator FileIter; File m_maildir; vector m_children; FileIter m_current; FileIter m_end; Ptr m_reader; }; #endif // _MaildirMailMessageReader_h spamprobe-1.4d/src/parser/MaildirMailMessageReader.cc0000664000076400007640000000461310527261701017660 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MaildirMailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "MailMessage.h" #include "FileMailMessageReader.h" #include "MaildirMailMessageReader.h" MaildirMailMessageReader::MaildirMailMessageReader(const File &maildir) : m_maildir(maildir) { File(m_maildir, "cur").children(m_children); File(m_maildir, "new").children(m_children); sort(m_children.begin(), m_children.end()); m_current = m_children.begin(); m_end = m_children.end(); } MaildirMailMessageReader::~MaildirMailMessageReader() { } bool MaildirMailMessageReader::isMaildir(const File &maildir) { return File(maildir, "cur").isDirectory() && File(maildir, "new").isDirectory(); } OWNED MailMessage *MaildirMailMessageReader::readMessage() { while (m_reader.isNotNull() || m_current != m_end) { if (m_reader.isNotNull()) { Ptr msg(m_reader->readMessage()); if (msg.isNotNull()) { return msg.release(); } m_reader.clear(); } while (m_reader.isNull() && (m_current != m_end)) { const File &child = *m_current; ++m_current; if (child.isFile() && !child.isHidden()) { Ptr tmp(new FileMailMessageReader); tmp->open(child.getPath(), true, true); m_reader.set(tmp.release()); } } } return 0; } spamprobe-1.4d/src/parser/HeaderParser.h0000664000076400007640000000336310527261701015254 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HeaderParser.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _HeaderParser_h #define _HeaderParser_h #include "MultiLineString.h" #include "MessageHeaderList.h" class HeaderParser { public: ~HeaderParser() { } Ref parseHeader(const CRef &headerText); private: bool isContinuationLine(const string &line); void addHeader(); void addLineToCurrent(const string &line); void startHeader(const string &line); void parse(); private: CRef m_headerText; Ref m_headerList; string m_currentName; Ref m_currentLines; }; #endif spamprobe-1.4d/src/parser/ImageParser.h0000664000076400007640000000363010527260212015077 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _ImageParser_h #define _ImageParser_h #include "util.h" #include "Buffer.h" class AbstractTokenizer; class AbstractTokenReceiver; class Message; class ImageParser { public: ImageParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes); virtual ~ImageParser(); virtual bool parseImage() = 0; protected: void sendToken(const string &token); void digestImage(); private: /// Not implemented. ImageParser(const ImageParser &); /// Not implemented. ImageParser& operator=(const ImageParser &); protected: Message *m_message; AbstractTokenizer *m_tokenizer; AbstractTokenReceiver *m_receiver; const string m_prefix; const Buffer &m_bytes; }; #endif // _ImageParser_h spamprobe-1.4d/src/parser/MbxMailMessageReader.h0000664000076400007640000000321610527261701016665 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MbxMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MbxMailMessageReader_h #define _MbxMailMessageReader_h #include "RegularExpression.h" #include "AbstractLineMailMessageReader.h" class AbstractCharReader; class MbxMailMessageReader : public AbstractLineMailMessageReader { public: MbxMailMessageReader(); virtual ~MbxMailMessageReader(); virtual OWNED MailMessage *readMessage(); static bool isMbxFile(AbstractCharReader *in); private: bool readMBXRecordHeader(); private: RegularExpression m_headerRegex; int m_recordLength; }; #endif spamprobe-1.4d/src/parser/HtmlTokenizer.cc0000664000076400007640000001716510527261701015651 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HtmlTokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractTokenReceiver.h" #include "StringReader.h" #include "RegularExpression.h" #include "TempPtr.h" #include "HtmlTokenizer.h" static const char SEPARATOR = ' '; static const int MAX_ENTITY_LENGTH = 6; static const string URL_REGEX("[^a-z0-9_](href|src)[ \t\r\n]*=[ \t\r\n]*('[^>' \t\r\n]+|\"[^>\" \t\r\n]+|[^> \t\r\n]+)"); static const string TAG_BASE_PREFIX("T"); static const string TAG_BASE_SUFFIX("_"); static const string URL_PREFIX("U_"); HtmlTokenizer::HtmlTokenizer(AbstractTokenizer *textTokenizer, AbstractTokenizer *tagTokenizer, int maxTagLength) : m_textTokenizer(textTokenizer), m_tagTokenizer(tagTokenizer), m_maxTagLength(maxTagLength), m_reader(0), m_receiver(0) { } HtmlTokenizer::~HtmlTokenizer() { } void HtmlTokenizer::tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix) { TempPtr tmp_reader(m_reader, reader); TempPtr tmp_receiver(m_receiver, receiver); m_prefix = prefix; m_textTokenizer->tokenize(m_receiver, this, m_prefix); } const string &HtmlTokenizer::decodeUrl(const string &url, string &buffer) { const int len = url.length(); const int hex_limit = len - 2; const char *chars = url.c_str(); buffer.erase(); buffer.reserve(len); for (int i = 0; i < len; ++i) { char ch = chars[i]; if (ch == '%' && i < hex_limit && is_xdigit(chars[i+1]) && is_xdigit(chars[i+2])) { buffer += (char)(hex_to_int(chars[i+1]) << 4 | hex_to_int(chars[i+2])); i += 2; } else { buffer += ch; } } if (is_debug) { cerr << "ORIG URL '" << url << "' DECODED '" << buffer << "'" << endl; } return buffer; } void HtmlTokenizer::processTagUrls(const string &tag) { static RegularExpression url_regex(URL_REGEX, 3, true); if (isCommentTag(tag)) { return; } int offset = 0; string url, decoded_url; RegularExpression::MatchData match; while (url_regex.match(tag.c_str() + offset)) { url_regex.getMatch(2, url); url_regex.getMatch(2, match); StringReader reader(decodeUrl(url, decoded_url)); m_tagTokenizer->tokenize(m_receiver, &reader, URL_PREFIX); offset += match.end_pos; assert(offset <= tag.length()); } } static const string &make_tag_prefix(const string &tag_body, string &prefix) { assert(tag_body.length() > 0); assert(!is_space(tag_body[0])); prefix = TAG_BASE_PREFIX; if (starts_with(tag_body, "!--")) { prefix += "CMT"; } else { for (const char *s = tag_body.c_str(); *s && !is_space(*s) && prefix.length() < 8; ++s) { if (is_alnum(*s)) { prefix += to_lower(*s); } } } prefix += TAG_BASE_SUFFIX; return prefix; } void HtmlTokenizer::processTagBody(const string &tag) { if (is_debug) { cerr << "PROCESSING TAG BODY: " << tag << endl; } string tag_prefix; StringReader reader(tag); m_tagTokenizer->tokenize(m_receiver, &reader, make_tag_prefix(tag, tag_prefix)); // TODO: leaving this in a for a while as a backward compatibility - remove after 3/31/2006 m_tagTokenizer->tokenize(m_receiver, &reader, URL_PREFIX); // TODO: end backward compatibility hook if (is_debug) { cerr << "PROCESSED TAG BODY: " << tag << endl; } } bool HtmlTokenizer::isCommentTag(const string &tag) { return starts_with(tag, "!--") && ends_with(tag, "--"); } bool HtmlTokenizer::isInvisibleTag(const string &tag) { return isCommentTag(tag); } bool HtmlTokenizer::isOpenCommentTag(const string &tag) { return starts_with(tag, "!--"); } bool HtmlTokenizer::isIncompleteCommentTag(const string &tag) { return starts_with(tag, "!--") && !ends_with(tag, "--"); } bool HtmlTokenizer::processedTag(string &tag) { if (m_reader->currentChar() != '<') { return false; } tag.erase(); Ptr pos(m_reader->createMark()); while (m_reader->forward() && (static_cast(tag.length()) < m_maxTagLength || isOpenCommentTag(tag))) { if (m_reader->currentChar() == '>' && !isIncompleteCommentTag(tag)) { if (tag.length() > 0) { processTagBody(tag); processTagUrls(tag); return true; } else { break; } } char ch = processedEntity() ? currentChar() : m_reader->currentChar(); if (tag.length() > 0 || !is_space(ch)) { tag += ch; } } m_reader->returnToMark(pos.get()); return false; } char HtmlTokenizer::parseEntityInteger(const string &entity) { char answer = ' '; if (entity.length() > 1 && (entity[1] == 'x' || entity[1] == 'X')) { answer = (char)hex_to_int(entity.c_str() + 1); } else { answer = (char)atoi(entity.c_str()); } return answer; } bool HtmlTokenizer::processEntity(const string &entity) { if (entity == "amp") { setCurrentChar('&'); return true; } if (entity == "apos") { setCurrentChar('\''); return true; } if (entity == "quot") { setCurrentChar('"'); return true; } if (entity == "lt") { setCurrentChar('<'); return true; } if (entity == "gt") { setCurrentChar('>'); return true; } if (entity == "nbsp") { setCurrentChar(' '); return true; } if (entity[0] == '#') { setCurrentChar(parseEntityInteger(entity)); return true; } return false; } bool HtmlTokenizer::processedEntity() { if (m_reader->currentChar() != '&') { return false; } Ptr startPos(m_reader->createMark()); string entity; while (m_reader->forward() && static_cast(entity.length()) < MAX_ENTITY_LENGTH) { if (m_reader->currentChar() == ';') { if (!processEntity(entity)) { break; } return true; } entity += m_reader->currentChar(); } m_reader->returnToMark(startPos.get()); return false; } bool HtmlTokenizer::forward() { while (true) { if (!m_reader->forward()) { return false; } if (processedEntity()) { return true; } string tagText; if (!processedTag(tagText)) { setCurrentChar(m_reader->currentChar()); return true; } if (!isInvisibleTag(tagText)) { setCurrentChar(' '); return true; } } } bool HtmlTokenizer::hasChar() { return m_reader->hasChar(); } bool HtmlTokenizer::atEnd() { return m_reader->atEnd(); } bool HtmlTokenizer::skip(int nchars) { bool have_char = true; while (have_char && nchars-- > 0) { have_char = forward(); } return have_char; } spamprobe-1.4d/src/parser/MimeDecoder.h0000664000076400007640000000506710527261701015067 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MimeDecoder.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MimeDecoder_h #define _MimeDecoder_h #include "Buffer.h" class AbstractCharReader; class AbstractMultiLineString; class MultiLineString; class MessageHeader; class MessageHeaderList; class MimeDecoder { public: bool isQuotedPrintable(const CRef &contentTransferEncoding); bool isBase64(const CRef &contentTransferEncoding); CRef decodeText(const MessageHeaderList *headers, const CRef &body); CRef unquoteString(const CRef &messageBody, bool convert_underscores = false); CRef decodeString(const CRef &messageBody); void decodeString(AbstractCharReader *reader, string &decoded_string); CRef decodeHeaderString(const CRef &body); void decodeData(const CRef &messageBody, Buffer &decoded_data); void decodeData(AbstractCharReader *reader, Buffer &decoded_data); private: void addLineToString(MultiLineString *answer, const string &new_line, const string &orig_line, bool lineChanged); }; #endif spamprobe-1.4d/src/parser/FileMailMessageReader.cc0000664000076400007640000000360310527261701017154 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FileMailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "StreamMailMessageReader.h" #include "FileMailMessageReader.h" FileMailMessageReader::FileMailMessageReader() { } FileMailMessageReader::~FileMailMessageReader() { close(); } void FileMailMessageReader::open(const string &path, bool ignore_from, bool ignore_content_length) { close(); m_stream.set(new ifstream(path.c_str())); m_reader.set(new StreamMailMessageReader()); m_reader->setStream(m_stream.get(), true, ignore_from, ignore_content_length); } void FileMailMessageReader::close() { m_reader.clear(); m_stream.clear(); } OWNED MailMessage *FileMailMessageReader::readMessage() { return m_reader.isNull() ? 0 : m_reader->readMessage(); } spamprobe-1.4d/src/parser/JpegParser.h0000664000076400007640000000427010527260213014744 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #if defined(HAVE_JPEG) #ifndef _JpegParser_h #define _JpegParser_h extern "C" { #include #include #include "jerror.h" } #include "ImageParser.h" #include "Buffer.h" class AbstractTokenizer; class AbstractTokenReceiver; class Message; class JpegParser : public ImageParser { public: JpegParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes); ~JpegParser(); virtual bool parseImage(); private: /// Not implemented. JpegParser(const JpegParser &); /// Not implemented. JpegParser& operator=(const JpegParser &); static void longjmp_error_exit(j_common_ptr cinfo); void initializeSource(); void tokenizeImage(); void tokenizeMarker(const string &base_token, jpeg_saved_marker_ptr marker); private: struct jpeg_decompress_struct m_compressionInfo; bool m_initialized; struct jpeg_source_mgr m_source; struct error_mgr { struct jpeg_error_mgr error_mgr; jmp_buf return_buffer; } m_error_mgr; }; #endif // _JpegParser_h #endif // HAVE_JPEG spamprobe-1.4d/src/parser/MBoxMailMessageReader.h0000664000076400007640000000310410527261701017000 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MBoxMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _MBoxMailMessageReader_h #define _MBoxMailMessageReader_h #include "RegularExpression.h" #include "MailMessageReader.h" class MBoxMailMessageReader : public MailMessageReader { public: MBoxMailMessageReader(bool use_content_length); virtual ~MBoxMailMessageReader(); protected: virtual bool isNewMessageBoundary(const string &line); private: bool m_isPrevLineBlank; RegularExpression m_newMessage; }; #endif spamprobe-1.4d/src/parser/PngParser.h0000664000076400007640000000365710527260213014613 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #if defined(HAVE_PNG) #ifndef _PngParser_h #define _PngParser_h extern "C" { #include } #include "ImageParser.h" #include "Buffer.h" class AbstractTokenizer; class AbstractTokenReceiver; class Message; class PngParser : public ImageParser { public: PngParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes); ~PngParser(); virtual bool parseImage(); private: void initializeImage(); void tokenizeImage(); static void receiveHeader(png_structp png_ptr, png_infop info); private: /// Not implemented. PngParser(const PngParser &); /// Not implemented. PngParser& operator=(const PngParser &); private: png_structp m_pngPtr; png_infop m_infoPtr; bool m_initialized; }; #endif // _PngParser_h #endif // HAVE_PNG spamprobe-1.4d/src/parser/GifParser.cc0000664000076400007640000001322410527261701014724 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: GifParser.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #if defined(HAVE_UNGIF) #include #include "AbstractTokenizer.h" #include "MD5Digester.h" #include "Message.h" #include "StringReader.h" #include "GifParser.h" static int throw_on_error(const char *function_name, int rc) { if (rc != GIF_ERROR) { return rc; } static string message(function_name); message += ": error: "; message += num_to_string(rc); throw runtime_error(message); } int GifParser::readFromBuffer(GifFileType *file, GifByteType *dst, int length) { GifParser *parser = (GifParser *)file->UserData; int remaining = parser->m_bytes.length() - parser->m_nextByteIndex; if (remaining == 0) { return 0; } if (length > remaining) { length = remaining; } memcpy(dst, parser->m_bytes.get() + parser->m_nextByteIndex, length); parser->m_nextByteIndex += length; return length; } GifParser::GifParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes) : ImageParser(message, tokenizer, receiver, prefix, bytes), m_gif(0) { } GifParser::~GifParser() { if (m_gif) { DGifCloseFile(m_gif); } } bool GifParser::parseImage() { try { openImage(); digestImage(); parseImageRecords(); } catch (runtime_error &ex) { return false; } } void GifParser::openImage() { m_nextByteIndex = 0; m_gif = DGifOpen(this, readFromBuffer); if (!m_gif) { throw runtime_error("open gif failed"); } } void GifParser::parseImageRecords() { GifRecordType rec_type; int max_loops = 1500; int image_num = 0; while ((max_loops-- > 0) && (throw_on_error("DGifGetRecordType", DGifGetRecordType(m_gif, &rec_type)) != TERMINATE_RECORD_TYPE)) { string base_token("image_"); base_token += num_to_string(image_num); switch (rec_type) { case IMAGE_DESC_RECORD_TYPE: { throw_on_error("DGifGetImageDesc", DGifGetImageDesc(m_gif)); sendToken(base_token + "_height_" + num_to_string(m_gif->Image.Height)); sendToken(base_token + "_width_" + num_to_string(m_gif->Image.Width)); sendToken(base_token + "_left_" + num_to_string(m_gif->Image.Left)); sendToken(base_token + "_top_" + num_to_string(m_gif->Image.Top)); sendToken(base_token + (m_gif->Image.Interlace ? "_interlaced" : "_noninterlaced")); sendToken(base_token + (m_gif->Image.ColorMap ? "_color_map" : "_no_color_map")); if (m_gif->Image.ColorMap) { sendToken(base_token + "_bpp_" + num_to_string(m_gif->Image.ColorMap->BitsPerPixel)); int len = 1 << m_gif->Image.ColorMap->BitsPerPixel; for (int i = 0; i < len; i+= 4) { for (int j = 0; j < 4 && j < len; ++j) { sendToken(base_token + "_color_red_" + num_to_string(m_gif->Image.ColorMap->Colors[i + j].Red)); sendToken(base_token + "_color_green_" + num_to_string(m_gif->Image.ColorMap->Colors[i + j].Green)); sendToken(base_token + "_color_blue_" + num_to_string(m_gif->Image.ColorMap->Colors[i + j].Blue)); } } } // skip the image int code_size; GifByteType *code_block; throw_on_error("DGifGetCode", DGifGetCode(m_gif, &code_size, &code_block)); while (code_block) { throw_on_error("DGifGetCodeNext", DGifGetCodeNext(m_gif, &code_block)); } ++image_num; } break; case EXTENSION_RECORD_TYPE: { int ext_code; GifByteType *extension; throw_on_error("DGifGetExtension", DGifGetExtension(m_gif, &ext_code, &extension)); sendToken(base_token + "_extcode_" + num_to_string(ext_code)); while (extension) { const int slen = (int)extension[0]; string prefix(base_token); prefix += "_extchars_"; string token; for (int i = 1; i <= slen; ++i) { if (isprint(extension[i])) { token += extension[i]; } else { token += '{'; token += num_to_string(extension[i]); token += '}'; } } sendToken(prefix + token); StringReader reader(token); m_tokenizer->tokenize(m_receiver, &reader, m_prefix + prefix); throw_on_error("DGifGetExtensionNext", DGifGetExtensionNext(m_gif, &extension)); } } break; default: break; } } } #endif // HAVE_UNGIF spamprobe-1.4d/src/parser/MailMessage.cc0000664000076400007640000001151210527261701015227 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessage.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MultiLineString.h" #include "MultiLineSubString.h" #include "MessageHeaderList.h" #include "MimeDecoder.h" #include "RegularExpression.h" #include "BodyParser.h" #include "HeaderParser.h" #include "MailMessage.h" #include "MailMessageList.h" static const string IS_HTML_REGEX("|

|
||||headText()->lineCount(); ++i) { cerr << "HEAD: '" << msg->headText()->line(i) << "'" << endl; } for (int i = 0; i < msg->bodyText()->lineCount(); ++i) { cerr << "BODY: '" << msg->bodyText()->line(i) << "'" << endl; } } MailMessage::MailMessage(const CRef &full_text) : m_fullText(full_text) { int first_blank = 0; while (first_blank < full_text->lineCount()) { if (full_text->line(first_blank).length() == 0) { break; } ++first_blank; } m_headText = make_ref(new MultiLineSubString(full_text, 0, first_blank)); m_bodyText = make_ref(new MultiLineSubString(full_text, first_blank + 1)); } MailMessage::MailMessage(const CRef &head_text, const CRef &body_text, const CRef &full_text) : m_headText(head_text), m_bodyText(body_text), m_fullText(full_text) { } MailMessage::~MailMessage() { } const MessageHeaderList *MailMessage::head() { if (m_head.isNull()) { HeaderParser parser; m_head = parser.parseHeader(m_headText); } return m_head.ptr(); } const MailMessageList *MailMessage::body() { if (m_body.isNull()) { if (isMultiPartType()) { BodyParser parser; m_body = parser.parseBody(head(), m_bodyText); } else { m_body = make_ref(new MailMessageList()); } } return m_body.ptr(); } bool MailMessage::isMultiPart() { return isMultiPartType(); } bool MailMessage::hasParts() { return body()->messageCount() >= 1; } bool MailMessage::isHtml(const AbstractMultiLineString *text) { string content_type; if (head()->getContentTypeString(content_type).length() > 0) { return starts_with(content_type, "text/html"); } if (text->lineCount() == 0) { return false; } RegularExpression html_regex(IS_HTML_REGEX, 1, true); for (int i = 0; i < 4 && i < text->lineCount(); ++i) { if (html_regex.match(text->line(i))) { return true; } } return false; } bool MailMessage::isMultiPartType() { return head()->hasBoundaryString() || head()->isMessageType(); } const AbstractMultiLineString *MailMessage::asText(bool &is_html) { if (body()->messageCount() == 1) { return body()->message(0)->asText(is_html); } if (body()->messageCount() != 0) { if (is_debug) { cerr << "IGNORED MULTI-PART BODY" << endl; } return 0; } if (!head()->isTextType()) { if (is_debug) { cerr << "IGNORED NON-TEXT BODY" << endl; } return 0; } if (m_decodedText.isNull()) { MimeDecoder decoder; m_decodedText = decoder.decodeText(head(), m_bodyText); m_isHtml = isHtml(m_decodedText.ptr()); if (is_debug) { cerr << "DECODED BODY" << endl; } } is_html = m_isHtml; return m_decodedText.ptr(); } bool MailMessage::asData(Buffer &buffer) { MimeDecoder decoder; if (!decoder.isBase64(head()->header("content-transfer-encoding"))) { return false; } buffer.reset(60 * m_bodyText->lineCount()); decoder.decodeData(m_bodyText, buffer); return true; } spamprobe-1.4d/src/parser/MailMessageDigester.cc0000664000076400007640000000714310527261701016723 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageDigester.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MD5Digester.h" #include "MessageHeaderList.h" #include "RegularExpression.h" #include "MailMessageDigester.h" void MailMessageDigester::assignDigestToMessage(Message *parsed_message, MailMessage *mail_message, const string &existing_digest_header) { string digest; if (!getExistingDigest(mail_message->head(), existing_digest_header, digest)) { digestMessage(mail_message, digest); } parsed_message->setDigest(digest); } const string &MailMessageDigester::digestMessage(MailMessage *message, string &buffer) { MD5Digester md5; md5.start(); digestLines(md5, message->bodyText()); digestHeaderLines(md5, message->head(), "date"); digestHeaderLines(md5, message->head(), "from"); digestHeaderLines(md5, message->head(), "to"); digestHeaderLines(md5, message->head(), "subject"); md5.stop(); buffer = md5.asString(); return buffer; } void MailMessageDigester::digestLines(MD5Digester &md5, const CRef lines) { for (int i = 0; i < lines->lineCount(); ++i) { const string &line(lines->line(i)); if (line.length() > 0) { md5.add(line); if (is_debug) { cerr << "DIGEST: " << line << endl; } } } } void MailMessageDigester::digestHeaderLines(MD5Digester &md5, const MessageHeaderList *message_headers, const string &header_name) { CRef header_lines(message_headers->header(header_name)); if (header_lines.isNotNull()) { digestLines(md5, header_lines); } } bool MailMessageDigester::getExistingDigest(const MessageHeaderList *message_headers, const string &header_name, string &buffer) { static RegularExpression digest_expr("^[a-z]+ +[0-9]\\.[0-9]+ +([0-9a-z]+)", 2, true); if (header_name.length() == 0) { return false; } CRef header_lines(message_headers->header(header_name)); if (header_lines.isNull()) { return false; } assert(header_lines->lineCount() >= 1); if (!digest_expr.match(header_lines->line(0))) { return false; } return digest_expr.getMatch(1, buffer).length() == 32; } spamprobe-1.4d/src/parser/AutoTrainMailMessageReader.cc0000664000076400007640000000777110527261701020215 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AutoTrainMailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "MailMessage.h" #include "AutoTrainMailMessageReader.h" AutoTrainMailMessageReader::AutoTrainMailMessageReader() : m_spamCount(0), m_totalCount(0), m_messageWasSpam(false) { m_readerFactory.setIgnoreFrom(false); m_readerFactory.setIgnoreContentLength(false); } AutoTrainMailMessageReader::~AutoTrainMailMessageReader() { } void AutoTrainMailMessageReader::addMailboxFile(bool is_spam, const string &path) { long num_messages = countMessagesInFile(path); if (num_messages == 0) { cerr << "IGNORING EMPTY FILE " << path << endl; return; } if (is_spam) { m_spamPaths.push_back(path); m_spamCount += num_messages; } else { m_goodPaths.push_back(path); } m_totalCount += num_messages; } long AutoTrainMailMessageReader::countMessagesInFile(const string &path) { if (is_verbose) { cerr << "counting messages in file " << path << endl; } Ptr reader; openFile(path, reader); long count = 0; Ptr message(reader->readMessage()); while (message.isNotNull()) { ++count; message.set(reader->readMessage()); } if (is_verbose) { cerr << "file " << path << " contains " << count << " messages." << endl; } return count; } void AutoTrainMailMessageReader::openFile(const string &path, Ptr &reader) { reader.set(m_readerFactory.createReader(File(path))); } bool AutoTrainMailMessageReader::readMessage(deque &paths, string &path, Ptr &reader, Ptr &message) { m_messageFile.setPath(path); message.clear(); if (reader.isNotNull()) { message.set(reader->readMessage()); } while (message.isNull() && paths.size() > 0) { path = paths.front(); paths.pop_front(); openFile(path, reader); message.set(reader->readMessage()); m_messageFile.setPath(path); } return message.isNotNull(); } bool AutoTrainMailMessageReader::readMessage(bool is_spam, Ptr &message) { m_messageWasSpam = is_spam; bool read_message = false; if (is_spam) { read_message = readMessage(m_spamPaths, m_spamPath, m_spamReader, message); } else { read_message = readMessage(m_goodPaths, m_goodPath, m_goodReader, message); } return read_message; } OWNED MailMessage *AutoTrainMailMessageReader::readMessage() { Ptr message; bool use_spam = shouldUseSpam(); if (!readMessage(use_spam, message)) { readMessage(!use_spam, message); } return message.release(); } bool AutoTrainMailMessageReader::shouldUseSpam() { return (m_totalCount >= 0) && ((random() % m_totalCount) < m_spamCount); } spamprobe-1.4d/src/parser/MbxMailMessageReader.cc0000664000076400007640000000735210527261701017030 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MbxMailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "MailMessage.h" #include "MailMessageList.h" #include "LineReader.h" #include "MultiLineString.h" #include "MbxMailMessageReader.h" static const int MBX_FILE_FIRST_LINE_LENGTH = 7; static const int MBX_FILE_HEADER_LENGTH = 2048; static const int MBX_SKIP_HEADER_COUNT = MBX_FILE_HEADER_LENGTH - MBX_FILE_FIRST_LINE_LENGTH; static const unsigned long MBX_DELETED_FLAG = 0x0002; static const string MBX_RECORD_HEADER_REGEX("^[ 0-9][0-9]+-[A-Za-z]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ .?[0-9]+,([0-9]+);[--9a-zA-Z]+([--9a-zA-Z][--9a-zA-Z][--9a-zA-Z][--9a-zA-Z])-[0-9a-zA-Z]+$"); MbxMailMessageReader::MbxMailMessageReader() : m_headerRegex(MBX_RECORD_HEADER_REGEX, 3), m_recordLength(0) { } MbxMailMessageReader::~MbxMailMessageReader() { } bool MbxMailMessageReader::readMBXRecordHeader() { bool again = true; while (again) { m_recordLength = 0; if (!reader()->hasLine()) { return false; } if (is_debug) { cerr << "MBX: HDR: " << reader()->currentLine() << endl; } if (!m_headerRegex.match(reader()->currentLine())) { throw runtime_error(string("IMAP-MBX: regex for record header did not match: ") + reader()->currentLine()); } string matched; m_recordLength = atoi(m_headerRegex.getMatch(1, matched).c_str()); unsigned long flags = strtoul(m_headerRegex.getMatch(2, matched).c_str(), 0, 16); if (is_debug) { cerr << "MBX: FLAGS " << hex << flags << " RECLEN " << dec << m_recordLength << endl; } if (!(flags & MBX_DELETED_FLAG)) { return true; } // message is marked deleted reader()->skipChars(m_recordLength); reader()->forward(); if (is_debug) { cerr << "MBX: SKIPPED DELETED MESSAGE" << endl; } } } OWNED MailMessage *MbxMailMessageReader::readMessage() { if (!readMBXRecordHeader()) { if (is_debug) { cerr << "MBX: END OF FILE" << endl; } return 0; } Ref text(new MultiLineString()); while (reader()->forward(m_recordLength)) { text->addLine(reader()->currentLine()); } reader()->forward(); return (text->lineCount() > 0) ? new MailMessage(text) : 0; } bool MbxMailMessageReader::isMbxFile(AbstractCharReader *in) { Ptr start_pos(in->createMark()); if (start_pos.isNull()) { return false; } if (in->matchChar('*') && in->matchChar('m') && in->matchChar('b') && in->matchChar('x') && in->matchChar('*') && in->matchChar('\r') && in->matchChar('\n')) { in->skip(MBX_SKIP_HEADER_COUNT); return true; } in->returnToMark(start_pos.get()); return false; } spamprobe-1.4d/src/parser/FileMailMessageReader.h0000664000076400007640000000352510527261701017021 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FileMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FileMailMessageReader_h #define _FileMailMessageReader_h #include "AbstractLineMailMessageReader.h" class StreamMailMessageReader; class FileMailMessageReader : public AbstractMailMessageReader { public: FileMailMessageReader(); virtual ~FileMailMessageReader(); void open(const string &path, bool ignore_from, bool ignore_content_length); void close(); virtual OWNED MailMessage *readMessage(); private: /// Not implemented. FileMailMessageReader(const FileMailMessageReader &); /// Not implemented. FileMailMessageReader& operator=(const FileMailMessageReader &); private: Ptr m_stream; Ptr m_reader; }; #endif // _FileMailMessageReader_h spamprobe-1.4d/src/parser/AbstractLineMailMessageReader.h0000664000076400007640000000324410527261701020513 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractLineMailMessageReader.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractLineMailMessageReader_h #define _AbstractLineMailMessageReader_h #include "AbstractMailMessageReader.h" class AbstractLineMailMessageReader : public AbstractMailMessageReader { public: AbstractLineMailMessageReader() : m_reader(0) {} virtual ~AbstractLineMailMessageReader() {} void setLineReader(LineReader *reader) { m_reader = reader; } LineReader *reader() { return m_reader; } private: bool readMBXRecordHeader(LineReader *reader); private: LineReader *m_reader; }; #endif spamprobe-1.4d/src/parser/MailMessageReaderFactory.cc0000664000076400007640000000531510527261701017706 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageReaderFactory.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "File.h" #include "AbstractMailMessageReader.h" #include "FileMailMessageReader.h" #include "MaildirMailMessageReader.h" #include "StreamMailMessageReader.h" #include "MailMessageReaderFactory.h" MailMessageReaderFactory::MailMessageReaderFactory() : m_ignoreFrom(false), m_ignoreContentLength(true) { } // Any Maildir directory is valid. // Just about any file is acceptable except for dot files inside // of a Maildir directory. The latter restriction prevents us from // processing password files, IMAPD cache files, etc. bool MailMessageReaderFactory::isAcceptableFile(const File &file) { if (file.isSelfOrParent()) { return false; } else if (file.isFile()) { return !(file.isHidden() && MaildirMailMessageReader::isMaildir(file.parent())); } else { return MaildirMailMessageReader::isMaildir(file); } } OWNED AbstractMailMessageReader *MailMessageReaderFactory::createReader(const File &file) { if (file.isDirectory()) { if (!MaildirMailMessageReader::isMaildir(file)) { throw runtime_error(string("not a maildir: ") + file.getPath()); } return new MaildirMailMessageReader(file); } else { Ptr reader(new FileMailMessageReader); reader->open(file.getPath(), m_ignoreFrom, m_ignoreContentLength); return reader.release(); } } OWNED AbstractMailMessageReader *MailMessageReaderFactory::createStdinReader() { Ptr reader(new StreamMailMessageReader); reader->setStream(&cin, false, m_ignoreFrom, m_ignoreContentLength); return reader.release(); } spamprobe-1.4d/src/parser/ParserConfig.cc0000664000076400007640000000362210527261701015425 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: ParserConfig.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "ParserConfig.h" #include "RegularExpression.h" ParserConfig::ParserConfig() : m_minTermLength(1), m_maxTermLength(90), m_replaceNonAsciiChars(true), m_nonAsciiChar('z'), m_removeHTML(true), m_keepSuspiciousTags(false), m_ignoreBody(false), m_minPhraseTerms(1), m_maxPhraseTerms(2), m_minPhraseChars(0), m_maxPhraseChars(0), m_maxTermsPerMessage(0), m_spamprobeFieldName("x-spamprobe") { #ifdef USE_8BIT setReplaceNonAsciiChars(0); #endif headers()->addSimpleHeaderPrefix("from"); headers()->addSimpleHeaderPrefix("to"); headers()->addSimpleHeaderPrefix("cc"); headers()->addSimpleHeaderPrefix("subject"); headers()->addHeaderPrefix("received", "recv", "recvx"); } ParserConfig::~ParserConfig() { } spamprobe-1.4d/src/parser/Tokenizer.cc0000664000076400007640000000557210527261701015023 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Tokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "Tokenizer.h" Tokenizer::Tokenizer() : m_state(STATE_START) { } Tokenizer::~Tokenizer() { } inline bool is_letter_char(char ch) { return (ch & 0x80) || is_alnum(ch) || (ch == '%'); } inline bool is_special_char(char ch) { switch (ch) { case '.': case '-': case '+': case ',': case '_': case '$': return true; default: return false; } } bool Tokenizer::addChar(char ch) { switch (m_state) { case STATE_START: m_word.erase(); m_state = STATE_WAITING; // fall through case STATE_WAITING: assert(m_word.length() == 0); assert(m_pending.length() == 0); if (ch == '$' || is_letter_char(ch)) { m_word += to_lower(ch); m_state = STATE_IN_WORD; return false; } return false; case STATE_IN_WORD: assert(m_word.length() > 0); assert(m_pending.length() == 0); if (is_letter_char(ch)) { m_word += to_lower(ch); return false; } if (is_special_char(ch)) { m_state = STATE_PENDING; m_pending += ch; return false; } m_state = STATE_START; return true; case STATE_PENDING: assert(m_word.length() > 0); assert(m_pending.length() > 0); if (is_letter_char(ch)) { m_state = STATE_IN_WORD; m_word += m_pending; m_word += to_lower(ch); m_pending.erase(); return false; } if (is_special_char(ch)) { m_pending += ch; return false; } m_state = STATE_START; m_pending.erase(); return true; default: assert(!"not a valid state"); break; } assert(!"not reached"); return false; } void Tokenizer::start() { m_state = STATE_START; m_pending.erase(); } bool Tokenizer::stop() { return (m_state != STATE_START) && (m_word.length() > 0); } spamprobe-1.4d/src/parser/PhrasingTokenizer.cc0000664000076400007640000000764410527261701016521 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: PhrasingTokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "TempPtr.h" #include "AbstractTokenReceiver.h" #include "PhrasingTokenizer.h" static const string SEPARATOR(" "); static const string::size_type MAX_START(2048); static const string::size_type RESERVE_LENGTH(3072); PhrasingTokenizer::PhrasingTokenizer(AbstractTokenizer *tokenizer, int min_words, int max_words, int min_char_length, int max_char_length) : m_tokenizer(tokenizer), m_minWords(min_words), m_maxWords(max_words), m_minCharLength(min_char_length), m_maxCharLength(max_char_length), m_receiver(0) { m_maxWordsInList = (min_char_length <= 0) ? m_maxWords : min_char_length; m_chars.reserve(RESERVE_LENGTH); } PhrasingTokenizer::~PhrasingTokenizer() { } string::size_type PhrasingTokenizer::charsStart() { assert((m_chars.length() == 0) == (m_offsets.size() == 0)); if (m_chars.length() == 0 || m_offsets.size() == 0) { return 0; } else { assert(m_offsets.back() <= m_offsets.front()); assert(m_offsets.size() == 1 || m_offsets.front() > m_offsets.back()); string::size_type answer = m_offsets.back(); assert(answer < m_chars.length()); return answer; } } void PhrasingTokenizer::compactChars() { string::size_type start = charsStart(); if (start > MAX_START) { for (deque::iterator i = m_offsets.begin(), limit = m_offsets.end(); i != limit; ++i) { assert(*i >= start); *i -= start; } m_chars.erase(0, start); } } void PhrasingTokenizer::receiveToken(const string &prefix, const string &token) { while (m_offsets.size() >= m_maxWordsInList) { m_offsets.pop_back(); } compactChars(); m_chars += SEPARATOR; m_offsets.push_front(m_chars.length()); m_chars += token; int num_words = 1; for (deque::const_iterator i = m_offsets.begin(), limit = m_offsets.end(); i != limit; ++i) { assert(*i < m_chars.length()); const char *phrase = m_chars.c_str() + *i; string::size_type phrase_length = m_chars.length() - *i; if (m_maxCharLength > 0 && phrase_length > m_maxCharLength) { break; } if ((num_words > m_maxWords) && (m_minCharLength <= 0 || phrase_length > m_minCharLength)) { break; } if (num_words >= m_minWords) { m_receiver->receiveToken(prefix, phrase); } ++num_words; } } void PhrasingTokenizer::tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix) { assert(!m_receiver); m_chars.erase(); m_offsets.clear(); TempPtr tmp_receiver(m_receiver, receiver); m_tokenizer->tokenize(this, reader, prefix); } spamprobe-1.4d/src/parser/HeaderPrefixList.cc0000664000076400007640000001143510527261701016246 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: HeaderPrefixList.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "HeaderPrefixList.h" static const char *SKIPPED_HEADERS[] = { "x-spam", "x-razor", "status", "x-status", "x-imap", 0 }; const string PREFIX_START("H"); const string PREFIX_END("_"); static bool is_skipped_header(const string &line) { for (const char **s = SKIPPED_HEADERS; *s; ++s) { if (starts_with(line, *s)) { return true; } } return false; } string HeaderPrefixList::const_iterator::getPrefixBody(const string &prefix) { return prefix.substr(PREFIX_START.length(), prefix.length() - PREFIX_START.length() - PREFIX_END.length()); } HeaderPrefixList::HeaderPrefixList() : m_visitAllHeaders(false), m_ignoreXHeaders(false), m_forceBlankPrefixes(false) { } HeaderPrefixList::~HeaderPrefixList() { } void HeaderPrefixList::resetHeaderCounts() { for (IteratorType i = m_values.begin(); i != m_values.end(); ++i) { i->second.visit_count = 0; } } bool HeaderPrefixList::shouldProcessHeader(const string &name, string &prefix) { IteratorType i = m_values.find(name); if (i != m_values.end()) { HeaderData &hd(i->second); hd.visit_count += 1; if (m_forceBlankPrefixes) { prefix.erase(); } else if (hd.visit_count > 1) { prefix = hd.other_prefix; } else { prefix = hd.first_prefix; } return true; } if (!m_visitAllHeaders) { return false; } if (m_ignoreXHeaders && starts_with(name, "x-")) { return false; } if (is_skipped_header(name)) { return false; } if (m_forceBlankPrefixes) { prefix.erase(); } else { prefix = PREFIX_START + name + PREFIX_END; } addHeaderPrefix(name, name, name); return true; } void HeaderPrefixList::setBlankPrefixesMode() { m_forceBlankPrefixes = true; } void HeaderPrefixList::setDefaultHeadersMode() { m_visitAllHeaders = false; m_ignoreXHeaders = false; m_forceBlankPrefixes = false; m_values.clear(); addHeaderPrefix("reply-to", "reply-to", "reply-to"); addHeaderPrefix("sender", "sender", "sender"); addHeaderPrefix("originator", "originator", "originator"); addHeaderPrefix("subject", "subject", "subject"); addHeaderPrefix("from", "from", "from"); addHeaderPrefix("to", "to", "to"); addHeaderPrefix("cc", "cc", "cc"); addHeaderPrefix("message-id", "message-id", "message-id"); addHeaderPrefix("received", "recv", "recvx"); addHeaderPrefix("content-type", "", ""); } void HeaderPrefixList::setNonXHeadersMode() { m_visitAllHeaders = true; m_ignoreXHeaders = true; m_forceBlankPrefixes = false; m_values.clear(); } void HeaderPrefixList::setAllHeadersMode() { m_visitAllHeaders = true; m_ignoreXHeaders = false; m_forceBlankPrefixes = false; m_values.clear(); } void HeaderPrefixList::setNoHeadersMode() { m_visitAllHeaders = false; m_ignoreXHeaders = false; m_forceBlankPrefixes = false; m_values.clear(); } void HeaderPrefixList::addSimpleHeaderPrefix(const string &name) { addHeaderPrefix(name, name, name); } void HeaderPrefixList::addHeaderPrefix(const string &name, const string &first_prefix, const string &other_prefix) { HeaderData hd; if (first_prefix.length() > 0) { hd.first_prefix = PREFIX_START + to_lower(first_prefix) + PREFIX_END; } if (other_prefix.length() > 0) { hd.other_prefix = PREFIX_START + to_lower(other_prefix) + PREFIX_END; } hd.visit_count = 0; m_values.insert(make_pair(to_lower(name), hd)); } void HeaderPrefixList::removeHeaderPrefix(const string &name) { string lower_name(to_lower(name)); MapType::iterator i = m_values.find(lower_name); if (i != m_values.end()) { m_values.erase(i); } } spamprobe-1.4d/src/parser/MailMessageReader.cc0000664000076400007640000000744610527261701016365 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "RegularExpression.h" #include "MailMessage.h" #include "MailMessageList.h" #include "LineReader.h" #include "MultiLineString.h" #include "MailMessageReader.h" // Defines how many chars to deduct from content-length so that we can // find a blank line before the message delimiter line that follows // the message. static const int CONTENT_LENGTH_PADDING = 10; MailMessageReader::MailMessageReader(bool use_content_length) : m_useContentLength(use_content_length) { } MailMessageReader::~MailMessageReader() { } bool MailMessageReader::findContentLength(MultiLineString *text, int &content_length) { RegularExpression regex("^content-length: *([0-9]+)", 2, true); for (int i = 0; i < text->lineCount(); ++i) { if (regex.match(text->line(i))) { string buffer; content_length = max(0, atoi(regex.getMatch(1, buffer).c_str()) - CONTENT_LENGTH_PADDING); return true; } } return false; } OWNED MailMessage *MailMessageReader::readMessage() { Ref text(new MultiLineString()); if (m_useContentLength) { readMessageWithContentLength(text.ptr()); } else { readMessageWithBoundary(text.ptr(), false); } return (text->lineCount() > 0) ? new MailMessage(text) : 0; } void MailMessageReader::readMessageWithBoundary(MultiLineString *text, bool append_to_last_line) { while (reader()->hasLine()) { if (isNewMessageBoundary(reader()->currentLine())) { break; } if (is_debug) { cerr << "LINE: '" << reader()->currentLine() << "'" << endl; } if (append_to_last_line) { text->appendToLastLine(reader()->currentLine()); append_to_last_line = false; } else { text->addLine(reader()->currentLine()); } reader()->forward(); } } void MailMessageReader::readMessageWithContentLength(MultiLineString *text) { while (reader()->hasLine()) { if (is_debug) { cerr << "HDR: '" << reader()->currentLine() << "'" << endl; } text->addLine(reader()->currentLine()); if (reader()->currentLine().length() == 0) { break; } reader()->forward(); } bool should_append = false; int content_length = 0; if (findContentLength(text, content_length)) { should_append = content_length > 0; while (reader()->forward(content_length)) { if (is_debug) { cerr << "CL: " << content_length << ": " << reader()->currentLine() << endl; } text->addLine(reader()->currentLine()); } reader()->forward(); } readMessageWithBoundary(text, should_append); } bool MailMessageReader::isNewMessageBoundary(const string &line) { return false; } spamprobe-1.4d/src/parser/Makefile.am0000664000076400007640000000211410527144253014565 00000000000000AUTOMAKE_OPTIONS=foreign INCLUDES= -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES=libparser.a libparser_a_SOURCES=\ AbstractLineMailMessageReader.h\ AutoTrainMailMessageReader.cc\ BodyParser.cc\ BodyParser.h\ FileMailMessageReader.cc\ FileMailMessageReader.h\ GifParser.cc\ GifParser.h\ HeaderParser.cc\ HeaderParser.h\ HeaderPrefixList.cc\ HtmlTokenizer.cc\ ImageParser.cc\ ImageParser.h\ JpegParser.cc\ JpegParser.h\ MaildirMailMessageReader.cc\ MaildirMailMessageReader.h\ MailMessage.cc\ MailMessageDigester.cc\ MailMessageReader.cc\ MailMessageReader.h\ MailMessageReaderFactory.cc\ MBoxMailMessageReader.cc\ MBoxMailMessageReader.h\ MbxMailMessageReader.cc\ MbxMailMessageReader.h\ MessageHeader.cc\ MessageHeaderList.cc\ MimeDecoder.cc\ MimeDecoder.h\ ParserConfig.cc\ PhrasingTokenizer.cc\ PhrasingTokenizer.h\ PngParser.cc\ PngParser.h\ SimpleTokenizer.cc\ StreamMailMessageReader.cc\ StreamMailMessageReader.h\ TokenCollector.cc\ TokenFilteringTokenizer.cc\ Tokenizer.cc\ TraditionalMailMessageParser.cc\ UrlOnlyHtmlTokenizer.cc spamprobe-1.4d/src/parser/JpegParser.cc0000664000076400007640000001107310527260214015102 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #if defined(HAVE_JPEG) #include #include "AbstractTokenizer.h" #include "MD5Digester.h" #include "Message.h" #include "StringReader.h" #include "JpegParser.h" JpegParser::JpegParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes) : ImageParser(message, tokenizer, receiver, prefix, bytes), m_initialized(false) { } JpegParser::~JpegParser() { if (m_initialized) { jpeg_destroy_decompress(&m_compressionInfo); m_initialized = false; } } bool JpegParser::parseImage() { try { initializeSource(); digestImage(); tokenizeImage(); } catch (runtime_error &ex) { return false; } } void JpegParser::tokenizeMarker(const string &base_token, jpeg_saved_marker_ptr marker) { string prefix("_marker_"); prefix += num_to_string(marker->marker); prefix += "_"; string token; for (int i = 0; i < marker->data_length; ++i) { char ch = (char)marker->data[i]; if (isprint(ch)) { token += ch; } else { token += '{'; token += num_to_string(ch); token += '}'; } } StringReader reader(token); m_tokenizer->tokenize(m_receiver, &reader, m_prefix + base_token + prefix); } void JpegParser::tokenizeImage() { if (setjmp(m_error_mgr.return_buffer)) { throw runtime_error("jpeg error"); } jpeg_save_markers(&m_compressionInfo, JPEG_COM, 1024); for (int i = 0; i <= 15; ++i) { jpeg_save_markers(&m_compressionInfo, JPEG_APP0 + i, 1024); } jpeg_read_header(&m_compressionInfo, TRUE); string base_token("image_0"); for (jpeg_saved_marker_ptr marker = m_compressionInfo.marker_list; marker; marker = marker->next) { tokenizeMarker(base_token, marker); } sendToken(base_token + "_height_" + num_to_string((int)m_compressionInfo.image_width)); sendToken(base_token + "_width_" + num_to_string((int)m_compressionInfo.image_height)); sendToken(base_token + "_color_space_" + num_to_string(m_compressionInfo.jpeg_color_space)); sendToken(base_token + "_num_components_" + num_to_string(m_compressionInfo.num_components)); } static void mem_init_source(j_decompress_ptr cinfo) { } static boolean mem_fill_input_buffer(j_decompress_ptr cinfo) { if (cinfo->src->bytes_in_buffer > 0) { return TRUE; } ERREXIT(cinfo, JERR_FILE_READ); } static void mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes) { while (num_bytes > 0 && cinfo->src->bytes_in_buffer > 0) { ++cinfo->src->next_input_byte; --cinfo->src->bytes_in_buffer; --num_bytes; } } static void mem_term_source(j_decompress_ptr cinfo) { } void JpegParser::longjmp_error_exit(j_common_ptr cinfo) { struct error_mgr *error_mgr = (struct error_mgr *)cinfo->err; longjmp(error_mgr->return_buffer, 1); } void JpegParser::initializeSource() { m_compressionInfo.err = jpeg_std_error(&m_error_mgr.error_mgr); m_error_mgr.error_mgr.error_exit = longjmp_error_exit; if (setjmp(m_error_mgr.return_buffer)) { throw runtime_error("jpeg error"); } jpeg_create_decompress(&m_compressionInfo); m_initialized = true; m_source.next_input_byte = m_bytes.get(); m_source.bytes_in_buffer = m_bytes.length(); m_source.init_source = mem_init_source; m_source.fill_input_buffer = mem_fill_input_buffer; m_source.skip_input_data = mem_skip_input_data; m_source.resync_to_restart = jpeg_resync_to_restart; m_source.term_source = mem_term_source; m_compressionInfo.src = &m_source; } #endif // HAVE_JPEG spamprobe-1.4d/src/parser/ImageParser.cc0000664000076400007640000000356410527260214015245 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "AbstractTokenizer.h" #include "MD5Digester.h" #include "Message.h" #include "StringReader.h" #include "ImageParser.h" ImageParser::ImageParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes) : m_message(message), m_tokenizer(tokenizer), m_receiver(receiver), m_prefix(prefix), m_bytes(bytes) { } ImageParser::~ImageParser() { } void ImageParser::sendToken(const string &token) { m_message->addToken(token, m_prefix, Token::FLAG_NORMAL); } void ImageParser::digestImage() { MD5Digester digester; digester.start(); digester.add(m_bytes.get(), m_bytes.length()); digester.stop(); sendToken(string("digest_") + digester.asString()); } spamprobe-1.4d/src/parser/TokenFilteringTokenizer.cc0000664000076400007640000000450710527261701017665 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TokenFilteringTokenizer.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "AbstractTokenReceiver.h" #include "TokenFilteringTokenizer.h" static const char SEPARATOR = ' '; TokenFilteringTokenizer::TokenFilteringTokenizer(AbstractTokenizer *tokenizer, int min_length, int max_length, bool allow_numbers) : m_tokenizer(tokenizer), m_minLength(min_length), m_maxLength(max_length), m_allowNumbers(allow_numbers) { } TokenFilteringTokenizer::~TokenFilteringTokenizer() { } void TokenFilteringTokenizer::receiveToken(const string &prefix, const string &token) { if (token.length() < m_minLength) { return; } if (token.length() > m_maxLength) { return; } if (!m_allowNumbers && is_digits(token)) { return; } m_receiver->receiveToken(prefix, token); } void TokenFilteringTokenizer::tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix) { m_receiver = receiver; m_tokenizer->tokenize(this, reader, prefix); } spamprobe-1.4d/src/parser/TokenCollector.cc0000664000076400007640000000313510527261701015771 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TokenCollector.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "TokenCollector.h" TokenCollector::~TokenCollector() { } void TokenCollector::receiveToken(const string &token) { MapType::iterator i = m_tokens.find(token); if (i == m_tokens.end()) { m_tokens[token] = 1; } else { i->second += 1; } } void TokenCollector::getTokens(TokenCollector::ListType &tokens) { for (MapType::const_iterator i = m_tokens.begin(); i != m_tokens.end(); ++i) { tokens.push_back(i->first); } } spamprobe-1.4d/src/parser/StreamMailMessageReader.cc0000664000076400007640000000466710527261701017543 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: StreamMailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "IstreamCharReader.h" #include "LineReader.h" #include "MbxMailMessageReader.h" #include "MBoxMailMessageReader.h" #include "StreamMailMessageReader.h" StreamMailMessageReader::StreamMailMessageReader() : m_stream(0) { } StreamMailMessageReader::~StreamMailMessageReader() { close(); } void StreamMailMessageReader::close() { m_mailReader.clear(); m_lineReader.clear(); m_charReader.clear(); m_stream = 0; } void StreamMailMessageReader::setStream(istream *in_stream, bool can_seek, bool ignore_from, bool ignore_content_length) { close(); m_stream = in_stream; m_charReader.set(new IstreamCharReader(in_stream, can_seek)); m_lineReader.set(new LineReader(m_charReader.get())); if (MbxMailMessageReader::isMbxFile(m_charReader.get())) { m_mailReader.set(new MbxMailMessageReader()); } else if (ignore_from) { m_mailReader.set(new MailMessageReader()); } else { m_mailReader.set(new MBoxMailMessageReader(!ignore_content_length)); } m_mailReader->setLineReader(m_lineReader.get()); m_lineReader->forward(); } OWNED MailMessage *StreamMailMessageReader::readMessage() { assert(m_mailReader.isNotNull()); return m_mailReader->readMessage(); } spamprobe-1.4d/src/parser/BodyParser.h0000664000076400007640000000374010527261701014760 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: BodyParser.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _BodyParser_h #define _BodyParser_h #include "util.h" class MessageHeaderList; class AbstractMultiLineString; class MailMessageList; class BodyParser { public: Ref parseBody(const MessageHeaderList *headers, const CRef &body_text); private: int skipToBlank(const CRef &lines, int &offset); int skipToNonBlank(const CRef &lines, int &offset); void addPart(const CRef &lines); void addPartsForBoundary(const CRef &lines, const string &boundary); void parse(); private: const MessageHeaderList *m_headers; CRef m_bodyText; Ref m_bodyParts; }; #endif spamprobe-1.4d/src/parser/Makefile.in0000664000076400007640000003705610527227177014622 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(libparser_a_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src/parser DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libparser_a_AR = $(AR) $(ARFLAGS) libparser_a_LIBADD = am_libparser_a_OBJECTS = AutoTrainMailMessageReader.$(OBJEXT) \ BodyParser.$(OBJEXT) FileMailMessageReader.$(OBJEXT) \ GifParser.$(OBJEXT) HeaderParser.$(OBJEXT) \ HeaderPrefixList.$(OBJEXT) HtmlTokenizer.$(OBJEXT) \ ImageParser.$(OBJEXT) JpegParser.$(OBJEXT) \ MaildirMailMessageReader.$(OBJEXT) MailMessage.$(OBJEXT) \ MailMessageDigester.$(OBJEXT) MailMessageReader.$(OBJEXT) \ MailMessageReaderFactory.$(OBJEXT) \ MBoxMailMessageReader.$(OBJEXT) MbxMailMessageReader.$(OBJEXT) \ MessageHeader.$(OBJEXT) MessageHeaderList.$(OBJEXT) \ MimeDecoder.$(OBJEXT) ParserConfig.$(OBJEXT) \ PhrasingTokenizer.$(OBJEXT) PngParser.$(OBJEXT) \ SimpleTokenizer.$(OBJEXT) StreamMailMessageReader.$(OBJEXT) \ TokenCollector.$(OBJEXT) TokenFilteringTokenizer.$(OBJEXT) \ Tokenizer.$(OBJEXT) TraditionalMailMessageParser.$(OBJEXT) \ UrlOnlyHtmlTokenizer.$(OBJEXT) libparser_a_OBJECTS = $(am_libparser_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libparser_a_SOURCES) DIST_SOURCES = $(libparser_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign INCLUDES = -I@top_srcdir@/src/includes -I@top_srcdir@/src noinst_LIBRARIES = libparser.a libparser_a_SOURCES = \ AbstractLineMailMessageReader.h\ AutoTrainMailMessageReader.cc\ BodyParser.cc\ BodyParser.h\ FileMailMessageReader.cc\ FileMailMessageReader.h\ GifParser.cc\ GifParser.h\ HeaderParser.cc\ HeaderParser.h\ HeaderPrefixList.cc\ HtmlTokenizer.cc\ ImageParser.cc\ ImageParser.h\ JpegParser.cc\ JpegParser.h\ MaildirMailMessageReader.cc\ MaildirMailMessageReader.h\ MailMessage.cc\ MailMessageDigester.cc\ MailMessageReader.cc\ MailMessageReader.h\ MailMessageReaderFactory.cc\ MBoxMailMessageReader.cc\ MBoxMailMessageReader.h\ MbxMailMessageReader.cc\ MbxMailMessageReader.h\ MessageHeader.cc\ MessageHeaderList.cc\ MimeDecoder.cc\ MimeDecoder.h\ ParserConfig.cc\ PhrasingTokenizer.cc\ PhrasingTokenizer.h\ PngParser.cc\ PngParser.h\ SimpleTokenizer.cc\ StreamMailMessageReader.cc\ StreamMailMessageReader.h\ TokenCollector.cc\ TokenFilteringTokenizer.cc\ Tokenizer.cc\ TraditionalMailMessageParser.cc\ UrlOnlyHtmlTokenizer.cc all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/parser/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/parser/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libparser.a: $(libparser_a_OBJECTS) $(libparser_a_DEPENDENCIES) -rm -f libparser.a $(libparser_a_AR) libparser.a $(libparser_a_OBJECTS) $(libparser_a_LIBADD) $(RANLIB) libparser.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AutoTrainMailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BodyParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileMailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GifParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeaderParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeaderPrefixList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HtmlTokenizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ImageParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JpegParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MBoxMailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MailMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MailMessageDigester.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MailMessageReaderFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MaildirMailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MbxMailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageHeader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageHeaderList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MimeDecoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParserConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PhrasingTokenizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PngParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleTokenizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamMailMessageReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TokenCollector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TokenFilteringTokenizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tokenizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TraditionalMailMessageParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlOnlyHtmlTokenizer.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/parser/MessageHeaderList.cc0000664000076400007640000001031410527261701016370 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MessageHeaderList.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "RegularExpression.h" #include "MultiLineSubString.h" #include "MultiLineJoinedString.h" #include "MessageHeader.h" #include "MessageHeaderList.h" static const string CONTENT_TYPE("content-type"); CRef MessageHeaderList::header(const string &name) const { MultiLineStringList values; for (int i = 0; i < m_headers.size(); ++i) { if (m_headers[i]->hasName(name)) { values.push_back(m_headers[i]->lines()); } } if (values.size() == 0) { return CRef(); } if (values.size() == 1) { return values[0]; } return CRef(new MultiLineJoinedString(values)); } const string &MessageHeaderList::getContentTypeString(string &buffer) const { getHeaderString(CONTENT_TYPE, EMPTY_STRING, buffer); buffer = to_lower(buffer); return buffer; } const string &MessageHeaderList::getBoundaryString(string &buffer) const { string header; getHeaderString(CONTENT_TYPE, EMPTY_STRING, header); return findParam(header, "boundary", EMPTY_STRING, buffer); } const string &MessageHeaderList::getCharsetString(string &buffer) const { string header; getHeaderString(CONTENT_TYPE, EMPTY_STRING, header); findParam(header, "charset", EMPTY_STRING, buffer); buffer = to_lower(buffer); return buffer; } const string &MessageHeaderList::getHeaderString(const string &header_name, const string &default_value, string &buffer) const { CRef header_strings(header(header_name)); if (header_strings.isNull()) { buffer = default_value; } else { header_strings->join(buffer); } return buffer; } bool MessageHeaderList::hasBoundaryString() const { string boundary_string; getBoundaryString(boundary_string); return boundary_string.length() > 0; } bool MessageHeaderList::isTextType() const { string content_type; getContentTypeString(content_type); return content_type.length() == 0 || starts_with(content_type, "text"); } bool MessageHeaderList::hasType(const string &type_name) const { string content_type; getContentTypeString(content_type); return starts_with(content_type, type_name); } bool MessageHeaderList::isMessageType() const { return hasType("message/rfc822"); } const string &MessageHeaderList::findParam(const string &header, const string ¶m, const string &defaultValue, string &buffer) const { RegularExpression param_regex(string("[^a-z]") + param + "[ \t]*=[ \t]*\"([^\"]+)\"", 2, true); if (param_regex.match(header)) { return param_regex.getMatch(1, buffer); } param_regex.setExpression(string("[^a-z]") + param + "[ \t]*=[ \t]*([^ \t;\"]+)", 2, true); if (param_regex.match(header)) { return param_regex.getMatch(1, buffer); } buffer = defaultValue; return buffer; } spamprobe-1.4d/src/parser/PhrasingTokenizer.h0000664000076400007640000000417510527261701016357 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: PhrasingTokenizer.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _PhrasingTokenizer_h #define _PhrasingTokenizer_h #include #include "AbstractTokenizer.h" class PhrasingTokenizer : public AbstractTokenizer, AbstractTokenReceiver { public: PhrasingTokenizer(OWNED AbstractTokenizer *tokenizer, int min_words, int max_words, int min_char_length, int max_char_length); virtual ~PhrasingTokenizer(); virtual void tokenize(AbstractTokenReceiver *receiver, AbstractCharReader *reader, const string &prefix); virtual void receiveToken(const string &prefix, const string &token); private: string::size_type charsStart(); void compactChars(); private: Ptr m_tokenizer; deque m_offsets; string m_chars; int m_maxWordsInList; int m_minWords; int m_maxWords; int m_minCharLength; int m_maxCharLength; AbstractTokenReceiver *m_receiver; }; #endif spamprobe-1.4d/src/parser/MBoxMailMessageReader.cc0000664000076400007640000000353710527261701017150 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: MBoxMailMessageReader.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "RegularExpression.h" #include "MBoxMailMessageReader.h" static const string NEW_MESSAGE_REGEX("^From[ \t]+[^ \t]+[ \t]+[a-zA-Z][a-zA-Z][a-zA-Z][ \t]+[a-zA-Z][a-zA-Z][a-zA-Z][ \t]+[0-9][0-9]?[ \t]+[0-9][0-9][ \t]*:[ \t]*[0-9][0-9][ \t]*:[ \t]*[0-9][0-9][ \t]+[0-9][0-9][0-9][0-9]"); MBoxMailMessageReader::MBoxMailMessageReader(bool use_content_length) : MailMessageReader(use_content_length), m_isPrevLineBlank(false), m_newMessage(NEW_MESSAGE_REGEX) { } MBoxMailMessageReader::~MBoxMailMessageReader() { } bool MBoxMailMessageReader::isNewMessageBoundary(const string &line) { bool answer = m_isPrevLineBlank && m_newMessage.match(line); m_isPrevLineBlank = (line.length() == 0); return answer; } spamprobe-1.4d/src/parser/PngParser.cc0000664000076400007640000000663510527260216014753 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #if defined(HAVE_PNG) #include #include "AbstractTokenizer.h" #include "MD5Digester.h" #include "Message.h" #include "StringReader.h" #include "PngParser.h" PngParser::PngParser(Message *message, AbstractTokenizer *tokenizer, AbstractTokenReceiver *receiver, const string &prefix, const Buffer &bytes) : ImageParser(message, tokenizer, receiver, prefix, bytes), m_pngPtr(0), m_infoPtr(0), m_initialized(false) { } PngParser::~PngParser() { if (m_initialized) { if (m_infoPtr) { png_destroy_read_struct(&m_pngPtr, &m_infoPtr, png_infopp_NULL); } else { png_destroy_read_struct(&m_pngPtr, png_infopp_NULL, png_infopp_NULL); } } } bool PngParser::parseImage() { try { digestImage(); initializeImage(); } catch (runtime_error &ex) { return false; } } void PngParser::initializeImage() { m_pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!m_pngPtr) { throw runtime_error("allocate png ptr failed"); } m_initialized = true; m_infoPtr = png_create_info_struct(m_pngPtr); if (!m_infoPtr) { throw runtime_error("allocate info ptr failed"); } if (setjmp(png_jmpbuf(m_pngPtr))) { throw runtime_error("png error"); } png_set_progressive_read_fn(m_pngPtr, this, receiveHeader, NULL, NULL); png_process_data(m_pngPtr, m_infoPtr, m_bytes.get(), m_bytes.length()); } void PngParser::receiveHeader(png_structp png_ptr, png_infop info) { PngParser *parser = (PngParser *)png_get_progressive_ptr(png_ptr); parser->tokenizeImage(); } void PngParser::tokenizeImage() { png_uint_32 width, height; int bit_depth, color_type, interlace_type; png_get_IHDR(m_pngPtr, m_infoPtr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); string base_token("image_0"); sendToken(base_token + "_height_" + num_to_string((int)width)); sendToken(base_token + "_width_" + num_to_string((int)height)); sendToken(base_token + "_bit_depth_" + num_to_string((int)bit_depth)); sendToken(base_token + "_color_type_" + num_to_string(color_type)); sendToken(base_token + "_interlace_type_" + num_to_string(interlace_type)); png_start_read_image(m_pngPtr); } #endif // HAVE_PNG spamprobe-1.4d/src/Makefile.in0000664000076400007640000003156010527227176013317 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign SUBDIRS = database includes input parser utility hdl spamprobe all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ clean clean-generic clean-recursive ctags ctags-recursive \ distclean distclean-generic distclean-recursive distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/spamprobe/0000777000076400007640000000000010527262443013313 500000000000000spamprobe-1.4d/src/spamprobe/AbstractFileCommand.cc0000664000076400007640000000477310527261701017411 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractFileCommand.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "File.h" #include "LockFile.h" #include "ConfigManager.h" #include "CommandConfig.h" #include "SpamFilter.h" #include "MailMessageReaderFactory.h" #include "AbstractFileCommand.h" bool AbstractFileCommand::argsOK(const ConfigManager &config) { bool answer = true; const CommandConfig *cmd_config = config.commandConfig(); const int num_args = cmd_config->numArgs(); for (int i = 0; i < num_args; ++i) { File f(cmd_config->arg(i)); if (!f.exists()) { answer = false; cerr << "error: " << f.getPath() << ": file not found" << endl; } } return answer; } int AbstractFileCommand::execute(const ConfigManager &config, SpamFilter &filter) { if (needsDatabase()) { openDatabase(config, filter); } const CommandConfig *cmd_config = config.commandConfig(); if (cmd_config->numArgs() == 0) { processFile(config, filter, 0); } else { for (int i = 0, limit = cmd_config->numArgs(); i < limit; ++i) { File f(cmd_config->arg(i)); if (!MailMessageReaderFactory::isAcceptableFile(f)) { cerr << "error: skipped " << f.getPath() << ": not a supported file or directory" << endl; } else { LockFile lock(f); if (f.isFile()) { lock.lock(LockFD::SHARED_LOCK); } processFile(config, filter, &f); } } } return 0; } spamprobe-1.4d/src/spamprobe/Command_remove.cc0000664000076400007640000000430310527261701016467 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_remove.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_remove.h" Command_remove::Command_remove() : AbstractMessageCommand("remove", "remove Removes messages from database", "remove [filename...]\n" " Scans each file (or stdin if no file is specified) and removes its\n" " term counts from the database. Messages which are not in the\n" " database (recognized using their MD5 digest) are ignored.\n", false, true) { } void Command_remove::processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam) { filter.removeMessage(message); logMessageProcessing(true, message, stream_file); } spamprobe-1.4d/src/spamprobe/FilterConfig.h0000664000076400007640000001013310527261701015747 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FilterConfig.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _FilterConfig_h #define _FilterConfig_h #include #include "TokenSelector.h" class TokenSelector; class FilterConfig { public: enum ScoreMode { SCORE_NORMAL, SCORE_ORIGINAL, SCORE_ALT1, }; FilterConfig(); ~FilterConfig(); void setScoreMode(ScoreMode mode); ScoreMode getScoreMode() const { return m_scoreMode; } void setGoodBias(int value) { m_goodBias = value; } int getGoodBias() const { return m_goodBias; } void setTermsForScore(int value) { m_termsForScore = value; } int getTermsForScore() const { return m_termsForScore; } void setMaxWordRepeats(int value) { m_maxWordRepeats = value; } int getMaxWordRepeats() const { return m_maxWordRepeats; } void setMinWordCount(int value) { m_defaultMinWordCount = value; m_minWordCount = value; } int getMinWordCount() const { return m_minWordCount; } void setNewWordScore(double value) { m_newWordScore = value; } double getNewWordScore() const { return m_newWordScore; } void setExtendTopTerms(bool value) { m_extendTopTerms = value; } bool getExtendTopTerms() const { return m_extendTopTerms; } double getSpamThreshold() const { return m_spamThreshold; } void setSpamThreshold(double value) { m_defaultThreshold = value; m_spamThreshold = value; } void setDefaultThreshold(double value) { m_defaultThreshold = value; setScoreMode(m_scoreMode); } double getDefaultThreshold() const { return m_defaultThreshold; } void setMinDistanceForScore(double value) { m_minDistanceForScore = value; } double getMinDistanceForScore() const { return m_minDistanceForScore; } void setMinArraySize(int value) { m_minArraySize = value; } int getMinArraySize() const { return m_minArraySize; } void setWaterCounts(bool value) { m_waterCounts = value; } bool getWaterCounts() const { return m_waterCounts; } int numTokenSelectors() const { return (int)m_tokenSelectors.size(); } TokenSelector *tokenSelector(int index) { return m_tokenSelectors[index].ptr(); } void addTokenSelector(OWNED TokenSelector *selector) { m_tokenSelectors.push_back(make_ref(selector)); } void clearTokenSelectors(); private: /// Not implemented. FilterConfig(const FilterConfig &); /// Not implemented. FilterConfig& operator=(const FilterConfig &); private: typedef vector > TokenSelectorVector; // settings related to scoring mode int m_goodBias; int m_minWordCount; int m_defaultMinWordCount; double m_spamThreshold; ScoreMode m_scoreMode; TokenSelectorVector m_tokenSelectors; // other settings int m_termsForScore; int m_maxWordRepeats; bool m_extendTopTerms; double m_newWordScore; double m_minDistanceForScore; int m_minArraySize; bool m_waterCounts; double m_defaultThreshold; }; #endif // _FilterConfig_h spamprobe-1.4d/src/spamprobe/AutoPurger.h0000664000076400007640000000337410527261701015502 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AutoPurger.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AutoPurger_h #define _AutoPurger_h #include "util.h" class ConfigManager; class CleanupManager; class FrequencyDB; class SpamFilter; class AutoPurger { public: AutoPurger(const ConfigManager &config, SpamFilter &filter, int junk_count = 2); ~AutoPurger(); void disable(); void processedMessage(); void finish(); private: /// Not implemented. AutoPurger(const AutoPurger &); /// Not implemented. AutoPurger& operator=(const AutoPurger &); private: Ptr m_cleaner; FrequencyDB *m_db; int m_messageCount; int m_messagesPerPurge; }; #endif // _AutoPurger_h spamprobe-1.4d/src/spamprobe/Command_auto_train.h0000664000076400007640000000406210527261701017203 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_auto_train.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_auto_train_h #define _Command_auto_train_h #include "AbstractCommand.h" class Command_auto_train : public AbstractCommand { public: static const Ref createAutoTrainCommand(); static const Ref createAutoLearnCommand(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); protected: Command_auto_train(const string &name, const string &short_help, const string &long_help, bool is_learn) : AbstractCommand(name, short_help, long_help, false), m_isLearn(is_learn) { } private: void logMessage(const ConfigManager &config, SpamFilter &filter, const string &type, bool correct, Message &message); private: bool m_isLearn; }; #endif // _Command_auto_train_h spamprobe-1.4d/src/spamprobe/Command_exec.cc0000664000076400007640000000762510527261701016130 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_exec.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "SpamFilter.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "Command_exec.h" Command_exec::Command_exec(bool shared) : AbstractCommand(shared ? "exec-shared" : "exec", shared ? "exec-shared Execute command with shared lock." : "exec Execute command with exclusive lock.", "exec[-shared] command [args...]\n" " Obtains a lock on the database and then executes the\n" " command using system(3). If multiple arguments are given after\n" " 'exec' they are combined to form the command to be executed. This\n" " command can be used when you want to perform some operation on the\n" " database without interference from incoming mail. For example, to\n" " back up your .spamprobe directory using tar you could do something\n" " like this:\n" "\n" " cd\n" " spamprobe exec tar cf spamprobe-data.tar.gz .spamprobe\n" "\n" " If you simply want to hold the lock while interactively running\n" " commands in a different xterm you could use 'spamprobe exec read'.\n" " The linux read program simply reads a line of text from your\n" " terminal so the lock would effectively be held until you pressed\n" " the enter key. Another option would be to use a shell as the\n" " command and type the commands into that shell:\n" "\n" " spamprobe /bin/bash\n" " ls\n" " date\n" " exit\n" "\n" " Be careful not to run spamprobe in the shell though since the\n" " spamprobe in the shell will wind up deadlocked waiting for the\n" " spamprobe running the exec command to release its lock.\n", shared) { } bool Command_exec::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args >= 1; } int Command_exec::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); string command; const CommandConfig *cmd_config = config.commandConfig(); for (int i = 0, limit = cmd_config->numArgs(); i < limit; ++i) { if (i > 0) { command += ' '; } command += cmd_config->arg(i); } if (is_debug) { cerr << "EXEC: " << command << endl; } int rc = system(command.c_str()); if (is_debug) { cerr << "EXEC RC: " << rc << endl; } return 0; } spamprobe-1.4d/src/spamprobe/Command_spam.cc0000664000076400007640000001461610527261701016142 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_spam.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_spam.h" const Ref Command_spam::createGoodCommand() { return Ref(new Command_spam("good", "good Classifies messages as good (non-spam).", "good [filename...]\n" " Scans each file (or stdin if no file is specified) and reclassifies\n" " every email in the file as non-spam. The databases are updated\n" " appropriately. Messages previously classified as good (recognized\n" " using their MD5 digest or message ids) are ignored. Messages\n" " previously classified as spam are reclassified as good.\n", false, true, false, false)); } const Ref Command_spam::createSpamCommand() { return Ref(new Command_spam("spam", "spam Classifies messages as spam.", "spam [filename...]\n" " Scans each file (or stdin if no file is specified) and reclassifies\n" " every email in the file as spam. The databases are updated\n" " appropriately. Messages previously classified as spam (recognized\n" " using their MD5 digest of message ids) are ignored. Messages\n" " previously classified as good are reclassified as spam.\n", false, true, true, false)); } const Ref Command_spam::createTrainGoodCommand() { return Ref(new Command_spam("train-good", "train-good Classifies messages as good (non-spam).", "train-good [filename...]\n" " Functionally identical to 'good' command except that it only\n" " updates the database for messages that are either incorrectly\n" " classified (i.e. classified as spam) or are difficult to\n" " classify. In practice this can reduce amount of database updates\n" " to as little as 10% of messages.\n", false, true, false, true)); } const Ref Command_spam::createTrainSpamCommand() { return Ref(new Command_spam("train-spam", "train-spam Classifies messages as spam.", "train-spam [filename...]\n" " Functionally identical to 'spam' command except that it only\n" " updates the database for messages that are either incorrectly\n" " classified (i.e. classified as good) or are difficult to\n" " classify. In practice this can reduce amount of database updates\n" " to as little as 10% of messages.\n", false, true, true, true)); } void Command_spam::processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam) { if (m_isTrain) { is_spam = filter.trainOnMessage(message, filter.scoreMessage(message), m_isSpam, false); } else { is_spam = filter.classifyMessage(message, m_isSpam); } logMessageProcessing(true, message, stream_file); } spamprobe-1.4d/src/spamprobe/CommandConfig.cc0000664000076400007640000000327210527261701016244 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: CommandConfig.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CommandConfig.h" CommandConfig::CommandConfig() : m_messagesPerPurge(0), m_shouldShowTerms(false), m_streamIsPretokenized(false), m_ignoreFrom(false), m_ignoreContentLength(false), m_shouldCreateDbDir(false) { } const Ref CommandConfig::findCommand(const string &name) const { for (CommandVector::const_iterator i = m_commands.begin(); i != m_commands.end(); ++i) { const Ref &command = *i; if (command->name() == name) { return command; } } return Ref(); } spamprobe-1.4d/src/spamprobe/AbstractFileCommand.h0000664000076400007640000000415610527261701017246 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractFileCommand.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractFileCommand_h #define _AbstractFileCommand_h #include "AbstractCommand.h" class ConfigManager; class File; class SpamFilter; class AbstractFileCommand : public AbstractCommand { public: AbstractFileCommand(const string &name, const string &short_help, const string &long_help, bool read_only, bool needs_database) : AbstractCommand(name, short_help, long_help, read_only), m_needsDatabase(needs_database) { } bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); bool needsDatabase() const { return m_needsDatabase; } virtual void processFile(const ConfigManager &config, SpamFilter &filter, const File *stream_file) = 0; static const int AUTO_PURGE_JUNK_COUNT; private: bool m_needsDatabase; }; #endif // _AbstractFileCommand_h spamprobe-1.4d/src/spamprobe/Command_create_db.cc0000664000076400007640000000407610527261701017111 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_create_db.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_create_db.h" Command_create_db::Command_create_db() : AbstractCommand("create-db", "create-db Creates a new database if none currently exists.", "create-db\n" " If no database currently exists a new one will be created.\n" " If a database already exists this command will have no effect.\n", false) { } bool Command_create_db::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0; } int Command_create_db::execute(const ConfigManager &config, SpamFilter &filter) { createDbDir(config); openDatabase(config, filter); return 0; } spamprobe-1.4d/src/spamprobe/Command_import.cc0000664000076400007640000000772310527261701016515 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_import.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "LineReader.h" #include "IstreamCharReader.h" #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_import.h" Command_import::Command_import() : AbstractFileCommand("import", "import Imports terms into database.", "import [filename...]\n" " Reads the specified files which must contain export data written by\n" " the export command. The terms and counts from this file are added\n" " to the database. This can be used to convert a database from a\n" " prior version.\n", false, true) { } void Command_import::processStream(const ConfigManager &config, SpamFilter &filter, const File *stream_file, istream &in_stream) { RegularExpression parts_expr("^(-?[0-9]+),(-?[0-9]+)(,([0-9]+))?,\"?([^\"]+)\"?$", 5); assert(parts_expr.isValid()); string match_buffer; int record_count = 0; IstreamCharReader char_reader(&in_stream); LineReader line_reader(&char_reader); while (line_reader.forward()) { if (is_debug) { cerr << "IMPORT " << line_reader.currentLine() << endl; } if (parts_expr.match(line_reader.currentLine())) { if (parts_expr.matchCount() >= 6) { int good_count = atoi(parts_expr.getMatch(1, match_buffer).c_str()); int spam_count = atoi(parts_expr.getMatch(2, match_buffer).c_str()); string flags_str = parts_expr.getMatch(4, match_buffer); parts_expr.getMatch(5, match_buffer); string decoded; decode_string(match_buffer, decoded); if (is_debug) { cerr << "gc " << good_count << " sc " << spam_count << " flags " << flags_str << " term " << match_buffer << endl; } if (flags_str.length() > 0) { unsigned long flags = atoi(flags_str.c_str()); filter.getDB()->addWord(decoded, good_count, spam_count, flags); } else { filter.getDB()->addWord(decoded, good_count, spam_count); } if (++record_count > 10000) { filter.flush(); record_count = 0; } } } } } void Command_import::processFile(const ConfigManager &config, SpamFilter &filter, const File *stream_file) { if (stream_file) { ifstream in_stream(stream_file->getPath().c_str()); processStream(config, filter, stream_file, in_stream); } else { processStream(config, filter, stream_file, cin); } } spamprobe-1.4d/src/spamprobe/Command_receive.cc0000664000076400007640000001615410527261701016623 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_receive.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_receive.h" const Ref Command_receive::createReceiveCommand() { return Ref(new Command_receive("receive", "receive Scores message, prints score, and updates database accordingly.", "receive\n" " Tells SpamProbe to read its standard input (or a file specified\n" " after the receive command) and score it using the current\n" " databases. Once the message has been scored the message is\n" " classified as either spam or non-spam and its word counts are\n" " written to the appropriate database. The message's score is\n" " written to stdout along with a single word. For example:\n" "\n" " SPAM 0.9999999 595f0150587edd7b395691964069d7af\n" "\n" " or\n" "\n" " GOOD 0.0200000 595f0150587edd7b395691964069d7af\n" "\n" " The string of numbers and letters after the score is the message's\n" " digest, a 32 character number which uniquely identifies the\n" " message. The digest is used by SpamProbe to recognize messages\n" " that it has processed previously so that it can keep its word\n" " counts consistent if the message is reclassified.\n" "\n" " Using the -T option additionally lists the terms used to produce\n" " the score along with their counts (number of times they were found\n" " in the message).\n", false, true, false, true)); } const Ref Command_receive::createScoreCommand() { return Ref(new Command_receive("score", "score Scores message and prints score.", "score\n" " Similar to receive except that the database is not modified in\n" " any way. Because it does not update the database multiple\n" " processes can run this command at the same time on a single\n" " database. You might use this instead of receive or train\n" " if you want to score incoming email and then use train-spam\n" " or train-good on the email later to update the database\n" " in a cron task. Generally train is a better command to\n" " use for incoming email.\n", true, true, false, false)); } const Ref Command_receive::createTrainCommand() { return Ref(new Command_receive("train", "train Scores message, prints score, and updates database if necessary.", "train [filename...]\n" " Functionally identical to receive except that the database is only\n" " modified if the message was difficult to classify. In practice\n" " this can reduce the number of database updates to as little as 10%\n" " of messages received. Generally this is the best command to use\n" " for incoming mail.\n", false, true, true, true)); } void Command_receive::processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam) { SpamFilter::Score score = filter.scoreMessage(message); is_spam = score.isSpam(); printMessageScore(config, filter, is_spam, score.getValue(), message); if (isReadOnly()) { // no updates needed } else if (m_isTrain) { is_spam = filter.trainOnMessage(message, score, is_spam, true); } else { is_spam = filter.classifyMessage(message, is_spam); } } spamprobe-1.4d/src/spamprobe/Command_import.h0000664000076400007640000000322710527261701016352 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_import.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_import_h #define _Command_import_h #include "AbstractFileCommand.h" class Command_import : public AbstractFileCommand { public: Command_import(); protected: void processFile(const ConfigManager &config, SpamFilter &filter, const File *stream_file); private: void processStream(const ConfigManager &config, SpamFilter &filter, const File *stream_file, istream &in_stream); }; #endif // _Command_import_h spamprobe-1.4d/src/spamprobe/SpamFilter.h0000664000076400007640000001222610527261701015447 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SpamFilter.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _SpamFilter_h #define _SpamFilter_h #include "File.h" #include "FrequencyDB.h" #include "FilterConfig.h" class ConfigManager; class LockFile; class TokenSelector; class SpamFilter { public: SpamFilter(ConfigManager *config); ~SpamFilter(); class Score { public: Score() :m_score(0.5), m_mode(FilterConfig::SCORE_NORMAL), m_isSpam(false) { } Score(double _score, FilterConfig::ScoreMode _mode, bool is_spam) : m_score(_score), m_mode(_mode), m_isSpam(is_spam) { } double getValue() const { return m_score; } FilterConfig::ScoreMode getMode() { return m_mode; } bool isSpam() const { return m_isSpam; } bool isGood() const { return !m_isSpam; } bool isConfident(bool should_be_spam) { switch (m_mode) { case FilterConfig::SCORE_ALT1: return should_be_spam ? (m_score >= 0.85) : (m_score <= 0.15); default: assert(m_mode == FilterConfig::SCORE_ORIGINAL || m_mode == FilterConfig::SCORE_NORMAL); return should_be_spam ? (m_score >= 0.995) : (m_score <= 0.005); } } private: double m_score; FilterConfig::ScoreMode m_mode; bool m_isSpam; }; void open(bool read_only); void close(bool abandon_writes = false); void flush() { m_db.flush(); } FrequencyDB *getDB() { return &m_db; } bool isNewMessage(const Message &msg) { bool is_spam; return !m_db.containsMessage(msg, is_spam); } void ensureGoodMessage(const Message &msg, bool force_update); void ensureSpamMessage(const Message &msg, bool force_update); void removeMessage(const Message &msg) { m_db.removeMessage(msg); } Score scoreMessage(Message &msg); Score scoreMessage(Message &msg, FilterConfig::ScoreMode mode); Score scoreMessageIfWrongMode(Score current_score, Message &msg, FilterConfig::ScoreMode mode) { return (current_score.getMode() == mode) ? current_score : scoreMessage(msg, mode); } bool isSpam(Message &msg) { return scoreMessage(msg).isSpam(); } double scoreTerm(int good_count, int spam_count, int good_message_count, int spam_message_count); bool classifyMessage(Message &msg, bool is_spam); bool trainOnMessage(Message &msg, const SpamFilter::Score &score, bool is_spam, bool update_timestamps); private: void dumpSortedTokens(vector &tokens); void sortTokens(vector &tokens); void removeTokensBelowMinDistance(vector &tokens); void scoreTokens(const Message &msg); double computeRatio(double count, double total_count); void computeScoreProducts(Message &msg, TokenSelector *selector, double &spamness, double &goodness, double &num_terms); void scoreToken(Token *tok, int good_message_count, int spam_message_count); void getSortedTokens(const Message &msg, TokenSelector *selector, int max_tokens, vector &tokens); double scoreMessage(Message &msg, TokenSelector *selector); double normalScoreMessage(Message &msg, TokenSelector *selector); double alt1ScoreMessage(Message &msg, TokenSelector *selector); double originalScoreMessage(Message &msg, TokenSelector *selector); void lock(const File &db_file, bool read_only); private: /// Not implemented. SpamFilter(const SpamFilter &); /// Not implemented. SpamFilter& operator=(const SpamFilter &); private: ConfigManager *m_config; FrequencyDB m_db; Ptr m_lock; }; #endif // _SpamFilter_h spamprobe-1.4d/src/spamprobe/AutoPurger.cc0000664000076400007640000000407310527261701015635 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AutoPurger.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CleanupManager.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "FrequencyDB.h" #include "SpamFilter.h" #include "AutoPurger.h" AutoPurger::AutoPurger(const ConfigManager &config, SpamFilter &filter, int junk_count) : m_cleaner(new CleanupManager(junk_count, -1)), // -1 forces today's to be removed too m_db(filter.getDB()), m_messageCount(0), m_messagesPerPurge(config.commandConfig()->messagesPerPurge()) { } AutoPurger::~AutoPurger() { } void AutoPurger::disable() { m_messagesPerPurge = 0; } void AutoPurger::processedMessage() { if (m_messagesPerPurge > 0) { ++m_messageCount; if (m_messageCount % m_messagesPerPurge == 0) { m_db->sweepOutOldTerms(*m_cleaner); } } } void AutoPurger::finish() { if (m_messagesPerPurge > 0) { if (m_messageCount % m_messagesPerPurge != 0) { m_db->sweepOutOldTerms(*m_cleaner); } } } spamprobe-1.4d/src/spamprobe/spamprobe.cc0000664000076400007640000010227510527261701015533 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: spamprobe.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include #include "CommandConfig.h" #include "Command_auto_train.h" #include "Command_cleanup.h" #include "Command_counts.h" #include "Command_create_config.h" #include "Command_create_db.h" #include "Command_dump.h" #include "Command_edit_term.h" #include "Command_exec.h" #include "Command_export.h" #include "Command_help.h" #include "Command_import.h" #include "Command_print.h" #include "Command_purge.h" #include "Command_purge_terms.h" #include "Command_receive.h" #include "Command_remove.h" #include "Command_spam.h" #include "Command_summarize.h" #include "Command_tokenize.h" #include "Command_train_test.h" #include "ConfigManager.h" #include "CleanupManager.h" #include "DatabaseConfig.h" #include "InterruptedException.h" #include "File.h" #include "SpamFilter.h" #include "ParserConfig.h" #include "WordData.h" #include "SimpleTokenSelector.h" static const string DB_FILENAME("sp_words"); static const int MAX_MAX_CACHE_TERMS = 100000; static const int MAX_MESSAGES_PER_PURGE = 100000; // must be global so that an atexit() routine can close the filter database static Ptr s_filter; bool process_extended_options(const vector &option_names, ConfigManager &config_mgr) { bool failed = false; for (vector::const_iterator i = option_names.begin(); i != option_names.end(); ++i) { string option_name(*i); if (option_name.length() > 0) { if (option_name == "graham") { config_mgr.parserConfig()->setMaxPhraseTerms(1); config_mgr.parserConfig()->setRemoveHTML(false); config_mgr.parserConfig()->setMinTermLength(1); config_mgr.parserConfig()->setMaxTermLength(90); config_mgr.filterConfig()->setTermsForScore(15); config_mgr.filterConfig()->setMaxWordRepeats(1); config_mgr.filterConfig()->setNewWordScore(0.4); config_mgr.filterConfig()->setExtendTopTerms(false); config_mgr.parserConfig()->headers()->setAllHeadersMode(); config_mgr.filterConfig()->setScoreMode(FilterConfig::SCORE_ORIGINAL); } else if (option_name == "suspicious-tags") { config_mgr.parserConfig()->setKeepSuspiciousTags(true); } else if (option_name == "honor-status-header") { config_mgr.commandConfig()->setStatusFieldName("status"); } else if (option_name == "honor-xstatus-header") { config_mgr.commandConfig()->setStatusFieldName("x-status"); } else if (option_name == "orig-score") { config_mgr.filterConfig()->setScoreMode(FilterConfig::SCORE_ORIGINAL); } else if (option_name == "tokenized") { config_mgr.commandConfig()->setStreamIsPretokenized(true); } else if (option_name == "ignore-body") { config_mgr.parserConfig()->setIgnoreBody(true); } else if (option_name == "whitelist") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.parserConfig()->setIgnoreBody(true); } else if (option_name != "normal") { cerr << "error: unknown option: " << option_name << endl; failed = true; } } } return failed; } bool process_test_cases(const vector &test_cases, ConfigManager &config_mgr) { bool failed = false; for (vector::const_iterator i = test_cases.begin(); i != test_cases.end(); ++i) { string test_case(*i); if (test_case.length() > 0) { if (test_case == "graham") { config_mgr.parserConfig()->setMaxPhraseTerms(1); config_mgr.parserConfig()->setRemoveHTML(false); config_mgr.parserConfig()->setMinTermLength(1); config_mgr.parserConfig()->setMaxTermLength(90); config_mgr.filterConfig()->setTermsForScore(15); config_mgr.filterConfig()->setMaxWordRepeats(1); config_mgr.filterConfig()->setNewWordScore(0.4); config_mgr.filterConfig()->setExtendTopTerms(false); config_mgr.parserConfig()->headers()->setAllHeadersMode(); } else if (test_case == "all-sigs") { config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); } else if (test_case == "all-sigs-3") { config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.parserConfig()->setMaxPhraseTerms(3); } else if (test_case == "all-sigs-5") { config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.parserConfig()->setMaxPhraseTerms(5); } else if (test_case == "all-phrases-2-3") { config_mgr.parserConfig()->setMinPhraseTerms(2); config_mgr.parserConfig()->setMaxPhraseTerms(3); } else if (test_case == "all-phrases-3-4") { config_mgr.parserConfig()->setMinPhraseTerms(3); config_mgr.parserConfig()->setMaxPhraseTerms(4); } else if (test_case == "all-phrases-4-5") { config_mgr.parserConfig()->setMinPhraseTerms(4); config_mgr.parserConfig()->setMaxPhraseTerms(5); } else if (test_case == "all-phrases-2-5") { config_mgr.parserConfig()->setMinPhraseTerms(2); config_mgr.parserConfig()->setMaxPhraseTerms(5); } else if (test_case == "all-phrases-2-3-ext") { config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.parserConfig()->setMinPhraseTerms(2); config_mgr.parserConfig()->setMaxPhraseTerms(3); } else if (test_case == "all-phrases-2-3-water") { config_mgr.filterConfig()->setWaterCounts(true); config_mgr.parserConfig()->setMinPhraseTerms(2); config_mgr.parserConfig()->setMaxPhraseTerms(3); } else if (test_case == "all-phrases-3-5") { config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.parserConfig()->setMinPhraseTerms(3); config_mgr.parserConfig()->setMaxPhraseTerms(5); } else if (test_case == "all-phrases-5") { config_mgr.filterConfig()->setTermsForScore(5); config_mgr.filterConfig()->setMaxWordRepeats(5); config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.parserConfig()->setMinPhraseTerms(5); config_mgr.parserConfig()->setMaxPhraseTerms(5); } else if (test_case == "old-graham") { config_mgr.parserConfig()->setMaxPhraseTerms(1); config_mgr.parserConfig()->setRemoveHTML(false); config_mgr.parserConfig()->setMinTermLength(1); config_mgr.parserConfig()->setMaxTermLength(90); config_mgr.filterConfig()->setTermsForScore(15); config_mgr.filterConfig()->setMaxWordRepeats(1); config_mgr.filterConfig()->setNewWordScore(0.2); config_mgr.filterConfig()->setExtendTopTerms(false); config_mgr.parserConfig()->headers()->setAllHeadersMode(); } else if (test_case == "nox") { config_mgr.parserConfig()->headers()->setNonXHeadersMode(); } else if (test_case == "all") { config_mgr.parserConfig()->headers()->setAllHeadersMode(); } else if (test_case == "wide-open") { config_mgr.parserConfig()->setRemoveHTML(false); config_mgr.parserConfig()->headers()->setAllHeadersMode(); } else if (test_case == "alt1") { config_mgr.filterConfig()->setScoreMode(FilterConfig::SCORE_ALT1); } else if (test_case == "low-score") { config_mgr.filterConfig()->setNewWordScore(0.2); config_mgr.filterConfig()->setMinWordCount(5); } else if (test_case == "high-score") { config_mgr.filterConfig()->setNewWordScore(0.88); config_mgr.filterConfig()->setMinWordCount(5); } else if (test_case == "nox-high-score") { config_mgr.filterConfig()->setNewWordScore(0.88); config_mgr.filterConfig()->setMinWordCount(5); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); } else if (test_case == "no-phrase") { config_mgr.parserConfig()->setMaxPhraseTerms(1); } else if (test_case == "normal-ext") { config_mgr.filterConfig()->setExtendTopTerms(true); } else if (test_case == "no-min") { config_mgr.filterConfig()->setMinWordCount(1); } else if (test_case == "1-days") { WordData::setTodayDate(1); } else if (test_case == "2-days") { WordData::setTodayDate(2); } else if (test_case == "3-days") { WordData::setTodayDate(3); } else if (test_case == "10-days") { WordData::setTodayDate(10); } else if (test_case == "normal-3") { config_mgr.parserConfig()->setMaxPhraseTerms(3); } else if (test_case == "normal-5") { config_mgr.parserConfig()->setMaxPhraseTerms(5); } else if (test_case == "phrases-2") { config_mgr.parserConfig()->setMaxPhraseTerms(2); config_mgr.parserConfig()->setMinPhraseTerms(2); } else if (test_case == "phrases-3") { config_mgr.parserConfig()->setMaxPhraseTerms(3); config_mgr.parserConfig()->setMinPhraseTerms(3); } else if (test_case == "phrases-4") { config_mgr.parserConfig()->setMaxPhraseTerms(4); config_mgr.parserConfig()->setMinPhraseTerms(4); } else if (test_case == "phrases-5") { config_mgr.parserConfig()->setMaxPhraseTerms(5); config_mgr.parserConfig()->setMinPhraseTerms(5); } else if (test_case == "no-prefixes") { config_mgr.parserConfig()->headers()->setBlankPrefixesMode(); } else if (test_case == "12-char-phrase") { config_mgr.parserConfig()->setMinPhraseChars(12); } else if (test_case == "20-char-phrase") { config_mgr.parserConfig()->setMaxPhraseTerms(20); config_mgr.parserConfig()->setMaxPhraseChars(20); } else if (test_case == "html") { config_mgr.parserConfig()->setRemoveHTML(false); } else if (test_case == "15/1") { config_mgr.filterConfig()->setTermsForScore(15); config_mgr.filterConfig()->setMaxWordRepeats(1); } else if (test_case == "15/1-no-phrase") { config_mgr.filterConfig()->setTermsForScore(15); config_mgr.filterConfig()->setMaxWordRepeats(1); config_mgr.parserConfig()->setMaxPhraseTerms(1); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); } else if (test_case == "suspicious") { config_mgr.parserConfig()->setKeepSuspiciousTags(true); } else if (test_case == "nox-suspicious") { config_mgr.parserConfig()->setKeepSuspiciousTags(true); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); } else if (test_case == "min-0.25") { config_mgr.filterConfig()->setMinDistanceForScore(0.25); config_mgr.filterConfig()->setMinArraySize(8); } else if (test_case == "min-0.33-10") { config_mgr.filterConfig()->setMinDistanceForScore(0.33); config_mgr.filterConfig()->setMinArraySize(10); } else if (test_case == "min-0.33-8") { config_mgr.filterConfig()->setMinDistanceForScore(0.33); config_mgr.filterConfig()->setMinArraySize(8); } else if (test_case == "min-0.40") { config_mgr.filterConfig()->setMinDistanceForScore(0.40); config_mgr.filterConfig()->setMinArraySize(8); } else if (test_case == "min-0.45") { config_mgr.filterConfig()->setMinDistanceForScore(0.45); config_mgr.filterConfig()->setMinArraySize(8); } else if (test_case == "min-0.49") { config_mgr.filterConfig()->setMinDistanceForScore(0.49); config_mgr.filterConfig()->setMinArraySize(8); } else if (test_case == "min-0.495") { config_mgr.filterConfig()->setMinDistanceForScore(0.495); config_mgr.filterConfig()->setMinArraySize(8); } else if (test_case == "trial") { config_mgr.filterConfig()->setMinDistanceForScore(0.40); config_mgr.filterConfig()->setMinArraySize(10); } else if (test_case == "trial-2") { config_mgr.filterConfig()->setMinDistanceForScore(0.25); config_mgr.filterConfig()->setMinArraySize(12); config_mgr.filterConfig()->setTermsForScore(30); config_mgr.filterConfig()->setMaxWordRepeats(2); config_mgr.filterConfig()->setWaterCounts(true); config_mgr.filterConfig()->setNewWordScore(0.5); config_mgr.filterConfig()->setExtendTopTerms(true); } else if (test_case == "trial-3") { config_mgr.filterConfig()->setExtendTopTerms(true); config_mgr.filterConfig()->setWaterCounts(true); } else if (test_case == "susp-high-score") { config_mgr.filterConfig()->setNewWordScore(0.88); config_mgr.parserConfig()->setKeepSuspiciousTags(true); } else if (test_case == "use-sa") { config_mgr.parserConfig()->headers()->addHeaderPrefix("x-spam-status", "sa", "sa"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("x-spam-status"); } else if (test_case == "water-counts") { config_mgr.filterConfig()->setWaterCounts(true); config_mgr.filterConfig()->setNewWordScore(0.4); } else if (test_case == "original") { config_mgr.filterConfig()->setScoreMode(FilterConfig::SCORE_ORIGINAL); } else if (test_case == "0.5") { config_mgr.filterConfig()->setDefaultThreshold(0.5); } else if (test_case == "0.6") { config_mgr.filterConfig()->setDefaultThreshold(0.6); } else if (test_case == "0.7") { config_mgr.filterConfig()->setDefaultThreshold(0.7); } else if (test_case == "0.8") { config_mgr.filterConfig()->setDefaultThreshold(0.8); } else if (test_case == "0.9") { config_mgr.filterConfig()->setDefaultThreshold(0.9); } else if (test_case == "min-10") { config_mgr.filterConfig()->setMinWordCount(10); } else if (test_case == "normal-headers-only") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->setIgnoreBody(true); config_mgr.parserConfig()->headers()->setDefaultHeadersMode(); } else if (test_case == "nox-headers-only") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->setIgnoreBody(true); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); } else if (test_case == "all-headers-only") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->setIgnoreBody(true); config_mgr.parserConfig()->headers()->setAllHeadersMode(); } else if (test_case == "headers-only") { config_mgr.parserConfig()->headers()->setNoHeadersMode(); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("from"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("to"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("cc"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("bcc"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("subject"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("reply-to"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("received"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("sender"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("x-mailer"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("errors-to"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("x-beenthere"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("list-id"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("user-agent"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("references"); config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix("message-id"); config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->setIgnoreBody(true); } else if (test_case == "multi") { config_mgr.filterConfig()->clearTokenSelectors(); config_mgr.filterConfig()->addTokenSelector(new SimpleTokenSelector(Token::FLAG_ANY, "H")); config_mgr.filterConfig()->addTokenSelector(new SimpleTokenSelector(Token::FLAG_ANY - Token::FLAG_PHRASE, "")); config_mgr.filterConfig()->addTokenSelector(new SimpleTokenSelector(Token::FLAG_ANY - Token::FLAG_DERIVED, "")); config_mgr.filterConfig()->addTokenSelector(new TokenSelector()); } else if (test_case == "max-250-terms") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); config_mgr.parserConfig()->setMaxTermsPerMessage(250); } else if (test_case == "max-350-terms") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); config_mgr.parserConfig()->setMaxTermsPerMessage(350); } else if (test_case == "max-500-terms") { config_mgr.filterConfig()->setMinDistanceForScore(0.30); config_mgr.filterConfig()->setMinArraySize(10); config_mgr.parserConfig()->headers()->setNonXHeadersMode(); config_mgr.parserConfig()->setMaxTermsPerMessage(500); } else if (test_case != "normal") { cerr << "error: unknown test case: " << test_case << endl; failed = true; } } } return failed; } static bool parse_int_arg(const char *arg, const char *option, int &value, int min_val, int max_val) { value = atoi(arg); if (value >= min_val && value <= max_val) { return true; } cerr << "error: -" << option << " requires integer argument between " << min_val << " and " << max_val << endl; return false; } static bool parse_double_arg(const char *arg, const char *option, double &value, double min_val, double max_val) { value = atof(arg); if (value >= min_val && value <= max_val) { return true; } cerr << "error: -" << option << " requires number argument between " << min_val << " and " << max_val << endl; return false; } static bool set_headers(ConfigManager &config_mgr, const char *optarg) { bool successful = true; if (strcmp(optarg, "all") == 0) { config_mgr.parserConfig()->headers()->setAllHeadersMode(); } else if (strcmp(optarg, "nox") == 0) { config_mgr.parserConfig()->headers()->setNonXHeadersMode(); } else if (strcmp(optarg, "normal") == 0) { config_mgr.parserConfig()->headers()->setDefaultHeadersMode(); } else if (strcmp(optarg, "none") == 0) { config_mgr.parserConfig()->headers()->setNoHeadersMode(); } else if (optarg[0] == '+') { config_mgr.parserConfig()->headers()->addSimpleHeaderPrefix(optarg + 1); } else if (optarg[0] == '-') { config_mgr.parserConfig()->headers()->removeHeaderPrefix(optarg + 1); } else { cerr << "error: -H option requires all, nox, none, normal, +header, or -header" << endl; successful = false; } return successful; } static void print_version() { cout << "SpamProbe v" << VERSION; if (s_filter.get()) { try { s_filter->open(true); } catch (...) { } if (s_filter->getDB()) { cout << " using " << s_filter->getDB()->getDatabaseType(); } } cout << " database." << endl << endl << "Copyright 2002-2006 Burton Computer Corporation" << endl << "This program is distributed in the hope that it will be useful," << endl << "but WITHOUT ANY WARRANTY; without even the implied warranty of" << endl << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << endl << "Q Public License for more details." << endl; } static void print_usage() { cerr << "usage: spamprobe [options] command [args]\n" << " Try \"spamprobe help\" to list all commands and options.\n" << " or \"spamprobe help command\" for detailed help on a single command.\n" << endl; } // // Cleanup function for use by signal handlers. // void quick_close(int signum) { signal(signum, SIG_DFL); try { cerr << "caught signal " << signum << ": quitting" << endl; } catch (...) { // not allowed to throw any exceptions in signal handlers } } // // For user interrupts give the any outstanding database operation time // to complete before exiting. // bool interrupt_or_exit(int signum) { if (s_filter.get() && s_filter->getDB()) { return s_filter->getDB()->requestInterrupt(); } else { return true; } } // // Signal handler to close the database on receipt of a signal // to ensure that any locks it might hold are cleared. // void close_and_exit(int signum) { if (interrupt_or_exit(signum)) { quick_close(signum); exit(127); } } // // Cleanup function to close the database on receipt of a signal // to ensure that any locks it might hold are cleared. After closing // calls abort to dump core. // void close_and_abort(int signum) { quick_close(signum); signal(SIGABRT, SIG_DFL); abort(); } // // Register signal handler to cleanup on abnormal exit from program (i.e. // ^C or a crash. // void install_signal_handler() { // clean shutdown signal(SIGINT, close_and_exit); signal(SIGTERM, close_and_exit); signal(SIGPIPE, close_and_exit); // close and abort signal(SIGQUIT, close_and_abort); signal(SIGSEGV, close_and_abort); signal(SIGBUS, close_and_abort); signal(SIGABRT, close_and_abort); } static void load_config_file(const File &basedir, const string &filename, ConfigManager &config_mgr) { File config_file(basedir, filename); if (config_file.isFile()) { config_mgr.loadFromFile(config_file); } } static void define_commands(CommandConfig *command_config) { command_config->addCommand(Command_auto_train::createAutoLearnCommand()); command_config->addCommand(Command_auto_train::createAutoTrainCommand()); command_config->addCommand(Ref(new Command_cleanup)); command_config->addCommand(Ref(new Command_counts)); command_config->addCommand(Ref(new Command_create_config)); command_config->addCommand(Ref(new Command_create_db)); command_config->addCommand(Ref(new Command_dump)); command_config->addCommand(Ref(new Command_edit_term)); command_config->addCommand(Ref(new Command_exec(false))); command_config->addCommand(Ref(new Command_exec(true))); command_config->addCommand(Ref(new Command_export)); command_config->addCommand(Command_summarize::createFindGoodCommand()); command_config->addCommand(Command_summarize::createFindSpamCommand()); command_config->addCommand(Command_spam::createGoodCommand()); command_config->addCommand(Ref(new Command_help)); command_config->addCommand(Ref(new Command_import)); command_config->addCommand(Command_train_test::createLearnTestCommand()); command_config->addCommand(Ref(new Command_print)); command_config->addCommand(Ref(new Command_purge)); command_config->addCommand(Ref(new Command_purge_terms)); command_config->addCommand(Command_receive::createReceiveCommand()); command_config->addCommand(Ref(new Command_remove)); command_config->addCommand(Command_receive::createScoreCommand()); command_config->addCommand(Command_spam::createSpamCommand()); command_config->addCommand(Command_summarize::createSummarizeCommand()); command_config->addCommand(Command_receive::createTrainCommand()); command_config->addCommand(Command_spam::createTrainGoodCommand()); command_config->addCommand(Command_spam::createTrainSpamCommand()); command_config->addCommand(Ref(new Command_tokenize)); command_config->addCommand(Command_train_test::createTrainTestCommand()); } int main(int argc, char **argv) { try { bool usage_error = false; bool force_mbox = false; bool single_message_file = false; bool wants_version = false; bool return_spam_status = false; File shared_db_dir; File basedir(File::getHomeDir(), ".spamprobe"); string config_filename("spamprobe.hdl"); vector test_cases; vector extended_options; ConfigManager config_mgr; define_commands(config_mgr.commandConfig()); load_config_file(basedir, config_filename, config_mgr); CommandConfig *command_config = config_mgr.commandConfig(); DatabaseConfig *database_config = config_mgr.databaseConfig(); ParserConfig *parser_config = config_mgr.parserConfig(); FilterConfig *filter_config = config_mgr.filterConfig(); optind = 1; int opt, opt_value; double opt_double_value; while ((opt = getopt(argc, argv, "a:cC:d:D:f:hH:g:l:mMo:p:P:r:Rs:t:TvVw:xXY78")) != EOF) { switch (opt) { case 'a': if (strlen(optarg) != 1) { cerr << "error: -a option requires a one character argument" << endl; usage_error = true; } else { parser_config->setReplaceNonAsciiChars(optarg[0]); } break; case 'c': command_config->setShouldCreateDbDir(true); break; case 'C': if (parse_int_arg(optarg, "C", opt_value, 0, 10000)) { filter_config->setMinWordCount(opt_value); } else { usage_error = true; } break; case 'd': { string path(optarg); string db_type; int target_size; database_config->parseCommandLineArg(path, db_type, target_size); database_config->setDatabaseType(db_type); database_config->setTargetSizeMB(target_size); basedir.setPath(path); load_config_file(basedir, config_filename, config_mgr); File private_db_file(basedir, DB_FILENAME); database_config->setPrivateFilename(private_db_file.getPath()); } break; case 'D': { string path(optarg); string db_type; int target_size; database_config->parseCommandLineArg(path, db_type, target_size); shared_db_dir.setPath(path); File shared_db_file(shared_db_dir, DB_FILENAME); database_config->setSharedFilename(shared_db_file.getPath()); } break; case 'f': { File config_file(optarg); if (!config_file.isFile()) { cerr << optarg << ": no such file" << endl; usage_error = true; } else { basedir.setPath(config_file.parent().getPath()); config_filename = config_file.getName(); load_config_file(basedir, config_filename, config_mgr); } } break; case 'g': parser_config->setSpamProbeFieldName(to_lower(optarg)); break; case 'h': parser_config->setRemoveHTML(false); break; case 'H': if (!set_headers(config_mgr, optarg)) { usage_error = true; } break; case 'l': if (parse_double_arg(optarg, "l", opt_double_value, 0.0, 1.0)) { filter_config->setDefaultThreshold(opt_double_value); } else { usage_error = true; } break; case 'm': force_mbox = true; break; case 'M': single_message_file = true; break; case 'o': extended_options.push_back(optarg); break; case 'p': if (parse_int_arg(optarg, "p", opt_value, 1, 10)) { parser_config->setMaxPhraseTerms(opt_value); } else { usage_error = true; } break; case 'P': if (parse_int_arg(optarg, "P", opt_value, 1, MAX_MESSAGES_PER_PURGE)) { command_config->setMessagesPerPurge(opt_value); } else { usage_error = true; } break; case 'r': if (parse_int_arg(optarg, "r", opt_value, 1, 10)) { filter_config->setMaxWordRepeats(opt_value); } else { usage_error = true; } break; case 'R': single_message_file = true; return_spam_status = true; break; case 's': if (parse_int_arg(optarg, "s", opt_value, 0, MAX_MAX_CACHE_TERMS)) { if (opt_value == 0) { opt_value = MAX_MAX_CACHE_TERMS; } database_config->setMaxCacheTerms(opt_value); } else { usage_error = true; } break; case 't': test_cases.push_back(optarg); break; case 'T': command_config->setShouldShowTerms(true); break; case 'v': if (is_verbose) { is_debug = true; } else { is_verbose = true; } break; case 'V': wants_version = true; break; case 'w': if (parse_int_arg(optarg, "w", opt_value, 5, 500)) { filter_config->setTermsForScore(opt_value); } else { usage_error = true; } break; case 'x': filter_config->setExtendTopTerms(true); break; case 'X': filter_config->setTermsForScore(5); filter_config->setMaxWordRepeats(5); filter_config->setExtendTopTerms(true); break; case 'Y': command_config->setIgnoreContentLength(true); break; case '7': parser_config->setReplaceNonAsciiChars(' '); break; case '8': parser_config->setReplaceNonAsciiChars(-1); break; default: usage_error = true; break; } } // import locales so that tolower() will work properly setlocale(LC_ALL, ""); if ((argc - optind) < 1) { usage_error = true; } string command; Ref cmd; if (!usage_error) { command = argv[optind++]; cmd = command_config->findCommand(command); if (cmd.isNull()) { cerr << "error: invalid command name: " << command << endl; usage_error = true; } else if (cmd->isReadOnly() && command_config->messagesPerPurge() > 0) { command_config->setMessagesPerPurge(0); } } if (cmd.isNotNull()) { command_config->addArgs(argv + optind); usage_error |= !cmd->argsOK(config_mgr); } install_signal_handler(); s_filter.set(new SpamFilter(&config_mgr)); if (usage_error || wants_version) { if (!wants_version) { print_usage(); } print_version(); return wants_version ? 0 : 1; } assert(cmd.isNotNull()); if (single_message_file || (cmd->isSingleMessageCommand() && !force_mbox)) { command_config->setIgnoreFrom(true); command_config->setIgnoreContentLength(true); } if (process_test_cases(test_cases, config_mgr)) { print_usage(); return 1; } if (process_extended_options(extended_options, config_mgr)) { print_usage(); return 1; } cmd->execute(config_mgr, *s_filter); s_filter->close(); s_filter.clear(); if (return_spam_status) { return cmd->isMessageSpam() ? 0 : 1; } } catch (InterruptedException &ex) { cerr << "interrupted by signal" << endl; } catch (runtime_error &ex) { cerr << "caught runtime exception: " << ex.what() << endl; return 1; } catch (logic_error &ex) { cerr << "caught logic exception: " << ex.what() << endl; return 1; } catch (...) { cerr << "caught unknown exception" << endl; return 1; } return 0; } spamprobe-1.4d/src/spamprobe/ConfigManager.cc0000664000076400007640000004145710527261701016247 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: ConfigManager.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "File.h" #include "CommandConfig.h" #include "DatabaseConfig.h" #include "FilterConfig.h" #include "ParserConfig.h" #include "HeaderPrefixList.h" #include "HdlToken.h" #include "HdlParser.h" #include "HdlPrinter.h" #include "HdlStatement.h" #include "HdlToken.h" #include "HdlSyntaxChecker.h" #include "ConfigManager.h" static const char *syntax_src = "begin language spamprobe;" " begin block parser;" " args 0 0;" " begin statement replace_non_ascii;" " args 1 1 table;" " table id true id false;" " end;" " begin statement non_ascii_replacement;" " args 1 1 string;" " end;" " begin statement min_term_length;" " args 1 1 int;" " end;" " begin statement max_term_length;" " args 1 1 int;" " end;" " begin statement remove_html;" " args 1 1 table;" " table id true id false;" " end;" " begin statement min_phrase_terms;" " args 1 1 int;" " end;" " begin statement max_phrase_terms;" " args 1 1 int;" " end;" " begin statement min_phrase_chars;" " args 1 1 int;" " end;" " begin statement max_phrase_chars;" " args 1 1 int;" " end;" " begin statement max_message_terms;" " args 1 1 int;" " end;" " begin statement spamprobe_field_name;" " args 1 1 string;" " end;" " begin statement keep_suspicious_tags;" " args 1 1 table;" " table id true id false;" " end;" " begin statement ignore_body;" " args 1 1 table;" " table id true id false;" " end;" " begin block header;" " args 0 0;" " begin statement simple_prefix;" " args 1 1 string;" " end;" " begin statement full_prefix;" " args 3 3 string string string;" " end;" " begin statement blank_prefixes_mode;" " args 1 1 table;" " table id true id false;" " end;" " begin statement ignore_x_headers_mode;" " args 1 1 table;" " table id true id false;" " end;" " begin statement all_headers_mode;" " args 1 1 table;" " table id true id false;" " end;" " begin statement no_headers_mode;" " args 1 1 table;" " table id true id false;" " end;" " end;" " end;" " begin block filter;" " args 0 0;" " begin statement score_mode;" " args 1 1 table;" " table id original id alt1 id normal;" " end;" " begin statement good_bias;" " args 1 1 int;" " end;" " begin statement terms_for_score;" " args 1 1 int;" " end;" " begin statement max_word_repeats;" " args 1 1 int;" " end;" " begin statement min_word_count;" " args 1 1 int;" " end;" " begin statement extend_top_terms;" " args 1 1 table;" " table id true id false;" " end;" " begin statement min_array_size;" " args 1 1 int;" " end;" " begin statement water_counts;" " args 1 1 table;" " table id true id false;" " end;" " begin statement new_word_score;" " args 1 1 double;" " end;" " begin statement spam_threshold;" " args 1 1 double;" " end;" " begin statement min_distance_for_score;" " args 1 1 double;" " end;" " end;" " begin block database;" " args 0 0;" " begin statement type;" " args 1 1 table;" " table id default id bdb id pbl id hash id split;" " end;" " begin statement private_filename;" " args 1 1 string;" " end;" " begin statement shared_filename;" " args 1 1 string;" " end;" " begin statement target_size_mb;" " args 1 1 int;" " end;" " begin statement max_cache_terms;" " args 1 1 int;" " end;" " end;" "end;" ; static const char *mode_to_string(FilterConfig::ScoreMode mode) { switch (mode) { case FilterConfig::SCORE_ORIGINAL: return "original"; case FilterConfig::SCORE_ALT1: return "alt1"; default: return "normal"; } } static FilterConfig::ScoreMode string_to_mode(const string &str) { if (str == "alt1") { return FilterConfig::SCORE_ALT1; } if (str == "original") { return FilterConfig::SCORE_ORIGINAL; } return FilterConfig::SCORE_NORMAL; } ConfigManager::ConfigManager() : m_commandConfig(new CommandConfig), m_databaseConfig(new DatabaseConfig), m_filterConfig(new FilterConfig), m_parserConfig(new ParserConfig) { File basedir(File::getHomeDir(), ".spamprobe"); m_configFile.set(new File(basedir, "spamprobe.hdl")); } ConfigManager::~ConfigManager() { } void ConfigManager::loadFromFile(const File &config_file) { HdlParser parser; Ref config_hdl(parser.parseFile(config_file)); Ref config_syntax(parser.parseString(syntax_src)); HdlSyntaxChecker checker(config_syntax); checker.checkSyntax(config_hdl); for (int i = 0; i < config_hdl->numChildren(); ++i) { const CRef &child = config_hdl->child(i); string name(child->name()->strValue()); if (name == "parser") { loadParserConfig(child); } else if (name == "filter") { loadFilterConfig(child); } else if (name == "database") { loadDatabaseConfig(child); } } *m_configFile = config_file; } void ConfigManager::loadParserConfig(const CRef &config_hdl) { const CRef noarg; for (int i = 0; i < config_hdl->numChildren(); ++i) { const CRef &child = config_hdl->child(i); string name(child->name()->strValue()); const CRef &arg = (child->numArguments() > 0) ? child->argument(0) : noarg; if (name == "replace_non_ascii") { m_parserConfig->setReplaceNonAsciiChars(arg->isTrueValue() ? 'z' : 0); } else if (name == "non_ascii_replacement") { if (arg->strValue().length() > 0) { m_parserConfig->setReplaceNonAsciiChars(arg->strValue()[0]); } } else if (name == "min_term_length") { m_parserConfig->setMinTermLength(arg->intValue()); } else if (name == "max_term_length") { m_parserConfig->setMaxTermLength(arg->intValue()); } else if (name == "remove_html") { m_parserConfig->setRemoveHTML(arg->isTrueValue()); } else if (name == "min_phrase_terms") { m_parserConfig->setMinPhraseTerms(arg->intValue()); } else if (name == "max_phrase_terms") { m_parserConfig->setMaxPhraseTerms(arg->intValue()); } else if (name == "min_phrase_chars") { m_parserConfig->setMinPhraseChars(arg->intValue()); } else if (name == "max_phrase_chars") { m_parserConfig->setMaxPhraseChars(arg->intValue()); } else if (name == "max_message_terms") { m_parserConfig->setMaxTermsPerMessage(arg->intValue()); } else if (name == "spamprobe_field_name") { m_parserConfig->setSpamProbeFieldName(arg->strValue()); } else if (name == "keep_suspicious_tags") { m_parserConfig->setKeepSuspiciousTags(arg->isTrueValue()); } else if (name == "ignore_body") { m_parserConfig->setIgnoreBody(arg->isTrueValue()); } else if (name == "header") { loadHeaderConfig(child); } } } void ConfigManager::loadHeaderConfig(const CRef &config_hdl) { HeaderPrefixList *headers = m_parserConfig->headers(); headers->setDefaultHeadersMode(); bool headers_reset = false; const CRef noarg; for (int i = 0; i < config_hdl->numChildren(); ++i) { const CRef &child = config_hdl->child(i); string name(child->name()->strValue()); const CRef &arg = (child->numArguments() > 0) ? child->argument(0) : noarg; if (name == "simple_prefix") { if (!headers_reset) { headers->setNoHeadersMode(); headers_reset = true; } headers->addSimpleHeaderPrefix(arg->strValue()); } else if (name == "full_prefix") { if (!headers_reset) { headers->setNoHeadersMode(); headers_reset = true; } string first_prefix = child->argument(1)->strValue(); string other_prefix = child->argument(2)->strValue(); headers->addHeaderPrefix(arg->strValue(), first_prefix, other_prefix); } else if (name == "blank_prefixes_mode") { if (arg->isTrueValue()) { headers->setBlankPrefixesMode(); } } else if (name == "ignore_x_headers_mode") { if (arg->isTrueValue()) { headers->setNonXHeadersMode(); headers_reset = true; } } else if (name == "all_headers_mode") { if (arg->isTrueValue()) { headers->setAllHeadersMode(); headers_reset = true; } } else if (name == "no_headers_mode") { if (arg->isTrueValue()) { headers->setNoHeadersMode(); headers_reset = true; } } } } void ConfigManager::loadFilterConfig(const CRef &config_hdl) { const CRef noarg; for (int i = 0, limit = config_hdl->numChildren(); i < limit; ++i) { const CRef &child = config_hdl->child(i); string name(child->name()->strValue()); const CRef &arg = (child->numArguments() > 0) ? child->argument(0) : noarg; if (name == "score_mode") { m_filterConfig->setScoreMode(string_to_mode(arg->strValue())); } else if (name == "good_bias") { m_filterConfig->setGoodBias(arg->intValue()); } else if (name == "terms_for_score") { m_filterConfig->setTermsForScore(arg->intValue()); } else if (name == "max_word_repeats") { m_filterConfig->setMaxWordRepeats(arg->intValue()); } else if (name == "min_word_count") { m_filterConfig->setMinWordCount(arg->intValue()); } else if (name == "extend_top_terms") { m_filterConfig->setExtendTopTerms(arg->isTrueValue()); } else if (name == "min_array_size") { m_filterConfig->setMinArraySize(arg->intValue()); } else if (name == "water_counts") { m_filterConfig->setWaterCounts(arg->isTrueValue()); } else if (name == "new_word_score") { m_filterConfig->setNewWordScore(arg->doubleValue()); } else if (name == "spam_threshold") { m_filterConfig->setSpamThreshold(arg->doubleValue()); } else if (name == "min_distance_for_score") { m_filterConfig->setMinDistanceForScore(arg->doubleValue()); } } } void ConfigManager::writeToFile(const File &config_file) const { ofstream out(config_file.getPath().c_str()); HdlPrinter printer; writeConfig(printer, out); } void ConfigManager::writeConfig(HdlPrinter &printer, ostream &out) const { printer.beginBlock(out); printer.beginStatement(out, "spamprobe"); printer.endStatement(out); writeParserConfig(printer, out); writeFilterConfig(printer, out); writeDatabaseConfig(printer, out); printer.endBlock(out); } void ConfigManager::writeParserConfig(HdlPrinter &printer, ostream &out) const { printer.beginBlock(out); printer.beginStatement(out, "parser"); printer.endStatement(out); printer.printBoolStatement(out, "replace_non_ascii", m_parserConfig->getReplaceNonAsciiChars()); if (m_parserConfig->getReplaceNonAsciiChars()) { printer.printStringStatement(out, "non_ascii_replacement", m_parserConfig->getNonAsciiCharReplacement()); } printer.printIntStatement(out, "min_term_length", m_parserConfig->getMinTermLength()); printer.printIntStatement(out, "max_term_length", m_parserConfig->getMaxTermLength()); printer.printBoolStatement(out, "remove_html", m_parserConfig->getRemoveHTML()); printer.printIntStatement(out, "min_phrase_terms", m_parserConfig->getMinPhraseTerms()); printer.printIntStatement(out, "max_phrase_terms", m_parserConfig->getMaxPhraseTerms()); printer.printIntStatement(out, "max_phrase_chars", m_parserConfig->getMaxPhraseChars()); printer.printIntStatement(out, "min_phrase_chars", m_parserConfig->getMinPhraseChars()); printer.printIntStatement(out, "max_message_terms", m_parserConfig->getMaxTermsPerMessage()); printer.printStringStatement(out, "spamprobe_field_name", m_parserConfig->spamprobeFieldName()); printer.printBoolStatement(out, "keep_suspicious_tags", m_parserConfig->getKeepSuspiciousTags()); printer.printBoolStatement(out, "ignore_body", m_parserConfig->getIgnoreBody()); printer.beginBlock(out); printer.beginStatement(out, "header"); printer.endStatement(out); HeaderPrefixList *headers = m_parserConfig->headers(); printer.printBoolStatement(out, "blank_prefixes_mode", headers->getBlankPrefixesMode()); printer.printBoolStatement(out, "ignore_x_headers_mode", headers->getNonXHeadersMode()); printer.printBoolStatement(out, "all_headers_mode", headers->getAllHeadersMode()); printer.printBoolStatement(out, "no_headers_mode", headers->getNoHeadersMode()); if (!headers->getAllHeadersMode()) { for (HeaderPrefixList::const_iterator i = headers->begin(); i != headers->end(); ++i) { printer.beginStatement(out, "full_prefix"); printer.addString(out, i.name()); printer.addString(out, i.firstPrefix()); printer.addString(out, i.otherPrefix()); printer.endStatement(out); } } printer.endBlock(out); // header printer.endBlock(out); // parser } void ConfigManager::writeFilterConfig(HdlPrinter &printer, ostream &out) const { const FilterConfig *config = filterConfig(); printer.beginBlock(out); printer.beginStatement(out, "filter"); printer.endStatement(out); printer.printIDStatement(out, "score_mode", mode_to_string(config->getScoreMode())); printer.printIntStatement(out, "good_bias", config->getGoodBias()); printer.printIntStatement(out, "terms_for_score", config->getTermsForScore()); printer.printIntStatement(out, "max_word_repeats", config->getMaxWordRepeats()); printer.printIntStatement(out, "min_word_count", config->getMinWordCount()); printer.printBoolStatement(out, "extend_top_terms", config->getExtendTopTerms()); printer.printIntStatement(out, "min_array_size", config->getMinArraySize()); printer.printBoolStatement(out, "water_counts", config->getWaterCounts()); printer.printDoubleStatement(out, "new_word_score", config->getNewWordScore()); printer.printDoubleStatement(out, "spam_threshold", config->getSpamThreshold()); printer.printDoubleStatement(out, "min_distance_for_score", config->getMinDistanceForScore()); printer.endBlock(out); // filter } void ConfigManager::loadDatabaseConfig(const CRef &config_hdl) { const CRef noarg; for (int i = 0, limit = config_hdl->numChildren(); i < limit; ++i) { const CRef &child = config_hdl->child(i); string name(child->name()->strValue()); const CRef &arg = (child->numArguments() > 0) ? child->argument(0) : noarg; if (name == "type") { string type_name(arg->strValue()); if (type_name == "default") { type_name = ""; } m_databaseConfig->setDatabaseType(type_name); } else if (name == "private_filename") { m_databaseConfig->setPrivateFilename(arg->strValue()); } else if (name == "shared_filename") { m_databaseConfig->setSharedFilename(arg->strValue()); } else if (name == "target_size_mb") { m_databaseConfig->setTargetSizeMB(arg->intValue()); } else if (name == "max_cache_terms") { m_databaseConfig->setMaxCacheTerms(arg->intValue()); } } } void ConfigManager::writeDatabaseConfig(HdlPrinter &printer, ostream &out) const { const DatabaseConfig *config = databaseConfig(); printer.beginBlock(out); printer.beginStatement(out, "database"); printer.endStatement(out); printer.printIDStatement(out, "type", config->databaseType().length() == 0 ? "default" : config->databaseType()); printer.printStringStatement(out, "private_filename", config->privateFilename()); printer.printStringStatement(out, "shared_filename", config->sharedFilename()); printer.printIntStatement(out, "target_size_mb", config->targetSizeMB()); printer.printIntStatement(out, "max_cache_terms", config->maxCacheTerms()); printer.endBlock(out); // database } spamprobe-1.4d/src/spamprobe/Command_print.cc0000664000076400007640000000574410527260233016337 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_print.h" Command_print::Command_print() : AbstractCommand("print", "print Prints counts for specified terms in database.", "print term...\n" " Prints the values of the specified terms in the word counts database\n" " one term per line in human readable format with spam probability, \n" " good count, spam count, flags, and word in columns separated by whitespace.\n", true) { } void Command_print::dumpWords(SpamFilter &filter, const CommandConfig *command_config) { int good_message_count, spam_message_count; filter.getDB()->getMessageCounts(good_message_count, spam_message_count); string word; WordData counts; for (int i = 0, limit = command_config->numArgs(); i < limit; ++i) { word = command_config->arg(i); if (filter.getDB()->readWord(word, counts)) { double score = filter.scoreTerm(counts.goodCount(), counts.spamCount(), good_message_count, spam_message_count); cout << scoreToString(score) << dec << setw(8) << counts.goodCount() << setw(8) << counts.spamCount() << " 0x" << setfill('0') << setw(8) << hex << counts.flags() << setfill(' ') << " " << word << "\n"; } } } bool Command_print::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args > 0; } int Command_print::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); dumpWords(filter, config.commandConfig()); return 0; } spamprobe-1.4d/src/spamprobe/AbstractCommand.cc0000664000076400007640000001017610527261701016603 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractCommand.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "ConfigManager.h" #include "CommandConfig.h" #include "DatabaseConfig.h" #include "File.h" #include "Message.h" #include "SpamFilter.h" #include "AbstractCommand.h" const char *AbstractCommand::scoreToString(double score) { static char buffer[32]; sprintf(buffer, "%9.7f", score); return buffer; } bool AbstractCommand::argsOK(const ConfigManager &config) { return true; } void AbstractCommand::openDatabase(const ConfigManager &config, SpamFilter &filter) { if (config.commandConfig()->shouldCreateDbDir() && !isReadOnly()) { createDbDir(config); } filter.open(isReadOnly()); } void AbstractCommand::printTerms(FrequencyDB *db, ostream &out, Message &msg, const string &indent) { int good_count, spam_count; out << indent << "Spam Prob Count Good Spam Word\n"; for (int i = 0; i < msg.getTopTokenCount(); ++i) { Token *tok = msg.getTopToken(i); db->getWordCounts(tok->getWord(), good_count, spam_count); out << indent << scoreToString(tok->getScore()) << setw(8) << tok->getCount() << setw(8) << good_count << setw(8) << spam_count << " " << tok->getWord() << "\n"; } } void AbstractCommand::printMessageScore(const ConfigManager &config, SpamFilter &filter, bool is_spam, double score, Message &msg, const File *source) { if (source) { cout << source->getPath() << ' '; } cout << (is_spam ? "SPAM " : "GOOD ") << scoreToString(score) << ' ' << msg.getDigest(); cout << endl; if (config.commandConfig()->shouldShowTerms() && msg.getTopTokenCount() > 0) { printTerms(filter.getDB(), cout, msg, " "); } } bool AbstractCommand::isMessageSpam() const { return false; } void AbstractCommand::createDbDir(const ConfigManager &config) { File db_file(config.databaseConfig()->privateFilename()); File db_dir = db_file.parent(); if (!db_dir.exists()) { db_dir.makeDirectory(0700); } } void AbstractCommand::logMessageProcessing(bool processed, Message &message, const File *stream_file) { if (!is_verbose) { return; } string subject; const string::size_type MAX_SUBJECT_LENGTH = 20; message.getHeader("subject", subject); if (subject.length() > MAX_SUBJECT_LENGTH) { subject.erase(MAX_SUBJECT_LENGTH, string::npos); subject += "..."; } cerr << "COMMAND " << name(); if (stream_file) { cerr << " FILE " << stream_file->getPath(); } cerr << " DIGEST " << message.getDigest() << " SUBJECT " << subject; if (processed) { cerr << " PROCESSED"; } else { cerr << " IGNORED"; } cerr << endl; } spamprobe-1.4d/src/spamprobe/Command_export.cc0000664000076400007640000000507710527261701016524 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_export.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_export.h" Command_export::Command_export() : AbstractCommand("export", "export Exports all terms from database.", "export\n" " Similar to the dump command but prints the counts and words in a\n" " comma separated format with the words surrounded by double quotes.\n" " This can be more useful for importing into some databases.\n", true) { } void Command_export::exportWords(SpamFilter &filter) { string word; WordData counts; bool again = filter.getDB()->firstWord(word, counts); while (again) { string encoded; encode_string(word, encoded); cout << dec << counts.goodCount() << ',' << counts.spamCount() << ',' << counts.flags() << ",\"" << encoded << "\"\n"; again = filter.getDB()->nextWord(word, counts); } } bool Command_export::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0; } int Command_export::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); exportWords(filter); return 0; } spamprobe-1.4d/src/spamprobe/Command_auto_train.cc0000664000076400007640000002257210527261701017347 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_auto_train.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "AutoTrainMailMessageReader.h" #include "AutoPurger.h" #include "ParserConfig.h" #include "IstreamCharReader.h" #include "TraditionalMailMessageParser.h" #include "LineReader.h" #include "MD5Digester.h" #include "MailMessageDigester.h" #include "Command_spam.h" #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "MailMessageReaderFactory.h" #include "Command_auto_train.h" const Ref Command_auto_train::createAutoTrainCommand() { return Ref(new Command_auto_train("auto-train", "auto-train Builds database using train mode.", "auto-train GOOD filename... SPAM filename...\n" " Attempts to efficiently build a database from all of the named\n" " files. You may specify one or more file of each type. Prior to\n" " each set of file names you must include the word SPAM or GOOD to\n" " indicate what type of mail is contained in the files which follow\n" " on the command line.\n" "\n" " The case of the SPAM and GOOD keywords is important. Any number of\n" " file names can be specified between the keywords. The command line\n" " format is very flexible. You can even use a find command in\n" " backticks to process whole directory trees of files. For example:\n" "\n" " spamprobe auto-train SPAM spams/* GOOD `find hams -type f`\n" "\n" " SpamProbe pre-scans the files to determine how many emails of each\n" " type exist and then trains on hams and spams in a random sequence\n" " that balances the inflow of each type so that the train command can\n" " work most effectively. For example if you had 400 hams and 400\n" " spams, auto-train will generally process one spam, then one ham,\n" " etc. If you had 4000 spams and 400 hams then auto-train will\n" " generally process 10 spams, then one ham, etc.\n" "\n" " Since this command will likely take a long time to run it is often\n" " desireable to use it with the -v option to see progress information\n" " as the messages are processed.\n" "\n" " spamprobe -v auto-train SPAM spams/* GOOD hams/* \n", false)); } const Ref Command_auto_train::createAutoLearnCommand() { return Ref(new Command_auto_train("auto-learn", "auto-learn Builds database using learn mode.", "auto-learn GOOD filename... SPAM filename...\n" " Similar to auto-train but adds all messages in all specified files to\n" " the database, even if they are easily determined to be good or spam.\n" " Generally speaking auto-train should be used instead of auto-learn.\n", true)); } void Command_auto_train::logMessage(const ConfigManager &config, SpamFilter &filter, const string &type, bool correct, Message &message) { string subject; const string::size_type MAX_SUBJECT_LENGTH = 20; message.getHeader("subject", subject); if (subject.length() > MAX_SUBJECT_LENGTH) { subject.erase(MAX_SUBJECT_LENGTH, string::npos); subject += "..."; } cout << type; if (correct) { cout << " PASS"; } else { cout << " FAIL"; } cout << " DIGEST " << message.getDigest() << " SUBJECT " << subject; cout << endl; if (config.commandConfig()->shouldShowTerms() && message.getTopTokenCount() > 0) { printTerms(filter.getDB(), cout, message, " "); } } bool Command_auto_train::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); bool answer = true; for (int i = 0; i < num_args; ++i) { string arg(config.commandConfig()->arg(i)); if (arg != "LOG" && arg != "SPAM" && arg != "GOOD" && !MailMessageReaderFactory::isAcceptableFile(File(arg))) { cerr << "error: " << arg << " is not a file" << endl; answer = false; } } return answer; } int Command_auto_train::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); Ptr mail_reader(new AutoTrainMailMessageReader()); bool is_spam_file = false; bool should_log = false; for (int i = 0, limit = config.commandConfig()->numArgs(); i < limit; ++i) { string arg(config.commandConfig()->arg(i)); if (arg == "LOG") { should_log = true; } else if (arg == "SPAM") { is_spam_file = true; } else if (arg == "GOOD") { is_spam_file = false; } else { File file(arg); if (!MailMessageReaderFactory::isAcceptableFile(file)) { throw runtime_error(string("file does not exist: ") + arg); } mail_reader->addMailboxFile(is_spam_file, arg); } } Ref good_command; Ref spam_command; if (m_isLearn) { good_command = Command_spam::createGoodCommand(); spam_command = Command_spam::createSpamCommand(); } else { good_command = Command_spam::createTrainGoodCommand(); spam_command = Command_spam::createTrainSpamCommand(); } bool is_message_spam = false; int message_num = 0; ParserConfig *parser_config = config.parserConfig(); TraditionalMailMessageParser parser(parser_config); MailMessageDigester digester; AutoPurger purger(config, filter); int cumulative_message_count = 0; Ptr mail_message; mail_message.set(mail_reader->readMessage()); while (mail_message.isNotNull()) { Ptr msg(parser.parseMailMessage(mail_message.get())); msg->setSource(mail_message.release()); digester.assignDigestToMessage(msg.get(), msg->source(), parser_config->spamprobeFieldName()); SpamFilter::Score score; if (should_log) { score = filter.scoreMessage(*msg); } bool scored_as_spam = should_log && filter.scoreMessage(*msg).isSpam(); bool is_spam = mail_reader->messageWasSpam(); if (should_log) { logMessage(config, filter, is_spam ? "SPAM" : "GOOD", score.isSpam() == is_spam, *msg); } if (is_spam) { spam_command->processMessage(config, filter, &mail_reader->messageFile(), *msg, message_num, is_spam); } else { good_command->processMessage(config, filter, &mail_reader->messageFile(), *msg, message_num, is_spam); } purger.processedMessage(); mail_message.set(mail_reader->readMessage()); } purger.finish(); return 0; } spamprobe-1.4d/src/spamprobe/Command_tokenize.h0000664000076400007640000000314110527261701016663 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_tokenize.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_tokenize_h #define _Command_tokenize_h #include "AbstractMessageCommand.h" class Command_tokenize : public AbstractMessageCommand { public: Command_tokenize(); void processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam); }; #endif // _Command_tokenize_h spamprobe-1.4d/src/spamprobe/Command_train_test.h0000664000076400007640000000355010527261701017213 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_train_test.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_train_test_h #define _Command_train_test_h #include "AbstractCommand.h" class Command_train_test : public AbstractCommand { public: static const Ref createTrainTestCommand(); static const Ref createLearnTestCommand(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); protected: Command_train_test(const string &name, const string &short_help, const string &long_help, bool is_learn) : AbstractCommand(name, short_help, long_help, false), m_isLearn(is_learn) { } private: bool m_isLearn; }; #endif // _Command_train_test_h spamprobe-1.4d/src/spamprobe/Command_summarize.h0000664000076400007640000000441310527261701017052 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_summarize.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_summarize_h #define _Command_summarize_h #include "AbstractMessageCommand.h" class Command_summarize : public AbstractMessageCommand { public: static const Ref createFindGoodCommand(); static const Ref createFindSpamCommand(); static const Ref createSummarizeCommand(); void processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam); protected: Command_summarize(const string &name, const string &short_help, const string &long_help, bool read_only, bool needs_database, bool include_good, bool include_spam) : AbstractMessageCommand(name, short_help, long_help, read_only, needs_database), m_includeGood(include_good), m_includeSpam(include_spam) { } private: bool m_includeGood; bool m_includeSpam; }; #endif // _Command_summarize_h spamprobe-1.4d/src/spamprobe/SimpleTokenSelector.cc0000664000076400007640000000317110527261701017471 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SimpleTokenSelector.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "Message.h" #include "Token.h" #include "SimpleTokenSelector.h" SimpleTokenSelector::SimpleTokenSelector(int required_flags, const string &required_prefix) : m_requiredFlags(required_flags), m_requiredPrefix(required_prefix) { } SimpleTokenSelector::~SimpleTokenSelector() { } bool SimpleTokenSelector::shouldAcceptToken(Token *tok) { return starts_with(tok->getWord(), m_requiredPrefix) && ((tok->getFlags() & m_requiredFlags) != 0); } spamprobe-1.4d/src/spamprobe/Command_cleanup.h0000664000076400007640000000321310527261701016462 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_cleanup.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_cleanup_h #define _Command_cleanup_h #include "AbstractCommand.h" class CleanupManager; class Command_cleanup : public AbstractCommand { public: Command_cleanup(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void parseArgs(const ConfigManager &config, CleanupManager &cleanman); void cleanup(SpamFilter &filter, CleanupManager &cleanman); }; #endif // _Command_cleanup_h spamprobe-1.4d/src/spamprobe/CommandConfig.h0000664000076400007640000000657710527261701016121 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: CommandConfig.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _CommandConfig_h #define _CommandConfig_h #include #include "AbstractCommand.h" class CommandConfig { public: CommandConfig(); int messagesPerPurge() const { return m_messagesPerPurge; } void setMessagesPerPurge(int value) { m_messagesPerPurge = value; } bool shouldShowTerms() const { return m_shouldShowTerms; } void setShouldShowTerms(bool value) { m_shouldShowTerms = value; } bool streamIsPretokenized() const { return m_streamIsPretokenized; } void setStreamIsPretokenized(bool value) { m_streamIsPretokenized = value; } bool ignoreFrom() const { return m_ignoreFrom; } void setIgnoreFrom(bool value) { m_ignoreFrom = value; } bool ignoreContentLength() const { return m_ignoreContentLength; } void setIgnoreContentLength(bool value) { m_ignoreContentLength = value; } bool shouldCreateDbDir() const { return m_shouldCreateDbDir; } void setShouldCreateDbDir(bool value) { m_shouldCreateDbDir = value; } const string &statusFieldName() const { return m_statusFieldName; } void setStatusFieldName(const string &value) { m_statusFieldName = value; } int numCommands() const { return (int)m_commands.size(); } const Ref command(int index) const { assert(index >= 0); assert(index < numCommands()); return m_commands[index]; } const Ref findCommand(const string &name) const; void addCommand(const Ref &command) { m_commands.push_back(command); } void addArg(const string &arg) { m_args.push_back(arg); } void addArgs(char **args) { while (*args) { addArg(*args++); } } int numArgs() const { return (int)m_args.size(); } const string &arg(int index) const { assert(index >= 0); assert(index < numArgs()); return m_args[index]; } private: int m_messagesPerPurge; bool m_shouldShowTerms; bool m_streamIsPretokenized; bool m_ignoreFrom; bool m_ignoreContentLength; bool m_shouldCreateDbDir; string m_statusFieldName; vector m_args; typedef vector > CommandVector; CommandVector m_commands; }; #endif // _CommandConfig_h spamprobe-1.4d/src/spamprobe/Command_dump.h0000664000076400007640000000300710527261701016001 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_dump.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_dump_h #define _Command_dump_h #include "AbstractCommand.h" class Command_dump : public AbstractCommand { public: Command_dump(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void dumpWords(SpamFilter &filter, const string ®ex); }; #endif // _Command_dump_h spamprobe-1.4d/src/spamprobe/TokenSelector.h0000664000076400007640000000313110527261701016155 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TokenSelector.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _TokenSelector_h #define _TokenSelector_h #include #include "util.h" class Message; class Token; class TokenSelector { public: TokenSelector(); virtual ~TokenSelector(); void selectTokens(const Message &msg, vector &tokens); void setNext(TokenSelector *other) { m_next = other; } protected: virtual bool shouldAcceptToken(Token *tok); private: TokenSelector *m_next; }; #endif // _TokenSelector_h spamprobe-1.4d/src/spamprobe/Command_spam.h0000664000076400007640000000437510527261701016005 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_spam.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_spam_h #define _Command_spam_h #include "AbstractMessageCommand.h" class Command_spam : public AbstractMessageCommand { public: static const Ref createGoodCommand(); static const Ref createSpamCommand(); static const Ref createTrainGoodCommand(); static const Ref createTrainSpamCommand(); void processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam); protected: Command_spam(const string &name, const string &short_help, const string &long_help, bool read_only, bool needs_database, bool is_spam, bool is_train) : AbstractMessageCommand(name, short_help, long_help, read_only, needs_database), m_isSpam(is_spam), m_isTrain(is_train) { } private: bool m_isSpam; bool m_isTrain; }; #endif // _Command_spam_h spamprobe-1.4d/src/spamprobe/Command_print.h0000664000076400007640000000275410527260230016174 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id$ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_print_h #define _Command_print_h #include "AbstractCommand.h" class Command_print : public AbstractCommand { public: Command_print(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void dumpWords(SpamFilter &filter, const CommandConfig *command_config); }; #endif // _Command_print_h spamprobe-1.4d/src/spamprobe/Command_purge_terms.h0000664000076400007640000000306310527261701017372 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_purge_terms.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_purge_terms_h #define _Command_purge_terms_h #include "AbstractCommand.h" class Command_purge_terms : public AbstractCommand { public: Command_purge_terms(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void purgeTerms(SpamFilter &filter, const string ®ex); }; #endif // _Command_purge_terms_h spamprobe-1.4d/src/spamprobe/Command_exec.h0000664000076400007640000000267410527261701015771 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_exec.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_exec_h #define _Command_exec_h #include "AbstractCommand.h" class Command_exec : public AbstractCommand { public: Command_exec(bool shared); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); }; #endif // _Command_exec_h spamprobe-1.4d/src/spamprobe/Command_create_config.cc0000664000076400007640000000410410527261701017761 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_create_config.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_create_config.h" Command_create_config::Command_create_config() : AbstractCommand("create-config", "create-config Creates a new config file if none currently exists.", "create-config\n" " Writes a config file containing the current settings. Any existing\n" " config file will be overwritten.\n", false) { } bool Command_create_config::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0; } int Command_create_config::execute(const ConfigManager &config, SpamFilter &filter) { config.writeToFile(config.configFile()); return 0; } spamprobe-1.4d/src/spamprobe/SimpleTokenSelector.h0000664000076400007640000000306310527261701017333 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SimpleTokenSelector.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _SimpleTokenSelector_h #define _SimpleTokenSelector_h #include "TokenSelector.h" class SimpleTokenSelector : public TokenSelector { public: SimpleTokenSelector(int required_flags, const string &required_prefix); virtual ~SimpleTokenSelector(); protected: bool shouldAcceptToken(Token *tok); private: int m_requiredFlags; string m_requiredPrefix; }; #endif // _SimpleTokenSelector_h spamprobe-1.4d/src/spamprobe/Command_cleanup.cc0000664000076400007640000000634610527261701016632 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_cleanup.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CleanupManager.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_cleanup.h" Command_cleanup::Command_cleanup() : AbstractCommand("cleanup", "cleanup Removes some or all terms from database.", "cleanup [min_count min_age]...\n" " Scans the database and removes all terms with junk_count or less\n" " (default 2) which have not had their counts modified in at least\n" " max_age days (default 7). You can specify multiple count/age pairs\n" " on a single command line but must specify both a count and an age\n" " for all but the last count. This should be run periodically to\n" " keep the database from growing endlessly.\n", false) { } void Command_cleanup::parseArgs(const ConfigManager &config, CleanupManager &cleanman) { if (config.commandConfig()->numArgs() == 0) { cleanman.addLimit(2, 7); } for (int i = 0, limit = config.commandConfig()->numArgs() - 1; i < limit; i += 2) { int junk_count = atoi(config.commandConfig()->arg(i).c_str()); int max_age = atoi(config.commandConfig()->arg(i + 1).c_str()); cleanman.addLimit(junk_count, max_age); } } void Command_cleanup::cleanup(SpamFilter &filter, CleanupManager &cleanman) { filter.getDB()->sweepOutOldTerms(cleanman); } bool Command_cleanup::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); if (num_args % 2 != 0) { return false; } for (int i = 0; i < num_args; ++i) { if (!is_digits(config.commandConfig()->arg(i))) { return false; } } return true; } int Command_cleanup::execute(const ConfigManager &config, SpamFilter &filter) { assert(argsOK(config)); openDatabase(config, filter); CleanupManager cleanman; parseArgs(config, cleanman); cleanup(filter, cleanman); return 0; } spamprobe-1.4d/src/spamprobe/Command_remove.h0000664000076400007640000000312510527261701016332 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_remove.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_remove_h #define _Command_remove_h #include "AbstractMessageCommand.h" class Command_remove : public AbstractMessageCommand { public: Command_remove(); void processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam); }; #endif // _Command_remove_h spamprobe-1.4d/src/spamprobe/Command_receive.h0000664000076400007640000000433110527261701016457 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_receive.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_receive_h #define _Command_receive_h #include "AbstractMessageCommand.h" class Command_receive : public AbstractMessageCommand { public: static const Ref createReceiveCommand(); static const Ref createScoreCommand(); static const Ref createTrainCommand(); void processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam); protected: Command_receive(const string &name, const string &short_help, const string &long_help, bool read_only, bool needs_database, bool is_train, bool is_single_message) : AbstractMessageCommand(name, short_help, long_help, read_only, needs_database), m_isTrain(is_train) { setIsSingleMessageCommand(is_single_message); } private: bool m_isTrain; }; #endif // _Command_receive_h spamprobe-1.4d/src/spamprobe/Command_create_config.h0000664000076400007640000000274710527261701017636 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_create_config.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_create_config_h #define _Command_create_config_h #include "AbstractCommand.h" class Command_create_config : public AbstractCommand { public: Command_create_config(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); }; #endif // _Command_create_config_h spamprobe-1.4d/src/spamprobe/Command_help.h0000664000076400007640000000321110527261701015761 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_help.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_help_h #define _Command_help_h #include "AbstractCommand.h" class Command_help : public AbstractCommand { public: Command_help(); int execute(const ConfigManager &config, SpamFilter &filter); private: void printCommandLineOptions(const CommandConfig *cmd_config); void printAllCommandsSummary(const CommandConfig *cmd_config); void printDetailedHelp(const CommandConfig *cmd_config); void printHelpForCommand(const Ref &cmd); }; #endif // _Command_help_h spamprobe-1.4d/src/spamprobe/AbstractCommand.h0000664000076400007640000000621610527261701016445 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractCommand.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractCommand_h #define _AbstractCommand_h #include "util.h" class ConfigManager; class File; class FrequencyDB; class Message; class SpamFilter; class AbstractCommand { public: AbstractCommand(const string &name, const string &short_help, const string &long_help, bool read_only) : m_name(name), m_shortHelp(short_help), m_longHelp(long_help), m_readOnly(read_only), m_isSingleMessageCommand(false) { } virtual ~AbstractCommand() { } const string &name() const { return m_name; } const string &shortHelp() const { return m_shortHelp; } const string &longHelp() const { return m_longHelp; } bool isReadOnly() const { return m_readOnly; } bool isSingleMessageCommand() const { return m_isSingleMessageCommand; } virtual bool isMessageSpam() const; virtual bool argsOK(const ConfigManager &config); virtual int execute(const ConfigManager &config, SpamFilter &filter) = 0; protected: void createDbDir(const ConfigManager &config); void openDatabase(const ConfigManager &config, SpamFilter &filter); const char *scoreToString(double score); void printTerms(FrequencyDB *db, ostream &out, Message &msg, const string &indent); void printMessageScore(const ConfigManager &config, SpamFilter &filter, bool is_spam, double score, Message &msg, const File *source = 0); void setIsSingleMessageCommand(bool value) { m_isSingleMessageCommand = value; } void logMessageProcessing(bool processed, Message &message, const File *stream_file); private: string m_name; string m_shortHelp; string m_longHelp; bool m_readOnly; bool m_isSingleMessageCommand; }; #endif // _AbstractCommand_h spamprobe-1.4d/src/spamprobe/SpamFilter.cc0000664000076400007640000003707710527261701015620 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: SpamFilter.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include #include #include #include "LockFile.h" #include "DatabaseConfig.h" #include "FilterConfig.h" #include "TokenSelector.h" #include "ConfigManager.h" #include "SpamFilter.h" static const double MIN_PROB = 0.000001; static const double MAX_PROB = 0.999999; static const double NEARLY_ZERO = 0.0000001; static const int MAX_COUNT_FOR_SORT = 20; static const int COUNT_SORT_DIVISOR = 3; static const double PROB_SORT_MULTIPLE = 100000.0; static const double EXT_ARRAY_THRESHOLD = 0.4999; static const string LOCK_FILENAME("lock"); // train-mode constants static const int MIN_TRAINING_SET = 1500; static const FilterConfig::ScoreMode TRAIN_SCORE_MODE = FilterConfig::SCORE_NORMAL; static const int MAX_SINGLE_MESSAGE_CLASSIFY = 25; typedef vector::size_type vecsize_t; typedef vector::iterator veciter_t; SpamFilter::SpamFilter(ConfigManager *config) : m_config(config), m_db(config->databaseConfig()) { } SpamFilter::~SpamFilter() { close(); } void SpamFilter::lock(const File &raw_db_file, bool read_only) { File db_file(raw_db_file.getPath()); File lock_file(db_file.parent(), LOCK_FILENAME); m_lock.set(new LockFile(lock_file)); m_lock->lock(read_only ? LockFD::SHARED_LOCK : LockFD::EXCLUSIVE_LOCK); if (is_debug) { cerr << "LOCKED FILE " << lock_file.getPath() << endl; } } void SpamFilter::open(bool read_only) { lock(File(m_config->databaseConfig()->privateFilename()), read_only); if (!m_db.open(read_only)) { throw runtime_error("unable to open words database"); } } void SpamFilter::close(bool abandon_writes) { if (m_db.isOpen()) { if (!abandon_writes) { m_db.flush(); } m_db.close(); } m_lock.clear(); } double SpamFilter::computeRatio(double count, double total_count) { if (count == 0) { return NEARLY_ZERO; } else { double score = count / total_count; return max(MIN_PROB, min(MAX_PROB, score)); } } double SpamFilter::scoreTerm(int good_count, int spam_count, int good_message_count, int spam_message_count) { good_count *= m_config->filterConfig()->getGoodBias(); int count = good_count + spam_count; double score; if (count >= m_config->filterConfig()->getMinWordCount()) { double good_ratio = computeRatio(good_count, good_message_count); double spam_ratio = computeRatio(spam_count, spam_message_count); score = computeRatio(spam_ratio, good_ratio + spam_ratio); } else { score = m_config->filterConfig()->getNewWordScore(); } return score; } // Returns "within document frequency" for sort. Uses a limit on max // value for sanity and also uses a ratio of the count to keep small // differences (3 vs. 2) from having a disproportionate impact on the // sort. inline long wdf_for_sort(int count) { return min(MAX_COUNT_FOR_SORT, count / COUNT_SORT_DIVISOR); } // Returns probability rounded to 5 decimal places to "band" results for sorting. // This prevents tiny differences from having excessive impact on results. inline double rounded_prob(double prob) { return floor(prob * PROB_SORT_MULTIPLE); } void SpamFilter::scoreToken(Token *tok, int good_message_count, int spam_message_count) { assert(tok->getCount() > 0); int good_count, spam_count; m_db.getWordCounts(tok->getWord(), good_count, spam_count); tok->setDBGoodCount(good_count); tok->setDBSpamCount(spam_count); if (tok->getDBTotalCount() < 0 && is_debug) { cerr << "WARNING: token " << tok->getWord() << " has negative count" << endl; } double score = scoreTerm(tok->getDBGoodCount(), tok->getDBSpamCount(), good_message_count, spam_message_count); assert(score >= MIN_PROB); assert(score <= MAX_PROB); tok->setScore(score); long sort_count = ((long)rounded_prob(abs(score - 0.5))) << 6; sort_count |= (wdf_for_sort(tok->getCount()) & 0x1f) << 1; if (score < 0.5) { sort_count |= 1; } assert(sort_count >= 0); tok->setSortCount(sort_count); double tie_break_ratio; if (score > 0.5) { tie_break_ratio = computeRatio(spam_count, spam_message_count); } else { tie_break_ratio = computeRatio(good_count, good_message_count); } tok->setTieBreakCount((long)(tie_break_ratio / MIN_PROB)); } void SpamFilter::scoreTokens(const Message &msg) { int good_message_count, spam_message_count; m_db.getMessageCounts(good_message_count, spam_message_count); for (int i = 0; i < msg.getTokenCount(); ++i) { Token *tok = msg.getToken(i); assert(tok); scoreToken(tok, good_message_count, spam_message_count); } } static int token_sort_descending(Token * const &t1, Token * const &t2) { int answer; if (t2->getSortCount() != t1->getSortCount()) { answer = t2->getSortCount() < t1->getSortCount(); } else if (t2->getTieBreakCount() != t1->getTieBreakCount()) { answer = t2->getTieBreakCount() < t1->getTieBreakCount(); } else { answer = t1->getWord() < t2->getWord(); } return answer; } // Remove tokens below min distance from mean but be sure that we have // at least the number of terms required by the min_array_size config option. void SpamFilter::removeTokensBelowMinDistance(vector &tokens) { double min_distance = m_config->filterConfig()->getMinDistanceForScore(); if (min_distance > 0.0) { const int min_size = m_config->filterConfig()->getMinArraySize(); int array_size = 0; for (veciter_t i = tokens.begin(), limit = tokens.end(); i != limit; ++i, ++array_size) { const Token *tok = *i; if ((tok->getDistanceFromMean() < min_distance) && (array_size >= min_size)) { tokens.erase(i, tokens.end()); break; } } } } void SpamFilter::sortTokens(vector &tokens) { bool need_whole_array = m_config->filterConfig()->getExtendTopTerms() || tokens.size() <= (vecsize_t)m_config->filterConfig()->getTermsForScore(); veciter_t sort_end; if (need_whole_array) { sort_end = tokens.end(); } else { sort_end = tokens.begin() + (vecsize_t)m_config->filterConfig()->getTermsForScore(); } assert((tokens.end() - tokens.begin()) >= (sort_end - tokens.begin())); partial_sort(tokens.begin(), sort_end, tokens.end(), token_sort_descending); if (!need_whole_array) { tokens.erase(sort_end, tokens.end()); } } void SpamFilter::dumpSortedTokens(vector &tokens) { if (is_debug) { for (vector::const_iterator i = tokens.begin(); i != tokens.end(); ++i) { Token *tok = *i; cerr << "SORTED " << tok->getWord() << " count " << tok->getCount() << " score " << tok->getScore() << " dist " << tok->getDistanceFromMean() << " good " << tok->getDBGoodCount() << " spam " << tok->getDBSpamCount() << " tiebreak " << tok->getTieBreakCount() << endl; } } } void SpamFilter::computeScoreProducts(Message &msg, TokenSelector *selector, double &spamness, double &goodness, double &num_terms) { vector tokens; tokens.reserve(msg.getTokenCount()); selector->selectTokens(msg, tokens); sortTokens(tokens); removeTokensBelowMinDistance(tokens); dumpSortedTokens(tokens); msg.clearTopTokens(); int max_word_repeats = m_config->filterConfig()->getMaxWordRepeats(); int max_terms = m_config->filterConfig()->getTermsForScore(); if (m_config->filterConfig()->getWaterCounts()) { max_terms = max(15, (int)tokens.size() / 25); max_word_repeats = max(1, max_terms / 15); } goodness = 1.0; spamness = 1.0; num_terms = 0; for (vector::const_iterator i = tokens.begin(); i != tokens.end(); ++i) { Token *tok = *i; if ((num_terms >= max_terms) && (!m_config->filterConfig()->getExtendTopTerms() || (tok->getDistanceFromMean() < EXT_ARRAY_THRESHOLD))) { break; } int count = tok->getCount(); double score = tok->getScore(); msg.addTopToken(tok); assert(count > 0); int times = min(max_word_repeats, count); if (is_debug) { cerr << "** TOKEN " << tok->getWord() << ": score " << score << ": times " << times << endl; } num_terms += times; while (times-- > 0) { spamness = spamness * score; goodness = goodness * (1.0 - score); } } } // // Paul Graham's original formula as outlined in A Plan For Spam. // Yields excellent results but nearly all messages score as 0 or 1 // double SpamFilter::originalScoreMessage(Message &msg, TokenSelector *selector) { double spamness, goodness, num_terms; computeScoreProducts(msg, selector, spamness, goodness, num_terms); double score = spamness / (spamness + goodness); if (is_nan(score)) { score = 0.5; } if (is_debug) { cerr << "** SPAMNESS " << spamness << ": GOODNESS " << goodness << ": SCORE " << score << endl; } return score; } // // Robinson's simple algorithm. Refer to his article for details: // http://radio.weblogs.com/0101454/stories/2002/09/16/spamDetection.html // double SpamFilter::alt1ScoreMessage(Message &msg, TokenSelector *selector) { double spamness, goodness, num_terms; computeScoreProducts(msg, selector, spamness, goodness, num_terms); double p = 1.0 - pow(goodness, 1.0 / num_terms); double q = 1.0 - pow(spamness, 1.0 / num_terms); double s = (p - q) / (p + q); s = (s + 1.0) / 2.0; if (is_debug) { cerr << "SCORE P " << p << ": Q " << q << ": SCORE " << s << endl; } return s; } // // Paul's formula modified to use the nth root of the products. Gives // same results as Paul's formula but spreads out scores more evenly. // Gives a better distribution than Robinson's simple formula. // double SpamFilter::normalScoreMessage(Message &msg, TokenSelector *selector) { double spamness, goodness, num_terms; computeScoreProducts(msg, selector, spamness, goodness, num_terms); spamness = pow(spamness, 1.0 / num_terms); goodness = pow(goodness, 1.0 / num_terms); double score = spamness / (spamness + goodness); if (is_nan(score)) { score = 0.5; } if (is_debug) { cerr << "** SPAMNESS " << spamness << ": GOODNESS " << goodness << ": SCORE " << score << endl; } return score; } SpamFilter::Score SpamFilter::scoreMessage(Message &msg) { scoreTokens(msg); double score_value = 0; for (int i = 0, limit = m_config->filterConfig()->numTokenSelectors(); i < limit; ++i) { score_value += scoreMessage(msg, m_config->filterConfig()->tokenSelector(i)); } score_value = score_value / ((double)m_config->filterConfig()->numTokenSelectors()); return Score(score_value, m_config->filterConfig()->getScoreMode(), score_value >= m_config->filterConfig()->getSpamThreshold()); } double SpamFilter::scoreMessage(Message &msg, TokenSelector *selector) { double score_value; switch (m_config->filterConfig()->getScoreMode()) { case FilterConfig::SCORE_ALT1: score_value = alt1ScoreMessage(msg, selector); break; case FilterConfig::SCORE_ORIGINAL: score_value = originalScoreMessage(msg, selector); break; default: assert(m_config->filterConfig()->getScoreMode() == FilterConfig::SCORE_NORMAL); score_value = normalScoreMessage(msg, selector); break; } return score_value; } SpamFilter::Score SpamFilter::scoreMessage(Message &msg, FilterConfig::ScoreMode mode) { if (m_config->filterConfig()->getScoreMode() == mode) { return scoreMessage(msg); } FilterConfig::ScoreMode old_mode = m_config->filterConfig()->getScoreMode(); m_config->filterConfig()->setScoreMode(mode); Score score = scoreMessage(msg); m_config->filterConfig()->setScoreMode(old_mode); return score; } void SpamFilter::ensureGoodMessage(const Message &msg, bool force_update) { bool is_spam = false; if (m_db.containsMessage(msg, is_spam) && is_spam) { // remove from database if previously classified as spam m_db.removeMessage(msg); } m_db.addMessage(msg, false, force_update); } void SpamFilter::ensureSpamMessage(const Message &msg, bool force_update) { bool is_spam = false; if (m_db.containsMessage(msg, is_spam) && !is_spam) { // remove from database if previously classified as good m_db.removeMessage(msg); } m_db.addMessage(msg, true, force_update); } bool SpamFilter::classifyMessage(Message &msg, bool is_spam) { if (is_spam) { ensureSpamMessage(msg, false); } else { ensureGoodMessage(msg, false); } Score score = scoreMessage(msg); while (!score.isConfident(is_spam)) { bool is_spam_in_db = false; int message_count = getDB()->getMessageCount(msg, is_spam_in_db); assert(!is_spam_in_db == !is_spam); if (message_count >= MAX_SINGLE_MESSAGE_CLASSIFY) { break; } if (is_debug) { cerr << "ANOTHER ATTEMPT to classify message " << msg.getDigest() << " SCORE " << score.getValue() << endl; } if (is_spam) { ensureSpamMessage(msg, true); } else { ensureGoodMessage(msg, true); } score = scoreMessage(msg); } return is_spam; } bool SpamFilter::trainOnMessage(Message &msg, const SpamFilter::Score &score, bool is_spam, bool update_timestamps) { int good_count, spam_count; getDB()->getMessageCounts(good_count, spam_count); bool counts_unbalanced, below_min_count; if (is_spam) { counts_unbalanced = spam_count < good_count; below_min_count = spam_count < MIN_TRAINING_SET; } else { counts_unbalanced = good_count < spam_count; below_min_count = good_count < MIN_TRAINING_SET; } if (below_min_count || counts_unbalanced || (score.isSpam() != is_spam) || !scoreMessageIfWrongMode(score, msg, TRAIN_SCORE_MODE).isConfident(is_spam)) { // train on the message if it was wrong or not a definite decision classifyMessage(msg, is_spam); } else if (update_timestamps) { // Otherwise just update term time stamps to keep them from expiring. // If we didn't do this terms that appear frequently in messages that // aren't classified would expire from the database. getDB()->touchMessage(msg); } return is_spam; } spamprobe-1.4d/src/spamprobe/Command_counts.h0000664000076400007640000000267510527261701016361 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_counts.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_counts_h #define _Command_counts_h #include "AbstractCommand.h" class Command_counts : public AbstractCommand { public: Command_counts(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); }; #endif // _Command_counts_h spamprobe-1.4d/src/spamprobe/Command_tokenize.cc0000664000076400007640000000713110527261701017024 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_tokenize.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_tokenize.h" Command_tokenize::Command_tokenize() : AbstractMessageCommand("tokenize", "tokenize Prints all tokens for messages.", "tokenize [filename...]\n" " Prints the tokens found in the file one word per line in human\n" " readable format with spam probability, good count, spam count,\n" " message count, and word in columns separated by whitespace. Terms\n" " are listed in the order in which they were encountered in the\n" " message. The standard unix sort command can be used to sort the\n" " terms as desired. For example to list all words from 'most good'\n" " to 'least good' use this command:\n" "\n" " spamprobe tokenize filename | sort -k 1nr -k 3nr\n" "\n" " To list all words from 'most spammy' to 'least spammy' use this\n" " command:\n" "\n" " spamprobe tokenize filename | sort -k 1n -k 2nr\n", false, true) { } void Command_tokenize::processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam) { int good_message_count, spam_message_count; filter.getDB()->getMessageCounts(good_message_count, spam_message_count); int good_count, spam_count; for (int token_num = 0; token_num < message.getTokenCount(); ++token_num) { Token *token = message.getToken(token_num); filter.getDB()->getWordCounts(token->getWord(), good_count, spam_count); double score = filter.scoreTerm(good_count, spam_count, good_message_count, spam_message_count); cout << scoreToString(score) << dec << setw(8) << good_count << setw(8) << spam_count << setw(8) << token->getCount() << " " << token->getWord() << "\n"; } } spamprobe-1.4d/src/spamprobe/Command_edit_term.h0000664000076400007640000000305310527261701017011 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_edit_term.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_edit_term_h #define _Command_edit_term_h #include "AbstractCommand.h" class Command_edit_term : public AbstractCommand { public: Command_edit_term(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void editTerm(const ConfigManager &config, SpamFilter &filter); }; #endif // _Command_edit_term_h spamprobe-1.4d/src/spamprobe/Command_counts.cc0000664000076400007640000000410410527261701016504 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_counts.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_counts.h" Command_counts::Command_counts() : AbstractCommand("counts", "counts Prints number of good and spam in database.", "counts\n" " Prints number of good and spam messages in database.\n", true) { } bool Command_counts::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0; } int Command_counts::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); int spam_count, good_count; filter.getDB()->getMessageCounts(good_count, spam_count); cout << "GOOD " << good_count << " SPAM " << spam_count << endl; return 0; } spamprobe-1.4d/src/spamprobe/Makefile.am0000664000076400007640000000267610526707112015274 00000000000000AUTOMAKE_OPTIONS = foreign LDADD = ../database/libdatabase.a ../parser/libparser.a ../hdl/libhdl.a ../input/libinput.a ../utility/libutility.a INCLUDES = -I@top_srcdir@/src/includes bin_PROGRAMS = spamprobe spamprobe_SOURCES=\ AbstractCommand.cc\ AbstractCommand.h\ AbstractFileCommand.cc\ AbstractFileCommand.h\ AbstractMessageCommand.cc\ AbstractMessageCommand.h\ AutoPurger.cc\ AutoPurger.h\ CommandConfig.cc\ CommandConfig.h\ Command_auto_train.cc\ Command_auto_train.h\ Command_cleanup.cc\ Command_cleanup.h\ Command_counts.cc\ Command_counts.h\ Command_create_config.cc\ Command_create_config.h\ Command_create_db.cc\ Command_create_db.h\ Command_dump.cc\ Command_dump.h\ Command_edit_term.cc\ Command_edit_term.h\ Command_exec.cc\ Command_exec.h\ Command_export.cc\ Command_export.h\ Command_help.cc\ Command_help.h\ Command_import.cc\ Command_import.h\ Command_print.cc\ Command_print.h\ Command_purge.cc\ Command_purge.h\ Command_purge_terms.cc\ Command_purge_terms.h\ Command_receive.cc\ Command_receive.h\ Command_remove.cc\ Command_remove.h\ Command_spam.cc\ Command_spam.h\ Command_summarize.cc\ Command_summarize.h\ Command_tokenize.cc\ Command_tokenize.h\ Command_train_test.cc\ Command_train_test.h\ ConfigManager.cc\ ConfigManager.h\ FilterConfig.cc\ FilterConfig.h\ SimpleTokenSelector.cc\ SimpleTokenSelector.h\ SpamFilter.cc\ SpamFilter.h\ spamprobe.cc\ TokenSelector.cc\ TokenSelector.h spamprobe-1.4d/src/spamprobe/AbstractMessageCommand.h0000664000076400007640000000554510527261701017756 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractMessageCommand.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _AbstractMessageCommand_h #define _AbstractMessageCommand_h #include "AbstractFileCommand.h" class AutoPurger; class Message; class AbstractMailMessageReader; class MailMessageReaderFactory; class AbstractMessageCommand : public AbstractFileCommand { public: AbstractMessageCommand(const string &name, const string &short_help, const string &long_help, bool read_only, bool needs_database) : AbstractFileCommand(name, short_help, long_help, read_only, needs_database) { } bool isMessageSpam() const; void processFile(const ConfigManager &config, SpamFilter &filter, const File *stream_file); virtual void processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam) = 0; private: bool shouldProcessMessage(const ConfigManager &config, Message &message); void processMailReader(const ConfigManager &config, SpamFilter &filter, AutoPurger &purger, const File *stream_file, Ptr &reader); void processTokenStream(const ConfigManager &config, SpamFilter &filter, AutoPurger &purger, const File *stream_file, istream &stream); bool m_isMessageSpam; }; #endif // _AbstractMessageCommand_h spamprobe-1.4d/src/spamprobe/Command_train_test.cc0000664000076400007640000001174110527261701017352 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_train_test.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "AutoTrainMailMessageReader.h" #include "ParserConfig.h" #include "IstreamCharReader.h" #include "TraditionalMailMessageParser.h" #include "AbstractMailMessageReader.h" #include "LineReader.h" #include "MD5Digester.h" #include "MailMessageDigester.h" #include "Command_spam.h" #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_train_test.h" const Ref Command_train_test::createTrainTestCommand() { return Ref(new Command_train_test("train-test", "train-test Builds database using specs on stdin.", "train-test\n" " Builds database using type and filenames read from stdin.\n" " Specified files are processed using train-good and train-spam.\n" " Each line of stdin must contain the word spam or good followed\n" " by the full path to a file containing one or more messages.\n" " This command is used by deveopers for testing spamprobe and is\n" " not really intended for general use.\n", false)); } const Ref Command_train_test::createLearnTestCommand() { return Ref(new Command_train_test("learn-test", "learn-test Builds database using learn mode.", "learn-test\n" " Builds database using type and filenames read from stdin.\n" " Specified files are processed using good and spam commands.\n" " Each line of stdin must contain the word spam or good followed\n" " by the full path to a file containing one or more messages.\n" " This command is used by deveopers for testing spamprobe and is\n" " not really intended for general use.\n", true)); } bool Command_train_test::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0; } int Command_train_test::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); Ref good_command; Ref spam_command; if (m_isLearn) { good_command = Command_spam::createGoodCommand(); spam_command = Command_spam::createSpamCommand(); } else { good_command = Command_spam::createTrainGoodCommand(); spam_command = Command_spam::createTrainSpamCommand(); } string type_name, file_name, command; while (cin) { cin >> type_name; cin >> file_name; if (cin) { File message_file(file_name); if (!message_file.isFile()) { throw runtime_error(file_name + ": does not exist"); } if (type_name == "spam") { spam_command->processFile(config, filter, &message_file); } else if (type_name == "good") { good_command->processFile(config, filter, &message_file); } else { throw runtime_error(string("invalid message type: ") + type_name); } } } return 0; } spamprobe-1.4d/src/spamprobe/Command_export.h0000664000076400007640000000275710527261701016370 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_export.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_export_h #define _Command_export_h #include "AbstractCommand.h" class Command_export : public AbstractCommand { public: Command_export(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void exportWords(SpamFilter &filter); }; #endif // _Command_export_h spamprobe-1.4d/src/spamprobe/AbstractMessageCommand.cc0000664000076400007640000001337110527261701020110 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: AbstractMessageCommand.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "CleanupManager.h" #include "ParserConfig.h" #include "IstreamCharReader.h" #include "TraditionalMailMessageParser.h" #include "AbstractMailMessageReader.h" #include "LineReader.h" #include "MD5Digester.h" #include "MailMessageDigester.h" #include "File.h" #include "ConfigManager.h" #include "CommandConfig.h" #include "SpamFilter.h" #include "AutoPurger.h" #include "MailMessageReaderFactory.h" #include "AbstractMessageCommand.h" bool AbstractMessageCommand::shouldProcessMessage(const ConfigManager &config, Message &message) { const string &status_field_name = config.commandConfig()->statusFieldName(); if (status_field_name.length() == 0) { return true; } string value; if (message.getHeader(status_field_name, value).length() == 0) { return true; } if (value.find('D') == string::npos) { return true; } if (is_debug) { cerr << "SKIPPING MESSAGE WITH STATUS: " << value << endl; } return false; } void AbstractMessageCommand::processMailReader(const ConfigManager &config, SpamFilter &filter, AutoPurger &purger, const File *stream_file, Ptr &mail_reader) { const CommandConfig *cmd_config = config.commandConfig(); const ParserConfig *prs_config = config.parserConfig(); TraditionalMailMessageParser parser(config.parserConfig()); MailMessageDigester digester; int message_number = 0; Ptr mail_message; mail_message.set(mail_reader->readMessage()); while (mail_message.isNotNull()) { Ptr msg(parser.parseMailMessage(mail_message.get())); msg->setSource(mail_message.release()); digester.assignDigestToMessage(msg.get(), msg->source(), prs_config->spamprobeFieldName()); bool should_process = shouldProcessMessage(config, *msg); if (should_process) { if (is_debug) { cerr << "*** NEW MESSAGE ***" << endl; } ++message_number; processMessage(config, filter, stream_file, *msg, message_number, m_isMessageSpam); purger.processedMessage(); } else { logMessageProcessing(false, *msg, stream_file); } mail_message.set(mail_reader->readMessage()); } } static bool read_tokens(LineReader &in, Message &msg) { MD5Digester digester; msg.clear(); digester.start(); while (in.forward() && in.currentLine().length() > 0) { digester.add(in.currentLine()); msg.addToken(in.currentLine(), Token::FLAG_NORMAL); } digester.stop(); msg.setDigest(digester.asString()); return msg.getTokenCount() > 0; } void AbstractMessageCommand::processTokenStream(const ConfigManager &config, SpamFilter &filter, AutoPurger &purger, const File *stream_file, istream &stream) { Message msg; int message_num = 0; IstreamCharReader char_reader(&stream); LineReader line_reader(&char_reader); while (read_tokens(line_reader, msg)) { if (is_debug) { cerr << "*** NEW MESSAGE ***" << endl; } ++message_num; processMessage(config, filter, stream_file, msg, message_num, m_isMessageSpam); purger.processedMessage(); } } void AbstractMessageCommand::processFile(const ConfigManager &config, SpamFilter &filter, const File *stream_file) { AutoPurger purger(config, filter); if (isReadOnly()) { purger.disable(); } m_isMessageSpam = false; if (config.commandConfig()->streamIsPretokenized()) { if (stream_file) { ifstream stream(stream_file->getPath().c_str()); processTokenStream(config, filter, purger, stream_file, stream); } else { processTokenStream(config, filter, purger, stream_file, cin); } } else { MailMessageReaderFactory factory; factory.setIgnoreFrom(config.commandConfig()->ignoreFrom()); factory.setIgnoreContentLength(config.commandConfig()->ignoreContentLength()); Ptr reader; if (stream_file) { reader.set(factory.createReader(*stream_file)); } else { reader.set(factory.createStdinReader()); } processMailReader(config, filter, purger, stream_file, reader); } purger.finish(); } bool AbstractMessageCommand::isMessageSpam() const { return m_isMessageSpam; } spamprobe-1.4d/src/spamprobe/Command_purge.cc0000664000076400007640000000536310527261701016323 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_purge.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CleanupManager.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_purge.h" Command_purge::Command_purge() : AbstractCommand("purge", "purge Removes some or all terms from database.", "purge [min_count]\n" " Similar to cleanup but forces the immediate deletion of all terms\n" " with total count less than junk_count (default is 2) no matter how\n" " long it has been since they were modified (i.e. even if they were\n" " just added today). This could be handy immediately after\n" " classifying a large mailbox of historical spam or good email to\n" " make room for the next batch.\n", false) { } void Command_purge::purgeTerms(SpamFilter &filter, int junk_count) { CleanupManager purger(junk_count, -1); // -1 forces todays to be removed too filter.getDB()->sweepOutOldTerms(purger); } bool Command_purge::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0 || (num_args == 1 && is_digits(config.commandConfig()->arg(0))); } int Command_purge::execute(const ConfigManager &config, SpamFilter &filter) { assert(argsOK(config)); openDatabase(config, filter); int junk_count = config.commandConfig()->numArgs() == 0 ? 2 : atoi(config.commandConfig()->arg(0).c_str()); purgeTerms(filter, junk_count); return 0; } spamprobe-1.4d/src/spamprobe/Command_purge.h0000664000076400007640000000301210527261701016152 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_purge.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_purge_h #define _Command_purge_h #include "AbstractCommand.h" class Command_purge : public AbstractCommand { public: Command_purge(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); private: void purgeTerms(SpamFilter &filter, int junk_count); }; #endif // _Command_purge_h spamprobe-1.4d/src/spamprobe/Command_help.cc0000664000076400007640000001543410527261701016131 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_help.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_help.h" Command_help::Command_help() : AbstractCommand("help", "help Prints information about supported commands and options.", "help [command...]\n" " With no arguments prints a summary of help for all commands and options.\n" " With arguments prints helpful information about each named command.\n", true) { } void Command_help::printCommandLineOptions(const CommandConfig *cmd_config) { cout << "Command Line Options:\n" << " -a char\n" << " Sets character used to replace non-ascii chars (default z).\n" << " -c\n" << " Causes database directory to be created if not already present.\n" << " -C count\n" << " Sets minimum count for a word to use computed probability.\n" << " Default value is 5.\n" << " -d dirname\n" << " Sets base directory in which spamprobe config file and database are stored.\n" << " -D dirname\n" << " Sets base directory in which shared (read only) database is stored.\n" << " -f filename\n" << " Sets configuration file used to set default options.\n" << " -g\n" << " Sets name of mail header used to store SpamProbe score (default X-SpamProbe).\n" << " This option is used to allow SpamProbe to find the current message's MD5 digest.\n" << " -h\n" << " Causes all HTML tags to be parsed for tokens.\n" << " -H namelist\n" << " Comma separated list of headers to be processed. Can use all or none to\n" << " cause all or none of the headers in the email to be processed. Header names\n" << " are not case sensitive,\n" << " -l number\n" << " Sets the spam threshold value. The number must be between 0.0 and 1.0.\n" << " All messages with scores >= the threshold will be considered spam. Default\n" << " value is 0.6.\n" << " -m\n" << " Causes SpamProbe to treat the message as an mbox file even if the command\n" << " being run would normally treat it as a single message (receive and train).\n" << " -M\n" << " Causes SpamProbe to assume that each file contains only one message.\n" << " -o option\n" << " Enables the specified extended option. Currently supported options are:\n" << " graham Use options similar to those from A Plan For Spam\n" << " suspicious-tags Force certain tags to be parsed for tokens\n" << " honor-status-header Ignore messages flagged as deleted in Status header\n" << " honor-xstatus-header Ignore messages flagged as deleted in X-Status header\n" << " orig-score Use original scoring algorithm (deprecated)\n" << " tokenized Assume file consists of tokens one per line\n" << " -p num_words\n" << " Sets maximum number of words per phrase (default 2)\n" << " -P num_messages\n" << " Causes terms with count <= 2 to be purged from database evern num_messages\n" << " messages. Useful when training on large files to remove unique terms and avoid\n" << " excessive database growth.\n" << " -r max_repeats\n" << " Sets maximum number of times words can appear in top tokens for scoring.\n" << " Default is 2.\n" << " -R\n" << " Causes SpamProbe to return exit status 0 if message was good or 1 if spam.\n" << " Also activates -M option.\n" << " -s max_terms\n" << " Sets size of in-memory cache. Larger values use more memory but boost performance.\n" << " -T\n" << " Causes SpamProbe to output terms used to compute score.\n" << " -v\n" << " Activates verbose output for some commands.\n" << " -V\n" << " Causes SpamProbe to print version information and exit.\n" << " -w num_terms\n" << " Sets number of terms used to compute score (default 27).\n" << " -x\n" << " Causes SpamProbe to extend top terms array to hold all highly significant terms\n" << " -X\n" << " Same as -w5 -r5 -x\n" << " -Y\n" << " Causes SpamProbe to ignore Content-Length header when parsing mbox files.\n" << " -7\n" << " Causes SpamProbe to ignore non-ascii characters.\n" << " -8\n" << " Causes SpamProbe to retain non-ascii characters.\n" << endl; } void Command_help::printAllCommandsSummary(const CommandConfig *cmd_config) { cout << "Supported Commands:\n"; for (int i = 0, len = cmd_config->numCommands(); i < len; ++i) { Ref cmd = cmd_config->command(i); cout << cmd->shortHelp() << endl; } } void Command_help::printDetailedHelp(const CommandConfig *cmd_config) { for (int i = 0, len = cmd_config->numArgs(); i < len; ++i) { string name = cmd_config->arg(i); Ref cmd = cmd_config->findCommand(name); if (cmd.isNull()) { cout << "NO SUCH COMMAND: " << name << endl; } else { printHelpForCommand(cmd); } } } void Command_help::printHelpForCommand(const Ref &command) { cout << command->longHelp() << endl; } int Command_help::execute(const ConfigManager &config, SpamFilter &filter) { const CommandConfig *cmd_config = config.commandConfig(); if (cmd_config->numArgs() == 0) { printCommandLineOptions(cmd_config); printAllCommandsSummary(cmd_config); } else { printDetailedHelp(cmd_config); } return 0; } spamprobe-1.4d/src/spamprobe/TokenSelector.cc0000664000076400007640000000327110527261701016320 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: TokenSelector.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "Message.h" #include "Token.h" #include "TokenSelector.h" TokenSelector::TokenSelector() : m_next(0) { } TokenSelector::~TokenSelector() { } bool TokenSelector::shouldAcceptToken(Token *tok) { return true; } void TokenSelector::selectTokens(const Message &msg, vector &tokens) { tokens.clear(); for (int i = 0; i < msg.getTokenCount(); ++i) { Token *tok = msg.getToken(i); if (shouldAcceptToken(tok) && (m_next == 0 || m_next->shouldAcceptToken(tok))) { tokens.push_back(tok); } } } spamprobe-1.4d/src/spamprobe/Command_summarize.cc0000664000076400007640000001341610527261701017213 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_summarize.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_summarize.h" const Ref Command_summarize::createFindGoodCommand() { return Ref(new Command_summarize("find-good", "find-good Prints a brief summary of each good (non-spam) message.", "find-good [filename...]\n" " Similar to score except that it prints a short summary and score\n" " for each message that is determined to be good. This can be useful\n" " when testing. Using the -T option additionally lists the terms\n" " used to produce the score along with their counts (number of times\n" " they were found in the message).\n", false, true, true, false)); } const Ref Command_summarize::createFindSpamCommand() { return Ref(new Command_summarize("find-spam", "find-spam Prints a brief summary of each spam message.", "find-spam [filename...]\n" " Similar to score except that it prints a short summary and score\n" " for each message that is determined to be spam. This can be useful\n" " when testing. Using the -T option additionally lists the terms\n" " used to produce the score along with their counts (number of times\n" " they were found in the message).\n", false, true, false, true)); } const Ref Command_summarize::createSummarizeCommand() { return Ref(new Command_summarize("summarize", "summarize Prints a brief summary of each message.", "summarize [filename...]\n" " Similar to score except that it prints a short summary and score\n" " for each message. This can be useful when testing. Using the -T\n" " option additionally lists the terms used to produce the score along\n" " with their counts (number of times they were found in the message).\n", false, true, true, true)); } void Command_summarize::processMessage(const ConfigManager &config, SpamFilter &filter, const File *stream_file, Message &message, int message_number, bool &is_spam) { SpamFilter::Score score = filter.scoreMessage(message); is_spam = score.isSpam(); bool should_show = (m_includeGood && !is_spam) || (m_includeSpam && is_spam); if (should_show) { string subject, msg_id; message.getHeader("subject", subject); if (stream_file) { cout << "File: " << stream_file->getPath() << "\n"; } cout << "Message Num: " << message_number << "\n" << "Message-ID: " << message.getID(msg_id) << "\n" << "Digest: " << message.getDigest() << "\n" << "Subject: " << subject << "\n" << "NumTerms: " << message.getTokenCount() << "\n" << "Score: " << scoreToString(score.getValue()) << "\n"; if (config.commandConfig()->shouldShowTerms() && message.getTopTokenCount() > 0) { printTerms(filter.getDB(), cout, message, " "); } } } spamprobe-1.4d/src/spamprobe/ConfigManager.h0000664000076400007640000000542510527261701016104 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: ConfigManager.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _ConfigManager_h #define _ConfigManager_h #include #include "util.h" class CommandConfig; class DatabaseConfig; class FilterConfig; class HdlStatement; class HdlPrinter; class ParserConfig; class File; class ConfigManager { public: ConfigManager(); ~ConfigManager(); const File &configFile() const { return *m_configFile; } void loadFromFile(const File &config_file); void writeToFile(const File &config_file) const; DatabaseConfig *databaseConfig() const { return m_databaseConfig.get(); } FilterConfig *filterConfig() const { return m_filterConfig.get(); } ParserConfig *parserConfig() const { return m_parserConfig.get(); } CommandConfig *commandConfig() const { return m_commandConfig.get(); } private: void loadDatabaseConfig(const CRef &database_stmt); void loadFilterConfig(const CRef &filter_stmt); void loadParserConfig(const CRef &parser_stmt); void loadHeaderConfig(const CRef &header_stmt); void writeConfig(HdlPrinter &printer, ostream &out) const; void writeDatabaseConfig(HdlPrinter &printer, ostream &out) const; void writeFilterConfig(HdlPrinter &printer, ostream &out) const; void writeParserConfig(HdlPrinter &printer, ostream &out) const; private: /// Not implemented. ConfigManager(const ConfigManager &); /// Not implemented. ConfigManager& operator=(const ConfigManager &); private: Ptr m_configFile; Ptr m_commandConfig; Ptr m_databaseConfig; Ptr m_filterConfig; Ptr m_parserConfig; }; #endif // _ConfigManager_h spamprobe-1.4d/src/spamprobe/Command_dump.cc0000664000076400007640000000716010527261701016143 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_dump.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_dump.h" Command_dump::Command_dump() : AbstractCommand("dump", "dump Prints some or all terms in database.", "dump [regex]\n" " Prints the contents of the word counts database one word per line\n" " in human readable format with spam probability, good count, spam\n" " count, flags, and word in columns separated by whitespace. PBL and\n" " Berkeley DB sort terms alphabetically. The standard unix sort\n" " command can be used to sort the terms as desired.\n" "\n" " Optionally you can specify a regular expression. If specified\n" " SpamProbe will only dump terms matching the regular expression.\n", true) { } void Command_dump::dumpWords(SpamFilter &filter, const string ®ex_str) { int good_message_count, spam_message_count; filter.getDB()->getMessageCounts(good_message_count, spam_message_count); const bool have_regex = regex_str.length() > 0; RegularExpression regex; if (have_regex) { regex.setExpression(regex_str); } string word; WordData counts; bool again = filter.getDB()->firstWord(word, counts); while (again) { if (!have_regex || regex.match(word)) { double score = filter.scoreTerm(counts.goodCount(), counts.spamCount(), good_message_count, spam_message_count); cout << scoreToString(score) << dec << setw(8) << counts.goodCount() << setw(8) << counts.spamCount() << " 0x" << setfill('0') << setw(8) << hex << counts.flags() << setfill(' ') << " " << word << "\n"; } again = filter.getDB()->nextWord(word, counts); } } bool Command_dump::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 0 || num_args == 1; } int Command_dump::execute(const ConfigManager &config, SpamFilter &filter) { openDatabase(config, filter); if (config.commandConfig()->numArgs() > 0) { dumpWords(filter, config.commandConfig()->arg(0)); } else { dumpWords(filter, EMPTY_STRING); } return 0; } spamprobe-1.4d/src/spamprobe/Command_edit_term.cc0000664000076400007640000000573410527261701017157 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_edit_term.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_edit_term.h" Command_edit_term::Command_edit_term() : AbstractCommand("edit-term", "edit-term Modifies counts for terms in database.", "edit-term term good_count spam_count\n" " Can be used to specifically set the good and spam counts of a term.\n" " Whether this is truly useful is doubtful but it is provided for\n" " completeness sake. For example it could be used to force a\n" " particular word to be very spammy or very good:\n" "\n" " spamprobe edit-term nigeria 0 1000000\n" " spamprobe edit-term burton 10000000 0\n", false) { } void Command_edit_term::editTerm(const ConfigManager &config, SpamFilter &filter) { const CommandConfig *cmd_config = config.commandConfig(); const string &term = cmd_config->arg(0); int good_count = atoi(cmd_config->arg(1).c_str()); int spam_count = atoi(cmd_config->arg(2).c_str()); if (is_debug) { cerr << "edit-term '" << term << "' gc " << good_count << " sc " << spam_count << endl; } filter.getDB()->setWordCounts(term, good_count, spam_count); } bool Command_edit_term::argsOK(const ConfigManager &config) { const CommandConfig *cmd_config = config.commandConfig(); const int num_args = cmd_config->numArgs(); return num_args == 3 && is_digits(cmd_config->arg(1)) && is_digits(cmd_config->arg(2)); } int Command_edit_term::execute(const ConfigManager &config, SpamFilter &filter) { assert(argsOK(config)); openDatabase(config, filter); editTerm(config, filter); return 0; } spamprobe-1.4d/src/spamprobe/Command_create_db.h0000664000076400007640000000271710527261701016753 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_create_db.h 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #ifndef _Command_create_db_h #define _Command_create_db_h #include "AbstractCommand.h" class Command_create_db : public AbstractCommand { public: Command_create_db(); bool argsOK(const ConfigManager &config); int execute(const ConfigManager &config, SpamFilter &filter); }; #endif // _Command_create_db_h spamprobe-1.4d/src/spamprobe/Command_purge_terms.cc0000664000076400007640000000552310527261701017533 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: Command_purge_terms.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include #include "WordData.h" #include "RegularExpression.h" #include "SpamFilter.h" #include "FrequencyDB.h" #include "CommandConfig.h" #include "ConfigManager.h" #include "SpamFilter.h" #include "Command_purge_terms.h" Command_purge_terms::Command_purge_terms() : AbstractCommand("purge-terms", "purge-terms Removes some or all terms from database.", "purge-terms regex\n" " Similar to purge except that it removes from the database all terms\n" " which match the specified regular expression. Be careful with this\n" " command because it could remove many more terms than you expect.\n" " Use dump with the same regex before running this command to see\n" " exactly what will be deleted.\n", false) { } void Command_purge_terms::purgeTerms(SpamFilter &filter, const string ®ex_str) { RegularExpression regex; regex.setExpression(regex_str); string word; WordData counts; bool again = filter.getDB()->firstWord(word, counts); while (again) { if (regex.match(word)) { filter.getDB()->removeWord(word, counts.goodCount(), counts.spamCount()); } again = filter.getDB()->nextWord(word, counts); } } bool Command_purge_terms::argsOK(const ConfigManager &config) { const int num_args = config.commandConfig()->numArgs(); return num_args == 1; } int Command_purge_terms::execute(const ConfigManager &config, SpamFilter &filter) { assert(argsOK(config)); openDatabase(config, filter); purgeTerms(filter, config.commandConfig()->arg(0)); return 0; } spamprobe-1.4d/src/spamprobe/Makefile.in0000664000076400007640000004213210527227200015270 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(spamprobe_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = spamprobe$(EXEEXT) subdir = src/spamprobe DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) am_spamprobe_OBJECTS = AbstractCommand.$(OBJEXT) \ AbstractFileCommand.$(OBJEXT) AbstractMessageCommand.$(OBJEXT) \ AutoPurger.$(OBJEXT) CommandConfig.$(OBJEXT) \ Command_auto_train.$(OBJEXT) Command_cleanup.$(OBJEXT) \ Command_counts.$(OBJEXT) Command_create_config.$(OBJEXT) \ Command_create_db.$(OBJEXT) Command_dump.$(OBJEXT) \ Command_edit_term.$(OBJEXT) Command_exec.$(OBJEXT) \ Command_export.$(OBJEXT) Command_help.$(OBJEXT) \ Command_import.$(OBJEXT) Command_print.$(OBJEXT) \ Command_purge.$(OBJEXT) Command_purge_terms.$(OBJEXT) \ Command_receive.$(OBJEXT) Command_remove.$(OBJEXT) \ Command_spam.$(OBJEXT) Command_summarize.$(OBJEXT) \ Command_tokenize.$(OBJEXT) Command_train_test.$(OBJEXT) \ ConfigManager.$(OBJEXT) FilterConfig.$(OBJEXT) \ SimpleTokenSelector.$(OBJEXT) SpamFilter.$(OBJEXT) \ spamprobe.$(OBJEXT) TokenSelector.$(OBJEXT) spamprobe_OBJECTS = $(am_spamprobe_OBJECTS) spamprobe_LDADD = $(LDADD) spamprobe_DEPENDENCIES = ../database/libdatabase.a \ ../parser/libparser.a ../hdl/libhdl.a ../input/libinput.a \ ../utility/libutility.a DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(spamprobe_SOURCES) DIST_SOURCES = $(spamprobe_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign LDADD = ../database/libdatabase.a ../parser/libparser.a ../hdl/libhdl.a ../input/libinput.a ../utility/libutility.a INCLUDES = -I@top_srcdir@/src/includes spamprobe_SOURCES = \ AbstractCommand.cc\ AbstractCommand.h\ AbstractFileCommand.cc\ AbstractFileCommand.h\ AbstractMessageCommand.cc\ AbstractMessageCommand.h\ AutoPurger.cc\ AutoPurger.h\ CommandConfig.cc\ CommandConfig.h\ Command_auto_train.cc\ Command_auto_train.h\ Command_cleanup.cc\ Command_cleanup.h\ Command_counts.cc\ Command_counts.h\ Command_create_config.cc\ Command_create_config.h\ Command_create_db.cc\ Command_create_db.h\ Command_dump.cc\ Command_dump.h\ Command_edit_term.cc\ Command_edit_term.h\ Command_exec.cc\ Command_exec.h\ Command_export.cc\ Command_export.h\ Command_help.cc\ Command_help.h\ Command_import.cc\ Command_import.h\ Command_print.cc\ Command_print.h\ Command_purge.cc\ Command_purge.h\ Command_purge_terms.cc\ Command_purge_terms.h\ Command_receive.cc\ Command_receive.h\ Command_remove.cc\ Command_remove.h\ Command_spam.cc\ Command_spam.h\ Command_summarize.cc\ Command_summarize.h\ Command_tokenize.cc\ Command_tokenize.h\ Command_train_test.cc\ Command_train_test.h\ ConfigManager.cc\ ConfigManager.h\ FilterConfig.cc\ FilterConfig.h\ SimpleTokenSelector.cc\ SimpleTokenSelector.h\ SpamFilter.cc\ SpamFilter.h\ spamprobe.cc\ TokenSelector.cc\ TokenSelector.h all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/spamprobe/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/spamprobe/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) spamprobe$(EXEEXT): $(spamprobe_OBJECTS) $(spamprobe_DEPENDENCIES) @rm -f spamprobe$(EXEEXT) $(CXXLINK) $(spamprobe_LDFLAGS) $(spamprobe_OBJECTS) $(spamprobe_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractFileCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractMessageCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AutoPurger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CommandConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_auto_train.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_cleanup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_counts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_create_config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_create_db.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_edit_term.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_exec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_export.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_help.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_import.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_print.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_purge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_purge_terms.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_receive.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_remove.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_spam.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_summarize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_tokenize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command_train_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FilterConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleTokenSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpamFilter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TokenSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spamprobe.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-binPROGRAMS install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-exec install-exec-am \ install-info install-info-am install-man install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/src/spamprobe/FilterConfig.cc0000664000076400007640000000417410527261701016115 00000000000000///###//////////////////////////////////////////////////////////////////////// // // Burton Computer Corporation // http://www.burton-computer.com // http://www.cooldevtools.com // $Id: FilterConfig.cc 272 2007-01-06 19:37:27Z brian $ // // Copyright (C) 2007 Burton Computer Corporation // ALL RIGHTS RESERVED // // This program is open source software; you can redistribute it // and/or modify it under the terms of the Q Public License (QPL) // version 1.0. Use of this software in whole or in part, including // linking it (modified or unmodified) into other programs is // subject to the terms of the QPL. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Q Public License for more details. // // You should have received a copy of the Q Public License // along with this program; see the file LICENSE.txt. If not, visit // the Burton Computer Corporation or CoolDevTools web site // QPL pages at: // // http://www.burton-computer.com/qpl.html // http://www.cooldevtools.com/qpl.html // #include "TokenSelector.h" #include "FilterConfig.h" FilterConfig::FilterConfig() : m_termsForScore(27), m_defaultMinWordCount(5), m_maxWordRepeats(2), m_extendTopTerms(false), m_newWordScore(0.3), m_minDistanceForScore(0.0), m_minArraySize(0), m_waterCounts(false), m_defaultThreshold(0.6) { setScoreMode(SCORE_NORMAL); m_tokenSelectors.push_back(make_ref(new TokenSelector())); } FilterConfig::~FilterConfig() { } void FilterConfig::setScoreMode(ScoreMode mode) { switch (mode) { case SCORE_ALT1: m_goodBias = 1; m_minWordCount = 1; m_spamThreshold = 0.6; break; case SCORE_ORIGINAL: m_goodBias = 2; m_minWordCount = m_defaultMinWordCount; m_spamThreshold = 0.9; break; default: assert(mode == SCORE_NORMAL); m_goodBias = 2; m_minWordCount = m_defaultMinWordCount; m_spamThreshold = m_defaultThreshold; break; } m_scoreMode = mode; } void FilterConfig::clearTokenSelectors() { m_tokenSelectors.clear(); } spamprobe-1.4d/missing0000775000076400007640000002405010526706577012064 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar ${1+"$@"} && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar ${1+"$@"} && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 spamprobe-1.4d/Makefile.am0000664000076400007640000000055010526706577012520 00000000000000AUTOMAKE_OPTIONS=foreign SUBDIRS=src EXTRA_DIST=\ ${man_MANS}\ LICENSE.txt\ README.txt\ contrib/README-maildrop.txt\ contrib/README-mta-mda-mua.txt\ contrib/spamprobe.el\ src/scripts/countscores.rb\ src/scripts/incrtest.rb\ src/scripts/multitest.sh\ src/scripts/runtest.sh\ src/scripts/splitmail.rb\ src/scripts/wordtests.sh man_MANS=spamprobe.1 spamprobe-1.4d/mkinstalldirs0000775000076400007640000000132510526706577013273 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.1 2002/10/15 21:31:00 bburton Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here spamprobe-1.4d/ChangeLog0000664000076400007640000015676110527262144012242 000000000000002006-11-16 Brian Burton * Released as 1.4d * configure.ac: Added ability to selectively disable image processing using --without-gif, --without-jpeg, and/or --without-png. * src/spamprobe/spamprobe.cc (set_headers): Added ability to selectively ignore individual headers using -H-headername. * src/includes/Ptr,Ref,Array.h: Restored missing include. * src/parser/PngParser.cc (tokenizeImage): added basic tokens from PNG images. 2006-11-16 Brian Burton * src/parser/PngParser.cc (PngParser): Stub for PNG parsing using libpng. * src/parser/JpegParser.cc (tokenizeMarker): Preliminary implementation of jpeg parsing using jpeglib. * configure.ac: Auto detect of either libungig or libgif depending on which one is available. 2007-01-04 Brian Burton * Released as 1.4c * spamprobe.1: Modified man page to remove unnecessary informaton and make it more conformant with man page conventions. * src/spamprobe/spamprobe.cc (process_extended_options): added ignore-body option. * src/parser/HeaderPrefixList.cc (HeaderPrefixList::addHeaderPrefix): Forced header prefixes and names to lower case instead of relying on an assert to enforce the restriction. * src/database/FrequencyDBImpl_hash.cc (hash::FrequencyDBImpl_hash): Disabled experimental hash database auto-cleaning. * src/includes/Ref.h: Removed cassert include. * src/spamprobe/spamprobe.cc (process_extended_options): Added whitelist option to allow use of SP as a bayesian white list in conjunction with other filters. 2006-02-17 Brian Burton * Released as 1.4b * src/parser/TraditionalMailMessageParser.cc (parseBody): Fixed bug reported by Jphn Chandler that prevented tokens from being extracted from headers of messages with no body. * src/input/SimpleMultiLineStringCharReader.cc (class SimpleMultiLineStringCharReaderPosition): Fixed crash bug reported by David Rosen when a missing base64 encoded body was parsed. 2006-01-30 Brian Burton * Released as 1.4a 2006-01-28 Brian Burton * src/includes/LRUCache.h (LRUCache): Reimplemented using STL list class. Map uses Node ptr as key to avoid having two copies of the key in memory. Changed iterators to use STL style syntax. * src/parser/PhrasingTokenizer.cc (compactChars): Improved efficiency. 2006-01-25 Brian Burton * src/parser/MimeDecoder.cc (next_char64): Fixed potential array bounds overflow bug in base64 decoding. Thanks to Chris Ross for the bug report. * src/spamprobe.cc: (and various other files) Added min_phrase_chars option that causes parser to keep adding tokens for phrases until they are at least min_phrase_chars long instead of stopping at phrase word limit. This might be useful for catching "v i a g r a" as a single term. So far though experiments with using this option are not very promising. * src/spamprobe/Command_auto_train.cc (execute): Added LOG sub-command to log each processed message to stdout along with whether or not it had been scored successfully prior to training. This is useful for experiments to determine how fast SP can learn. * src/spamprobe/Command_receive.cc (createScoreCommand): Fixed documentation bug and improved online help for score command. Thanks to Chris Ross for the bug report. 2006-01-03 Brian Burton * src/parser/MailMessage.cc (MailMessage): Removed redundant bounds check. * src/utility/MultiLineString.cc (line): Added bounds check. * src/parser/HtmlTokenizer.cc (tokenize): Added TempPtr to ensure reader and receiver are cleared between runs. * src/utility/MultiLineSubString.cc (m_target): Fixed boundary conditions if passed in indexes are outside bounds of target. 2005-12-28 Brian Burton * Released as 1.4. * src/includes/LRUPtrCache.h (LRUPtrCache): Fixed clear() bug that caused -P command line option to crash on some architectures due to an invalid delete. * src/database/FrequencyDBImpl_bdb.cc (openDatabase): Fixed relative path database opening bug in CDB mode. (Thanks to Nicolas Duboc for report and suggested fix). * src/spamprobe/AbstractCommand.cc (openDatabase): All non-read only commands will now create the database directory if it's missing when they open the database for the first time and the -c option was specified on the command line. * src/database/HashDataFile.cc (close): Replaced clear() with erase(). * src/spamprobe/Command_help.cc (printCommandLineOptions): Added comprehensive command line option help. * src/input/IstreamCharReader.cc (forward): Now uses rdbuf directly when reading characters and seeking to eliminate extra overhead of istream class. * src/spamprobe/spamprobe.cc (main): -V option now returns exit code 0 instead of 1. 2005-12-25 Brian Burton * src/database/FrequencyDBImpl_cache.cc (writeWord): Modified database cache to keep modified/unmodified terms within cache size limit. (flush): number of records written to disk per transaction limited to avoid problem with PBL using excessive amounts of memory to write a large cache to disk if the database is large. 2005-12-23 Brian Burton * src/database/DatabaseConfig.cc (createDatabaseImpl): Restored use of database cache. 2005-12-21 Brian Burton * src/includes/Ref.h (T>): Eliminated RefObject base class. 2005-12-18 Brian Burton * src/utility/util.cc (to_7bits): Removed use of string::+= * src/input/LineReader.cc (forward): Removed use of string::+= * src/utility/MultiLineString.cc (parseText): Fixed bug that caused each succeeding line in decoded text to contain all prior lines as well. Thanks to Nico for catching that one. (parseText): More efficient algorithm for breaking string into multiple lines without use of string::+= * src/input/SimpleMultiLineStringCharReader.cc (class SimpleMultiLineStringCharReaderPosition): Refactored code into position object. (ensureCharReady): Cached calls to m_target->line() based on profiler results showing they were consuming too much time during parsing. 2005-12-17 Brian Burton * src/parser/HtmlTokenizer.cc (processTagBody): Restored support for -o suspicious-tags option. * src/parser/HtmlTokenizer.cc (processTagBody): Added tag specific prefixes when parsing HTML tags. Left in the old prefix (U_) even though it collides with url terms for backward compatibility with people who used -h option. The compatibility code should be removed after a few months. 2005-12-16 Brian Burton * src/parser/MaildirMailMessageReader.cc (readMessage): Fixed skipping of hidden files and sorting of files in cur and new. 2005-12-15 Brian Burton * Released as 1.3x3. * Added support for maildir directories to all file based commands. 2005-12-13 Brian Burton * src/spamprobe/AbstractMessageCommand.cc (processStream): Improved auto-purge support to work for both token and mime streams and to perform a final purge after processing all messages. * src/spamprobe/Command_auto_train.cc (execute): Added support for auto-purge (-P command line option). 2005-12-11 Brian Burton * src/spamprobe/Command_create_config.cc (execute): Added create-config command to write a new config file based on the current configuration. * src/spamprobe/Command_create_db.cc (execute): Added create-db command to auto-create a database if none is present. * src/spamprobe/spamprobe.cc: Moved code from spamprobe.cc into separate strategy objects for each supported commands. * Added help command to print a list of all available commands and (optionally) also provide a verbose description of any named command. * Config file is not automatically generated if missing since that caused some confusion for users who don't use config files. 2005-12-09 Brian Burton * src/includes/Buffer.h (class Buffer): Added assertions and sanity checks. Made reset() exception safe. * src/spamprobe/SpamFilter.cc (getSortedTokens): Removed use of qsort(). Now sorting with std::sort(). * Removed unnecessary uses of NewArray. Now its only used by Buffer. * Removed old RCPtr in favor of new Ref. This affected lots of classes in all modules. 2005-12-02 Brian Burton * Changes below were actually made over the last few weeks but I'm catching up on previous changes that I hadn't added to ChangeLog. * Fixed include that didn't work with older gcc versions. * Added preliminary gif parser support using libungif. configure attempts to auto-detect libungif id present and uses it to extract terms from information about any gifs in the message. I used gifs first since those seem to be the most common format used in spams. * Added -f command line option. -d option reloads config file. * Moved spamprobe app code into its own directory. Added copyright notices to hdl source. * Restored deleted lock file code. * Added DatabaseConfig. * Added FilterConfig * Now generates config file if none present. * Spamprobe has a config file! * Added HDL code with validation. * Refactored source code into multiple directories and non-installed libraries for better code structure and organization. * Removed broken (never worked right) BNR code. * Removed obsolete data conversion utility left over from version 0.6 upgrade. 2005-06-23 Brian Burton * SimpleTokenizer.cc (isLetterChar): Fixed broken -8 command line option that was causing 8 bit characters to be treated as word boundaries. 2005-06-22 Brian Burton * Released version 1.2. 2005-03-29 Brian Burton * spamprobe.cc (cleanup_database): Added ability to specify multiple counts and ages for the cleanup command. This allows more efficient use of multiple criteria for cleaning the database. 2005-03-28 Brian Burton * FrequencyDBImpl_hash.h (class FrequencyDBImpl_hash): Changed default hash file size to 32 megs. * FrequencyDB.cc: SP now defaults to using hash data file format if neither PBL nor Berkeley DB are available. (createDB): Now auto-detects database type based on files in database directory if possible. * FrequencyDBImpl_null.h (class FrequencyDBImpl_null): Added "null" database instance to avoid null pointer issues when command line arguments are invalid. * spamprobe.cc (quick_close): removed code for closing the database since it created a race condition that could corrupt memory and crash out in ::delete. (main): changed usage/version printing again to avoid crashes when invalid command line used with -V option. 2005-03-26 Brian Burton * FrequencyDBImpl_hash.cc (initializeHeaderRecords): Added a header record to hash data files to identify file format and version. 2005-03-24 Brian Burton * spamprobe.cc: Applied usage message/version reporting fix supplied by Chris Ross. * FrequencyDBImpl_split.cc (open): Removed addition of .hash suffix to hash file name. The suffix is now added automatically by the FrequencyDBImpl_hash class. * FrequencyDBImpl_hash.cc: Lots of improvements such as hash collision detection and mitigation (tries next array element). Factored out hash file code into a new class (HashDataFile). Added code to rehash the file whenever cleanup is run. Hash data file size is now selectable in 1 MB increments instead of the old use of powers of two. Actual number of elements in hash table is now based on a prime number that yields as close to the target file size as possible. * FrequencyDB.cc: Changed hash: db prefix to use a pure hash file instead of a split file. Added split: prefix for when that is more desireable. 2004-11-19 Brian Burton * spamprobe.cc: Added verbose mode as a less overwhelming alternative to existing debug mode. Using -v once triggers verbose mode. Twice triggers debug mode. (auto_train): Added auto-train command to improve initial training for new users. 2004-11-13 Brian Burton * FrequencyDB.cc (class InterruptTest): Attempted to make shutdown due to user interrupts cleaner by using a guard object in each method that calls the database. If an interrupt is requested during a database operation it will be noted and an exception thrown after the call completes. Multiple interrupts will fall back to the default signal handler and shut down the process more forcefully. 2004-11-12 Brian Burton * README.txt: Fixed -s command line option doc. * spamprobe.1: Fixed -s command line option doc. * spamprobe.cc (process_mime_stream): Added support for -Y option to suppress content-length support in mailboxes. * MailMessageReader.cc (readMessage): Added support for MIME's Content-Length header as a way of bypassing embedded From_ lines inside of a message. Only supported in outermost headers since attachment bodies are already delimited using MIME boundaries. * MultiLineString.cc (appendToLastLine): Added ability to append to last line in string. * IstreamCharReader.cc (createMark): Added ability to mark and return when underlying stream is seekable. * spamprobe.cc (process_mime_stream): Added support for MBX file format. Added support for ignoring From_ line in mbox files. 2004-11-11 Brian Burton * Replaced uses of string::clear() with string::erase(). 2004-11-07 Brian Burton * MimeDecoder.cc (decodeHeaderString): Fixed memory bug. * Proximity phraser is history. It never performed well in experiments anyway. * All header terms are now prefixed instead of having some that did not receive a prefix. * Fully integrated new parser and removed code for old parser. All headers are now run through the MIME decoder since the RFC says the encoding can apply to more than just Subject. 2004-11-01 Brian Burton * FrequencyDBImpl_cache.cc; Cache size is now limited to a maximum number of terms and is automatically flushed when the size is exceeded. Uses LRUPtrCache instead of just a map so that the most recently used terms can be kept in memory instead of being periodically flushed. 2004-10-31 Brian Burton * Added new email parsing implementation based on the experimental C# implementation. This parser does less byte twiddling and parses most emails in a single pass over the message. Many of the old parsing related command line options are not yet enabled but the standard processing of mbox files and scoring with basic paramaters is working well. 2004-10-14 Brian Burton * spamprobe.cc (main): Added exec and exec-shared commands. (import_words): modified import command to allow negative values to be specified in the import file. * Applied patches for configure.in and aclocal.m4 contributed by Siggy Brentrup for debian compatibility. 2004-04-24 Brian Burton * FrequencyDBImpl_pbl.cc: Invokes new WordData methods to allow storing data in big endian format. * WordData.h: Added optional support for storing counts/flags in big endian order for data portability. 2004-02-05 Brian Burton * MimeLineReader.cc (readMBXFileHeader): UW IMAP MBX file format is now auto detected from the first line of the mailbox file. * spamprobe.cc (process_extended_options): Removed -o imap-mbx option. 2004-02-04 Brian Burton * spamprobe.cc (process_extended_options): Added -o imap-mbx option to process files as WU-IMAP MBX files rather than mbox files. * MimeLineReader.cc (readLine): Added support for WU-IMAP MBX file format. 2004-02-02 Brian Burton * Released as 0.9h. 2004-01-26 Brian Burton * spamprobe.cc (process_stream): Added -o tokenized option to allow people to use an external tokenizer with spamprobe. 2004-01-22 Brian Burton * SpamFilter.cc (scoreToken): Reduced sorting overhead by pre-computing and integer sort value with sorting priorities reflected in the value. This eliminates several calculations inside of the sort routine. 2004-01-21 Brian Burton * SpamFilter.cc (computeRatio): Capped ratios in calculations to within MIN_PROB and MAX_PROB. Widened that range. This avoids problems with div/0 and makes it easier to sort terms. 2004-01-20 Brian Burton * spamprobe.cc (dump_words): dump command can now optionally accept a regular expression as an argument and will only dump terms matching the regular expression. (purge_terms): Added purge-terms command to purge from the database all terms matching a regular expression. 2004-01-17 Brian Burton * Released as 0.9g2. * spamprobe.cc (main): Fixed bug in command line processing. Thanks to Jem for bug report. * Released as 0.9g. 2004-01-16 Brian Burton * spamprobe.cc (train_on_message): Code simplified. Eliminated redundant recalculation of scores. (train_on_message): Timestamps are now longer updated by train-spam and train-good commands. They are still updated by train command. (main): Fixed assertion if -P option is specified in a read only operation. 2004-01-14 Brian Burton * spamprobe.cc (main): Added -C command line option to allow users to specify their own min word count. * SpamFilter.cc (SpamFilter): Set default minimum word count back to 5 (was 3). * spamprobe.cc (process_extended_options): Removed "alt-score" from -o options list because it distributes scores poorly. New formula achieves the same end with better accuracy. Added "orig-score" option to allow people to continue using the old formula. Added "honor-xstatus-header" option for people whose mail server uses X-Status: rather than Status: for the deleted flag. (main): Added -l command line option to allow people to set their own spam threshold if they don't like the default value. * SpamFilter.cc (scoreMessage): Added a new scoring formula based on Paul's but taking the nth root of spam and good probabilities to produce more evenly distributed scores. Lowered the spam threshold to 0.6 to keep accuracy about the same as the original formula. Highest score seen for a ham so far in tests is 0.44 so 0.6 seems safe. Made the new formula the default instead of Paul's. 2004-01-12 Brian Burton * Released as 0.9f * spamprobe.cc (set_headers): Added -H+name command line option to allow users to specifically add inidividual headers to the list of headers to process. (process_extended_options): Added -o option with graham and honor-status-header options. 2004-01-09 Brian Burton * spamprobe.cc (edit_term): Removed validity check from edit term command since it made it impossible to edit terms from headers. (dump_message_words): Added "tokenize" command to allow a user to see all of the terms in a message and their scores. * What follows is a collection of changes not added here as they were made: * util.h (num_to_string3): Added function to produce a three digit zero padded number. * spamprobe.cc (train_on_message): Added option to have train mode try to keep the spam/good counts balanced to minimize skewing results towards whichever type we've seen the most. * SpamFilter.cc (SpamFilter): Improved "extended top terms array" logic to make the minimum distance from mean for the array settable by caller of SpamFilter. Added ability to set a minimum size for the top terms array. * RegularExpression.cc (removeMatch): Added method for removing a matched substring from the text. (replaceMatch): Added method for replacing a matched substring in the text. * PhraseBuilder.h (class PhraseBuilder): Added ability to limit the maximum length of a phrase so that the filter can use more words per phrase without filling the database (i.e. min 2 and max 8 words per phrase but limit phrases to max of 20 characters). * MessageFactory.cc (addIPAddressTerm): Added a new logical term for IP addresses found in a message. (isSuspiciousTag): Added support for processing just "suspicious" HTML tags (suggested by Paul Graham). (processUrls): Added special prefix for terms found in URLs. (addHeadersToMessage): Added support for processing arbitrary headers. * Message.cc (getAllTokensCount): Added AllTokensCount property (total within document count of all terms). * FrequencyDB.h (class FrequencyDB): Added MessageCount property. 2003-09-10 Brian Burton * Released as 0.9e. * spamprobe.cc (print_terms): Changed -T output to include overall good/spam database counts of each term. * SpamFilter.cc (token_qsort_criterion): Modified token sorting algorithm to improve selection of top terms for scoring. Changes appear to reduce the chances of false positives. The new criteria are: higher distance from mean to 5 decimal places, higher within document frequency div 3 (to make less selective), less spammy score, higher count in database, and (final tie break) alphabetical. The wdf div helps to make a small difference in wdf to be less significant. * MessageFactory.h (class MessageFactory): Added useProximityPhraser(). * ProximityPhraseBuilder.h: Added "proximity" phrase builder that stores distances between words instead of phrases themselves. Not nearly as effective as phrases so far. * AbstractPhraseBuilder.h: Added abstract super class for PhraseBuilder to allow plugging in different kinds of phrasers. 2003-09-04 Brian Burton * FrequencyDBImpl_pbl.cc (sweepOutOldTerms): Changed to commit based on number of records deleted instead of number of records scanned. (getWord): Changed to handle retrieval of current record properly. 2003-09-03 Brian Burton * FrequencyDBImpl_pbl.h (class FrequencyDBImpl_pbl): Peter Graf contributed a patch to switch over to using PBL's key files instead of ISAM. This change cuts disk space usage by a factor of 2 and seems to provide a comparable speed improvement as well. 2003-09-01 Brian Burton * FrequencyDBImpl_pbl.cc (beginTransaction): Fixed some broken assertions. * spamprobe.cc (train_test): Added train-test message to facilitate testing train mode. Reads a line at a time from stdin. Each line contains a message type (spam/good) and a file name. SP then reads the file and does a train-spam or train-good on the message. Great for quickly building a database from a lot of known emails using train mode. * Released as 0.9d. * Fixed configure to remove default -Wno-deprecated. 2003-08-30 Brian Burton * LockFD.h (class LockFD): Changed SHARED to SHARED_LOCK to fix compile problems on solaris 2.6. Thanks to Cornell Binder for bug report. * Released as 0.9c. * README.txt: Updated for release 0.9c. 2003-08-29 Brian Burton * FrequencyDBImpl_split.cc (open): Modified to be compatible with PBL in place of BDB for btree portion of database. * FrequencyDBImpl_cache.cc (flush): Performs all writes to it's impl db using a transaction for safety. Note that the cache itself does not support transactions but only utilizes it's impl's support for them (bug?). * FrequencyDB.h (class FrequencyDB): Added beginTransaction() and endTransaction() methods for impls that support transaction semantics (currently only PBL). Also added createDB() static method to allow other classes to create impl dbs without knowing what type they are creating. * FrequencyDBImpl.h (class FrequencyDBImpl): Added beginTransaction() and endTransaction() empty default implementations. * FrequencyDBImpl_pbl.h (class FrequencyDBImpl_pbl): Added support for Peter Graf's PBL (The Program Base Library) ISAM database as an optional replacement for Berkeley DB. PBL offers transaction semantics without all of the complicated background processing of BDB but none of the locking. Since SP does its own locking that should be fine. PBL files appear to be larger than BDB files by a significant margin. PBL can be downloaded here: http://mission.base.com/peter/source/ * FrequencyDBImpl_bdb.cc (writeWord): Any word with zero counts can now be deleted on write. Previously __* terms were kept but that's not really necessary and this will clear out redundant empty digests. * spamprobe.cc (quick_close): Fixed potential infinite loop when processing signals. * FrequencyDBImpl_bdb.cc: Improved error checking and reporting. Made use of environment a compile time option controlled by --enable-cdb passed to configure at build time. (writeWord): Removed load/compare of existing record to speed up writes to database except when in debug mode. (flush): Added call to db->sync() during flush(). 2003-08-23 Brian Burton * spamprobe.cc (process_test_cases): Added some more test cases. Changed AUTO_PURGE_JUNK_COUNT to 2 instead of 4. * SpamFilter.cc (token_qsort_criterion): When selecting top terms now assigns terms to "bands" of roughly 0.005% rather than sorting on raw probability. This helps to prevent almost equally significant good terms from being overshadowed and excluded by only slightly more significant spam terms and should reduce number of false positives. * PhraseBuilder.h (class PhraseBuilder): Dynamically resizes buffer now rather than using a fixed size buffer. Supports min as well as max number of words in phrases. * MimeMessageReader.cc (unquoteText): Now converts _ to space in quoted headers (thanks Junior for bug report!). * MimeHeader.cc (getFieldName): Added accessor for field names. * MessageFactory.cc (setMinPhraseLength): Phrases can now have a minimum length as well as a maximum length. (addHeadersToMessage): Improved header processing uses prefixes for all headers, not just a subset of them. Better recognition of ignored headers. (getHeaderPrefix): Creates a prefix for any header with escaping of non alphanumeric characters. (addHeaderToMessage): terms from headers are only stored with prefixes now instead of both prefixed and unprefixed. 2003-08-13 Brian Burton * MimeMessageReader.cc (unquoteText): Added RFC 1522 support for _ as space in headers. Thanks jxz. 2003-08-07 Brian Burton * Released as 0.9b. * MessageFactory.cc (addHeadersToMessage): Modifed header processing to decode RFC2047 encoded headers. Thanks to Junior for the suggestion! * MimeMessageReader.cc (decodeHeader): Added method for decoding mime encoded headers. * FrequencyDBImpl_bdb.cc (open): If berkeley db environment files cannot be opened but the database is running in read only mode we carry on without any environment. This allows shared database directories to be kept purely read only for users. * SpamFilter.cc (lock): locking now removes colon prefixes from database filenames when creating filename for lock file. This is done by nuking up to the last : so it will break windows paths that include a drive letter. 2003-08-02 Brian Burton * Released as 0.9a. 2003-08-01 Brian Burton * Modified FrequencyDBImpl to accept file mode as an argument and use that mode when creating database related files. This allows shared and private dbs to have different modes. 2003-07-29 Brian Burton * Added rebuilddb to contrib directory. This script from David A. Lee automatically rebuilds your .spamprobe directory to reclaim any space left unused by berkeley db. 2003-07-28 Brian Burton * FrequencyDBImpl_hash.cc (open): Removed obsolete reference to MAP_FILE because it broke compilation on solaris 9 systems. 2003-07-27 Brian Burton * Released as 0.9-dev-6. 2003-07-26 Brian Burton * SpamFilter.cc (lock): Global lock file only used for commands that write to the database. Using berkeley environment allows reads to coexist safely with writes. 2003-07-25 Brian Burton * FrequencyDB.cc (addWord): addWord() preserves flags if word already in database or sets them to specified value if the word is new. * FrequencyDBImpl_cache.cc (close): no longer flushes automatically. This allows SpamFilter to be closed quickly if necessary. Caller must now specifically flush() before closing. * SpamFilter.cc (close): SpamFilter now can be closed in flush mode or "abandon writes mode" so that cleanup code can avoid writes if the user interrupted the program with ^C or kill. * spamprobe.cc (close_on_exit): Added code to close database on exit to ensure that berkeley db gets a chance to remove its locks. Without this using ^C on one process could cause the next SP process to hang when it tried to write because the killed procs locks were still in the envronment (db_recover could be used to clear them but that's a pain). (import_words): import/export now include flags as well as counts for each word so that timestamps can be preserved. (train_on_message): Increased min message count for training from 500 to 1500 to help ensure sufficient number of messages for people using train from the beginning. * SpamFilter.cc (lock): Added locking code to SpamFilter to ensure locks are performed uniformly no matter what database is used. Databases can still perform their own locking if needed. This solved the weakness of berkeley db's concurrent data store locking when performing read-update-write of terms (lack of write locks while record being updated could cause counts to be incorrect even though database was not corrupted). * spamprobe.cc (main): Added -R option to return 0 if message was spam and 1 otherwise. Based on patch from jxz@uol.com.br. * FrequencyDBImpl_dbm.h: Removed locking code. Locks now at spamprobe.cc level. 2003-07-24 Brian Burton * FrequencyDBImpl_bdb.cc (open): removed lock file code and replaced it with use of a berkeley db environment and the berkeley db concurrent data store to provide more concurrency and better compatibility with other berkeley db routines. * RegularExpression.cc (class RegularExpressionImpl): Fixed (yet another) regexec() crash bug. Have to convert 8 bit chars to 7 bit before calling regexec() or it might crash on certain sequences of 8 bit characters. * Released as 0.9-dev-5 unstable package. * spamprobe.cc (main): Temporarily disabled shared (read only) locks in commands that used them as experiment to see if it eliminates database corruption in berkeley db databases. * MimeLineReader.cc: Using safe_char() to auto convert non-space control chars to spaces. 2003-06-29 Brian Burton * Added spamprobe-howto.html to contrib directory. Thanks to Herman Oosthuysen. * MessageFactory.cc (assignDigestToMessage): Added getMD5Digest() call to top of function to fix an assertion thrown when messages had digests in their headers. * spamprobe.cc (main): Added setlocale() call (thanks to Junior (don't know his name) for the suggestion) to fix tolower() problems with accented characters in eight bit mode. * FrequencyDBImpl_bdb.cc (writeWord): optimized writes to berkeley db databases. Deletes records when their counts were going to be written as zero to make purge 0 unnecessary. (sweepOutOldTerms): Added code to remove MD5 records if they have a count of zero. Removed code that wrote every record back to the database (left over from mark and sweep days) for better performance. 2003-05-20 Brian Burton * spamprobe.cc (main): Cleaned up version printing (-V). (main): summarize, find-good, and find-spam now print filename if processing a file instead of stdin. * FrequencyDBImpl_bdb.cc (open): Switched back to using a separate lock file for berkeley db databases to avoid a possible race condition. 2003-03-14 Brian Burton * FrequencyDBImpl_cache.cc: Added feedback about whether a term is from shared db to CacheEntry so that migration can be avoided if counts don't change. This prevents terms from moving into the private database if their time stamp changed but their counts did not as might happen when running in training mode. * FrequencyDBImpl_dual.cc (readWord): Added readWord() implementation that gives a hint about whether or not the counts came from the shared database. 2003-03-11 Brian Burton * FrequencyDBImpl_hash.cc (readWord): Fixed return value to allow proper operation with shared database. 2003-03-09 Brian Burton * Message.cc (addToken): Removed duplication when adding prefixed terms. Previously term was added both with and without prefix. Now only prefixed form is added. * spamprobe.cc (main): Fixed -V option. (train_on_message): Added current score test when training. train-spam and train-good now use existing digest if any. 2003-03-08 Brian Burton * FrequencyDBImpl_hash.cc (setSize): Changed from using mod prime to a bit mask for computing array indexes. Hash size can be specified as number of bits in the range 33-63. Half that number of bits will be used as a mask. The doubling allows file size to increase by smaller increments than doublings. The most reasonable hash values will be in the range 38 (4 MB) - 44 (32 MB). File sizes in this range are roughly: size megabytes terms 38 4 512k 39 6 768k 40 8 1024k 41 12 1536k (default) 42 16 2048k 43 24 3072k 44 32 4096k * spamprobe.cc (process_stream): Train mode now updates timestamps of terms in messages that don't need to be classified. This prevents terms that are actually being used to score messages from expiring. * FrequencyDB.cc (touchMessage): Added new method to update timestamp of terms in a message so that train commands can keep terms from expiring. 2003-03-03 Brian Burton * spamprobe.cc (process_stream): Added train, train-good, and train-spam commands for building database with a minimum number of emails for better performance and less disk usage. 2003-02-28 Brian Burton * MimeMessageReader.cc (readText): Fixed bug that caused rfc822 attachments to be treated as text rather than parsed into their own mime parts. As a result base64 encoded attachments in embedded messages wound up being tokenized rather than decoded or ignored based on their mimetype. * spamprobe.cc (main): Added support for combining multiple test cases on the command line. Added counts command to print out total message counts. * SpamFilter.cc: Cleaned up code for computing score to share more code. Fixed bug that ignored terms with wdf of 1. Added support for wdf to alt1 scoring method. CHanged spam threshold of alt1 method. 2003-02-26 Brian Burton * MessageFactory.cc (removeHTMLFromText): Added test for each tag to determine if it should add a space in its place. Previously text like: j
u
n would be treated as "jun" instead of "j u n". Prevents words from being combined if only space tags separated them. * configure.in: Added test for mmap. * MessageFactory.cc (addWordToMessage): Fixed bug that did not prefix word parts in prefixed headers. * spamprobe.cc (main): Added Received header to list of headers stored with a prefix. First Received header and subsequent ones stored with different prefix to maybe detect falsified received headers. First Received header should generally be more trustworthy since it comes from your own mail server rather than from the sending mail server or relay. (main): Added From header to list of headers stored with prefix since some spammers seem to use the same from line repeatedly - I guess they think we trust their "brand". * MessageFactory.cc (MessageFactory): Changed minimum word length to 1. * README.txt: Updated readme for -P option. * spamprobe.1 (Content-Length): updated manpage for -P option. * spamprobe.cc (main): Added -P command line option to automatically purge terms with total count <= 4 after specified number of messages. 2003-02-07 Brian Burton * Added new FrequencyDBImpl_hash class and made assorted changes to FrequencyDB and other impl classes to support it. The hash impl uses a fixed size array and Bob Jenkin's hash function to provide an efficient though somewhat inaccurate database. Based on the database structure in CRM114's mailfilter program. The impl supports all the semantics of the other impls including cleanup, dump, import, export, etc. 2003-02-06 Brian Burton * FrequencyDBImpl_bdb.cc (open): Modified berkeley db implementation to lock the actual database file instead of creating a separate lock file. This should work much more smoothly with shared databases than the lock file did. Chose not to use BDB's own locking environment because it seemed hard to get right and prone to lock ups. * LockFD.h (class LockFD): Added LockFD class to handle locking an arbitrary file descriptor. * LockFile.cc (lock): Changed LockFile to use a LockFD object instead of calling fcntl() directly. 2003-01-30 Brian Burton * Updated version of spamprobe.el from Dave Pearson's web site. * Added README-mta-mda-mua.txt graciously contributed by Anto Veldre. * MessageFactory.cc (removeHTMLFromText): replaces all whitespace with space characters to avoid wierd crash in regex routines on RedHat 8 systems. 2003-01-28 Brian Burton * spamprobe.cc (main): Added -M option to force a single message per file (ignores content-length and From). * Fixed manpage. * Changed lock file mode to 0666 instead of 0600 so that shared locks will work better. TODO: need to eliminate the need for the lock file altogether. 2002-12-29 Brian Burton * MessageFactory.cc (expandCharsInURL): Added decoding of %xx encoded characters in URLs. Using this to prevent spammers from slipping URLs through unchallenged by encoding them completely as hex. 2002-12-26 Brian Burton * spamprobe.cc (main): SpamProbe now stores words and phrases in the to, cc, and subject headers both normally and with a special prefix to improve accuracy since some words are spammier in the subject than in the message body. (main): Added -p option to limit number of words per phrase. * Released version 0.8 2002-11-12 Brian Burton * spamprobe.cc (classify_message): spam and good commands now count the words from messages multiple times if necessary to ensure that they are recalled correctly. receive command does not do this since it's decisions are not as reliable as manual ones. This is intended to improve overall accuracy by maximizing recall and making it harder for "spams of the future" to slip through the cracks because of their low word counts. 2002-10-28 Brian Burton * spamprobe.cc (import_words): Fixed broken import command. 2002-10-27 Brian Burton * spamprobe.cc (process_stream): Added summarize command to print find-good style output for every message whether good or spam. 2002-10-26 Brian Burton * MimeMessageReader.cc (readNextHeader): Uses inexact content length in case the mbox has incorrect content-length values. * spamprobe.cc (process_stream): score and receive now print message digest along with the score. (main): all commands except receive look for digest in X-SpamProbe header * MessageFactory.cc (assignDigestToMessage): message digest now taken from header if available. 2002-10-24 Brian Burton * spamprobe.cc (dump_words): flags now show all 8 digits in dump (process_stream): receive mode supports -T option 2002-10-22 Brian Burton * WordData.h (class WordData): Modified database to store a 16 bit time stamp (days since August 12, 2002) instead of using sweep count for database cleanup. 2002-10-20 Brian Burton * MessageFactory.cc (addTextToMessage): Removed the to_lower() to avoid unecessary string copying. Made regex's case insensitive so that they are not needed. * spamprobe.cc (import_words): Uses regular expression to parse import lines instead of hard coded logic. * configure.in: Added test to verify existence of regex.h on target system. * MimeHeader.cc (isFromLine): Uses regular expression to detect From lines instead of the hard coded scans. * RegularExpression.h (class RegularExpression): Added RegularExpression class as a front-end for POSIX regular expression library. * MessageFactory.cc: Uses regular expressions instead of hardcoded logic to detect html tags in pages and find urls inside of tags. * README.txt (including): Aded --enable-assert to configure script so that assertions are off by default but can still be enabled for debugging purposes. 2002-10-16 Brian Burton * spamprobe.1: Changed version to just 0.7 so I don't have to keep it up to date constantly. * contrib/spamprobe.el: Updated to latest version of spamprobe.el Thanks Dave! * spamprobe.cc (main): Added --enable-8bit option to configure script. 2002-10-15 Brian Burton * configure.in (have_database): Moved berkeleydb tests into a common spot. Added -ldb3 to the list of libraries to check. * Switched to autoconf generated Makefile instead of the manual one. The original makefile is now named Makefile.orig. * Moved md5 files out of thirdparty and into the top level directory. 2002-10-14 Brian Burton * countscores.rb (goods): Changed to accomodate change to score output. * spamprobe.cc (process_stream): score command prints in same format as receive command to simplify using it in procmailrc. (find_message): Prints subject of message to make output more human understandable. * SpamFilter.cc (normalScoreMessage): Fixed NAN bug if inner and outer both approx. 0. Returns 0.5 in that case to be safe. * spamprobe.cc (main): Added command name validation and support for shared locks for read only commands. Moved database lock acquisition into the FrequencyDBImpl classes. 2002-10-11 Brian Burton * FrequencyDBImpl_dual.h (class FrequencyDBImpl_dual): Added new database impl class that uses a shared read only database and a private read-write one. Also added -D option to program to allow user to specify the shared db dir and made numerous changes to other classes to put this new option into effect. * spamprobe.cc (main): Modified to process multiple mboxes much faster by opening and closing the database only once instead of once per file. * Released SpamProbe-0.7d * spamprobe.cc (main): Added purge and edit-term commands. * FrequencyDBImpl_bdb.cc (sweepOutJunk): Added purge mode. 2002-10-08 Brian Burton * FrequencyDB.h (class FrequencyDB, class FrequencyDBImpl*): added sweepOutJunk method for use by cleanup function. * spamprobe.cc (cleanup_database): Added cleanup command to do a mark and sweep database cleanup. * WordData.h (class WordData): Promoted WordData to its own class so that the cleanup function could be implemented. 2002-10-06 Brian Burton * MimeMessageReader.cc (getMD5Digest): Replaced sprintf call with hex_digit() util.cc function call. * spamprobe.cc (import_words): import and export now use the encode_string and decode_string functions from util.cc to properly handle non-printable characters. (main): Added -X option to rely almost exclusively on terms with distance from mean >= 0.4 and allow word repeats of 5 (equivalent to -w 5 -r 5 -x) 2002-10-02 Brian Burton * SpamFilter.cc (computeRatio): Fixed bug that returned word score of 0.5 for messages which had 0 in one count. Only happened if corresponding message count was also zero. * FrequencyDB.cc: Removed uses of message id as database key. * spamprobe.cc (dump_words): spamprobe dump now prints word probabilities in addition to counts. (main): Added -x command line option to allow top terms array to extend past size limit if there are more significant terms than can fit. 2002-09-20 Brian Burton * SpamFilter.cc (scoreMessage): Relaxed the maximum top terms array size limit to allow more terms to be used if their distance from the mean is at least 0.4. This way emails with many good and spam words get a more accurate evaluation since the good terms don't squeeze all of the spammy words out. Seems to yield a slight improvement on new, difficult spams without increasing false positives. 2002-09-19 Brian Burton * NewPtr.h (class NewPtr): Added NewPtr class to use in place of auto_ptr. I'd rather follow the standard but some older versions of g++ came with a broken auto_ptr. * FrequencyDBImpl_bdb.cc (open): Added #if condition to handle the gratuitous api change made by SleepyCat to the open() function. 2002-09-17 Brian Burton * Released 0.7b with better mbox support, domain name break down, and md5 digests for message identification. * spamprobe.cc (import_words): Changed constructor arguments as suggested by Xavier Nodet to work around problem with MSVC. (set_headers): Added -H none command line option to ignore headers when scoring a message. * FrequencyDB.cc and lots of other files: Added MD5 digest as unique identifier for emails instead of using message-id. For now message-id is still used if digest not found but eventually will remove it since digest is better identifier anyway. 2002-09-16 Brian Burton * SpamFilter.cc (scoreMessage): Added code to put top tokens into the Message object while scoring. * Message.h (class Message): Added code to store and retrieve top tokens. * spamprobe.cc (main): Added -T command line option to print top terms and their score and message count. * Tokenizer.cc (is_special_char): Removed ' from special chars since it seemed to hurt accuracy to include it. 2002-09-15 Brian Burton * MimeMessageReader.cc (readText): Content type is now returned with each text block so that it can be added to the token list. 2002-09-13 Brian Burton * MimeHeader.cc (isFromLine): Improved mbox reading logic by incorporating the From line format specification as defined in the qmail mbox man page. Tried to be a little flexible for flawed variations but still strict enough to not think a sentence starting with From is a new message. * MessageFactory.cc (addWordPartsToMessage): Now breaks tokens containing non-alnums into pieces adding each sub-word plus each suffix. This breaks host names down into their host and domain names. This seems to improve accurracy. * MimeHeader.cc (read): Added extra argument to control whether or not to allow the header to begin with a From_ line. This fixes a bug causing SP to miss some emails in mboxes if the preceeding email was multipart and did not have a terminator. * Released 0.7a with receive mode bug fix, solaris ctype functions bug fix, and better tokenizer. 2002-09-12 Brian Burton * Tokenizer.h (class Tokenizer): Changed tokenizing of text to involve less copying. * util.h: Added ctype front-end functions to work around problems on solaris with non-ascii chars. * MimeLineReader.cc (readLine): Rewrote loop to make it handle lines terminated by only CR as well as CR or CRLF. 2002-09-11 Brian Burton * MessageFactory.cc (addStringToMessage): Fixed bug that dropped 8 bit characters when m_replaceNonAsciiChars was false. * MimeLineReader.cc (readLine): Converts null bytes into spaces. * spamprobe.cc (import_words): Added import command to import terms previously saved using export command. 2002-09-10 Brian Burton * util.cc (is_all_digits): Added is_all_digits. * MessageFactory.cc (addWordToMessage): Fixed all digits token removal so that IP addresses are added as tokens. * MimeMessageReader.cc (readToBoundary): When reading messages from mboxes now honor content-length fields in the headers unless -Y option was specified. * FrequencyDBImpl_cache.h (class FrequencyDBImpl_cache): Added is_dirty flag to cache entries so that values that haven't changed don't get written to the database. * spamprobe.cc (main): Added -S command line option to allow messages per cache flush to be controlled from command line. Some other code cleanup as well. * FrequencyDBImpl_cache.h (class FrequencyDBImpl_cache): Added a caching proxy frequency db impl class that uses an STL map to cache term counts to reduce disk i/o at the expense of more cpu time and memory usage. * FrequencyDBImpl.h (class FrequencyDBImpl): Added an abstract base class for frequency db impls so that I could have a caching proxy. * SpamFilter.cc (token_qsort_criterion): Fixed incorrect sort order that put spammy words ahead of good words in the tie breaker. Also imposed a limit on the term count when sorting since counts above a certain number become basically identical. * FrequencyDB.h (class FrequencyDB): Modified to use an implementation class for all database access. This will make it easier to plug in new ones later. * FrequencyDBImpl_bdb.h (class FrequencyDBImpl): Added berkeley db based implementation class to isolate the rest of the code from the choice of database. This version uses btree files instead of hash for better performance, smaller file sizes, and sorted output during traversals. * FrequencyDBImpl_dbm.h (class FrequencyDBImpl): Added dbm based implementation class to isolate the rest of the code from the choice of database. * MessageFactory.cc (addWordToMessage): Fixed bug that allowed all digit tokens to slip in. 2002-09-07 Brian Burton * contrib/README-maildrop.txt: Added Matthias Andree's maildrop howto to the contrib directory. * MimeLineReader.cc (readLine): Fixed to properly handle null bytes in lines. Not that those are valid but bugged mailer sometimes embed them. 2002-09-06 Brian Burton * spamprobe.cc: added two new commands: dump and export. * SpamFilter.cc: Fixed a memory leak in scoreToken(). Converted to use only a single FrequencyDB now. Added an accessor to allow clients to get access to the db. Changed comparisons to zero to allow for inexact floating point differences. * FrequencyDB.cc: FrequencyDB modified to store both spam and good word counts for each word in a single dbm file. Added a pair of traveral functions for the export command. * util.h: Moved iostream inclusion into util.h. Also added cctype include there at Matthias Andree's suggestion for better gcc 3 compatibility. 2002-09-05 Brian Burton * FrequencyDB.h: Added hooks for switching to berkeley db in ndbm compatibility mode. GDBM does not scale well for large databases. Will continue to use GDBM until 0.7 but will switch over at that release. * util.h: Added using namespace std to avoid problems on modern C++ compilers. Thanks to Matthias Andree for bug report. * README.txt: Put in fix to procmail recipe. Thanks to Steven Grimm for bug report. * FrequencyDB.cc (removeMessage): Will not attempt to remove a message which has no message id. (addMessage): Will not attempt to add a message which has no message id. * MessageFactory.cc (initMessage): Fixed bug 604808 which caused messages with no message id to not have their bodies read. Thanks to Steven Grimm for bug report. * MimeMessageReader.cc (readText): Fixed potential bug which could incorrectly skip part of message body for non-multipart messages. * MessageFactory.cc (addWordToMessage): Allows leading $ in tokens. Ignores tokens consisting entirely of digits. 2002-09-03 Brian Burton * spamprobe.cc (set_headers): Removed obsolete test cases. (process_stream): Added find-spam and find-good commands. 2002-09-02 Brian Burton * Changed the use to string::find() == 0 to use a new inline function that used strncmp() for greater efficiency. * SpamFilter.cc (SpamFilter): Changed default scoring params to use top 27 words and max of 2 repeats. Found this to be a good option based on test runs with sample corpus. * spamprobe.cc (set_headers): Added -H command line option to control which headers are parsed to find tokens. 2002-08-30 Brian Burton * spamprobe.cc (main): Added -h command line option to retain html tags when generating tokens. * MessageFactory.cc (expandEntitiesInHtml): When not removing html we still expand any entities in the html. * SpamFilter.cc (token_qsort_criterion): Modified token sort criteria to favor good words over spammy ones if their distance from mean and counts are equal. * spamprobe.cc (process_test_case): Removed tune_1 test case. * MessageFactory.cc (MessageFactory): Changed default settings for better spam detection. * SpamFilter.cc (SpamFilter): Changed default settings for better spam detection. * MessageFactory.cc (initMessage): Scoring additional headers. Scoring subject header twice for extra emphasis. * MessageFactory.h: Made the scoring parameters setting member variables. * SpamFilter.h: Made the scoring parameters setting member variables. * MimeMessageReader.cc (readText): skips junk at end of message in mime multipart messages. Previously became confused by the extra junk and generated spurious scores for some messages which threw off accuracy. * Misc: Added scripts for testing accuracy of results. spamprobe-1.4d/Makefile.in0000664000076400007640000004647010527227200012522 00000000000000# Makefile.in generated by automake 1.9.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure ChangeLog \ depcomp install-sh missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign SUBDIRS = src EXTRA_DIST = \ ${man_MANS}\ LICENSE.txt\ README.txt\ contrib/README-maildrop.txt\ contrib/README-mta-mda-mua.txt\ contrib/spamprobe.el\ src/scripts/countscores.rb\ src/scripts/incrtest.rb\ src/scripts/multitest.sh\ src/scripts/runtest.sh\ src/scripts/splitmail.rb\ src/scripts/wordtests.sh man_MANS = spamprobe.1 all: all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) uninstall-info-am: install-man1: $(man1_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)" @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 1*) ;; \ *) ext='1' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ done uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 1*) ;; \ *) ext='1' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkdir_p) $(distdir)/contrib $(distdir)/src/scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(MANS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-man install-exec-am: install-info: install-info-recursive install-man: install-man1 installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-man uninstall-info: uninstall-info-recursive uninstall-man: uninstall-man1 .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-recursive ctags \ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \ dist-tarZ dist-zip distcheck distclean distclean-generic \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-man1 install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive \ mostlyclean mostlyclean-generic mostlyclean-recursive pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: spamprobe-1.4d/install-sh0000775000076400007640000001273610526706577012501 00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0