summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL7
-rw-r--r--doc/INSTRUCTION9
-rw-r--r--src/config.c40
-rw-r--r--src/config.h6
-rw-r--r--src/dbase.c136
-rw-r--r--src/dbase.h26
-rw-r--r--src/kbs.c8
-rw-r--r--src/rexp.c33
-rw-r--r--src/rexp.h21
9 files changed, 211 insertions, 75 deletions
diff --git a/INSTALL b/INSTALL
index 5674bb7..c0b1b86 100644
--- a/INSTALL
+++ b/INSTALL
@@ -8,15 +8,16 @@ To build the software, type the following:
make depend
make
-Then copy the kbs executable wherever you want.
+Then copy the kbs executable wherever you want (sorry there is no install,
+but it does only generate one executable and no other dependencies).
Other or broken systems
=======================
If the Makefile is not usable on your system, you simply need to compile all
-the .c files and produce a single kbs object. E.g. (using the cc command
-as an example):
+the .c files and produce a single kbs executable. E.g. (using a UNIX-style cc
+compiler as an example):
cd src
cc -o casm *.c
diff --git a/doc/INSTRUCTION b/doc/INSTRUCTION
index 921d8ee..ef0cdc6 100644
--- a/doc/INSTRUCTION
+++ b/doc/INSTRUCTION
@@ -16,7 +16,8 @@ a special keyword in a subject header to be used.
Config file format
==================
-The kbs config file is read from $HOME/.kbsrc and is in the form:
+The kbs config file is read from $HOME/.kbsrc and has sections in the suggested
+order:
[config settings]
@@ -34,9 +35,9 @@ includes spaces, simple quote them (with either single or double quotes).
Note that escapes aren't used (to make regular expression writing easier), so
if you want to include a quote in a string, simply use the other sort of quote.
-If you want both, you're stuck!
+If you want both, sorry, you're stuck!
-To see and example kbsrc file, see kbsrc in the src directory.
+To see an example kbsrc file, see kbsrc in the src directory.
Config settings
@@ -151,4 +152,4 @@ domain.
-------------------------------------------------------------------------------
-$Id: INSTRUCTION,v 1.2 2003-12-05 02:33:05 ianc Exp $
+$Id: INSTRUCTION,v 1.3 2003-12-07 01:46:44 ianc Exp $
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 */
diff --git a/src/kbs.c b/src/kbs.c
index f5f3aab..5c978b4 100644
--- a/src/kbs.c
+++ b/src/kbs.c
@@ -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;
}
diff --git a/src/rexp.c b/src/rexp.c
index 0311c44..3e51aa6 100644
--- a/src/rexp.c
+++ b/src/rexp.c
@@ -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);
+ }
}
diff --git a/src/rexp.h b/src/rexp.h
index 04d1bb6..98d685f 100644
--- a/src/rexp.h
+++ b/src/rexp.h
@@ -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