You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2005/05/12 05:11:40 UTC

svn commit: r169750 - in /spamassassin/trunk: MANIFEST Makefile.PL spamc/configure spamc/configure.in spamc/spamc.c spamc/spamc.pod t/SATest.pm t/data/spamc_test.cf t/spamc_cf.t

Author: jm
Date: Wed May 11 20:11:39 2005
New Revision: 169750

URL: http://svn.apache.org/viewcvs?rev=169750&view=rev
Log:
bug 4153: spamc now supports reading its flags from a configuration file using the -F switch.  Thanks to John Madden <maddenj+spamassassin at skynet.ie>

Added:
    spamassassin/trunk/t/data/spamc_test.cf
    spamassassin/trunk/t/spamc_cf.t   (with props)
Modified:
    spamassassin/trunk/MANIFEST
    spamassassin/trunk/Makefile.PL
    spamassassin/trunk/spamc/configure
    spamassassin/trunk/spamc/configure.in
    spamassassin/trunk/spamc/spamc.c
    spamassassin/trunk/spamc/spamc.pod
    spamassassin/trunk/t/SATest.pm

Modified: spamassassin/trunk/MANIFEST
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/MANIFEST?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/MANIFEST (original)
+++ spamassassin/trunk/MANIFEST Wed May 11 20:11:39 2005
@@ -347,6 +347,7 @@
 t/data/whitelists/sf.net
 t/data/whitelists/winxpnews.com
 t/data/whitelists/yahoo-inc.com
+t/data/spamc_test.cf
 t/db_awl_path.t
 t/db_based_whitelist.t
 t/db_based_whitelist_ips.t
@@ -389,6 +390,7 @@
 t/spamc_E.t
 t/spamc_c.t
 t/spamc_c_stdout_closed.t
+t/spamc_cf.t
 t/spamc_l.t
 t/spamc_optC.t
 t/spamc_optL.t

Modified: spamassassin/trunk/Makefile.PL
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/Makefile.PL?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/Makefile.PL (original)
+++ spamassassin/trunk/Makefile.PL Wed May 11 20:11:39 2005
@@ -210,6 +210,7 @@
         'spamd/spamd',
 
         'spamc/spamc$(EXE_EXT)',
+        'spamc/spamc.h',
         'spamc/qmail-spamc$(EXE_EXT)',
         'spamc/*.o*', 'spamc/replace/*.o*',
         'spamc/*.so',

Modified: spamassassin/trunk/spamc/configure
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/spamc/configure?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/spamc/configure (original)
+++ spamassassin/trunk/spamc/configure Wed May 11 20:11:39 2005
@@ -943,7 +943,7 @@
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd $ac_popdir
+    cd "$ac_popdir"
   done
 fi
 
@@ -1874,8 +1874,7 @@
   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'
