From f28e7ba9c3eb0353fbbb54ef3ed5f7d2d9f433d4 Mon Sep 17 00:00:00 2001 From: Carlos Daniel Ruvalcaba Valenzuela Date: Wed, 1 Aug 2007 19:42:43 -0700 Subject: [PATCH] Updated and cleaned SMTP code, added comments and queue support --- backends/protocol/smtp.cpp | 111 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 23 deletions(-) diff --git a/backends/protocol/smtp.cpp b/backends/protocol/smtp.cpp index 923de26..cf59071 100644 --- a/backends/protocol/smtp.cpp +++ b/backends/protocol/smtp.cpp @@ -65,7 +65,7 @@ public: cmdtree.Insert("RSET", 7); } int Handle(Socket *s){ - char buffer[255], username[255], recipent[255]; + char buffer[255], *slotname; int r, l, ret; int onrun, cmd, state; FILE *fd; @@ -75,14 +75,19 @@ public: cmd = 0; string mailfrom, rcpt; + IPC *ipc; + IPCMessage *msg; + /* Write out the SMTP server Greeting */ s->Write("220 FancyMail v0.1", 18); s->Write( CRLF, 2); while (onrun){ + /* Wait for client input */ memset(buffer, 0, 255); r = s->Read(buffer, 255); + /* Find the given command on our search tree */ try{ cmd = cmdtree.Lookup(buffer); }catch (SearchNotFound){ @@ -91,79 +96,142 @@ public: switch(cmd){ case CMD_HELO: + /* We got normal SMTP HELO, write response */ s->Write("250 ok localhost", 16); s->Write(CRLF, 2); + + /* Client presented itself, we can accept other + * commands, we pass to state 1 */ state = 1; break; case CMD_EHLO: + /* We still not support ESMTP, write not implemented */ s->Write( "502 Not implemented", 19); s->Write( CRLF, 2); break; case CMD_MAIL: + /* Check if we had the proper greeting */ if (state != 1){ s->Write( "502 Not implemented", 19); s->Write( CRLF, 2); break; } + + /* Extract the command mail from data */ ret = reCmd.PartialMatch(buffer, &mailfrom); printf("[Debug] Sending Mail From: %s\n", mailfrom.c_str()); + + /* Write Response */ s->Write( "250 OK", 6); s->Write( CRLF, 2); + + /* We pass to next state */ state = 2; break; case CMD_RCPT: + /* Check that we have recieved the MAIL command first */ if (state != 2){ s->Write( "502 Not implemented", 19); s->Write( CRLF, 2); break; } + + /* Extract the recipent */ reCmd.PartialMatch(buffer, &rcpt); printf("[Debug] Recipent: %s\n", rcpt.c_str()); - s->Write( "250 OK", 6); + + s->Write( "250 OK", 6); s->Write( CRLF, 2); - state = 3; + + state = 3; break; case CMD_DATA: + /* Check that we have recived the RCPT command first */ if (state != 3){ s->Write( "502 Not implemented", 19); s->Write( CRLF, 2); break; } + + /* Give the client green light to send its data */ printf("Reciving Data!\n"); s->Write( "354 OK", 6); s->Write( CRLF, 2); - - //fd = tmpfile(); - + + /* Connect to the Queue server */ + ipc = IPC::CreateIPC("socket://127.0.0.1:14002"); + ipc->RequestIPC(); + + /* Request a slot */ + msg = new IPCMessage("slot"); + msg->PushParam("incoming"); + ipc->PushMessage(msg); + + /* Retrieve Response */ + msg = ipc->PopMessage(); + if (!strcmp(msg->GetMessageName(), "ok"){ + slotname = msg->PopParam(); + }else{ + break; + } + + /* Open Queue Slot File */ + fd = fopen(slotname, "w"); + + /* Write our headers */ + fprintf(fd, "MAIL FROM: %s\n", mailfrom.c_str()); + fprintf(fd, "RCPT: %s\n", rcp.c_str()); + fprintf(fd, "\n"); + r = 1; while (r){ + /* Read incoming client data */ memset(buffer, 0, 255); - l = s->Read( buffer, 255); - printf("%s", buffer); - - if (strstr(buffer, KEY_END_DATA)){ + + /* Write to slot file */ + fwrite(buffer, 1, l, fd); + + /* Check for EOF */ + if (strstr(buffer, KEY_END_DATA)){ r = 0; printf("\nEnd of Data\n"); }else{ printf("Buffer[%i]: %s\n", l, buffer); } } - - + + /* Close our slot file */ + fclose(fd); + + /* Push the message to the Queue */ + msg = new IPCMessage("push"); + msg->PushParam("incoming"); + msg->PushParam(slotname); + ipc->PushMessage(msg); + + /* Close IPC*/ + ipc->Close(); + s->Write( "250 OK", 6); s->Write( CRLF, 2); + + /* Go back to initial state */ state = 1; break; case CMD_RSET: s->Write( "250 OK", 6); s->Write( CRLF, 2); - state = 1; + + /* Reset state */ + state = 1; break; case CMD_QUIT: printf("Got Quit, Exiting\n"); s->Write( "221 Exiting", 11); s->Write(CRLF, 2); + + /* Stop main loop */ onrun = 0; break; default: @@ -176,6 +244,7 @@ public: printf("[COMMAND]: %s\n", buffer); } + /* Close Connection */ printf("Closing Connection\n"); s->Close(); } @@ -191,35 +260,31 @@ public: }; int main(int argc, char **argv){ - BaseServer *srv; - SimpleLoad *lh; ThreadLoad *tlh; SMTPHandler *handler; Socket *s, *cl; int ret; + /* Create a Socket and bind it to SMTP port */ s = Socket::CreateSocket(SOCKET_INET, 0); s->setAddress("localhost"); s->setPort(SMTP_PORT); s->Bind(); s->Listen(15); + /* Create a handler object */ handler = new SMTPHandler(); - //lh = new SimpleLoad(); + + /* Create a LoadHandler Object*/ tlh = new ThreadLoad(handler); - //srv = new BaseServer(handler, SMTP_PORT); - //srv->SetLoadhandler(lh); - //srv->Listen(); while(1){ - + /* Poll for incoming connections */ ret = s->Poll(1000000, SOCKET_POLL_READ); if (ret == SOCKET_POLL_READ){ - + /* Accept client and dispatch */ cl = s->Accept(); - tlh->Dispatch(cl, handler); - } } -- 2.11.4.GIT