From 8520befe602e9b90d455342068a623f2cf89f631 Mon Sep 17 00:00:00 2001 From: Ian C Date: Thu, 4 Dec 2003 01:54:55 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2, which included commits to RCS files with non-trunk default branches. --- src/pop3.c | 530 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 src/pop3.c (limited to 'src/pop3.c') diff --git a/src/pop3.c b/src/pop3.c new file mode 100644 index 0000000..8fd2750 --- /dev/null +++ b/src/pop3.c @@ -0,0 +1,530 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------- + + POP3 Interface + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "pop3.h" +#include "dstring.h" +#include "util.h" + + +/* ---------------------------------------- CONSTANTS +*/ +#define BLOCKSIZE 512 + +#define HDR_UNKNOWN -1 +#define HDR_SUBJECT 0 +#define HDR_FROM 1 +#define HDR_TO 2 +#define HDR_CONTENT_TYPE 3 + +/* ---------------------------------------- TYPES +*/ + + +/* ---------------------------------------- GLOBALS +*/ +static int sock; +static int timeout; +static int connected=FALSE; + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static void Chomp(char *p) +{ + size_t l; + + l=strlen(p); + + if (l && p[l-1]=='\012') + { + p[--l]=0; + } + + if (l && p[l-1]=='\015') + { + p[--l]=0; + } +} + + +static char *ChompQuotesWS(char *p) +{ + size_t l; + + l=strlen(p); + + while (l && (p[l-1]=='"' || isspace(p[l-1]))) + { + p[--l]=0; + } + + while (l && (p[0]=='"' || isspace(p[0]))) + memmove(p,p+1,--l); + + return p; +} + + +static int Connect(const char *hostname, int port) +{ + struct hostent *remote; + struct sockaddr_in addr; + + if (!(remote=gethostbyname(hostname))) + { + return FALSE; + } + + memcpy(&addr.sin_addr,remote->h_addr,remote->h_length); + + if ((sock=socket(PF_INET,SOCK_STREAM,0))==-1) + return FALSE; + + addr.sin_family=AF_INET; + addr.sin_port=htons(port); + + if (connect(sock,(const void *)&addr,sizeof(addr))==-1) + return FALSE; + + return TRUE; +} + + +static int SendSock(const char *p, size_t len) +{ + size_t sent=0; + + while(senttext); + + return TRUE; +} + + +static int GetResponse(DString ret) +{ + DString t; + int flag; + + t=DSInit(); + + if (GetLine(t)) + flag=t->text[0]=='+'; + else + flag=FALSE; + + if (ret) + DSAddDS(ret,t); + + DSFree(t); + + return flag; +} + + +static int GetMultiLine(DString ret) +{ + int flag; + + if (GetLine(ret)) + flag=TRUE; + else + flag=FALSE; + + return flag; +} + + +static void ParseHeader(POP3Message *msg, char *line) +{ + static const struct + { + const char *text; + int type; + } field[]= + { + {"Subject: ", HDR_SUBJECT}, + {"From: ", HDR_FROM}, + {"To: ", HDR_TO}, + {"Content-type: ", HDR_CONTENT_TYPE}, + {"Content-Type: ", HDR_CONTENT_TYPE}, + {NULL, HDR_UNKNOWN} + }; + + int f; + int type=HDR_UNKNOWN; + + for(f=0;type==HDR_UNKNOWN && field[f].text;f++) + if (strncmp(field[f].text,line,strlen(field[f].text))==0) + { + type=field[f].type; + line+=strlen(field[f].text); + } + + switch(type) + { + case HDR_SUBJECT: + msg->subject=CopyStr(line); + break; + + case HDR_FROM: + if (strchr(line,'<')) + { + char *t[3]; + + for(f=0;f<3 && t[f-1];f++) + t[f]=strtok(f==0 ? line:NULL,"<>@"); + + msg->from=CopyStr(t[0] ? ChompQuotesWS(t[0]) : "UNKNOWN"); + msg->from_uname=CopyStr(t[1] ? t[1] : "UNKNOWN"); + msg->from_domain=CopyStr(t[2] ? t[2] : "UNKNOWN"); + } + else + { + char *t[2]; + + for(f=0;f<2 && t[f-1];f++) + t[f]=strtok(f==0 ? line:NULL,"@"); + + msg->from=CopyStr("UNKNOWN"); + msg->from_uname=CopyStr(t[0] ? t[0] : "UNKNOWN"); + msg->from_domain=CopyStr(t[1] ? t[1] : "UNKNOWN"); + } + break; + + case HDR_TO: + msg->to=CopyStr(line); + break; + + case HDR_CONTENT_TYPE: + msg->content_type=CopyStr(line); + break; + + default: + break; + } +} + + +/* ---------------------------------------- INTERFACES +*/ + +POP3Status POP3Connect(const char *hostname, int port, + const char *username, const char *passwd, + int t) +{ + timeout=t; + connected=FALSE; + + if (port==0) + { + struct servent *ent; + + if ((ent=getservbyname("pop3","tcp"))) + port=ntohs(ent->s_port); + else + port=110; + } + + if (!Connect(hostname,port)) + return POP3_NOCONNECT; + + if (!GetResponse(NULL)) + return POP3_COMMERROR; + + if (Send("USER ",username,(const char *)NULL)!=1) + return POP3_COMMERROR; + + if (!GetResponse(NULL)) + return POP3_BADUSER; + + if (Send("PASS ",passwd,(const char *)NULL)!=1) + return POP3_COMMERROR; + + if(!GetResponse(NULL)) + return POP3_BADPASSWD; + + connected=TRUE; + + return POP3_OK; +} + + +POP3Message *POP3GetList(void) +{ + POP3Message *msg=NULL; + DString t; + char *p; + int no; + int f; + + if (!connected) + return NULL; + + t=DSInit(); + + Send("STAT",(const char *)NULL); + + if (!GetResponse(t)) + goto end; + + p=strtok(t->text," "); + + if (p) + p=strtok(NULL," "); + + if (!p) + goto end; + + no=atoi(p); + + msg=Malloc(sizeof *msg * (no+1)); + + for(f=0;ftext,".")==0) + done=TRUE; + else + { + ParseHeader(msg+f,t->text); + } + } + + if (!msg[f].to) + msg[f].to=CopyStr("UNKNOWN"); + + if (!msg[f].from) + msg[f].from=CopyStr("UNKNOWN"); + + if (!msg[f].from_uname) + msg[f].from_uname=CopyStr("UNKNOWN"); + + if (!msg[f].from_domain) + msg[f].from_domain=CopyStr("UNKNOWN"); + + if (!msg[f].subject) + msg[f].subject=CopyStr("UNKNOWN"); + + if (!msg[f].content_type) + msg[f].content_type=CopyStr("UNKNOWN"); + } + + msg[no].id=0; + msg[no].to=NULL; + msg[no].from=NULL; + msg[no].from_uname=NULL; + msg[no].from_domain=NULL; + msg[no].subject=NULL; + +end: + DSFree(t); + return msg; +} + + +POP3Status POP3Delete(int msg) +{ + return POP3_OK; +} + + +void POP3Logoff(void) +{ + Send("QUIT",(const char *)NULL); + GetResponse(NULL); +} + + +void POP3FreeList(POP3Message *list) +{ + if (list) + { + int f; + + for(f=0;list[f].to;f++) + { + free(list[f].to); + free(list[f].from); + free(list[f].from_uname); + free(list[f].from_domain); + free(list[f].subject); + } + + free(list); + } +} + + +/* END OF FILE */ -- cgit v1.2.3