diff options
author | Ian C <ianc@noddybox.co.uk> | 2003-12-07 01:46:44 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2003-12-07 01:46:44 +0000 |
commit | 787bb7625c9abc6b09efbc6bbe004a19d4b96166 (patch) | |
tree | 87b38cae639ced0b5a705a3d1e45d977ea419756 /src | |
parent | f1658930db64af8fecff9c8697592f676114409c (diff) |
Made RE compiled once and added memory release
Diffstat (limited to 'src')
-rw-r--r-- | src/config.c | 40 | ||||
-rw-r--r-- | src/config.h | 6 | ||||
-rw-r--r-- | src/dbase.c | 136 | ||||
-rw-r--r-- | src/dbase.h | 26 | ||||
-rw-r--r-- | src/kbs.c | 8 | ||||
-rw-r--r-- | src/rexp.c | 33 | ||||
-rw-r--r-- | src/rexp.h | 21 |
7 files changed, 202 insertions, 68 deletions
diff --git a/src/config.c b/src/config.c index 18d7cfd..616fabf 100644 --- a/src/config.c +++ b/src/config.c @@ -81,10 +81,10 @@ typedef struct Command /* ---------------------------------------- GLOBALS */ static DString error; -static char *hostname="localhost"; -static char *username="nobody"; -static char *password=""; -static char *log=""; +static char *hostname=NULL; +static char *username=NULL; +static char *password=NULL; +static char *log=NULL; static int port=110; static int timeout=60; static int casesense=FALSE; @@ -196,6 +196,10 @@ static int DoSet(FILE *fp) case TYPE_STR: cp=vt->ptr; tok=GetToken(fp,&ds); + + if (*cp) + free(*cp); + *cp=CopyStr(ds->text); break; @@ -250,6 +254,7 @@ static int DoDomain(FILE *fp) Token tok; int status=TRUE; Domain *domain; + RE_Expression re; ds=DSInit(); @@ -263,7 +268,7 @@ static int DoDomain(FILE *fp) return FALSE; } - if (RExpSearch(ds->text,"dummy")==RE_BadExpression) + if (!(re=RECompile(ds->text))) { DSAddCP(error,"Bad regular expression: "); DSAddDS(error,ds); @@ -271,7 +276,7 @@ static int DoDomain(FILE *fp) return FALSE; } - domain=DBNewDomain(ds->text); + domain=DBNewDomain(re); tok=GetToken(fp,&ds); @@ -322,7 +327,7 @@ static int DoDomain(FILE *fp) case TOK_AllowSubject: GetToken(fp,&ds); - if (RExpSearch(ds->text,"dummy")==RE_BadExpression) + if (!(re=RECompile(ds->text))) { DSAddCP(error,"Bad regular expression: "); DSAddDS(error,ds); @@ -330,13 +335,13 @@ static int DoDomain(FILE *fp) return FALSE; } - DBAllowSubject(domain,ds->text); + DBAllowSubject(domain,re); break; case TOK_BlockSubject: GetToken(fp,&ds); - if (RExpSearch(ds->text,"dummy")==RE_BadExpression) + if (!(re=RECompile(ds->text))) { DSAddCP(error,"Bad regular expression: "); DSAddDS(error,ds); @@ -344,7 +349,7 @@ static int DoDomain(FILE *fp) return FALSE; } - DBBlockSubject(domain,ds->text); + DBBlockSubject(domain,re); break; default: @@ -631,6 +636,11 @@ int ConfigLoad(void) error=DSInit(); + hostname=CopyStr("localhost"); + username=CopyStr("nobody"); + password=CopyStr(""); + log=CopyStr(""); + if (!getenv("HOME")) return FALSE; @@ -713,4 +723,14 @@ int ConfigInt(ConfigIntVar var) } +void ConfigClose(void) +{ + DSFree(error); + free(hostname); + free(username); + free(password); + free(log); +} + + /* END OF FILE */ diff --git a/src/config.h b/src/config.h index 40140dc..3fec38f 100644 --- a/src/config.h +++ b/src/config.h @@ -75,6 +75,12 @@ const char *ConfigError(void); const char *ConfigString(ConfigStringVar var); int ConfigInt(ConfigIntVar var); + +/* Free any memory allocated +*/ +void ConfigClose(void); + + #endif /* END OF FILE */ diff --git a/src/dbase.c b/src/dbase.c index ce568af..aed142d 100644 --- a/src/dbase.c +++ b/src/dbase.c @@ -35,7 +35,6 @@ static const char id[]="$Id$"; #include "dbase.h" #include "dstring.h" #include "config.h" -#include "rexp.h" #include "util.h" @@ -43,29 +42,31 @@ static const char id[]="$Id$"; */ struct Domain { - char *name; - int def_block; - int no_user; - int no_block; - int no_allow; - char **user; - char **block; - char **allow; - Domain *next; - Domain *prev; + RE_Expression name; + int def_block; + int no_user; + int no_block; + int no_allow; + char **user; + RE_Expression *block; + RE_Expression *allow; + Domain *next; + Domain *prev; }; /* ---------------------------------------- GLOBALS */ -static Domain *head; -static Domain *tail; +static Domain *head; +static Domain *tail; -static int no_trusted_users=0; -static int no_trusted_domains=0; +static int no_trusted_users=0; +static int no_trusted_domains=0; -static char **trusted_user=NULL; -static char **trusted_domain=NULL; +static char **trusted_user=NULL; +static char **trusted_domain=NULL; + +static const char *reason; /* ---------------------------------------- PRVIVATE FUNCTIONS @@ -106,7 +107,7 @@ static const Domain *GetDomain(const char *domain) while(dom) { - if (RExpSearch(dom->name,domain)==RE_Found) + if (RESearch(dom->name,domain)) return dom; dom=dom->next; @@ -144,13 +145,13 @@ static void DeJunk(DString ds, const char *p) /* ---------------------------------------- INTERFACES */ -Domain *DBNewDomain(const char *regexp) +Domain *DBNewDomain(RE_Expression name) { Domain *dom; dom=Malloc(sizeof *dom); - dom->name=CopyStr(regexp); + dom->name=name; dom->def_block=FALSE; dom->no_user=0; @@ -187,19 +188,19 @@ void DBBlockUser(Domain *domain, const char *username) } -void DBAllowSubject(Domain *domain, const char *regexp) +void DBAllowSubject(Domain *domain, RE_Expression re) { domain->no_allow++; - domain->allow=Realloc(domain->allow,sizeof(char *)*domain->no_allow); - domain->allow[domain->no_allow-1]=CopyStr(regexp); + domain->allow=Realloc(domain->allow,sizeof(RE_Expression)*domain->no_allow); + domain->allow[domain->no_allow-1]=re; } -void DBBlockSubject(Domain *domain, const char *regexp) +void DBBlockSubject(Domain *domain, RE_Expression re) { domain->no_block++; - domain->block=Realloc(domain->block,sizeof(char *)*domain->no_block); - domain->block[domain->no_block-1]=CopyStr(regexp); + domain->block=Realloc(domain->block,sizeof(RE_Expression)*domain->no_block); + domain->block[domain->no_block-1]=re; } @@ -226,6 +227,8 @@ int DBBlockMessage(const POP3Message *msg) const Domain *dom; int f; + reason="None"; + if (IsTrustedDomain(msg->from_domain)) return FALSE; @@ -234,22 +237,27 @@ int DBBlockMessage(const POP3Message *msg) if (ConfigInt(CONFIG_BLOCKHTML) && strncmp(msg->content_type,html,strlen(html))==0) + { + reason="HTML message"; return TRUE; + } if (!(dom=GetDomain(msg->from_domain))) return FALSE; for(f=0;f<dom->no_user;f++) { + int res; + if (ConfigInt(CONFIG_CASESENSE)) - { - if (strcmp(dom->user[f],msg->from_uname)==0) - return TRUE; - } + res=strcmp(dom->user[f],msg->from_uname); else + res=strcasecmp(dom->user[f],msg->from_uname); + + if (res==0) { - if (strcasecmp(dom->user[f],msg->from_uname)==0) - return TRUE; + reason="disallowed name"; + return TRUE; } } @@ -262,7 +270,7 @@ int DBBlockMessage(const POP3Message *msg) for(f=0;f<dom->no_allow;f++) { - if (RExpSearch(dom->allow[f],ds->text)==RE_Found) + if (RESearch(dom->allow[f],ds->text)) { DSFree(ds); return FALSE; @@ -271,16 +279,76 @@ int DBBlockMessage(const POP3Message *msg) for(f=0;f<dom->no_block;f++) { - if (RExpSearch(dom->block[f],ds->text)==RE_Found) + if (RESearch(dom->block[f],ds->text)) { + reason="disallowed subject"; DSFree(ds); return TRUE; } } + reason="default"; DSFree(ds); return dom->def_block; } +const char *DBBlockReason(void) +{ + return reason; +} + + +void DBClose(void) +{ + Domain *d; + int f; + + for(f=0;f<no_trusted_domains;f++) + free(trusted_domain[f]); + + free(trusted_domain); + + for(f=0;f<no_trusted_users;f++) + free(trusted_user[f]); + + free(trusted_user); + + d=head; + + while(d) + { + Domain *t; + + t=d; + + d=d->next; + + for(f=0;f<t->no_user;f++) + free(t->user[f]); + + free(t->user); + + for(f=0;f<t->no_block;f++) + REFree(t->block[f]); + + free(t->block); + + for(f=0;f<t->no_allow;f++) + free(t->allow[f]); + + free(t->allow); + + free(t); + } + + no_trusted_users=0; + no_trusted_domains=0; + + head=tail=NULL; + trusted_user=NULL; + trusted_domain=NULL; +} + + /* END OF FILE */ diff --git a/src/dbase.h b/src/dbase.h index df64927..c7a98ee 100644 --- a/src/dbase.h +++ b/src/dbase.h @@ -30,6 +30,7 @@ #define KBS_DBASE_H #include "msg.h" +#include "rexp.h" /* ---------------------------------------- TYPES */ @@ -41,9 +42,10 @@ typedef struct Domain Domain; /* ---------------------------------------- INTERFACES */ -/* Add a new domain and define the regular expression that defines it +/* Add a new domain and define the regular expression that defines it. + re will be freed by the database when closed. */ -Domain *DBNewDomain(const char *regexp); +Domain *DBNewDomain(RE_Expression name); /* Define the default mode for a domain @@ -56,14 +58,16 @@ void DBDefault(Domain *domain, int block); void DBBlockUser(Domain *domain, const char *username); -/* Add an allowable subject for a domain +/* Add an allowable subject for a domain. + re will be freed by the database when closed. */ -void DBAllowSubject(Domain *domain, const char *regexp); +void DBAllowSubject(Domain *domain, RE_Expression re); -/* Adds a disallowed subject for a domain +/* Adds a disallowed subject for a domain. + re will be freed by the database when closed. */ -void DBBlockSubject(Domain *domain, const char *regexp); +void DBBlockSubject(Domain *domain, RE_Expression re); /* Adds a trusted username @@ -81,6 +85,16 @@ void DBTrustedDomain(const char *domain); int DBBlockMessage(const POP3Message *msg); +/* Returns reason for last block if message is to be blocked. +*/ +const char *DBBlockReason(void); + + +/* Free up memory allocated to database. +*/ +void DBClose(void); + + #endif /* END OF FILE */ @@ -142,10 +142,13 @@ int main(int argc, char *argv[]) Log(fp,"From %s@%s\n",msg[f].from_uname, msg[f].from_domain); Log(fp,"Subject %.40s\n",msg[f].subject); + Log(fp,"Reason %s\n",DBBlockReason()); } else { - Log(fp,"%s@%s\n",msg[f].from_uname,msg[f].from_domain); + Log(fp,"%s@%s (%s)\n",msg[f].from_uname, + msg[f].from_domain, + DBBlockReason()); } if (!ConfigInt(CONFIG_TESTMODE)) @@ -172,6 +175,9 @@ int main(int argc, char *argv[]) fclose(fp); } + DBClose(); + ConfigClose(); + return EXIT_SUCCESS; } @@ -31,32 +31,47 @@ static const char id[]="$Id$"; #include "global.h" #include "rexp.h" #include "config.h" +#include "util.h" /* ---------------------------------------- INTERFACES */ -RExpStatus RExpSearch(const char *regexpr, const char *string) +RE_Expression RECompile(const char *regexpr) { - regex_t re; + regex_t *re; int flags; - int res; + + re=Malloc(sizeof *re); flags=REG_EXTENDED|REG_NOSUB; if (!ConfigInt(CONFIG_CASESENSE)) flags|=REG_ICASE; - if (regcomp(&re,regexpr,flags)) - return RE_BadExpression; + if (regcomp(re,regexpr,flags)) + { + free(re); + re=NULL; + } + + return re; +} - res=regexec(&re,string,0,NULL,0); - regfree(&re); +int RESearch(const RE_Expression re, const char *string) +{ + return !regexec(re,string,0,NULL,0); +} - /* printf("RExpSearch(%s,%s)=%d\n",regexpr,string,res); */ - return res ? RE_NotFound : RE_Found; +void REFree(RE_Expression re) +{ + if (re) + { + regfree(re); + free(re); + } } @@ -33,18 +33,23 @@ /* ---------------------------------------- INTERFACES */ +typedef void *RE_Expression; -typedef enum - { - RE_Found, - RE_NotFound, - RE_BadExpression, - } RExpStatus; + +/* Compile a regular expression for use. Returns NULL if the expression + cannot be compiled. +*/ +RE_Expression RECompile(const char *regexpr); + + +/* Search string for regexpr. Returns TRUE for match. +*/ +int RESearch(const RE_Expression re, const char *string); -/* Search string for regexpr +/* Free a regular expression */ -RExpStatus RExpSearch(const char *regexpr, const char *string); +void REFree(RE_Expression re); #endif |