/* 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);
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",
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);
}
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;
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");
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();
}
*/
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) ) {
}
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");
}
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;
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, " ");
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$";
}