home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
lpopper.zip
/
mbox.c-
< prev
next >
Wrap
Text File
|
1997-12-06
|
44KB
|
1,255 lines
#include "popper.h"
int Debug=0;
struct Letter *mBox=NULL;
long msgCount=0;
long TotalLen=0;
long uMsgCount=0;
long uTotalLen=0;
char PwdPath[512]="passwd";
char BoxPath[512]=".\\";
#pragma argsused
int PackBox(char * User, int DoDelete)
{ FILE *Tmp;
FILE *fBox;
FILE *rBox;
char TmpPath[512];
char mBoxPath[512];
char rBoxPath[512];
long i, Len;
int Res;
if(DoDelete==0)
{ for(i=0;i<msgCount;i++)
mBox[i].Deleted=0;
uMsgCount=msgCount;
uTotalLen=TotalLen;
}
sprintf(TmpPath, "%s%s.tmp", BoxPath, User);
sprintf(mBoxPath, "%s%s.mb", BoxPath, User);
sprintf(rBoxPath, "%s%s", BoxPath, User);
if(msgCount==0)
{ unlink(mBoxPath);
return(0);
}
Tmp =_fsopen(TmpPath, "wb", SH_DENYRW);
if(Tmp==NULL)
{ perror("Can't create temporary mailbox");
return(-1);
}
fBox=_fsopen(mBoxPath, "rb", SH_DENYRW);
if(fBox==NULL)
{ perror("Can't open mailbox");
fclose(Tmp);
return(-1);
}
for(i=0;i<msgCount;i++)
{
/* fprintf(stderr,
"Message %lu\n"
"From %lX to %lX\n"
"Header to %lX\n"
"Status from %lX to %lX\n"
"Status=%u, Old Status=%u\n",
i,
mBox[i].Begin, mBox[i].End,
mBox[i].hEnd,
mBox[i].sBeg, mBox[i].sEnd, mBox[i].Status, mBox[i].oStatus);*/
if(mBox[i].Deleted) continue;
/*************************************************************/
if(mBox[i].oStatus==None)
{ if(CopyBlock(fBox, Tmp, mBox[i].Begin, mBox[i].hEnd)!=0)
{ perror("Mailbox -> TempBox copy failed");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
switch(mBox[i].Status)
{ case Unreaded : Res=AddBlock(Tmp, "Status: U\x0D\x0A");
break;
case Readed : Res=AddBlock(Tmp, "Status: R\x0D\x0A");
break;
case Old : Res=AddBlock(Tmp, "Status: O\x0D\x0A");
break;
case ROld : Res=AddBlock(Tmp, "Status: RO\x0D\x0A");
break;
default : Res=AddBlock(Tmp, "Status: U\x0D\x0A");
break;
}
if(Res!=0)
{ perror("Can't add \"Status:\"");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
if(CopyBlock(fBox, Tmp, mBox[i].hEnd, mBox[i].End+1)!=0)
{ perror("Mailbox -> TempBox copy failed");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
}
else
{ if(CopyBlock(fBox, Tmp, mBox[i].Begin, mBox[i].sBeg)!=0)
{ perror("Mailbox -> TempBox copy failed");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
switch(mBox[i].Status)
{ case Unreaded : Res=AddBlock(Tmp, "Status: U\x0D\x0A");
break;
case Readed : Res=AddBlock(Tmp, "Status: R\x0D\x0A");
break;
case Old : Res=AddBlock(Tmp, "Status: O\x0D\x0A");
break;
case ROld : Res=AddBlock(Tmp, "Status: RO\x0D\x0A");
break;
default : Res=AddBlock(Tmp, "Status: U\x0D\x0A");
break;
}
if(Res!=0)
{ perror("Can't add \"Status:\"");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
if(CopyBlock(fBox, Tmp, mBox[i].sEnd, mBox[i].End+1)!=0)
{ perror("Mailbox -> TempBox copy failed");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
}
/************************************************/
}
fseek(Tmp, 0, SEEK_END);
Len=ftell(Tmp);
fclose(fBox);
fBox=_fsopen(mBoxPath, "wb", SH_DENYRW);
if(fBox==NULL)
{ perror("Can't reopen mailbox");
fclose(Tmp);
unlink(TmpPath);
return(-1);
}
if(CopyBlock(Tmp, fBox, 0, Len)!=0)
{ perror("Can't copy TmpBox to mailbox");
fclose(Tmp);
unlink(TmpPath);
fclose(fBox);
return(-1);
}
else
{
fclose(fBox);
fclose(Tmp);
Tmp =_fsopen(TmpPath, "rb", SH_DENYRW);
if(Tmp==NULL)
{ perror("Can't reopen temporary mailbox");
return(-1);
}
unlink(mBoxPath);
if(access(rBoxPath, 0)==0)
{ errno=0;
rBox=_fsopen(rBoxPath, "r+b", SH_DENYRW);
}
else
{ errno=0;
rBox=_fsopen(rBoxPath, "w+b", SH_DENYRW);
}
if(rBox==NULL)
{ perror("Can't open maildrop");
}
else
{ fseek(Tmp, 0, SEEK_END);
Len=ftell(Tmp);
if(CopyBlock(Tmp, rBox, 0l, Len)!=0)
{ perror("Can't append mailbox to main maildrop : some mails wasted");
}
fclose(rBox);
}
fclose(Tmp);
unlink(TmpPath);
}
return(0);
}
static char UserName[9]={0};
void CrashPack (void)
{ fprintf(stderr, "Session crashed for user %s, emergency packing mailbox\n");
PackBox(UserName, 0);
}
#define NEWLETTER "From "
#define MSGID "Message-Id:"
#define CHARSET "Content-Type:"
#define STATUS "Status:"
#define C866 "x-cp866"
/*Content-Type: text/plain; charset=x-cp866*/
int RescanBox(FILE * fBox)
{ long i, Begin, cBegin;
char *Buffer;
/*Allocate temporary buffer and check it*/
Buffer=(char*)malloc(10240);
if(Buffer==NULL)
{ return(-1);
}
/*Clear old index if any*/
for(i=0;i<msgCount;i++)
{ free(mBox[i].msgID);
}
if(mBox!=NULL) free(mBox);
msgCount=0;
TotalLen=0l;
mBox=NULL;
fseek(fBox, 0, SEEK_SET);
/*Build new index*/
do { /*Skip to next From*/
do { Begin=ftell(fBox);
if(fgets(Buffer, 10230, fBox)==NULL)
{ if(feof(fBox)) break;
free(Buffer);
for(i=0;i<msgCount;i++)
{ free(mBox[i].msgID);
}
if(mBox!=NULL) free(mBox);
return(-1);
}
DelEndCRLF(Buffer);
} while(memcmp(Buffer, NEWLETTER, strlen(NEWLETTER))!=0);
if(feof(fBox))
{ break;
}
/*New message found, allocating memory for it*/
if(msgCount==0) mBox=(struct Letter*)malloc(sizeof(struct Letter));
else mBox=(struct Letter*)realloc(mBox, sizeof(struct Letter)*(msgCount+1));
if(mBox==NULL)
{ return(-1);
}
/*Let's set values*/
mBox[msgCount].Begin=Begin;
if(msgCount!=0)
{ mBox[msgCount-1].End=mBox[msgCount].Begin-1;
mBox[msgCount-1].Size=mBox[msgCount-1].End-mBox[msgCount-1].Begin+1;
TotalLen+=mBox[msgCount-1].Size;
}
mBox[msgCount].Deleted=0;
mBox[msgCount].Is866=0;
mBox[msgCount].msgID=(char*)malloc(1);
if(mBox[msgCount].msgID==NULL)
{ for(i=0;i<msgCount;i++)
{ free(mBox[i].msgID);
}
if(mBox!=NULL) free(mBox);
return(-1);
}
mBox[msgCount].msgID[0]=0;
mBox[msgCount].Status=None;
mBox[msgCount].sBeg=0;
mBox[msgCount].sEnd=0;
/*Scanning header for the CHARSET and MSGID*/
do { cBegin=ftell(fBox);
if(fgets(Buffer, 10230, fBox)==NULL)
{ if(feof(fBox)) break;
free(Buffer);
for(i=0;i<msgCount;i++)
{ free(mBox[i].msgID);
}
if(mBox!=NULL) free(mBox);
return(-1);
}
DelSpaces(Buffer);
/*Content-Type: text/plain; charset=x-cp866*/
/*C866*/
if(memicmp(Buffer, CHARSET, strlen(CHARSET))==0)
{ if(strstr(Buffer, C866)!=NULL)
{ mBox[msgCount].Is866=1;
mBox[msgCount].cBeg=cBegin;
mBox[msgCount].cEnd=ftell(fBox);
}
continue;
}
if(memicmp(Buffer, MSGID, strlen(MSGID))==0)
{
DelSpaces(&Buffer[strlen(MSGID)]);
mBox[msgCount].msgID=(char*)realloc(mBox[msgCount].msgID, strlen(&Buffer[strlen(MSGID)])+1);
strcpy(mBox[msgCount].msgID, &Buffer[strlen(MSGID)+1]);
mBox[msgCount].msgID[strlen(mBox[msgCount].msgID)-1]=0;
continue;
}
if(memicmp(Buffer, STATUS, strlen(STATUS))==0)
{ DelSpaces(&Buffer[strlen(STATUS)]);
mBox[msgCount].sBeg=cBegin;
mBox[msgCount].sEnd=ftell(fBox);
if(stricmp(&Buffer[strlen(STATUS)], "U")==0)
{ mBox[msgCount].Status=Unreaded;
continue;
}
if(stricmp(&Buffer[strlen(STATUS)], "R")==0)
{ mBox[msgCount].Status=Readed;
continue;
}
if(stricmp(&Buffer[strlen(STATUS)], "O")==0)
{ mBox[msgCount].Status=Old;
continue;
}
if(stricmp(&Buffer[strlen(STATUS)], "RO")==0)
{ mBox[msgCount].Status=ROld;
continue;
}
mBox[msgCount].Status=Unreaded;
}
} while(!IsEmpty(Buffer));
mBox[msgCount].hEnd=cBegin;
mBox[msgCount].oStatus=mBox[msgCount].Status;
msgCount++;
}while(!feof(fBox));
fseek(fBox, 0, SEEK_END);
if(msgCount>0)
{
mBox[msgCount-1].End=ftell(fBox)-1;
mBox[msgCount-1].Size=mBox[msgCount-1].End-mBox[msgCount-1].Begin+1;
TotalLen+=mBox[msgCount-1].Size;
}
uTotalLen=TotalLen;
uMsgCount=msgCount;
free(Buffer);
if(msgCount==0)
{ mBox=(struct Letter*)malloc(sizeof(struct Letter));
if(mBox==NULL) return(-1);
}
return(0);
}
int CheckUser(char * UserName)
{ struct Pwd Pw;
strncpy(Pw.User, UserName, 8);
if(ReadUser(&Pw, PwdPath)!=0) return(0);
if(Pw.Pass[0]=='*') return(0);
return(1);
}
int CheckPass(char * User, char * Pass)
{ struct Pwd Pw;
strncpy(Pw.User, User, 8);
if(ReadUser(&Pw, PwdPath)!=0) return(0);
if(Pw.Pass[0]=='*') return(0);
if(strcmp(Pw.Pass, Pass)==0) return(1);
return(0);
}
#define USERCMD "USER"
#define PASSCMD "PASS"
#define QUITCMD "QUIT"
#define NOCMD "NOOP"
#define STATCMD "STAT"
#define LISTCMD "LIST"
#define RETRCMD "RETR"
#define DELECMD "DELE"
#define LASTCMD "LAST"
#define RSETCMD "RSET"
#define TOPCMD "TOP"
#define UIDLCMD "UIDL"
int DoCommand(int Socket)
{ char * Buffer;
char * Buffer2;
int Res;
char Password[19]={0};
FILE * fBox=NULL;
register unsigned long i;
long MsgNo, LastMsg=0;
char Ch;
int WasLF;
int sRes;
int Lines;
char * Arg1;
char * Arg2;
int LoggedIn=0;
Buffer=(char*)malloc(2048);
if(Buffer==NULL) return(-1);
Buffer2=(char*)malloc(2048);
if(Buffer2==NULL)
{ free(Buffer);
return(-1);
}
sprintf(Buffer2, "+OK POP3 server glad to meet you here ;) %s\x0D\x0A", ""/*TimeStamp*/);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
do {
/*Waiting for USER command*/
do { sRes=SkGetS(Socket, Buffer);
if(sRes!=0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
DelEndCRLF(Buffer);
DelSpaces(Buffer);
if(memicmp(Buffer, USERCMD, strlen(USERCMD))==0)
{ DelSpaces(&Buffer[strlen(USERCMD)]);
strncpy(UserName, &Buffer[strlen(USERCMD)], 8);
if(CheckUser(UserName))
{ sprintf(Buffer2, "+OK Hello, %s! Please remember your password!\x0D\x0A", UserName);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
}
else
{ sprintf(Buffer2, "-ERR Don't know who is %s\x0D\x0A", UserName);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
UserName[0]=0;
continue;
}
break;
}
if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0)
{ sprintf(Buffer2, "+OK POP3 server signing off\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
break;
}
sprintf(Buffer2, "-ERR Don't know how to do \"%s\"\x0D\x0A", Buffer);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
} while(1);
if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0) return(0);
/*Get password and check it*/
LoggedIn=0;
sRes=SkGetS(Socket, Buffer);
if(sRes!=0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
DelEndCRLF(Buffer);
DelSpaces(Buffer);
if(memicmp(Buffer, PASSCMD, strlen(PASSCMD))==0)
{ DelSpaces(&Buffer[strlen(PASSCMD)]);
strncpy(Password, &Buffer[strlen(PASSCMD)], 8);
if(!CheckPass(UserName, Password))
{ sprintf(Buffer2, "-ERR Login failed\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
Password[0]=0;
UserName[0]=0;
continue;
}
else
{ sprintf(Buffer, "%s%s", BoxPath, UserName);
sprintf(Buffer2, "%s%s.mb", BoxPath, UserName);
/*Open mailbox*/
if(rename(Buffer, Buffer2)<0)
{ sprintf(Buffer2, "-ERR Can't open maildrop for %s\x0D\x0A", UserName);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
strcpy(Buffer, QUITCMD);
break;
}
fBox=_fsopen(Buffer, "w+b", SH_DENYRW);
if(fBox==NULL)
{ sprintf(Buffer2, "-ERR Can't clear maildrop for %s\x0D\x0A", UserName);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
strcpy(Buffer, QUITCMD);
break;
}
fclose(fBox);
fBox=_fsopen(Buffer2, "r+b", SH_DENYRW);
if(fBox==NULL)
{ sprintf(Buffer2, "-ERR Can't open maildrop for %s\x0D\x0A", UserName);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
return(-1);
}
strcpy(Buffer, QUITCMD);
break;
}
sRes=RescanBox(fBox);
if(sRes)
{ sprintf(Buffer2, "-ERR Can't process maildrop for %s\x0D\x0A", UserName);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
strcpy(Buffer, QUITCMD);
break;
}
signal(SIGHUP, (void*)&CrashPack);
signal(SIGINT, (void*)&CrashPack);
signal(SIGQUIT, (void*)&CrashPack);
signal(SIGILL, (void*)&CrashPack);
signal(SIGTRAP, (void*)&CrashPack);
signal(SIGABRT, (void*)&CrashPack);
signal(SIGEMT, (void*)&CrashPack);
signal(SIGFPE, (void*)&CrashPack);
signal(SIGBUS, (void*)&CrashPack);
signal(SIGSEGV, (void*)&CrashPack);
signal(SIGSYS, (void*)&CrashPack);
signal(SIGPIPE, (void*)&CrashPack);
signal(SIGTERM, (void*)&CrashPack);
signal(SIGBREAK, (void*)&CrashPack);
sprintf(Buffer2, "+OK %s's maildrop has %lu messages (%lu octets)\x0D\x0A", UserName, uMsgCount, uTotalLen);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
LoggedIn=1;
}
break;
}
if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0)
{ sprintf(Buffer2, "+OK POP3 server signing off\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
break;
}
sprintf(Buffer2, "-ERR Don't know how to do \"%s\"\x0D\x0A", Buffer);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
} while(LoggedIn==0);
if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0) return(0);
/*Transaction state*/
do { sRes=SkGetS(Socket, Buffer);
if(sRes!=0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
DelEndCRLF(Buffer);
DelSpaces(Buffer);
/*NOOP*/
if(memicmp(Buffer, NOCMD, strlen(NOCMD))==0)
{ sprintf(Buffer2, "+OK It was so hard, but i've done it!\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
continue;
}
/*STAT*/
if(memicmp(Buffer, STATCMD, strlen(STATCMD))==0)
{ sprintf(Buffer2, "+OK %lu %lu\x0D\x0A", uMsgCount, uTotalLen);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
continue;
}
/*LIST*/
if(memicmp(Buffer, LISTCMD, strlen(LISTCMD))==0)
{ DelSpaces(&Buffer[strlen(LISTCMD)]);
if(IsEmpty(&Buffer[strlen(LISTCMD)]))
{ sprintf(Buffer2, "+OK %lu messages (%lu octets)\x0D\x0A", uMsgCount, uTotalLen);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
for(i=0;i<msgCount;i++)
{ if(mBox[i].Deleted) continue;
sprintf(Buffer2, "%lu %lu\x0D\x0A", i+1, mBox[i].Size);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
sprintf(Buffer2, ".\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
if((MsgNo>=msgCount) || (MsgNo<0))
{ sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if(mBox[MsgNo].Deleted)
{ sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ sprintf(Buffer2, "+OK %lu %lu\x0D\x0A", MsgNo+1, mBox[MsgNo].Size);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
LastMsg=MsgNo+1;
}
}
}
continue;
}
/*UIDL*/
if(memicmp(Buffer, UIDLCMD, strlen(UIDLCMD))==0)
{ DelSpaces(&Buffer[strlen(UIDLCMD)]);
if(IsEmpty(&Buffer[strlen(UIDLCMD)]))
{ sprintf(Buffer2, "+OK There's message's names\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
for(i=0;i<msgCount;i++)
{ if(mBox[i].Deleted) continue;
sprintf(Buffer2, "%lu %s\x0D\x0A", i+1, mBox[i].msgID);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
sprintf(Buffer2, ".\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
if((MsgNo>=msgCount) || (MsgNo<0))
{ sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if(mBox[MsgNo].Deleted)
{ sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ sprintf(Buffer2, "+OK %lu %s\x0D\x0A", MsgNo+1, mBox[MsgNo].msgID);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
LastMsg=MsgNo+1;
}
}
}
continue;
}
/*RETR*/
if(memicmp(Buffer, RETRCMD, strlen(RETRCMD))==0)
{ DelSpaces(&Buffer[strlen(RETRCMD)]);
if(IsEmpty(&Buffer[strlen(RETRCMD)]))
{ sprintf(Buffer2, "-ERR Don't know which message you want :~(\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
if((MsgNo>=msgCount) || (MsgNo<0))
{ sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if(mBox[MsgNo].Deleted)
{ sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ sprintf(Buffer2, "+OK %u message's lines follow\x0D\x0A", Lines);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
fseek(fBox, mBox[MsgNo].Begin, SEEK_SET);
WasLF=0;
for(i=mBox[MsgNo].Begin;i<=mBox[MsgNo].End;i++)
{ if(fread(&Ch, 1, 1, fBox)!=1) break;
if((WasLF) && (Ch=='.'))
{ sprintf(Buffer2, ".");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
if(mBox[MsgNo].Is866)
{ if(i==mBox[MsgNo].cBeg)
{
sprintf(Buffer2, "Content-Type: text/plain; charset=koi8-r\x0D\x0A");
i=mBox[MsgNo].cEnd;
fseek(fBox, i, SEEK_SET);
/*i--;*/
}
else
{ sprintf(Buffer2, "%c", cDOS2KOI(Ch));
}
}
else
{ sprintf(Buffer2, "%c", Ch);
}
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
if((Ch==0x0D) || (Ch==0x0A)) WasLF=1;
else WasLF=0;
}
sprintf(Buffer2, ".\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
mBox[MsgNo].Status=ROld;
LastMsg=MsgNo+1;
}
}
}
continue;
}
/*TOP*/
if(memicmp(Buffer, TOPCMD, strlen(TOPCMD))==0)
{ Lines=0;
MsgNo=0;
Arg1=&Buffer[strlen(TOPCMD)];
DelSpaces(Arg1);
for(i=0;i<strlen(Arg1);i++)
{ if(IsSpace(Arg1[i])) break;
}
if(Arg1[i]==0)
{ Arg2=&Arg1[i];
}
else
{ Arg2=&Arg1[i+1];
Arg1[i]=0;
}
DelSpaces(Arg1);
DelSpaces(Arg2);
MsgNo=atol(Arg1)-1;
Lines=atoi(Arg2);
if(IsEmpty(Arg1))
{ sprintf(Buffer2, "-ERR Don't know which message you want :~(\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if((MsgNo>=msgCount) || (MsgNo<0))
{ sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if(mBox[MsgNo].Deleted)
{ sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if(Lines<0)
{ sprintf(Buffer2, "-ERR Value %d is invalid for lines count\x0D\x0A", Lines);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ sprintf(Buffer2, "+OK %u message's lines follow\x0D\x0A", Lines);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
fseek(fBox, mBox[MsgNo].Begin, SEEK_SET);
WasLF=0;
for(i=mBox[MsgNo].Begin;i<=mBox[MsgNo].End;i++)
{ if(fread(&Ch, 1, 1, fBox)!=1) break;
if((WasLF) && (Ch=='.'))
{ sprintf(Buffer2, ".");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
if(mBox[MsgNo].Is866)
{ if(i==mBox[MsgNo].cBeg)
{
sprintf(Buffer2, "Content-Type: text/plain; charset=koi8-r\x0D\x0A");
i=mBox[MsgNo].cEnd;
fseek(fBox, i, SEEK_SET);
/*i--;*/
}
else
{ sprintf(Buffer2, "%c", cDOS2KOI(Ch));
}
}
else
{ sprintf(Buffer2, "%c", Ch);
}
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
if(Ch==0x0A)
{ WasLF=1;
if(i>mBox[MsgNo].hEnd)
{ Lines--;
}
}
else
{ WasLF=0;
}
if(Lines<0) break;
}
sprintf(Buffer2, ".\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
mBox[MsgNo].Status=ROld;
LastMsg=MsgNo+1;
}
}
}
}
continue;
}
/*DELE*/
if(memicmp(Buffer, DELECMD, strlen(DELECMD))==0)
{ DelSpaces(&Buffer[strlen(DELECMD)]);
if(IsEmpty(&Buffer[strlen(DELECMD)]))
{ sprintf(Buffer2, "-ERR Don't know which message you want to delete\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
if((MsgNo>=msgCount) || (MsgNo<0))
{ sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo, msgCount);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ if(mBox[MsgNo].Deleted)
{ sprintf(Buffer2, "-ERR Pervert! You can't kill one message twice\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
}
else
{ sprintf(Buffer2, "+OK message %u killed\x0D\x0A", MsgNo+1);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
mBox[MsgNo].Deleted=1;
uMsgCount--;
uTotalLen-=mBox[MsgNo].Size;
}
}
}
continue;
}
/*LAST*/
if(memicmp(Buffer, LASTCMD, strlen(LASTCMD))==0)
{ if(mBox[LastMsg-1].Deleted) LastMsg=0;
if(LastMsg>msgCount) LastMsg=0;
sprintf(Buffer2, "+OK %lu\x0D\x0A", LastMsg);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
continue;
}
/*RSET*/
if(memicmp(Buffer, RSETCMD, strlen(RSETCMD))==0)
{ for(i=0;i<msgCount;i++)
mBox[i].Deleted=0;
uMsgCount=msgCount;
uTotalLen=TotalLen;
continue;
}
/*QUIT*/
if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0)
{ break;
}
sprintf(Buffer2, "-ERR Don't know how to do \"%s\"\x0D\x0A", Buffer);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
PackBox(UserName, 0);
return(-1);
}
} while(1);
free(Buffer);
free(Buffer2);
if(fBox!=NULL) fclose(fBox);
if(PackBox(UserName, 1)==0)
{ sprintf(Buffer2, "+OK %lu messages (%lu octets) remains\x0D\x0A", uMsgCount, uTotalLen);
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
}
else
{ sprintf(Buffer2, "-ERR All changes has been discarded :(\x0D\x0A");
sRes=write(Socket, Buffer2, strlen(Buffer2));
if(sRes<0)
{ free(Buffer);
free(Buffer2);
if(fBox) fclose(fBox);
return(-1);
}
}
for(i=0;i<msgCount;i++)
{ free(mBox[i].msgID);
}
if(mBox!=NULL) free(mBox);
return(Res);
}
char MyName[512];
int main (int ArgC, char * ArgV[])
{ int Res;
struct hostent MyHost;
struct in_addr MyAddr;
unsigned long * lMyAddr;
fprintf(stderr,"vPopper/2. (C)'97 VR vik@lada.kiev.ua 2:463/262 2:463/278\n");
if((ArgC>1) && (ArgV[1][1]=='?'))
{ fprintf(stderr, "POP3 server/2.\nUsage : %s [mailboxes path [passwd file]]\n", ArgV[0]);
fprintf(stderr, "Default values : mailbox path = ./\n"
" passwd file = passwd\n");
return(0);
}
if(ArgC>1)
{ strncpy(BoxPath, ArgV[1], 510);
if((BoxPath[strlen(BoxPath)-1]!='\\') && (BoxPath[strlen(BoxPath)-1]!='/'))
{ strcat(BoxPath, "\\");
}
}
if(ArgC>2)
{ strncpy(PwdPath, ArgV[2], 511);
}
MyName[0]=0;
gethostname(MyName, 511);
/* memcpy(&MyHost, gethostbyname(MyName), sizeof(MyHost));*/
/* memcpy(&MyAddr.s_addr, MyHost->h_addr_list[0], MyHost->h_length);*/
/* fprintf(stderr, "POP3@%s [%s]\n", MyName, inet_ntoa(MyAddr));*/
fprintf(stderr, "POP3@%s\n", MyName);
fprintf(stderr, "Using [%s] as passwd\nand [%s] as mail/boxes\n", PwdPath, BoxPath);
fprintf(stderr, "Initializing\n");
WaitConn();
fprintf(stderr, " \nTerminated\n\n");
return(0);
}