[cvs] bogofilter config.c,NONE,1.1
Fast Bayesian spam filter along lines suggested by Paul Graham
Brought to you by:
m-a
From: <re...@us...> - 2002-10-30 17:25:15
|
Update of /cvsroot/bogofilter/bogofilter In directory usw-pr-cvs1:/tmp/cvs-serv11615 Added Files: config.c Log Message: Initial release of config file capability. --- NEW FILE: config.c --- /* $Id: config.c,v 1.1 2002/10/30 17:25:10 relson Exp $ */ /***************************************************************************** NAME: config.c -- process config file parameters AUTHOR: David Relson <re...@os...> ******************************************************************************/ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "config.h" #include "common.h" #include "debug.h" #include "wordlists.h" #include "xmalloc.h" #include "xstrdup.h" #ifndef DEBUG_CONFIG #define DEBUG_CONFIG(level) (verbose > level) #endif /*---------------------------------------------------------------------------*/ // Global variables extern int verbose; extern int thresh_index; extern double thresh_stats; extern double thresh_rtable; extern char *spam_header_name; /*---------------------------------------------------------------------------*/ #define MAXBUFFLEN 200 typedef enum { CP_INTEGER, CP_DOUBLE, CP_STRING, CP_WORDLIST, } ArgType; typedef struct { const char *name; ArgType type; union { int *i; double *d; char **s; } addr; } ArgDefinition; ArgDefinition ArgDefList[] = { { "thresh_index", CP_INTEGER, { (void *) &thresh_index } }, { "thresh_rtable", CP_DOUBLE, { (void *) &thresh_rtable } }, { "thresh_stats", CP_DOUBLE, { (void *) &thresh_stats } }, { "spam_header_name",CP_STRING, { (void *) &spam_header_name } }, { "wordlist", CP_WORDLIST, { (void *) NULL } }, }; int ArgDefListSize = sizeof(ArgDefList)/sizeof(ArgDefList[0]); bool process_config_parameter( ArgDefinition * arg, const char *val) { bool ok = TRUE; while (isspace(*val) || *val == '=') val += 1; switch (arg->type) { case CP_INTEGER: { int sign = (*val == '-') ? -1 : 1; if (*val == '-' || *val == '+') val += 1; *arg->addr.i = atoi(val) * sign; if (DEBUG_CONFIG(0)) fprintf( stderr, "%s -> %d\n", arg->name, *arg->addr.i ); break; } case CP_DOUBLE: { double sign = (*val == '-') ? -1.0f : 1.0f; if (*val == '-' || *val == '+') val += 1; *arg->addr.d = atof(val) * sign; if (DEBUG_CONFIG(0)) fprintf( stderr, "%s -> %f\n", arg->name, *arg->addr.d ); break; } case CP_STRING: { *arg->addr.s = xstrdup( (char *) val ); if (DEBUG_CONFIG(0)) fprintf( stderr, "%s -> '%s'\n", arg->name, *arg->addr.s ); break; } case CP_WORDLIST: { configure_wordlist(val); break; } default: { ok = FALSE; fprintf( stderr, "Unknown parameter type for '%s'\n", arg->name ); break; } } return ok; } bool process_config_line( const char *line ) { int i; int len; const char *val; for (val=line; *val != '\0'; val += 1) if (isspace(*val) || *val == '=' ) break; len = val - line; for (i=0; i<ArgDefListSize; i += 1) { ArgDefinition *arg = &ArgDefList[i]; if (strncmp(arg->name, line, len) == 0) { bool ok = process_config_parameter(arg, val); return ok; } } return FALSE; } void read_config_file(const char *filename) { bool error = FALSE; int lineno = 0; char *tmp = NULL; FILE *fp; if ( *filename == '~' ) { char *home = getenv( "HOME" ); if ( home == NULL ) { fprintf( stderr, "Can't find $HOME.\n" ); exit(2); } tmp = xmalloc(strlen(home) + strlen(filename) + 2); strcpy( tmp, home ); if (tmp[strlen(tmp)-1] != '/' ) strcat( tmp, "/" ); while (*filename == '~' || *filename == '/') filename += 1; strcat( tmp, filename ); filename = tmp; } fp = fopen( filename, "r"); if (fp == NULL) return; if (DEBUG_CONFIG(0)) fprintf( stderr, "Reading %s\n", filename ); while (!feof(fp)) { int len; char buff[MAXBUFFLEN]; lineno += 1; if (fgets(buff, sizeof(buff), fp) == NULL) break; len = strlen(buff); if ( buff[0] == '#' || buff[0] == ';' || buff[0] == '\n' ) continue; while (iscntrl(buff[len-1])) buff[--len] = '\0'; if ( ! process_config_line( buff )) { fprintf( stderr, "Unknown config line #%d\n", lineno ); fprintf( stderr, " %s\n", buff ); error = TRUE; } } fclose(fp); if (error) exit(2); } #ifdef MAIN int verbose = 0; int thresh_index = 1; double thresh_prob = 0.2f; // EVEN_ODDS double thresh_rtable=0.3f; char *spam_header_name = "X-Bogosity"; int main( int argc, char **argv) { while (--argc > 0) { char *arg = *++argv; if (strcmp(arg, "-v") == 0) verbose = 1; } read_config_file( "/etc/bogofilter.cf" ); read_config_file( "./bogofilter.cf" ); read_config_file( "~/.bogofilter.cf" ); return 0; } int init_list(wordlist_t* list, const char* name, const char* filepath, double weight, bool bad, int override, bool ignore) { if (DEBUG_CONFIG(0)) { fprintf( stderr, "list: %p\n", list); fprintf( stderr, "name: %s\n", name); fprintf( stderr, "filepath: %s\n", filepath); fprintf( stderr, "weight: %f\n", weight); fprintf( stderr, "bad: %s\n", bad ? "T" : "F" ); fprintf( stderr, "override: %d\n", override); fprintf( stderr, "ignore: %s\n", ignore ? "T" : "F" ); } return 0; } #endif |