X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fpop3%2Fserv_pop3.c;h=43a2545d871d81e747c3347cceadce6d545363d1;hb=e87452481eae22f861f601fdb082a4fa75567dc4;hp=e8f975c4dc5999508a6db56ed31aea114f86a0c6;hpb=0526fe52327b7b7c24eaf436f3437b524ec3b75b;p=citadel.git diff --git a/citadel/modules/pop3/serv_pop3.c b/citadel/modules/pop3/serv_pop3.c index e8f975c4d..43a2545d8 100644 --- a/citadel/modules/pop3/serv_pop3.c +++ b/citadel/modules/pop3/serv_pop3.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "citadel.h" #include "server.h" #include "citserver.h" @@ -51,7 +52,6 @@ #include "policy.h" #include "database.h" #include "msgbase.h" -#include "tools.h" #include "internet_addressing.h" #include "serv_pop3.h" #include "md5.h" @@ -71,7 +71,7 @@ void pop3_cleanup_function(void) { /* Don't do this stuff if this is not a POP3 session! */ if (CC->h_command_function != pop3_command_loop) return; - lprintf(CTDL_DEBUG, "Performing POP3 cleanup hook\n"); + CtdlLogPrintf(CTDL_DEBUG, "Performing POP3 cleanup hook\n"); if (POP3->msgs != NULL) free(POP3->msgs); free(POP3); @@ -85,7 +85,7 @@ void pop3_cleanup_function(void) { void pop3_greeting(void) { strcpy(CC->cs_clientname, "POP3 session"); CC->internal_pgm = 1; - POP3 = malloc(sizeof(struct citpop3)); + CC->session_specific_data = malloc(sizeof(struct citpop3)); memset(POP3, 0, sizeof(struct citpop3)); cprintf("+OK Citadel POP3 server %s\r\n", @@ -125,7 +125,7 @@ void pop3_user(char *argbuf) { strcpy(username, argbuf); striplt(username); - /* lprintf(CTDL_DEBUG, "Trying <%s>\n", username); */ + /* CtdlLogPrintf(CTDL_DEBUG, "Trying <%s>\n", username); */ if (CtdlLoginExistingUser(NULL, username) == login_ok) { cprintf("+OK Password required for %s\r\n", username); } @@ -159,7 +159,7 @@ void pop3_add_message(long msgnum, void *userdata) { CC->redirect_buffer = malloc(SIZ); CC->redirect_len = 0; CC->redirect_alloc = SIZ; - CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL); + CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, 0); smi.meta_rfc822_length = CC->redirect_len; free(CC->redirect_buffer); CC->redirect_buffer = NULL; @@ -208,7 +208,7 @@ void pop3_login(void) if (msgs >= 0) { cprintf("+OK %s is logged in (%d messages)\r\n", CC->user.fullname, msgs); - lprintf(CTDL_NOTICE, "POP3 authenticated %s\n", CC->user.fullname); + CtdlLogPrintf(CTDL_NOTICE, "POP3 authenticated %s\n", CC->user.fullname); } else { cprintf("-ERR Can't open your mailbox\r\n"); @@ -280,7 +280,7 @@ void pop3_pass(char *argbuf) { strcpy(password, argbuf); striplt(password); - /* lprintf(CTDL_DEBUG, "Trying <%s>\n", password); */ + /* CtdlLogPrintf(CTDL_DEBUG, "Trying <%s>\n", password); */ if (CtdlTryPassword(password) == pass_ok) { pop3_login(); } @@ -360,6 +360,10 @@ void pop3_stat(char *argbuf) { */ void pop3_retr(char *argbuf) { int which_one; + char *msgtext; + char *nextline; + char *chunk_to_send; + char prev_char; which_one = atoi(argbuf); if ( (which_one < 1) || (which_one > POP3->num_msgs) ) { @@ -373,7 +377,41 @@ void pop3_retr(char *argbuf) { } cprintf("+OK Message %d:\r\n", which_one); - CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL); + CC->redirect_buffer = malloc(SIZ); + CC->redirect_len = 0; + CC->redirect_alloc = SIZ; + CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum, + MT_RFC822, HEADERS_ALL, 0, 1, NULL, 0); + msgtext = CC->redirect_buffer; + CC->redirect_buffer = NULL; + CC->redirect_len = 0; + CC->redirect_alloc = 0; + + /* If we reach this point, the client is expecting data. + * Need to parse each line of the message here since someone may have sent + * a message containing a single dot on a line of its own. In that case we + * need to escape it in accordance with RFC821. + * We could do this with the tokenizer functions but num_tokens returns an + * int and the message may contain more lines than that, also copying each + * line would be slow. + */ + nextline = msgtext; + while (*nextline) + { + chunk_to_send = nextline; + while (*nextline != '\n') + nextline++; + nextline++; + prev_char = *nextline; + *nextline = '\0'; + if (!strcmp(chunk_to_send, ".\r\n")) { + client_write("..\r\n", 4); + } + else { + client_write(chunk_to_send, (size_t)(nextline-chunk_to_send)); + } + *nextline = prev_char; + } cprintf(".\r\n"); } @@ -406,7 +444,7 @@ void pop3_top(char *argbuf) { CC->redirect_len = 0; CC->redirect_alloc = SIZ; CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum, - MT_RFC822, HEADERS_ALL, 0, 1, NULL); + MT_RFC822, HEADERS_ALL, 0, 1, NULL, 0); msgtext = CC->redirect_buffer; CC->redirect_buffer = NULL; CC->redirect_len = 0; @@ -622,15 +660,15 @@ void pop3_command_loop(void) { time(&CC->lastcmd); memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */ if (client_getln(cmdbuf, sizeof cmdbuf) < 1) { - lprintf(CTDL_ERR, "Client disconnected: ending session.\r\n"); + CtdlLogPrintf(CTDL_ERR, "Client disconnected: ending session.\r\n"); CC->kill_me = 1; return; } if (!strncasecmp(cmdbuf, "PASS", 4)) { - lprintf(CTDL_INFO, "POP3: PASS...\r\n"); + CtdlLogPrintf(CTDL_INFO, "POP3: PASS...\r\n"); } else { - lprintf(CTDL_INFO, "POP3: %s\r\n", cmdbuf); + CtdlLogPrintf(CTDL_INFO, "POP3: %s\r\n", cmdbuf); } while (strlen(cmdbuf) < 5) strcat(cmdbuf, " "); @@ -716,22 +754,25 @@ const char *CitadelServicePop3S="POP3S"; CTDL_MODULE_INIT(pop3) { - CtdlRegisterServiceHook(config.c_pop3_port, - NULL, - pop3_greeting, - pop3_command_loop, - NULL, - CitadelServicePop3); + if(!threading) + { + CtdlRegisterServiceHook(config.c_pop3_port, + NULL, + pop3_greeting, + pop3_command_loop, + NULL, + CitadelServicePop3); #ifdef HAVE_OPENSSL - CtdlRegisterServiceHook(config.c_pop3s_port, - NULL, - pop3s_greeting, - pop3_command_loop, - NULL, - CitadelServicePop3S); + CtdlRegisterServiceHook(config.c_pop3s_port, + NULL, + pop3s_greeting, + pop3_command_loop, + NULL, + CitadelServicePop3S); #endif - CtdlRegisterSessionHook(pop3_cleanup_function, EVT_STOP); - + CtdlRegisterSessionHook(pop3_cleanup_function, EVT_STOP); + } + /* return our Subversion id for the Log */ return "$Id$"; }