+	 { 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=$?
@@ -1933,8 +1932,7 @@
   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'
+	 { 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=$?
@@ -2050,8 +2048,7 @@
   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'
+	 { 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=$?
@@ -2105,8 +2102,7 @@
   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'
+	 { 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=$?
@@ -2151,8 +2147,7 @@
   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'
+	 { 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=$?
@@ -2196,8 +2191,7 @@
   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'
+	 { 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=$?
@@ -2528,8 +2522,7 @@
   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'
+	 { 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=$?
@@ -2699,8 +2692,7 @@
   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'
+	 { 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=$?
@@ -2771,8 +2763,7 @@
   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'
+	 { 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=$?
@@ -2925,8 +2916,7 @@
   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'
+	 { 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=$?
@@ -3078,8 +3068,7 @@
   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'
+	 { 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=$?
@@ -3270,8 +3259,7 @@
   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'
+	 { 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=$?
@@ -3334,8 +3322,7 @@
   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'
+	 { 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=$?
@@ -3400,8 +3387,7 @@
   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'
+	 { 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=$?
@@ -3504,8 +3490,7 @@
   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'
+	 { 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=$?
@@ -3571,8 +3556,7 @@
   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'
+	 { 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=$?
@@ -3643,8 +3627,7 @@
   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'
+	 { 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=$?
@@ -3720,8 +3703,7 @@
   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'
+	 { 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=$?
@@ -3788,8 +3770,7 @@
   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'
+	 { 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=$?
@@ -3872,8 +3853,7 @@
   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'
+	 { 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=$?
@@ -3946,8 +3926,7 @@
   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'
+	 { 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=$?
@@ -4020,8 +3999,7 @@
   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'
+	 { 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=$?
@@ -4130,8 +4108,7 @@
   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'
+	 { 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=$?
@@ -4195,8 +4172,7 @@
   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'
+	 { 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=$?
@@ -4258,8 +4234,7 @@
   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'
+	 { 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=$?
@@ -4322,8 +4297,7 @@
   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'
+	 { 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=$?
@@ -4380,8 +4354,7 @@
   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'
+	 { 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=$?
@@ -4448,8 +4421,7 @@
   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'
+	 { 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=$?
@@ -4514,8 +4486,7 @@
   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'
+	 { 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=$?
@@ -4559,6 +4530,8 @@
 
           ac_config_files="$ac_config_files Makefile"
 
+          ac_config_files="$ac_config_files spamc.h"
+
 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
@@ -5084,6 +5057,7 @@
   case "$ac_config_target" in
   # Handling of arguments.
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "spamc.h" ) CONFIG_FILES="$CONFIG_FILES spamc.h" ;;
   "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@ -5347,11 +5321,6 @@
 
 
 
-  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.  */
@@ -5390,6 +5359,12 @@
 	 fi;;
       esac
     done` || { (exit 1); exit 1; }
+
+  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
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub

Modified: spamassassin/trunk/spamc/configure.in
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/spamc/configure.in?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/spamc/configure.in (original)
+++ spamassassin/trunk/spamc/configure.in Wed May 11 20:11:39 2005
@@ -160,4 +160,5 @@
 AC_SUBST(HAVE_SHUT_RD)
 
 AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([spamc.h])
 AC_OUTPUT

Modified: spamassassin/trunk/spamc/spamc.c
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/spamc/spamc.c?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/spamc/spamc.c (original)
+++ spamassassin/trunk/spamc/spamc.c Wed May 11 20:11:39 2005
@@ -19,10 +19,13 @@
 #include "version.h"
 #include "libspamc.h"
 #include "utils.h"
+#include "spamc.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <ctype.h>
 
 #ifdef _WIN32
 #include <io.h>
@@ -134,6 +137,7 @@
 #ifndef _WIN32
     usg("  -U path             Connect to spamd via UNIX domain sockets.\n");
 #endif
+    usg("  -F path             Use this configuration file.\n");
     usg("  -t timeout          Timeout in seconds for communications to\n"
         "                      spamd. [default: 600]\n");
     usg("  -s size             Specify maximum message size, in bytes.\n"
@@ -184,9 +188,9 @@
           struct transport *ptrn)
 {
 #ifndef _WIN32
-    const char *opts = "-BcrRd:e:fyp:t:s:u:L:C:xSHU:ElhV";
+    const char *opts = "-BcrRd:e:fyp:t:s:u:L:C:xSHU:ElhVF:";
 #else
-    const char *opts = "-BcrRd:fyp:t:s:u:L:C:xSHElhV";
+    const char *opts = "-BcrRd:fyp:t:s:u:L:C:xSHElhVF:";
 #endif
     int opt;
     int ret = EX_OK;
@@ -387,6 +391,132 @@
     return ret;
 }
 
+/* find_config()
+ *
+ * looks for the config file in default locations as well as
+ * ${prefix}/etc
+ *
+ * return config path if found, NULL if not, or if there's an error
+ */
+char *find_config(char *prefix) {
+   struct stat buf;
+   char *config_path = NULL;
+
+   if((strncasecmp(prefix, "/usr", 4)) == 0) {
+      if((config_path = (char *)malloc(32)) != NULL) {
+         strcat(config_path, "/etc/mail/spamassassin/spamc.conf");
+      } else {
+         libspamc_log(flags, LOG_ERR, 
+           "Out of memory while searching for config file");
+         return NULL;
+      }
+
+      if((stat(config_path, &buf) < 0) || (!(S_ISREG(buf.st_mode)))) {
+         config_path = NULL;
+      } else {
+         return(config_path);
+      }
+   } else if((strncasecmp(prefix, "/opt", 4)) == 0) {
+      if((config_path = (char *)malloc(38)) != NULL) {
+         strcat(config_path, "/etc/opt/mail/spamassassin/spamc.conf");
+      } else {
+         libspamc_log(flags, LOG_ERR,
+           "Out of memory while searching for config file");
+         return NULL;
+      }
+
+      if((stat(config_path, &buf) < 0) || (!(S_ISREG(buf.st_mode)))) {
+         config_path = NULL;
+      } else {
+         return(config_path);
+      }
+   }
+
+   if(config_path == NULL) {
+      if((config_path = (char *)malloc(strlen(prefix)+16)) != NULL) {
+         strcat(config_path, prefix);
+         strcat(config_path, "/etc/spamc.conf");
+      } else {
+         libspamc_log(flags, LOG_ERR,
+           "Out of memory while searching for config file");
+         return NULL;
+      }
+
+      if((stat(config_path, &buf) < 0) || (!(S_ISREG(buf.st_mode)))) {
+         config_path = NULL;
+      } else {
+         return(config_path);
+      }
+   }
+   return NULL; // if we get to here, it hasn't been found
+}
+
+/* combine_args() :: parses spamc.conf for options, and combines those
+ * with options passed via command line
+ *
+ * lines beginning with # or blank lines are ignored
+ *
+ * returns EX_OK on success, EX_CONFIG on failure
+ */
+int combine_args(char *prefix, char *config_file, 
+      int argc, char **argv, int *combo_argc, char **combo_argv) {
+   FILE *config;
+   char option[100];
+   int i, count = 0;
+   char *tok = NULL;
+
+   if(config_file == NULL) {
+      // look for the file 
+      if((config_file = find_config(prefix)) == NULL)
+         return EX_CONFIG;
+   }
+
+   if((config = fopen(config_file, "r")) == NULL) {
+      libspamc_log(flags, LOG_ERR,
+        "Cannot open %s : %s", config_file, strerror(errno));
+      return EX_CONFIG;
+   }
+
+   while(!(feof(config)) && (fgets(option, 100, config))) {
+
+      count++; // increment the line counter
+
+      if(option[0] == '#' || option[0] == '\n')
+         continue;
+
+      tok = option;
+      while((tok = strtok(tok, " "))) {
+         for(i=strlen(tok); i>0; i--) {
+            if(tok[i] == '\n')
+               tok[i] = '\0';
+         }
+         if((combo_argv[*combo_argc] = 
+                  (char *)malloc(strlen(tok)+1)) == NULL) {
+            libspamc_log(flags, LOG_ERR,
+              "Error allocating memory for option \"%s\" in %s line %d", 
+              tok, config_file, count);
+            continue;
+         }
+         strcpy(combo_argv[*combo_argc], tok);
+         tok = NULL;
+         *combo_argc+=1;
+      }
+   }
+   for(i=0; i<argc; i++) {
+      if((combo_argv[*combo_argc] =
+               (char *)malloc(strlen(argv[i]+1))) == NULL) {
+         libspamc_log(flags, LOG_ERR,
+           "Error allocating memory for command line option \"%s\"",
+           argv[i]);
+         continue;
+      } else {
+         strcpy(combo_argv[*combo_argc], argv[i]);
+         *combo_argc+=1;
+      }
+   }
+   return EX_OK;
+}
+
 void
 get_output_fd(int *fd)
 {
@@ -527,6 +657,15 @@
     int islearned = 0;
     int isreported = 0;
 
+    /* these are to hold CLI and config options combined, to be passed
+     * to read_args() */
+    char *combo_argv[24];
+    int combo_argc;
+
+    int i;
+    char *config_file = CONFIG_FILE;
+    char *prefix = PREFIX;
+
     transport_init(&trans);
 
 #ifdef LIBSPAMC_UNIT_TESTS
@@ -539,13 +678,40 @@
     signal(SIGPIPE, SIG_IGN);
 #endif
 
-   /* Now parse the command line arguments. First, set the defaults. */
+   /* set some defaults */
    max_size = 250 * 1024;
    username = NULL;
-   if ((ret = read_args(argc, argv, &max_size, &username, &extratype, &trans)) != EX_OK) {
-       if (ret == EX_TEMPFAIL )
-           ret = EX_OK;
-       goto finish;
+   if(strncasecmp(config_file, "${prefix}", 9) == 0)
+      config_file = NULL;
+
+   combo_argc = 1;
+   if((combo_argv[0] = (char *)malloc(strlen(argv[0]))) != NULL)
+      strcpy(combo_argv[0], argv[0]);
+
+   for(i=0; i<argc; i++) {
+      if(strncmp(argv[i], "-F", 2) == 0) {
+         config_file = argv[i+1];
+         break;
+      }
+   }
+
+   if((combine_args(prefix, config_file, argc, argv, 
+               &combo_argc, combo_argv)) != EX_OK) {
+      /* parse only command line arguments (default behaviour) */
+      if((ret = read_args(argc, argv, &max_size, &username, 
+                  &extratype, &trans)) != EX_OK) {
+         if(ret == EX_TEMPFAIL)
+            ret = EX_OK;
+         goto finish;
+      }
+   } else {
+   /* Parse the combined arguments of command line and config file */
+      if ((ret = read_args(combo_argc, combo_argv, &max_size, &username, 
+                  &extratype, &trans)) != EX_OK) {
+          if (ret == EX_TEMPFAIL)
+              ret = EX_OK;
+          goto finish;
+      }
    }
 
    ret = get_current_user(&username);

Modified: spamassassin/trunk/spamc/spamc.pod
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/spamc/spamc.pod?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/spamc/spamc.pod (original)
+++ spamassassin/trunk/spamc/spamc.pod Wed May 11 20:11:39 2005
@@ -41,6 +41,18 @@
 
 =head1 OPTIONS
 
+All options detailed below can be passed as command line arguments, or
+be contained in a configuration file. The layout of the configuration
+file is :
+
+B<[option]> B<(value)>
+
+B<(value)> is required for any options that require an argument.
+Whitespace and new lines delimit the options. Blank lines, and lines
+beginning with a '#' are ignored.
+
+See F<spamc/spamc.conf> for a sample configuration file.
+
 =over
 
 =item B<-B>
@@ -178,6 +190,104 @@
 
 Just output the names of the tests hit to stdout, on one line, separated
 by commas.
+
+=back
+
+=head1 CONFIGURATION PARAMETERS
+
+=over
+
+=item B<Host>
+
+Set the hostname for the spamd daemon that spamc should connect to. This 
+option, and the F<Socket> option are mutually exclusive, and only the first 
+listed in the configuration file will be used.
+
+Default : C<localhost>.
+
+Valid options : server DNS name (server.tld) or IP address.
+
+=item B<Port>
+
+Set the port that the spamd daemon is running on. 
+
+Default : C<783>.
+
+Valid options : an integer less than or equal to 65535
+
+=item B<Socket>
+
+Set the path to the unix domain socket to use to connect to spamd. This
+option and the F<Host> option are mutually exclusive, and only the first
+listed in the configuration file will be used. 
+
+Default : don't use unix domain sockets.
+
+Valid options : /path/to/socket
+
+=item B<User>
+
+Set the user that spamc should run as. 
+
+Default : user running spamc.
+
+Valid options : any user on the system
+
+=item B<Max-Size>
+
+Set the maximum message size (in bytes). 
+
+Default : C<256000> bytes.
+
+Valid options : an integer size for the message in bytes
+
+=item B<UseSSL>
+
+Turn on or off whether to use SSL when connecting to spamd. 
+
+Default : C<off>.
+
+Valid options : C<yes> / C<on> or C<no> / C<off>
+
+=item B<Timeout>
+
+Set the timeout (in seconds) for connecting to spamd. 
+
+Default : C<600>.
+
+Valid options : an integer
+
+=item B<BSMTP>
+
+Assume input is a single BSMTP formatted message. 
+
+Default : C<off>.
+
+Valid options : C<yes> / C<on> or C<no> / C<off>
+
+=item B<Fallback>
+
+Turn on or off safe fallback.
+
+Default : C<on>
+
+Valid options : C<yes> / C<on> or C<no> / C<off>
+
+=item B<Randomize>
+
+Turn on or off whether to randomize IP addresses for looked-up hostname.
+
+Default : C<off>
+
+Valid options : C<yes> / C<on> or C<no> / C<off>
+
+=item B<LogSTDERR>
+
+Log errors and warnings to stderr.
+
+Default : C<off>
+
+Valid options : C<yes> / C<on> or C<no> / C<off>
 
 =back
 

Modified: spamassassin/trunk/t/SATest.pm
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/t/SATest.pm?rev=169750&r1=169749&r2=169750&view=diff
==============================================================================
--- spamassassin/trunk/t/SATest.pm (original)
+++ spamassassin/trunk/t/SATest.pm Wed May 11 20:11:39 2005
@@ -290,7 +290,7 @@
   }
 
   my $spamcargs;
-  if($args !~ /\b(?:-p\s*[0-9]+|-U)\b/)
+  if($args !~ /\b(?:-p\s*[0-9]+|-F|-U)\b/)
   {
     $spamcargs = "$spamc -d $spamdhost -p $spamdport $args";
   }

Added: spamassassin/trunk/t/data/spamc_test.cf
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/t/data/spamc_test.cf?rev=169750&view=auto
==============================================================================
--- spamassassin/trunk/t/data/spamc_test.cf (added)
+++ spamassassin/trunk/t/data/spamc_test.cf Wed May 11 20:11:39 2005
@@ -0,0 +1 @@
+-U log/spamd.sock

Added: spamassassin/trunk/t/spamc_cf.t
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/t/spamc_cf.t?rev=169750&view=auto
==============================================================================
--- spamassassin/trunk/t/spamc_cf.t (added)
+++ spamassassin/trunk/t/spamc_cf.t Wed May 11 20:11:39 2005
@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+
+use lib '.'; use lib 't';
+use SATest; sa_t_init("spamc_cf");
+use Test; plan tests => ($SKIP_SPAMC_TESTS ? 0 : 4);
+
+exit if $SKIP_SPAMC_TESTS;
+
+# ---------------------------------------------------------------------------
+
+%patterns = (
+
+q{ Subject: There yours for FREE!}, 'subj',
+q{ X-Spam-Status: Yes, score=}, 'status',
+q{ X-Spam-Flag: YES}, 'flag',
+
+
+);
+
+start_spamd("-D -L --socketpath=log/spamd.sock");
+ok (spamcrun ("-F data/spamc_test.cf < data/spam/001", \&patterns_run_cb));
+ok_all_patterns();
+stop_spamd();
+

Propchange: spamassassin/trunk/t/spamc_cf.t
------------------------------------------------------------------------------
    svn:executable = *