summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/INSTRUCTION21
-rw-r--r--src/Makefile8
-rw-r--r--src/config.c67
-rw-r--r--src/config.h4
-rw-r--r--src/dbase.c7
-rw-r--r--src/kbs.c128
-rw-r--r--src/pop3.c10
-rw-r--r--src/pop3.h3
8 files changed, 164 insertions, 84 deletions
diff --git a/doc/INSTRUCTION b/doc/INSTRUCTION
index d4ffc69..921d8ee 100644
--- a/doc/INSTRUCTION
+++ b/doc/INSTRUCTION
@@ -61,15 +61,18 @@ And understand the following variables:
password <username> The password to give to the server.
Defaults to an empty string.
- log <path> Log information to the given file (note the file is
- appended to).
+ log <path> Logs deleted messages to the given file, which is
+ appended to. Note that non-deletion diagnostics go to
+ stderr.
If not used, or is an illegal path, logging is to
- stdout.
+ $HOME/.kbs-deletelog unless the variable is set to
+ a dash (-), in which case logging is disabled.
- delete_log <path> Logs deleted messages to the given file, which is
- appended to.
- If not used, or is an illegal path, logging is to
- $HOME/.kbs-deletelog.
+ verbose <on|off> Whether logging is verbose. If it's verbose then
+ the username, subject and a tailing report is generated.
+ If logging is not verbose, then just usernames are
+ logged.
+ Defaults to verbose (on).
timeout <seconds> Number of seconds to allow for no response from the
server.
@@ -89,7 +92,7 @@ And understand the following variables:
Defaults to off.
testmode <on|off> Whether things will be really deleted, or just
- the actions logged. Note that the delete_log is still
+ the actions logged. Note that the log is still
filled out as if the deletion occured.
Defaults to off, though it is recommended to use this
for early runs to ensure your rules are not too harsh
@@ -148,4 +151,4 @@ domain.
-------------------------------------------------------------------------------
-$Id: INSTRUCTION,v 1.1.1.1 2003-12-04 01:54:55 ianc Exp $
+$Id: INSTRUCTION,v 1.2 2003-12-05 02:33:05 ianc Exp $
diff --git a/src/Makefile b/src/Makefile
index 22cc523..15285d1 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,7 +18,7 @@
#
# -------------------------------------------------------------------------
#
-# $Id: Makefile,v 1.1.1.1 2003-12-04 01:54:55 ianc Exp $
+# $Id: Makefile,v 1.2 2003-12-05 02:33:05 ianc Exp $
#
CFLAGS += -g
@@ -60,7 +60,7 @@ kbs.o: /usr/include/limits.h /usr/include/sys/limits.h
kbs.o: /usr/include/machine/_limits.h /usr/include/sys/syslimits.h
kbs.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h
kbs.o: /usr/include/stdarg.h /usr/include/time.h /usr/include/sys/timespec.h
-kbs.o: /usr/include/errno.h global.h config.h pop3.h msg.h rexp.h util.h
+kbs.o: /usr/include/errno.h global.h config.h pop3.h msg.h dbase.h util.h
pop3.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
pop3.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
pop3.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h
@@ -78,8 +78,8 @@ config.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h
config.o: /usr/include/errno.h /usr/include/ctype.h /usr/include/runetype.h
config.o: global.h config.h dstring.h dbase.h msg.h rexp.h util.h
rexp.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
-rexp.o: /usr/include/sys/_types.h /usr/include/machine/_types.h global.h
-rexp.o: rexp.h
+rexp.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
+rexp.o: /usr/include/regex.h global.h rexp.h config.h
dbase.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
dbase.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
dbase.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h
diff --git a/src/config.c b/src/config.c
index af55d58..18d7cfd 100644
--- a/src/config.c
+++ b/src/config.c
@@ -63,7 +63,7 @@ typedef enum {
TOK_VarDejunk,
TOK_VarTestmode,
TOK_VarBlockHTML,
- TOK_VarDeletelog,
+ TOK_VarVerbose,
TOK_ConstOn,
TOK_ConstOff,
TOK_ConstBlock,
@@ -85,13 +85,13 @@ static char *hostname="localhost";
static char *username="nobody";
static char *password="";
static char *log="";
-static char *deletelog="";
static int port=110;
static int timeout=60;
static int casesense=FALSE;
static int dejunk=FALSE;
static int testmode=FALSE;
static int blockhtml=FALSE;
+static int verbose=TRUE;
/* ---------------------------------------- COMMAND TABLE
@@ -123,6 +123,7 @@ static const Command cmd_table[]=
{"dejunk", TOK_VarDejunk},
{"testmode", TOK_VarTestmode},
{"blockhtml", TOK_VarBlockHTML},
+ {"verbose", TOK_VarVerbose},
/* Constants
*/
@@ -139,7 +140,7 @@ static const Command cmd_table[]=
/* ---------------------------------------- REQUIRED PROTOS
*/
-static Token GetToken(FILE *fp, DString ret);
+static Token GetToken(FILE *fp, DString *ret);
/* ---------------------------------------- COMMAND HANDLERS
@@ -167,7 +168,7 @@ static int DoSet(FILE *fp)
{TOK_VarDejunk, TYPE_ONOFF, (void *)&dejunk},
{TOK_VarTestmode, TYPE_ONOFF, (void *)&testmode},
{TOK_VarBlockHTML, TYPE_ONOFF, (void *)&blockhtml},
- {TOK_VarDeletelog, TYPE_STR, (void *)&deletelog},
+ {TOK_VarVerbose, TYPE_ONOFF, (void *)&verbose},
{TOK_EOF,0,NULL}
};
@@ -179,7 +180,7 @@ static int DoSet(FILE *fp)
ds=DSInit();
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
for(f=0;var_table[f].token!=TOK_EOF && !vt;f++)
if (var_table[f].token==tok)
@@ -194,19 +195,19 @@ static int DoSet(FILE *fp)
{
case TYPE_STR:
cp=vt->ptr;
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
*cp=CopyStr(ds->text);
break;
case TYPE_INT:
ip=vt->ptr;
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
*ip=atoi(ds->text);
break;
case TYPE_ONOFF:
ip=vt->ptr;
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
switch(tok)
{
@@ -252,7 +253,7 @@ static int DoDomain(FILE *fp)
ds=DSInit();
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
if (tok!=TOK_Expression)
{
@@ -272,7 +273,7 @@ static int DoDomain(FILE *fp)
domain=DBNewDomain(ds->text);
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
if (tok!=TOK_OpenBracket)
{
@@ -281,7 +282,7 @@ static int DoDomain(FILE *fp)
return FALSE;
}
- while((tok=GetToken(fp,ds))!=TOK_CloseBracket)
+ while((tok=GetToken(fp,&ds))!=TOK_CloseBracket)
{
if (tok==TOK_EOF)
{
@@ -293,7 +294,7 @@ static int DoDomain(FILE *fp)
switch(tok)
{
case TOK_Default:
- switch(GetToken(fp,ds))
+ switch(GetToken(fp,&ds))
{
case TOK_ConstAllow:
DBDefault(domain,FALSE);
@@ -314,12 +315,12 @@ static int DoDomain(FILE *fp)
break;
case TOK_BlockUser:
- GetToken(fp,ds);
+ GetToken(fp,&ds);
DBBlockUser(domain,ds->text);
break;
case TOK_AllowSubject:
- GetToken(fp,ds);
+ GetToken(fp,&ds);
if (RExpSearch(ds->text,"dummy")==RE_BadExpression)
{
@@ -333,7 +334,7 @@ static int DoDomain(FILE *fp)
break;
case TOK_BlockSubject:
- GetToken(fp,ds);
+ GetToken(fp,&ds);
if (RExpSearch(ds->text,"dummy")==RE_BadExpression)
{
@@ -369,7 +370,7 @@ static int DoTrustedUsers(FILE *fp)
ds=DSInit();
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
if (tok!=TOK_OpenBracket)
{
@@ -378,7 +379,7 @@ static int DoTrustedUsers(FILE *fp)
return FALSE;
}
- while((tok=GetToken(fp,ds))!=TOK_CloseBracket)
+ while((tok=GetToken(fp,&ds))!=TOK_CloseBracket)
{
if (tok==TOK_EOF)
{
@@ -404,7 +405,7 @@ static int DoTrustedDomains(FILE *fp)
ds=DSInit();
- tok=GetToken(fp,ds);
+ tok=GetToken(fp,&ds);
if (tok!=TOK_OpenBracket)
{
@@ -412,7 +413,7 @@ static int DoTrustedDomains(FILE *fp)
return FALSE;
}
- while((tok=GetToken(fp,ds))!=TOK_CloseBracket)
+ while((tok=GetToken(fp,&ds))!=TOK_CloseBracket)
{
if (tok==TOK_EOF)
{
@@ -484,24 +485,24 @@ static int IsTerm(int ch)
}
-static Token GetToken(FILE *fp, DString ret)
+static Token GetToken(FILE *fp, DString *ret)
{
int ch;
int done=FALSE;
int quote=0;
Token tok;
- ret=DSReset(ret);
+ *ret=DSReset(*ret);
if (feof(fp))
{
- DSAddCP(ret,"EOF");
+ DSAddCP(*ret,"EOF");
return TOK_EOF;
}
if (!SkipWS(fp))
{
- DSAddCP(ret,"EOF");
+ DSAddCP(*ret,"EOF");
return TOK_EOF;
}
@@ -521,11 +522,11 @@ static Token GetToken(FILE *fp, DString ret)
else if (ch==quote)
{
done=TRUE;
- tok=FindToken(ret->text);
+ tok=FindToken((*ret)->text);
}
else
{
- DSAddChar(ret,ch);
+ DSAddChar(*ret,ch);
}
}
else
@@ -534,8 +535,8 @@ static Token GetToken(FILE *fp, DString ret)
{
done=TRUE;
- if (ret->len)
- tok=FindToken(ret->text);
+ if ((*ret)->len)
+ tok=FindToken((*ret)->text);
else
tok=TOK_EOF;
}
@@ -543,7 +544,7 @@ static Token GetToken(FILE *fp, DString ret)
{
ungetc(ch,fp);
done=TRUE;
- tok=FindToken(ret->text);
+ tok=FindToken((*ret)->text);
}
else if (ch=='\'' || ch=='"')
{
@@ -551,7 +552,7 @@ static Token GetToken(FILE *fp, DString ret)
}
else
{
- DSAddChar(ret,ch);
+ DSAddChar(*ret,ch);
}
}
}
@@ -568,7 +569,7 @@ static int Parse(FILE *fp)
txt=DSInit();
- while((tok=GetToken(fp,txt))!=TOK_EOF)
+ while((tok=GetToken(fp,&txt))!=TOK_EOF)
{
int ok=TRUE;
@@ -675,9 +676,6 @@ const char *ConfigString(ConfigStringVar var)
case CONFIG_LOG:
return log;
- case CONFIG_DELETE_LOG:
- return deletelog;
-
default:
return "";
}
@@ -706,6 +704,9 @@ int ConfigInt(ConfigIntVar var)
case CONFIG_BLOCKHTML:
return blockhtml;
+ case CONFIG_VERBOSE:
+ return verbose;
+
default:
return 0;
}
diff --git a/src/config.h b/src/config.h
index a2ddc78..40140dc 100644
--- a/src/config.h
+++ b/src/config.h
@@ -41,7 +41,6 @@ typedef enum
CONFIG_USERNAME,
CONFIG_PASSWORD,
CONFIG_LOG,
- CONFIG_DELETE_LOG
} ConfigStringVar;
@@ -54,7 +53,8 @@ typedef enum
CONFIG_CASESENSE,
CONFIG_DEJUNK,
CONFIG_TESTMODE,
- CONFIG_BLOCKHTML
+ CONFIG_BLOCKHTML,
+ CONFIG_VERBOSE
} ConfigIntVar;
/* ---------------------------------------- INTERFACES
diff --git a/src/dbase.c b/src/dbase.c
index 5eca1a9..14263dd 100644
--- a/src/dbase.c
+++ b/src/dbase.c
@@ -221,10 +221,17 @@ void DBTrustedDomain(const char *domain)
int DBBlockMessage(const POP3Message *msg)
{
+ static const char *html="text/html";
DString ds;
const Domain *dom;
int f;
+ if (ConfigInt(CONFIG_BLOCKHTML) &&
+ strncmp(msg->content_type,html,strlen(html))==0)
+ {
+ return TRUE;
+ }
+
if (IsTrustedDomain(msg->from_domain))
return FALSE;
diff --git a/src/kbs.c b/src/kbs.c
index 25afe5f..f5f3aab 100644
--- a/src/kbs.c
+++ b/src/kbs.c
@@ -35,32 +35,23 @@ static const char id[]="$Id$";
#include "config.h"
#include "pop3.h"
#include "dbase.h"
+#include "dstring.h"
#include "util.h"
-/* ---------------------------------------- MACROS
-*/
-#define LOG (logfp ? logfp:stderr)
-
-
-/* ---------------------------------------- TYPES
-*/
-
-
-/* ---------------------------------------- GLOBALS
-*/
-static const char *name=NULL;
-static FILE *logfp=NULL;
-
/* ---------------------------------------- PROTOS
*/
+static void Log(FILE *fp, const char *fmt, ...);
/* ---------------------------------------- MAIN
*/
int main(int argc, char *argv[])
{
+ FILE *fp;
+ const char *name;
POP3Message *msg;
+ int f;
if (strchr(argv[0],'/'))
name=strchr(argv[0],'/')+1;
@@ -69,7 +60,7 @@ int main(int argc, char *argv[])
if (!ConfigLoad())
{
- fprintf(stderr,"%s\n",ConfigError());
+ fprintf(stderr,"%s: %s\n",name,ConfigError());
exit(EXIT_FAILURE);
}
@@ -83,22 +74,23 @@ int main(int argc, char *argv[])
break;
case POP3_COMMERROR:
- fprintf(LOG,"Comms error (errno = %d)\n",errno);
+ fprintf(stderr,"%s: Comms error (errno = %d)\n",name,errno);
exit(EXIT_FAILURE);
break;
case POP3_NOCONNECT:
- fprintf(LOG,"No connection to host (errno = %d)\n",errno);
+ fprintf(stderr,"%s: No connection "
+ "to host (errno = %d)\n",name,errno);
exit(EXIT_FAILURE);
break;
case POP3_BADUSER:
- fprintf(LOG,"Bad username\n");
+ fprintf(stderr,"%s: Bad username\n",name);
exit(EXIT_FAILURE);
break;
case POP3_BADPASSWD:
- fprintf(LOG,"Bad password\n");
+ fprintf(stderr,"%s: Bad password\n",name);
exit(EXIT_FAILURE);
break;
@@ -106,42 +98,110 @@ int main(int argc, char *argv[])
break;
}
+
+ if (strcmp(ConfigString(CONFIG_LOG),"-")!=0)
+ {
+ if (!(fp=fopen(ConfigString(CONFIG_LOG),"a")))
+ {
+ DString ds;
+
+ ds=DSInit();
+
+ if (getenv("HOME"))
+ DSAddCP(ds,getenv("HOME"));
+ else
+ DSAddChar(ds,'.');
+
+ DSAddCP(ds,"/.kbs-deletelog");
+
+ if (!(fp=fopen(ds->text,"a")))
+ fp=stderr;
+ }
+ }
+ else
+ {
+ fp=NULL;
+ }
+
if ((msg=POP3GetList()))
{
- int f;
int tot=0;
- int block=0;
+ int del=0;
for(f=0;msg[f].to;f++)
{
tot++;
- printf("Num %d\n",msg[f].id);
- printf(" From : %s@%s\n",msg[f].from_uname,msg[f].from_domain);
- printf(" Subject : %s\n",msg[f].subject);
-
+
if (DBBlockMessage(msg+f))
{
- printf(" BLOCKED : YES\n\n");
- block++;
+ del++;
+
+ if (ConfigInt(CONFIG_VERBOSE))
+ {
+ Log(fp,"-----\n");
+ Log(fp,"From %s@%s\n",msg[f].from_uname,
+ msg[f].from_domain);
+ Log(fp,"Subject %.40s\n",msg[f].subject);
+ }
+ else
+ {
+ Log(fp,"%s@%s\n",msg[f].from_uname,msg[f].from_domain);
+ }
+
+ if (!ConfigInt(CONFIG_TESTMODE))
+ {
+ POP3Delete(msg[f].id);
+ }
}
- else
- printf(" BLOCKED : NO\n\n");
}
- printf("%d messages, %d blocked\n",tot,block);
+ if (ConfigInt(CONFIG_VERBOSE))
+ {
+ Log(fp,"*****\n");
+ Log(fp,"Processed %d messages, %sdeleted %d\n",
+ tot,ConfigInt(CONFIG_TESTMODE) ? "would have ":"",del);
+ }
POP3FreeList(msg);
}
- else
+
+ POP3Logoff();
+
+ if (fp && fp!=stderr)
{
- printf("No messages\n");
+ fclose(fp);
}
return EXIT_SUCCESS;
}
-/* ---------------------------------------- UTIL
-*/
+static void Log(FILE *fp, const char *fmt,...)
+{
+ char buff[128];
+ time_t t;
+ struct tm *ts;
+
+ if (!fp)
+ return;
+
+ t=time(NULL);
+ ts=localtime(&t);
+
+ strftime(buff,sizeof buff,
+ "%Y-%m-%d %H:%M:%S: ",
+ ts);
+
+
+ fprintf(fp,"%s",buff);
+
+ va_list va;
+ va_start(va,fmt);
+
+ vfprintf(fp,fmt,va);
+
+ va_end(va);
+}
+
/* END OF FILE */
diff --git a/src/pop3.c b/src/pop3.c
index 8fd2750..660283e 100644
--- a/src/pop3.c
+++ b/src/pop3.c
@@ -496,7 +496,15 @@ end:
POP3Status POP3Delete(int msg)
{
- return POP3_OK;
+ char buff[256];
+
+ sprintf(buff,"DELE %d",msg);
+ Send(buff,(const char *)NULL);
+
+ if (GetResponse(NULL))
+ return POP3_OK;
+ else
+ return POP3_BADDELETE;
}
diff --git a/src/pop3.h b/src/pop3.h
index c684634..c9ab4c8 100644
--- a/src/pop3.h
+++ b/src/pop3.h
@@ -39,7 +39,8 @@ typedef enum
POP3_COMMERROR,
POP3_NOCONNECT,
POP3_BADUSER,
- POP3_BADPASSWD
+ POP3_BADPASSWD,
+ POP3_BADDELETE
} POP3Status;
/* ---------------------------------------- INTERFACES