Main Page | Compound List | File List | Compound Members | File Members

SpamParameters.C

00001 
00002 /*
00003   This email filter was written by Ian Kaplan, Bear Products
00004   International.  It is copyrighted by Ian Kaplan, 2004,
00005   www.bearcave.com.
00006 
00007   You have permission to use this software without restriction on two
00008   conditions:
00009 
00010     1. You must preserve this copyright notice in this software and
00011        any software derived from it.
00012 
00013     2. You accept any risk entailed in using this software.  By
00014        using this software, you acknowledge that you have a
00015        sophisticated background in software engineering and 
00016        understand the way this software functions.  You further
00017        acknowledge that using this software may result in the
00018        irretrievable loss of important e-email and you alone
00019        are responsible for this loss.
00020 
00021   If either of these conditions are unacceptable, you may not use any
00022   part of this software.
00023 
00024  */
00025 
00026 #include <assert.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 
00030 #include <stdexcept>
00031 
00032 #include "SpamUtil.h"
00033 #include "Logger.h"
00034 #include "SpamParameters.h"
00035 
00036 using namespace std;
00037 
00038 const SpamParameters::enumTableElem SpamParameters::enumTable[] = {
00039   enumTableElem("to_list", to_list ),
00040   enumTableElem("from_address", from_address ),
00041   enumTableElem("from_kill", from_kill ),
00042   enumTableElem("spam_words", spam_words),
00043   enumTableElem("kill_words", kill_words ),
00044   enumTableElem("flags", flags),
00045   enumTableElem("my_domain", my_domain ),
00046   enumTableElem("valid_users", valid_users ),
00047 };
00048 
00049 vector<const char *> SpamParameters::section[(size_t)SpamParameters::SpamEnumMax];
00050 
00051 bool SpamParameters::initialized = false;
00052 
00058 bool SpamParameters::skipLine(const char *buf)
00059 {
00060   bool skipIt = false;
00061   char ch = *buf;
00062   if (ch == '\0' || ch == '#') {
00063     skipIt = true;
00064   }
00065   return skipIt;
00066 }  // skipLine
00067 
00072 SpamParameters::SpamEnum SpamParameters::findEnum(const char *str )
00073 {
00074   SpamEnum enumVal = SpamEnumMax;
00075   size_t tableSize = sizeof(enumTable) / sizeof(enumTableElem);
00076   for (size_t i = 0; i < tableSize; i++) {
00077     const char *enumName = enumTable[i].name;
00078     if (strcmp(str, enumName) == 0) {
00079       enumVal = enumTable[i].enumVal;
00080       break;
00081     }
00082   }
00083   return enumVal;
00084 } // findEnum
00085 
00086 
00091 void SpamParameters::enterPhrase(const char *buf)
00092 {
00093   size_t len = strlen( buf );
00094   char *storage = new char[ len + 1 ];
00095   SpamUtil().strncpy(storage, buf, len + 1);
00096   section[ (size_t)currentSection ].push_back( storage );
00097 } // enterPhrase
00098 
00099 
00106 void SpamParameters::finiteStateMachine( const char *buf )
00107   throw( SpamException )
00108 {
00109   paramState nextState = BadState;
00110   switch (currentState) {
00111   case sectionDef: 
00112     {
00113       SpamEnum sec = findEnum(buf);
00114       if (sec != SpamEnumMax) {
00115         currentSection = sec;
00116         nextState = beginBracket;
00117       }
00118       else {
00119         throw SpamException("finiteStateMachine: section defintion expected");
00120       }
00121     }
00122     break;
00123   case beginBracket:
00124     {
00125       if (*buf == '[') {
00126         nextState = spamPhrase;
00127       }
00128       else {
00129         throw SpamException("finiteStateMachine: '[' expected");
00130       }
00131     }
00132     break;
00133   case spamPhrase:
00134     {
00135       if (*buf == ']') {
00136         nextState = sectionDef;
00137       }
00138       else {
00139         enterPhrase( buf );
00140         nextState = spamPhrase;
00141       }
00142     }
00143     break;
00144   default: 
00145     {
00146       throw SpamException("finiteStateMachine: unexpected state");
00147     }
00148     break;
00149   } // switch
00150 
00151   currentState = nextState;
00152 } // finiteStateMachine
00153 
00154 
00158 void SpamParameters::print()
00159 {
00160   size_t tableSize = sizeof(enumTable) / sizeof(enumTableElem);
00161   for (size_t i = 0; i < tableSize; i++) {
00162     const char *name = enumTable[i].name;
00163     printf("%s\n", name );
00164     printf("[\n");
00165     vector<const char *> &vec = getSection( (SpamEnum)i );
00166     size_t len = vec.size();
00167     for (size_t j = 0; j < len; j++) {
00168       const char *ptr = vec[j];
00169       printf("   %s\n",  ptr );
00170     }
00171 
00172     printf("]\n");
00173   }  
00174 } // print
00175 
00176 
00177 
00182 vector<const char *> &SpamParameters::getSection( SpamEnum sec )
00183   throw( SpamException )
00184 {
00185   static vector<const char *> bogus;
00186   vector<const char *> &vec = bogus;
00187   if (sec < SpamEnumMax) {
00188     vec = section[ (size_t)sec ];
00189   }
00190   else {
00191     throw out_of_range("getSection: bad enumeration argument");
00192   }
00193   return vec;
00194 } // getSection
00195 
00196 
00201 bool SpamParameters::hasFlag(const char *name)
00202 {
00203   bool foundFlag = false;
00204   vector<const char *> flagVec = getSection( flags );
00205   size_t len = flagVec.size();
00206   for (size_t i = 0; i < len; i++) {
00207     if (strcmp(flagVec[i], name) == 0) {
00208       foundFlag = true;
00209       break;
00210     }
00211   }
00212   return foundFlag;
00213 } // hasFlag
00214 
00215 
00216 
00221 SpamParameters::~SpamParameters()
00222 {
00223   for (size_t i = 0; i < (size_t)SpamEnumMax; i++) {
00224     vector<const char *> oneSec = section[i];
00225     size_t len = oneSec.size();
00226     for (size_t j = 0; j < len; j++) {
00227       const char *ptr = oneSec[j];
00228       if (ptr != 0) {
00229         delete [] (char *)ptr;
00230       }
00231     }
00232   }
00233 } // SpamParameters destructor
00234 
00235 
00241 SpamParameters::SpamParameters()
00242 {
00243   assert( initialized );
00244 }
00245 
00250 SpamParameters::SpamParameters(const char *paramFileName )
00251   throw( SpamException )
00252 {
00253   currentState = sectionDef;
00254   currentSection = SpamEnumMax;
00255 
00256   const size_t BUF_SIZE = 1024;
00257   const char *mode = "r";
00258   FILE *file = fopen( paramFileName, mode );
00259   if (file != 0) {
00260     size_t lineNum = 0;
00261 
00262     char buf[BUF_SIZE];
00263     while (fgets(buf, sizeof(buf), file) != 0) {
00264       lineNum++;
00265       SpamUtil().trim(buf); // remove leading and trailing spaces
00266       if (!skipLine(buf)) {
00267         try {
00268           finiteStateMachine( buf );
00269         }
00270         catch (SpamException e) {
00271           static char msg[128];
00272           sprintf(msg, "%s, line %d", e.what(), lineNum );
00273           throw SpamException( msg );
00274         }
00275       }
00276     }  // while
00277     if (lineNum > 0) {
00278       Logger log = pLogger->getLogger("SpamParameters");
00279       log.log(Logger::DEBUG, "SpamParameters", "finished reading parameter file");
00280     }
00281     if (feof(file)) {
00282       fclose(file);
00283     }
00284     else {
00285       throw SpamException("SpamParameters::SpamParameters:error reading file");
00286     }
00287   }
00288   else { 
00289     throw SpamException("SpamParameters::SpamParameters: could not open parameter file");
00290   }
00291   initialized = true;
00292 } // SpamParameters

Generated on Sat Mar 27 13:07:38 2004 for Mail Filter by doxygen 1.3.3