From f5d7521339a918da19ca91971cf3317bb2f5c93f Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 16 Apr 2005 16:23:40 +0000 Subject: [PATCH] Making these plugins. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@944 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/email/imapnoti.c | 432 --------------------------- engine/email/pop3noti.c | 523 -------------------------------- engine/email/sv_pop3.c | 644 ---------------------------------------- engine/email/sv_smtp.c | 449 ---------------------------- 4 files changed, 2048 deletions(-) delete mode 100644 engine/email/imapnoti.c delete mode 100644 engine/email/pop3noti.c delete mode 100644 engine/email/sv_pop3.c delete mode 100644 engine/email/sv_smtp.c diff --git a/engine/email/imapnoti.c b/engine/email/imapnoti.c deleted file mode 100644 index 8c6d81c75..000000000 --- a/engine/email/imapnoti.c +++ /dev/null @@ -1,432 +0,0 @@ -#include "quakedef.h" - -#ifdef EMAILCLIENT - -//code to sit on an imap server and check for new emails every now and then. - -#include "winquake.h" - -#ifdef _WIN32 - #define EWOULDBLOCK WSAEWOULDBLOCK - #define EMSGSIZE WSAEMSGSIZE - #define ECONNRESET WSAECONNRESET - #define ECONNABORTED WSAECONNABORTED - #define ECONNREFUSED WSAECONNREFUSED - #define EADDRNOTAVAIL WSAEADDRNOTAVAIL - -#define qerrno WSAGetLastError() -#else -#define qerrno errno - - #define MSG_PARTIAL 0 - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - - #define closesocket close - #define ioctlsocket ioctl -#endif - - - -//exported. -void IMAP_CreateConnection(char *servername, char *username, char *password); -cvar_t imap_checkfrequency = {"imap_checkfrequency", "60"}; //once a min -void IMAP_Think (void); -//end export list. - - - - -#define IMAP_PORT 143 - - -typedef struct imap_con_s { - char server[128]; - char username[128]; - char password[128]; - - float lastnoop; - - //these are used so we can fail a send. - //or recieve only part of an input. - //FIXME: make dynamically sizable, as it could drop if the send is too small (That's okay. - // but if the read is bigger than one command we suddenly fail entirly. - int sendlen; - int sendbuffersize; - char *sendbuffer; - int readlen; - int readbuffersize; - char *readbuffer; - - qboolean drop; - - int socket; - - enum { - IMAP_WAITINGFORINITIALRESPONCE, - IMAP_AUTHING, - IMAP_AUTHED, - IMAP_INBOX - } state; - - struct imap_con_s *next; -} imap_con_t; - -static imap_con_t *imapsv; - -void IMAP_CreateConnection(char *addy, char *username, char *password) -{ - unsigned long _true = true; - struct sockaddr_qstorage from; - imap_con_t *con; - - for (con = imapsv; con; con = con->next) - { - if (!strcmp(con->server, addy)) - { - Con_Printf("Already connected to that imap server\n"); - return; - } - } - - con = IWebMalloc(sizeof(imap_con_t)); - - - - if ((con->socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - { - Sys_Error ("IMAP_CreateConnection: socket: %s\n", strerror(qerrno)); - } - - - {//quake routines using dns and stuff (Really, I wanna keep quake and imap fairly seperate) - netadr_t qaddy; - NET_StringToAdr (addy, &qaddy); - if (!qaddy.port) - qaddy.port = htons(IMAP_PORT); - NetadrToSockadr(&qaddy, &from); - } - - //not yet blocking. - if (connect(con->socket, (struct sockaddr *)&from, sizeof(from)) == -1) - { - IWebWarnPrintf ("IMAP_CreateConnection: connect: %i %s\n", qerrno, strerror(qerrno)); - closesocket(con->socket); - IWebFree(con); - return; - } - - if (ioctlsocket (con->socket, FIONBIO, &_true) == -1) //now make it non blocking. - { - Sys_Error ("IMAP_CreateConnection: ioctl FIONBIO: %s\n", strerror(qerrno)); - } - - Q_strncpyz(con->server, addy, sizeof(con->server)); - Q_strncpyz(con->username, username, sizeof(con->username)); - Q_strncpyz(con->password, password, sizeof(con->password)); - - con->next = imapsv; - imapsv = con; -} - -static void IMAP_EmitCommand(imap_con_t *imap, char *text) -{ - int newlen; - char rt[64]; - sprintf(rt, "* "); //now this is lame. Quite possibly unreliable... - //makes a few things easier though - - newlen = imap->sendlen + strlen(text) + strlen(rt) + 2; - - if (newlen >= imap->sendbuffersize || !imap->sendbuffer) //pre-length check. - { - char *newbuf; - imap->sendbuffersize = newlen*2; - newbuf = IWebMalloc(imap->sendbuffersize); - if (!newbuf) - { - Con_Printf("Memory is low\n"); - imap->drop = true; //failed. - return; - } - if (imap->sendbuffer) - { - memcpy(newbuf, imap->sendbuffer, imap->sendlen); - IWebFree(imap->sendbuffer); - } - imap->sendbuffer = newbuf; - } - - imap->sendlen = newlen; - - strncat(imap->sendbuffer, rt, imap->sendbuffersize-1); - strncat(imap->sendbuffer, text, imap->sendbuffersize-1); - strncat(imap->sendbuffer, "\r\n", imap->sendbuffersize-1); -} - -static char *IMAP_AddressStructure(char *msg, char *out, int outsize) -{ - char name[256]; - char mailbox[64]; - char hostname[128]; - int indents=0; - while(*msg == ' ') - msg++; - while(*msg == '(') //do it like this, we can get 2... I'm not sure if that's always true.. - { - msg++; - indents++; - } - - msg = COM_Parse(msg); //name - Q_strncpyz(name, com_token, sizeof(name)); - msg = COM_Parse(msg); //smtp route (ignored normally) - msg = COM_Parse(msg); //mailbox - Q_strncpyz(mailbox, com_token, sizeof(mailbox)); - msg = COM_Parse(msg); //hostname - Q_strncpyz(hostname, com_token, sizeof(hostname)); - - while(indents && *msg == ')') - msg++; - - if (out) - { - if (!strcmp(name, "NIL")) - { - Q_strncpyz(out, mailbox, outsize-1); - strncat(out, "@", outsize-1); - strncat(out, hostname, outsize-1); - } - else - { - Q_strncpyz(out, name, outsize-1); - - strncat(out, " <", outsize-1); - strncat(out, mailbox, outsize-1); - strncat(out, "@", outsize-1); - strncat(out, hostname, outsize-1); - strncat(out, ">", outsize-1); - } - } - - return msg; -} - -static qboolean IMAP_ThinkCon(imap_con_t *imap) //false means drop the connection. -{ - char *ending; - int len; - - //get the buffer, stick it in our read holder - if (imap->readlen+32 >= imap->readbuffersize || !imap->readbuffer) - { - len = imap->readbuffersize; - if (!imap->readbuffer) - imap->readbuffersize = 256; - else - imap->readbuffersize*=2; - - ending = IWebMalloc(imap->readbuffersize); - if (!ending) - { - Con_Printf("Memory is low\n"); - return false; - } - if (imap->readbuffer) - { - memcpy(ending, imap->readbuffer, len); - IWebFree(imap->readbuffer); - } - imap->readbuffer = ending; - } - - len = recv(imap->socket, imap->readbuffer+imap->readlen, imap->readbuffersize-imap->readlen-1, 0); - if (len>0) - { - imap->readlen+=len; - imap->readbuffer[imap->readlen] = '\0'; - } - - if (imap->readlen>0) - { - ending = strstr(imap->readbuffer, "\r\n"); - - if (ending) //pollable text. - { - *ending = '\0'; -// Con_Printf("%s\n", imap->readbuffer); - - ending+=2; - if (imap->state == IMAP_WAITINGFORINITIALRESPONCE) - { - //can be one of two things. - if (!strncmp(imap->readbuffer, "* OK", 4)) - { - IMAP_EmitCommand(imap, va("LOGIN %s %s", imap->username, imap->password)); - imap->state = IMAP_AUTHING; - } - else if (!strncmp(imap->readbuffer, "* PREAUTH", 9)) - { - Con_Printf("Logged on to %s\n", imap->server); - IMAP_EmitCommand(imap, "SELECT INBOX"); - imap->state = IMAP_AUTHED; - imap->lastnoop = Sys_DoubleTime(); - } - else - { - Con_Printf("Unexpected response from IMAP server\n"); - return false; - } - } - else if (imap->state == IMAP_AUTHING) - { - if (!strncmp(imap->readbuffer, "* OK", 4)) - { - Con_Printf("Logged on to %s\n", imap->server); - IMAP_EmitCommand(imap, "SELECT INBOX"); - imap->state = IMAP_AUTHED; - imap->lastnoop = Sys_DoubleTime(); - } - else - { - Con_Printf("Unexpected response from IMAP server\n"); - return false; - } - } - else if (imap->state == IMAP_AUTHED) - { - char *num; - num = imap->readbuffer; - if (!strncmp(imap->readbuffer, "* SEARCH ", 8)) //we only ever search for recent messages. So we fetch them and get sender and subject. - { - char *s; - s = imap->readbuffer+8; - num = NULL; - while(*s) - { - s++; - num = s; - while (*s >= '0' && *s <= '9') - s++; - - IMAP_EmitCommand(imap, va("FETCH %i ENVELOPE", atoi(num))); //envelope so that it's all one line. - } - } - else if (imap->readbuffer[0] == '*' && imap->readbuffer[1] == ' ') - { - num = imap->readbuffer+2; - while(*num >= '0' && *num <= '9') - { - num++; - } - if (!strcmp(num, " RECENT")) - { - if (atoi(imap->readbuffer+2) > 0) - { - IMAP_EmitCommand(imap, "SEARCH RECENT"); - } - } - else if (!strncmp(num, " FETCH (ENVELOPE (", 18)) - { - char from[256]; - char subject[256]; - - num += 18; - - num = COM_Parse(num); -// Con_Printf("Date/Time: %s\n", com_token); - - num = COM_Parse(num); - Q_strncpyz(subject, com_token, sizeof(subject)); - - num = IMAP_AddressStructure(num, from, sizeof(from)); - - - if ((rand() & 3) == 3) - { - if (rand()) - Con_Printf("\n^2New spam has arrived\n"); - else - Con_Printf("\n^2You have new spam\n"); - } - else if (rand()&1) - Con_Printf("\n^2New mail has arrived\n"); - else - Con_Printf("\n^2You have new mail\n"); - - Con_Printf("Subject: %s\n", subject); - Con_Printf("From: %s\n", from); - - SCR_CenterPrint(0, va("NEW MAIL HAS ARRIVED\n\nTo: %s@%s\nFrom: %s\nSubject: %s", imap->username, imap->server, from, subject)); - - //throw the rest away. - } - } - } - else - { - Con_Printf("Bad client state\n"); - return false; - } - imap->readlen -= ending - imap->readbuffer; - memmove(imap->readbuffer, ending, strlen(ending)+1); - } - } - if (imap->drop) - return false; - - if (imap->state == IMAP_AUTHED) - { - if (imap->lastnoop + imap_checkfrequency.value < Sys_DoubleTime()) - { //we need to keep the connection reasonably active - - IMAP_EmitCommand(imap, "SELECT INBOX"); //this causes the recent flags to be reset. This is the only way I found. - imap->lastnoop = Sys_DoubleTime(); - } - } - - if (imap->sendlen) - { - len = send(imap->socket, imap->sendbuffer, imap->sendlen, 0); - if (len>0) - { - imap->sendlen-=len; - memmove(imap->sendbuffer, imap->sendbuffer+len, imap->sendlen+1); - } - } - return true; -} - -void IMAP_Think (void) -{ - imap_con_t *prev = NULL; - imap_con_t *imap; - - for (imap = imapsv; imap; imap = imap->next) - { - if (imap->drop || !IMAP_ThinkCon(imap)) - { - if (!prev) - imapsv = imap->next; - else - prev->next = imap->next; - closesocket(imap->socket); - BZ_Free(imap); - if (!prev) - break; - } - - prev = imap; - } -} - -#endif diff --git a/engine/email/pop3noti.c b/engine/email/pop3noti.c deleted file mode 100644 index 83edfa56f..000000000 --- a/engine/email/pop3noti.c +++ /dev/null @@ -1,523 +0,0 @@ -#include "quakedef.h" - -#ifdef EMAILCLIENT - -//the idea is to send a UIDL request, and compare against the previous list. -//this list will be stored on disk on quit. - -//be aware that we cannot stay connected. POP3 mailboxs are not refreshable without disconnecting. -//so we have a special state. - - -#include "winquake.h" - -#ifdef _WIN32 - #define EWOULDBLOCK WSAEWOULDBLOCK - #define EMSGSIZE WSAEMSGSIZE - #define ECONNRESET WSAECONNRESET - #define ECONNABORTED WSAECONNABORTED - #define ECONNREFUSED WSAECONNREFUSED - #define EADDRNOTAVAIL WSAEADDRNOTAVAIL - -#define qerrno WSAGetLastError() -#else -#define qerrno errno - - #define MSG_PARTIAL 0 - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - - #define closesocket close - #define ioctlsocket ioctl -#endif - - -char *MD5_GetPop3APOPString(char *timestamp, char *secrit); - - - -#include "hash.h" - - - - - - -//exported. -void POP3_CreateConnection(char *servername, char *username, char *password); -cvar_t pop3_checkfrequency = {"pop3_checkfrequency", "60"}; //once a min -void POP3_Think (void); -void POP3_WriteCache (void); -//end export list. - -#define HASHELEMENTS 512 - -static hashtable_t pop3msghash; - -qboolean POP3_IsMessageUnique(char *hash) -{ - char *buf; - if (!pop3msghash.numbuckets) - Hash_InitTable(&pop3msghash, HASHELEMENTS, BZ_Malloc(Hash_BytesForBuckets(HASHELEMENTS))); - if (Hash_Get(&pop3msghash, hash)) - return false; - - buf = Z_Malloc(sizeof(bucket_t) + strlen(hash)+1); - strcpy(buf+sizeof(bucket_t), hash); - hash = buf+sizeof(bucket_t); - Hash_Add(&pop3msghash, hash, hash, (bucket_t *)buf); - - return true; -} - -#define POP3_PORT 110 - - -typedef struct pop3_con_s { - char server[128]; - char username[128]; - char password[128]; - - float lastnoop; - - //these are used so we can fail a send. - //or recieve only part of an input. - //FIXME: make dynamically sizable, as it could drop if the send is too small (That's okay. - // but if the read is bigger than one command we suddenly fail entirly.) - int sendlen; - int sendbuffersize; - char *sendbuffer; - int readlen; - int readbuffersize; - char *readbuffer; - - qboolean drop; - - int socket; - - //we have a certain number of stages. - enum { - POP3_NOTCONNECTED, - POP3_WAITINGFORINITIALRESPONCE, //waiting for an initial response. - POP3_AUTHING, //wating for a response from USER - POP3_AUTHING2, //Set PASS, waiting to see if we passed. - POP3_LISTING, //Sent UIDL, waiting to see - POP3_RETRIEVING, //sent TOP, waiting for message headers to print info. - POP3_HEADER, - POP3_BODY, - POP3_QUITTING - } state; - - int retrlist[256]; //unrecognised uidls are added to this list. - int numtoretrieve; - - char msgsubject[256]; - char msgfrom[256]; - - struct pop3_con_s *next; -} pop3_con_t; - -static pop3_con_t *pop3sv; - -void POP3_CreateConnection(char *addy, char *username, char *password) -{ - unsigned long _true = true; - struct sockaddr_in from; - struct sockaddr_qstorage to; - pop3_con_t *con; - - for (con = pop3sv; con; con = con->next) - { - if (!strcmp(con->server, addy) && !strcmp(con->username, username)) - { - if (con->state == POP3_NOTCONNECTED && !con->socket) - break; - Con_Printf("Already connected to that pop3 server\n"); - return; - } - } - - {//quake routines using dns and stuff (Really, I wanna keep quake and pop3 fairly seperate) - netadr_t qaddy; - if (!NET_StringToAdr (addy, &qaddy)) - return; //failed to resolve dns. - if (!qaddy.port) - qaddy.port = htons(POP3_PORT); - NetadrToSockadr(&qaddy, &to); - } - - if (!con) - con = IWebMalloc(sizeof(pop3_con_t)); - else - con->state = POP3_WAITINGFORINITIALRESPONCE; - - - - if ((con->socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - { - Sys_Error ("POP3_CreateConnection: socket: %s\n", strerror(qerrno)); - } - - memset(&from, 0, sizeof(from)); - from.sin_family = AF_INET; - if (bind(con->socket, (struct sockaddr*)&from, sizeof(from)) == -1) - { - IWebWarnPrintf ("POP3_CreateConnection: failed to bind: %s\n", strerror(qerrno)); - } - - //not yet blocking. - if (connect(con->socket, (struct sockaddr*)&to, sizeof(to)) == -1) - { - IWebWarnPrintf ("POP3_CreateConnection: connect: %s\n", strerror(qerrno)); - closesocket(con->socket); - IWebFree(con); - return; - } - - if (ioctlsocket (con->socket, FIONBIO, &_true) == -1) //now make it non blocking. - { - Sys_Error ("POP3_CreateConnection: ioctl FIONBIO: %s\n", strerror(qerrno)); - } - - Q_strncpyz(con->server, addy, sizeof(con->server)); - Q_strncpyz(con->username, username, sizeof(con->username)); - Q_strncpyz(con->password, password, sizeof(con->password)); - - if (!con->state) - { - con->state = POP3_WAITINGFORINITIALRESPONCE; - - con->next = pop3sv; - pop3sv = con; - - Con_Printf("Connected to %s\n", con->server); - } -} - -static void POP3_EmitCommand(pop3_con_t *pop3, char *text) -{ - int newlen; - - newlen = pop3->sendlen + strlen(text) + 2; - - if (newlen >= pop3->sendbuffersize || !pop3->sendbuffer) //pre-length check. - { - char *newbuf; - pop3->sendbuffersize = newlen*2; - newbuf = IWebMalloc(pop3->sendbuffersize); - if (!newbuf) - { - Con_Printf("Memory is low\n"); - pop3->drop = true; //failed. - return; - } - if (pop3->sendbuffer) - { - memcpy(newbuf, pop3->sendbuffer, pop3->sendlen); - IWebFree(pop3->sendbuffer); - } - pop3->sendbuffer = newbuf; - } - - pop3->sendlen = newlen; - - strncat(pop3->sendbuffer, text, pop3->sendbuffersize-1); - strncat(pop3->sendbuffer, "\r\n", pop3->sendbuffersize-1); - -// Con_Printf("^3%s\n", text); -} - -static qboolean POP3_ThinkCon(pop3_con_t *pop3) //false means drop the connection. -{ - char *ending; - int len; - - if (pop3->state == POP3_NOTCONNECTED && !pop3->socket) - { - if (pop3->lastnoop + pop3_checkfrequency.value < Sys_DoubleTime()) - { //we need to recreate the connection now. - pop3->lastnoop = Sys_DoubleTime(); - POP3_CreateConnection(pop3->server, pop3->username, pop3->password); - } - - return true; - } - - //get the buffer, stick it in our read holder - if (pop3->readlen+32 >= pop3->readbuffersize || !pop3->readbuffer) - { - len = pop3->readbuffersize; - if (!pop3->readbuffer) - pop3->readbuffersize = 256; - else - pop3->readbuffersize*=2; - - ending = IWebMalloc(pop3->readbuffersize); - if (!ending) - { - Con_Printf("Memory is low\n"); - return false; - } - if (pop3->readbuffer) - { - memcpy(ending, pop3->readbuffer, len); - IWebFree(pop3->readbuffer); - } - pop3->readbuffer = ending; - } - - len = recv(pop3->socket, pop3->readbuffer+pop3->readlen, pop3->readbuffersize-pop3->readlen-1, 0); - if (len>0) - { - pop3->readlen+=len; - pop3->readbuffer[pop3->readlen] = '\0'; - } - - if (pop3->readlen>0) - { - ending = strstr(pop3->readbuffer, "\r\n"); - - if (ending) //pollable text. - { - *ending = '\0'; -// Con_Printf("^2%s\n", pop3->readbuffer); - - ending+=2; - if (pop3->state == POP3_WAITINGFORINITIALRESPONCE) - { - if (!strncmp(pop3->readbuffer, "+OK", 3)) - { - char *angle1; - char *angle2 = NULL; - angle1 = strchr(pop3->readbuffer, '<'); - if (angle1) - { - angle2 = strchr(angle1+1, '>'); - } - if (angle2) - { //just in case - angle2[1] = '\0'; - - POP3_EmitCommand(pop3, va("APOP %s %s", pop3->username, MD5_GetPop3APOPString(angle1, pop3->password))); - pop3->state = POP3_AUTHING2; - } - else - { - POP3_EmitCommand(pop3, va("USER %s", pop3->username)); - pop3->state = POP3_AUTHING; - } - } - else - { - Con_Printf("Unexpected response from POP3 server\n"); - return false; //some sort of error. - } - } - else if (pop3->state == POP3_AUTHING) - { - if (!strncmp(pop3->readbuffer, "+OK", 3)) - { - POP3_EmitCommand(pop3, va("PASS %s", pop3->password)); - pop3->state = POP3_AUTHING2; - } - else - { - Con_Printf("Unexpected response from POP3 server.\nCheck username/password\n"); - return false; //some sort of error. - } - } - else if (pop3->state == POP3_AUTHING2) - { - if (!strncmp(pop3->readbuffer, "+OK", 3)) - { - POP3_EmitCommand(pop3, "UIDL"); - pop3->state = POP3_LISTING; - pop3->lastnoop = Sys_DoubleTime(); - } - else - { - Con_Printf("Unexpected response from POP3 server.\nCheck username/password\n"); - return false; - } - } - else if (pop3->state == POP3_LISTING) - { - if (!strncmp(pop3->readbuffer, "-ERR", 4)) - { - Con_Printf("Unexpected response from POP3 server.\nUIDL not supported?\n"); - return false; - } - else if (!strncmp(pop3->readbuffer, "+OK", 3)) - { - } - else if (!strncmp(pop3->readbuffer, ".", 1)) //we only ever search for recent messages. So we fetch them and get sender and subject. - { - if (!pop3->numtoretrieve) - { - pop3->state = POP3_QUITTING; - POP3_EmitCommand(pop3, "QUIT"); - } - else - { - pop3->state = POP3_RETRIEVING; - POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve])); - } - } - else - { - char *s; - s = pop3->readbuffer; - if (*s) - { - s++; - while (*s >= '0' && *s <= '9') - s++; - while (*s == ' ') - s++; - } - - if (POP3_IsMessageUnique(s)) - if (pop3->numtoretrieve < sizeof(pop3->retrlist)/sizeof(pop3->retrlist[0])) - pop3->retrlist[pop3->numtoretrieve++] = atoi(pop3->readbuffer); - } - } - else if (pop3->state == POP3_RETRIEVING) - { - if (!strncmp(pop3->readbuffer, "+OK", 3)) - { - pop3->msgsubject[0] = '\0'; - pop3->msgfrom[0] = '\0'; - - pop3->state = POP3_HEADER; - } - else - { //erm... go for the next? - if (!pop3->numtoretrieve) - { - pop3->state = POP3_QUITTING; - POP3_EmitCommand(pop3, "QUIT"); - } - else - POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve])); - } - } - else if (pop3->state == POP3_HEADER) - { - if (!strnicmp(pop3->readbuffer, "From: ", 6)) - Q_strncpyz(pop3->msgfrom, pop3->readbuffer + 6, sizeof(pop3->msgfrom)); - else if (!strnicmp(pop3->readbuffer, "Subject: ", 9)) - Q_strncpyz(pop3->msgsubject, pop3->readbuffer + 9, sizeof(pop3->msgsubject)); - else if (!strncmp(pop3->readbuffer, ".", 1)) - { - Con_Printf("New message:\nFrom: %s\nSubject: %s\n", pop3->msgfrom, pop3->msgsubject); - - if (!pop3->numtoretrieve) - { - pop3->state = POP3_QUITTING; - POP3_EmitCommand(pop3, "QUIT"); - } - else - { - pop3->state = POP3_RETRIEVING; - POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve])); - } - } - else if (!*pop3->readbuffer) - pop3->state = POP3_BODY; - } - else if (pop3->state == POP3_BODY) - { - if (!strncmp(pop3->readbuffer, "..", 2)) - { - //line of text, skipping first '.' - Con_Printf("%s\n", pop3->readbuffer+1); - } - else if (!strncmp(pop3->readbuffer, ".", 1)) - { - Con_Printf("New message:\nFrom: %s\nSubject: %s\n", pop3->msgfrom, pop3->msgsubject); - - if (!pop3->numtoretrieve) - { - pop3->state = POP3_QUITTING; - POP3_EmitCommand(pop3, "QUIT"); - } - else - { - pop3->state = POP3_RETRIEVING; - POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve])); - } - } - else - { - //normal line of text - Con_Printf("%s\n", pop3->readbuffer); - } - } - else if (pop3->state == POP3_QUITTING) - { - pop3->state = POP3_NOTCONNECTED; - closesocket(pop3->socket); - pop3->lastnoop = Sys_DoubleTime(); - pop3->socket = 0; - pop3->readlen = 0; - pop3->sendlen = 0; - return true; - } - else - { - Con_Printf("Bad client state\n"); - return false; - } - pop3->readlen -= ending - pop3->readbuffer; - memmove(pop3->readbuffer, ending, strlen(ending)+1); - } - } - if (pop3->drop) - return false; - - if (pop3->sendlen) - { - len = send(pop3->socket, pop3->sendbuffer, pop3->sendlen, 0); - if (len>0) - { - pop3->sendlen-=len; - memmove(pop3->sendbuffer, pop3->sendbuffer+len, pop3->sendlen+1); - } - } - return true; -} - -void POP3_Think (void) -{ - pop3_con_t *prev = NULL; - pop3_con_t *pop3; - - for (pop3 = pop3sv; pop3; pop3 = pop3->next) - { - if (pop3->drop || !POP3_ThinkCon(pop3)) - { - if (!prev) - pop3sv = pop3->next; - else - prev->next = pop3->next; - if (pop3->socket) - closesocket(pop3->socket); - BZ_Free(pop3); - if (!prev) - break; - } - - prev = pop3; - } -} - -#endif diff --git a/engine/email/sv_pop3.c b/engine/email/sv_pop3.c deleted file mode 100644 index 1c46fc835..000000000 --- a/engine/email/sv_pop3.c +++ /dev/null @@ -1,644 +0,0 @@ -#include "quakedef.h" - -#ifdef EMAILSERVER - -#include "winquake.h" - -//FIXME: the DELE command's effects arn't properly checked. -//FIXME: no UIDL command - -//FIXME: remove sequential naming. - -char *MD5_GetPop3APOPString(char *timestamp, char *secrit); - - - - - - - -#include "hash.h" - - - - - - - - -#ifdef _WIN32 -#define EWOULDBLOCK WSAEWOULDBLOCK -#define EMSGSIZE WSAEMSGSIZE -#define ECONNRESET WSAECONNRESET -#define ECONNABORTED WSAECONNABORTED -#define ECONNREFUSED WSAECONNREFUSED -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL - - -#define qerrno WSAGetLastError() -#else -#define qerrno errno - -#define MSG_PARTIAL 0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define closesocket close -#define ioctlsocket ioctl -#endif - - -#define POP3_PORT 110 -#define POP3_TIMEOUT 30 - -static qboolean pop3active; -static int pop3serversocket; - -typedef struct { - char filename[MAX_QPATH]; - int size; - qboolean deleted; - bucket_t bucket; -} pop3message_t; - -typedef struct svpop3client_s { - struct svpop3client_s *next; - - int socket; - - float timeout; - - char *messagelump; - int messagelumppos; - int messagelumplen; - qboolean messagelumphitbody; - int messagelumplines; //lines to send past header - - int nummessages; - int totalsize; - - char greeting[64]; - char username[64]; - qboolean loggedin; - - char inmessagebuffer[1024]; - int inmessagelen; - char outmessagebuffer[1024]; - int outmessagelen; - qboolean dropwhensent; - -#define NUMBUCKETS 64 - hashtable_t emails; - bucket_t *bucketpointer[NUMBUCKETS]; -} svpop3client_t; -static svpop3client_t *svpop3client; - - - - - -static void POP3_ServerInit(void) -{ - struct sockaddr_in address; - unsigned long _true = true; - int port = POP3_PORT; - - if ((pop3serversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - { - Sys_Error ("FTP_TCP_OpenSocket: socket:", strerror(qerrno)); - } - - if (ioctlsocket (pop3serversocket, FIONBIO, &_true) == -1) - { - Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); - } - - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - - if (port == PORT_ANY) - address.sin_port = 0; - else - address.sin_port = htons((short)port); - - if( bind (pop3serversocket, (void *)&address, sizeof(address)) == -1) - { - closesocket(pop3serversocket); - return; - } - - listen(pop3serversocket, 3); - - pop3active = true; - - - IWebPrintf("POP3 server is running\n"); - return; -} - -static void POP3_ServerShutdown(void) -{ - closesocket(pop3serversocket); - pop3active = false; -} - -static void SV_POP3_QueueMessage(svpop3client_t *cl, char *msg) -{ - int len = strlen(msg); - if (len + cl->outmessagelen > sizeof(cl->outmessagebuffer)-1) - len = sizeof(cl->outmessagebuffer)-1 - cl->outmessagelen; - Q_strncpyz(cl->outmessagebuffer+cl->outmessagelen, msg, len+1); - cl->outmessagelen += len; -} - -static void POP3_NewConnection(int socket) -{ - unsigned long _true = true; - svpop3client_t *newcl; - newcl = IWebMalloc(sizeof(svpop3client_t)); - if (!newcl) //bother - { - closesocket(socket); - return; - } - if (ioctlsocket (socket, FIONBIO, &_true) == -1) - { - closesocket(socket); - return; - } - memset(newcl, 0, sizeof(svpop3client_t)); - - newcl->socket = socket; - newcl->next = svpop3client; - svpop3client = newcl; - - newcl->timeout = realtime + POP3_TIMEOUT; - - *newcl->outmessagebuffer = '\0'; - - sprintf(newcl->greeting, "<%i.%i.%i.%i.%i.%i.%i>", rand(), rand(), rand(), rand(), rand(), rand(), rand()); -// _true = strlen(newcl->greeting); - -printf("newclient\n"); - - SV_POP3_QueueMessage(newcl, va("+OK %s\r\n", newcl->greeting)); -} - -static int SV_POP3_AddMessage(char *filename, int flags, void *incl) -{ - FILE *f; - svpop3client_t *cl = incl; - pop3message_t *msg; - - f = fopen(filename, "rb"); - if (!f) - return true; //shouldn't happen - - msg = IWebMalloc(sizeof(pop3message_t)); - if (!msg) - { - fclose(f); - return false; - } - - Q_strncpyz(msg->filename, filename, sizeof(msg->filename)); - msg->deleted = false; - - fseek(f, 0, SEEK_END); - msg->size = ftell(f); - fclose(f); - - cl->totalsize+=msg->size; - cl->nummessages++; - - Hash_Add(&cl->emails, va("%i", ++cl->nummessages), msg, &msg->bucket); - - return true; -} - -static void SV_POP3_CountMessages(svpop3client_t *cl) -{ - Hash_InitTable(&cl->emails, NUMBUCKETS, cl->bucketpointer); - cl->totalsize=0; - Sys_EnumerateFiles(".", va("emails/%s/*.eml", cl->username), SV_POP3_AddMessage, cl); -} - -static pop3message_t *SV_POP3_GetMessage(svpop3client_t *cl, int num) -{ - pop3message_t *msg; - - msg = IWebMalloc(sizeof(pop3message_t)); - if (!msg) - return NULL; - - if (msg->deleted) - return NULL; - - msg = Hash_Get(&cl->emails, va("%i", num)); - - return msg; -} - -static void SV_POP3_CleanUp(svpop3client_t *cl, qboolean dodelete) //closes the messages list created by SV_POP3_CountMessages -{ - pop3message_t *msg; - int mn; - for (mn = 1; mn <= cl->nummessages; mn++) - { - msg = SV_POP3_GetMessage(cl, mn); - if (!msg) - continue; - - if (dodelete && msg->deleted) - { - remove(msg->filename); - } - - Hash_Remove(&cl->emails, va("%i", mn)); - BZ_Free(msg); - } -} - -static qboolean SV_POP3_ReadMessage(svpop3client_t *cl, int index) -{ - FILE *f; - pop3message_t *msg; - - msg = SV_POP3_GetMessage(cl, index); - if (!msg) - return false; - if (msg->deleted) - return false; - - f = fopen(msg->filename, "rb"); - if (!f) - return false; - fseek(f, 0, SEEK_END); - cl->messagelumplen = ftell(f); - fseek(f, 0, SEEK_SET); - cl->messagelump = IWebMalloc(cl->messagelumplen+3); - fread(cl->messagelump, 1, cl->messagelumplen, f); - cl->messagelump[cl->messagelumplen++] = '\r'; - cl->messagelump[cl->messagelumplen++] = '\n'; - fclose(f); - - cl->messagelumplen = strlen(cl->messagelump); - cl->messagelumppos = 0; - cl->messagelumphitbody = false; - cl->messagelumplines = 0x7fffffff; - - return true; -} - -static void SV_POP3_BuildListing(svpop3client_t *cl, qboolean isuidl) -{ - pop3message_t *msg; - int mn; - char *listing; - - listing = cl->messagelump = IWebMalloc(cl->nummessages*64+3); - - for (mn = 1; mn <= cl->nummessages; mn++) - { - msg = SV_POP3_GetMessage(cl, mn); - if (!msg || msg->deleted) - continue; - - if (isuidl) - sprintf(listing, "%i %s,S=%i\r\n", mn, msg->filename, msg->size); - else - sprintf(listing, "%i %i\r\n", mn, msg->size); - listing += strlen(listing); - } - - cl->messagelumplen = listing - cl->messagelump; -} - -static qboolean SV_POP3_RunClient(svpop3client_t *cl) //true means client should be dropped -{ - int read; - char *nl; - const char *token; - int blankline; - - if (cl->messagelump) - { - blankline=false; - while (cl->outmessagelen < sizeof(cl->outmessagebuffer)-100) - { - if (cl->messagelumppos >= cl->messagelumplen) - break; - - if (cl->messagelump[cl->messagelumppos] == '.') //double up all '.'s at start of lines - cl->outmessagebuffer[cl->outmessagelen++] = '.'; - - blankline = true; - for(;;) - { - if (cl->messagelumppos >= cl->messagelumplen) - break; - if (cl->messagelump[cl->messagelumppos] > ' ') - blankline = false; - cl->outmessagebuffer[cl->outmessagelen++] = cl->messagelump[cl->messagelumppos]; - if (cl->messagelump[cl->messagelumppos++] == '\n') - break; - } - if (blankline) - cl->messagelumphitbody = true; - if (cl->messagelumphitbody) - { - if (cl->messagelumplines--<=0) - cl->messagelumppos = cl->messagelumplen; //easy way to terminate. - } - } - if (cl->messagelumppos >= cl->messagelumplen) - { //we've sent the entire buffer now. - cl->outmessagebuffer[cl->outmessagelen++] = '.'; - cl->outmessagebuffer[cl->outmessagelen++] = '\r'; - cl->outmessagebuffer[cl->outmessagelen++] = '\n'; - - BZ_Free(cl->messagelump); - cl->messagelump = NULL; - } - cl->outmessagebuffer[cl->outmessagelen] = '\0'; -printf("%s\n", cl->outmessagebuffer); - } - if (cl->outmessagelen) - { - read = send(cl->socket, cl->outmessagebuffer, cl->outmessagelen, MSG_PARTIAL); - if (read < 0) - read = 0; - memmove(cl->outmessagebuffer, cl->outmessagebuffer + read, cl->outmessagelen - read); - cl->outmessagelen -= read; - cl->outmessagebuffer[cl->outmessagelen] = '\0'; - - if (cl->dropwhensent && !cl->outmessagelen) - return true; - } - - read = recv(cl->socket, cl->inmessagebuffer+cl->inmessagelen, sizeof(cl->inmessagebuffer)-1-cl->inmessagelen, MSG_PARTIAL); - - if (read == -1) - { - if (qerrno != EWOULDBLOCK) //blocking is the only way to keep the connection on fail. - return true; - - if (!*cl->inmessagebuffer) - return false; -//nonblocking allows us to get multiple commands from one packet. - } - else if (read == 0) //don't quite know why this happens. - return true; //believed to be an indication that the other end has disconnected. - else - { - cl->timeout = realtime + POP3_TIMEOUT; - - cl->inmessagelen += read; - if (cl->inmessagelen >= sizeof(cl->inmessagebuffer)-1) //happens if we fill the buffer with no hope of empting it. - return true; - cl->inmessagebuffer[cl->inmessagelen] = '\0'; - } - nl = strchr(cl->inmessagebuffer, '\n'); - if (nl) - { - *nl = '\0'; -//Con_Printf("%s\n", cl->inmessagebuffer); - read = nl - cl->inmessagebuffer + 1; - - token = COM_ParseToken(cl->inmessagebuffer); - -//auth mechanism 1 - if (!strcmp(com_token, "USER")) - { - token = COM_ParseToken(token); - if (*com_token) - { - Q_strncpyz(cl->username, com_token, sizeof(cl->username)); - SV_POP3_QueueMessage(cl, "+OK User name accepted, password please\r\n"); - - SV_POP3_CleanUp(cl, true); - cl->loggedin = false; - } - else - SV_POP3_QueueMessage(cl, "-ERR no username was specified\r\n"); - } - else if (!strcmp(com_token, "PASS")) - { -#ifndef CLIENTONLY - int id; - extern cvar_t rank_filename; - - token = COM_ParseToken(token); - id = Rank_GetPlayerID(cl->username, atoi(com_token), false, true); - if (!id && *rank_filename.string) - { - SV_POP3_QueueMessage(cl, "-ERR User or Password not valid\r\n"); - - SV_POP3_CleanUp(cl, true); - cl->loggedin = false; - } - else -#endif - { - SV_POP3_QueueMessage(cl, "+OK Logged in\r\n"); - cl->loggedin = true; - SV_POP3_CountMessages(cl); - } - } - -//auth2 - else if (!strcmp(com_token, "APOP")) - { - int id; - int pass; - extern cvar_t rank_filename; - - token = COM_ParseToken(token); - if (*com_token) - { - Q_strncpyz(cl->username, com_token, sizeof(cl->username)); - -#ifndef CLIENTONLY - token = COM_ParseToken(token); - pass = Rank_GetPass(cl->username); - id = Rank_GetPlayerID(cl->username, pass, false, true); - if ((!id && *rank_filename.string) || strcmp(MD5_GetPop3APOPString(cl->greeting, va("%i", pass)), com_token)) - { - SV_POP3_QueueMessage(cl, "-ERR User or Password not valid\r\n"); - - SV_POP3_CleanUp(cl, true); - cl->loggedin = false; - } - else -#endif - { - SV_POP3_QueueMessage(cl, "+OK Logged in\r\n"); - cl->loggedin = true; - SV_POP3_CountMessages(cl); - } - } - } - - -//now they need to have been logged in properly. - else if (!cl->loggedin) - SV_POP3_QueueMessage(cl, "-ERR You didn't log in properly\r\n"); - else if (!strcmp(com_token, "STAT")) - { - char text[64]; - sprintf(text, "+OK %i %i\r\n", cl->nummessages, cl->totalsize); - SV_POP3_QueueMessage(cl, text); - } - else if (!strcmp(com_token, "LIST")) - { - SV_POP3_QueueMessage(cl, "+OK EMail listing follows:\r\n"); - SV_POP3_BuildListing(cl, false); - } - else if (!strcmp(com_token, "DELE")) - { - pop3message_t *msg; - int mnum; - token = COM_ParseToken(token); - mnum = atoi(com_token); - - msg = SV_POP3_GetMessage(cl, mnum); - if (!msg) - SV_POP3_QueueMessage(cl, "-ERR message index out of range\r\n"); - else if (msg->deleted) - SV_POP3_QueueMessage(cl, "-ERR message already deleted\r\n"); - else - { - msg->deleted = true; - SV_POP3_QueueMessage(cl, "+OK Message marked for deleted\r\n"); - } - } - else if (!strcmp(com_token, "TOP")) - { - token = COM_ParseToken(token); - if (SV_POP3_ReadMessage(cl, atoi(com_token))) - { - token = COM_ParseToken(token); - SV_POP3_QueueMessage(cl, "+OK message contents follow:\n"); - cl->messagelumplines = atoi(com_token); - } - else - SV_POP3_QueueMessage(cl, "-ERR Message index wasn't valid\n"); - } - else if (!strcmp(com_token, "RETR")) - { - token = COM_ParseToken(token); - if (SV_POP3_ReadMessage(cl, atoi(com_token))) - SV_POP3_QueueMessage(cl, "+OK message contents follow:\n"); - else - SV_POP3_QueueMessage(cl, "-ERR Message index wasn't valid\n"); - } - else if (!strcmp(com_token, "UIDL")) - { - SV_POP3_QueueMessage(cl, "+OK I hope someone likes you\r\n"); - SV_POP3_BuildListing(cl, true); - } - else if (!strcmp(com_token, "QUIT")) - { - SV_POP3_CleanUp(cl, true); - - SV_POP3_QueueMessage(cl, "+OK I hope someone likes you\r\n"); - cl->dropwhensent = true; - } - else - SV_POP3_QueueMessage(cl, "-ERR Unrecognised command\r\n"); -//printf("%s\n", cl->outmessagebuffer); - - memmove(cl->inmessagebuffer, cl->inmessagebuffer + read, cl->inmessagelen - read); - cl->inmessagelen -= read; - } - - return false; -} - -static void SV_POP3_RunClients(void) -{ - svpop3client_t *cl, *prev; - - cl = svpop3client; - prev = NULL; - while(cl) - { - if (cl->timeout < realtime || SV_POP3_RunClient(cl)) - { -printf("drop client\n"); - closesocket(cl->socket); - if (prev) - prev->next = cl->next; - else - svpop3client = cl->next; - - if (cl->messagelump) - IWebFree(cl->messagelump); - SV_POP3_CleanUp(cl, false); - - IWebFree(cl); - if (prev) - cl = prev->next; - else - cl = svpop3client; - continue; - } - prev = cl; - cl = cl->next; - } -} - -qboolean SV_POP3(qboolean activewanted) -{ - struct sockaddr from; - int fromlen; - int clientsock; - - if (!pop3active) - { - if (activewanted) - POP3_ServerInit(); - else - return false; - } - else if (!activewanted) - { - POP3_ServerShutdown(); - return false; - } - - fromlen = sizeof(from); - clientsock = accept(pop3serversocket, (struct sockaddr *)&from, &fromlen); - - if (clientsock == -1) - { - if (qerrno == ECONNABORTED || qerrno == ECONNRESET) - { - Con_TPrintf (TL_CONNECTIONLOSTORABORTED); - return false; - } - else if (qerrno != EWOULDBLOCK) - { - Con_TPrintf (TL_NETGETPACKETERROR, strerror(qerrno)); - return false; - } - } - else //we got a new client. yay. - POP3_NewConnection(clientsock); - - SV_POP3_RunClients(); - - return true; -} - -#endif diff --git a/engine/email/sv_smtp.c b/engine/email/sv_smtp.c deleted file mode 100644 index 662047ab6..000000000 --- a/engine/email/sv_smtp.c +++ /dev/null @@ -1,449 +0,0 @@ -#include "quakedef.h" - -#ifdef EMAILSERVER - -#include "../http/iweb.h" - - - -#ifdef _WIN32 -#define EWOULDBLOCK WSAEWOULDBLOCK -#define EMSGSIZE WSAEMSGSIZE -#define ECONNRESET WSAECONNRESET -#define ECONNABORTED WSAECONNABORTED -#define ECONNREFUSED WSAECONNREFUSED -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL - -#define qerrno WSAGetLastError() -#else -#define qerrno errno - -#define MSG_PARTIAL 0 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define closesocket close -#define ioctlsocket ioctl -#endif - - -#define SMTP_PORT 25 -#define SMTP_TIMEOUT 30 - -static qboolean smtpactive; -static int smtpserversocket; - -typedef struct svsmtpclient_s { - struct svsmtpclient_s *next; - - int socket; - - float timeout; - - char fromaddr[64]; - char toaddr[64]; - - char inmessagebuffer[1024]; - int inmessagelen; - char outmessagebuffer[1024]; - int outmessagelen; - - qboolean gettingdata; - - FILE *file; - char sendingtotemp[256]; -} svsmtpclient_t; -static svsmtpclient_t *svsmtpclient; - - - - - -static void SMTP_ServerInit(void) -{ - struct sockaddr_in address; - unsigned long _true = true; - int port = SMTP_PORT; - - if ((smtpserversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - { - Sys_Error ("FTP_TCP_OpenSocket: socket:", strerror(qerrno)); - } - - if (ioctlsocket (smtpserversocket, FIONBIO, &_true) == -1) - { - Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); - } - - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - - if (port == PORT_ANY) - address.sin_port = 0; - else - address.sin_port = htons((short)port); - - if( bind (smtpserversocket, (void *)&address, sizeof(address)) == -1) - { - closesocket(smtpserversocket); - return; - } - - listen(smtpserversocket, 3); - - smtpactive = true; - - - IWebPrintf("SMTP server is running\n"); - return; -} - -static void SMTP_ServerShutdown(void) -{ - closesocket(smtpserversocket); - smtpactive = false; -} - -static void SV_SMTP_QueueMessage(svsmtpclient_t *cl, char *msg) -{ - int len = strlen(msg); - if (len + cl->outmessagelen > sizeof(cl->outmessagebuffer)-1) - len = sizeof(cl->outmessagebuffer)-1 - cl->outmessagelen; - Q_strncpyz(cl->outmessagebuffer+cl->outmessagelen, msg, len+1); - cl->outmessagelen += len; -} - -static void SMTP_NewConnection(int socket) -{ - svsmtpclient_t *newcl; - newcl = IWebMalloc(sizeof(svsmtpclient_t)); - if (!newcl) //bother - { - closesocket(socket); - return; - } - memset(newcl, 0, sizeof(svsmtpclient_t)); - - newcl->socket = socket; - newcl->next = svsmtpclient; - svsmtpclient = newcl; - - newcl->timeout = realtime + SMTP_TIMEOUT; - - *newcl->outmessagebuffer = '\0'; - - SV_SMTP_QueueMessage(newcl, "220 81.157.120.30 Probably best to say HELO now.\r\n"); -} - -static qboolean SV_SMTP_RunClient(svsmtpclient_t *cl) //true means client should be dropped -{ - int read; - char *nl, *token; - - if (cl->outmessagelen) - { - read = send(cl->socket, cl->outmessagebuffer, cl->outmessagelen, 0); - if (read < 0) - read = 0; - memmove(cl->outmessagebuffer, cl->outmessagebuffer + read, cl->outmessagelen - read+1); - cl->outmessagelen -= read; - } - - read = recv(cl->socket, cl->inmessagebuffer+cl->inmessagelen, sizeof(cl->inmessagebuffer)-1-cl->inmessagelen, 0); - - if (read == -1) - { - - if (qerrno != EWOULDBLOCK) //blocking is the only way to keep the connection on fail. - return true; - if (!cl->inmessagelen) - return false; - } - else if (read == 0) //don't quite know why this happens. - { - if (!cl->inmessagelen) - return false; - } - else - { - cl->timeout = realtime + SMTP_TIMEOUT; - - cl->inmessagelen += read; - if (cl->inmessagelen >= sizeof(cl->inmessagebuffer)-1 && !cl->gettingdata) //happens if we fill the buffer with no hope of empting it. - return true; - cl->inmessagebuffer[cl->inmessagelen] = '\0'; - } - - while (cl->gettingdata) - { - nl = strstr(cl->inmessagebuffer, "\r\n."); - if (!nl) - nl = cl->inmessagebuffer + cl->inmessagelen - 10; - else - nl+=2; - if (nl < cl->inmessagebuffer) - nl = cl->inmessagebuffer; //waiting for a crnl, so we can'texast this buffer in case we chop the \r\n - - if (!strcmp(cl->inmessagebuffer, ".\r\n")) - { - FILE *f; - int tries; - int len; - char name[256]; - char buffer[1024]; - char *to; - char *at; - - cl->gettingdata = false; - - - to = strchr(cl->toaddr, '<'); - at = strchr(cl->toaddr, '@'); - if (!to || !at || strstr(to, "..")) - SV_SMTP_QueueMessage(cl, "452 Couldn't open file.\r\n"); - else - { - to++; - *at = '\0'; - f=NULL; - for (tries = 0; tries < 10; tries++) //give it a few goes. - { - sprintf(name, "emails/%s/e%i.eml", to, rand()); - COM_CreatePath(name); - f = fopen(name, "wb"); - if (f) - break; - } - - if (f) - { - - { - netadr_t adr; - struct sockaddr_qstorage name; - int namelen = sizeof(name); - - getpeername(cl->socket, (struct sockaddr*)&name, &namelen); - SockadrToNetadr(&name, &adr); - sprintf(buffer, "Received: from %s\r\n", NET_AdrToString(adr)); - fwrite(buffer, strlen(buffer), 1, f); - } - - fseek(cl->file, 0, SEEK_END); - len = ftell(cl->file); - fseek(cl->file, 0, SEEK_SET); - while(len) - { - tries = sizeof(buffer); - if (tries > len) - tries = len; - len -= tries; - - fread(buffer, tries, 1, cl->file); - if (fwrite(buffer, tries, 1, f) != 1) - { - fclose(f); - f = NULL; - unlink(name); - len = 0; - SV_SMTP_QueueMessage(cl, "452 Insufficient system storage.\r\n"); - } - } - if (f) - { - fclose(f); - SV_SMTP_QueueMessage(cl, "250 Finally. You do go on a bit.\r\n"); - } - } - else - SV_SMTP_QueueMessage(cl, "452 Couldn't open file.\r\n"); - } - - fclose(cl->file); - } - else - { -// for (read = 0; read < nl - cl->inmessagebuffer; read++) -// putch(cl->inmessagebuffer[read]); - fwrite(cl->inmessagebuffer, nl - cl->inmessagebuffer, 1, cl->file); - } - - cl->inmessagelen -= nl - cl->inmessagebuffer; - memmove(cl->inmessagebuffer, nl, strlen(nl)+1); - return false; - } - - nl = strstr(cl->inmessagebuffer, "\r\n"); - if (nl) - { - *nl = '\0'; - nl+=2; - - { - - printf("%s\n", cl->inmessagebuffer); - - token = COM_Parse(cl->inmessagebuffer); - - if (!strcmp(com_token, "QUIT")) - { - SV_SMTP_QueueMessage(cl, "221 Well, it was good while it lasted\r\n"); - return true; - } - else if (!strcmp(com_token, "HELO")) - { - SV_SMTP_QueueMessage(cl, va("250 %s Electronic you say? That's good then. :o)\r\n", "81.107.21.148")); - } - else if (!strcmp(com_token, "MAIL")) - { - token = COM_Parse(token); - if (strcmp(com_token, "FROM:")) - { - if (strncmp(com_token, "FROM:", 5)) - SV_SMTP_QueueMessage(cl, "501 Syntax error. Expected MAIL FROM: fromaddr\r\n"); - else - { - SV_SMTP_QueueMessage(cl, "250 Get on with it\r\n"); - Q_strncpyz(cl->fromaddr, com_token+5, sizeof(cl->fromaddr)); - } - } - else - { - SV_SMTP_QueueMessage(cl, "250 Get on with it\r\n"); - Q_strncpyz(cl->fromaddr, token, sizeof(cl->fromaddr)); - } - } - else if (!strcmp(com_token, "RCPT")) - { - token = COM_Parse(token); - if (strcmp(com_token, "TO:")) - { - if (!strncmp(com_token, "TO:<", 4)) - { - token = com_token+3; - } - else - { - token = NULL; - SV_SMTP_QueueMessage(cl, "501 Syntax error. Expected RCPT TO: toaddr\r\n"); - } - } - if (token) - { - SV_SMTP_QueueMessage(cl, "250 Yada yada yada\r\n"); - Q_strncpyz(cl->toaddr, token, sizeof(cl->toaddr)); - } - } - else if (!strcmp(com_token, "DATA")) - { - cl->file = tmpfile(); - if (!cl->file) - { - SV_SMTP_QueueMessage(cl, "550 Access Denied to You.\r\n"); - } - else - { - SV_SMTP_QueueMessage(cl, "354 I'm waiting\r\n"); - cl->gettingdata = true; - } - } - else - SV_SMTP_QueueMessage(cl, "500 Stop speaking pig-latin\r\n"); - } - cl->inmessagelen -= nl - cl->inmessagebuffer; - memmove(cl->inmessagebuffer, nl, strlen(nl)+1); - } - - return false; -} - -static void SV_SMTP_RunClients(void) -{ - svsmtpclient_t *cl, *prev; - - cl = svsmtpclient; - prev = NULL; - while(cl) - { - if (cl->timeout < realtime || SV_SMTP_RunClient(cl)) - { - closesocket(cl->socket); - if (prev) - prev->next = cl->next; - else - svsmtpclient = cl->next; - - if (cl->file) - fclose(cl->file); - IWebFree(cl); - if (prev) - cl = prev->next; - else - cl = svsmtpclient; - continue; - } - prev = cl; - cl = cl->next; - } -} - -qboolean SV_SMTP(qboolean activewanted) -{ - struct sockaddr_qstorage from; - int fromlen; - int clientsock; - - if (!smtpactive) - { - if (activewanted) - SMTP_ServerInit(); - else - return false; - } - else if (!activewanted) - { - SMTP_ServerShutdown(); - return false; - } - - fromlen = sizeof(from); - clientsock = accept(smtpserversocket, (struct sockaddr *)&from, &fromlen); - - if (clientsock == -1) - { - if (qerrno == ECONNABORTED || qerrno == ECONNRESET) - { - Con_TPrintf (TL_CONNECTIONLOSTORABORTED); - return false; - } - else if (qerrno != EWOULDBLOCK) - { - Con_TPrintf (TL_NETGETPACKETERROR, strerror(qerrno)); - return false; - } - } - else //we got a new client. yay. - { - { - netadr_t adr; - SockadrToNetadr(&from, &adr); - Con_DPrintf("SMTP connect initiated from %s\n", NET_AdrToString(adr)); - } - SMTP_NewConnection(clientsock); - } - - SV_SMTP_RunClients(); - - return true; -} - -#endif