Moved to new module init structure.
[citadel.git] / citadel / serv_pop3.c
index 3e76c8abdcb7232873093be55104c0f8b7c31535..c49c5cad98da96edb683b99bcc1135a0697fc2f9 100644 (file)
@@ -8,12 +8,11 @@
  * Current status of standards conformance:
  *
  * -> All required POP3 commands described in RFC1939 are implemented.
- *
  * -> All optional POP3 commands described in RFC1939 are also implemented.
- * 
  * -> The deprecated "LAST" command is included in this implementation, because
  *    there exist mail clients which insist on using it (such as Bynari
  *    TradeMail, and certain versions of Eudora).
+ * -> Capability detection via the method described in RFC2449 is implemented.
  * 
  */
 
 #include <ctype.h>
 #include "citadel.h"
 #include "server.h"
-#include "sysdep_decls.h"
 #include "citserver.h"
 #include "support.h"
 #include "config.h"
-#include "serv_extensions.h"
 #include "room_ops.h"
 #include "user_ops.h"
 #include "policy.h"
@@ -64,6 +61,9 @@
 #endif
 
 
+#include "ctdl_module.h"
+
+
 
 /*
  * This cleanup function blows away the temporary memory and files used by
@@ -123,7 +123,7 @@ void pop3_user(char *argbuf) {
        striplt(username);
 
        /* lprintf(CTDL_DEBUG, "Trying <%s>\n", username); */
-       if (CtdlLoginExistingUser(username) == login_ok) {
+       if (CtdlLoginExistingUser(NULL, username) == login_ok) {
                cprintf("+OK Password required for %s\r\n", username);
        }
        else {
@@ -181,7 +181,7 @@ int pop3_grab_mailbox(void) {
        if (getroom(&CC->room, MAILROOM) != 0) return(-1);
 
        /* Load up the messages */
-       CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL,
+       CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL,
                pop3_add_message, NULL);
 
        /* Figure out which are old and which are new */
@@ -243,7 +243,7 @@ void pop3_apop(char *argbuf)
    memset(userdigest, MD5_HEXSTRING_SIZE, 0);
    strncpy(userdigest, sptr, MD5_HEXSTRING_SIZE-1);
    
-   if (CtdlLoginExistingUser(username) != login_ok)
+   if (CtdlLoginExistingUser(NULL, username) != login_ok)
    {
        cprintf("-ERR No such user.\r\n");
        return;
@@ -467,12 +467,21 @@ void pop3_update(void) {
        int i;
         struct visit vbuf;
 
+       long *deletemsgs = NULL;
+       int num_deletemsgs = 0;
+
        /* Remove messages marked for deletion */
-       if (POP3->num_msgs > 0) for (i=0; i<POP3->num_msgs; ++i) {
-               if (POP3->msgs[i].deleted) {
-                       CtdlDeleteMessages(MAILROOM,
-                               POP3->msgs[i].msgnum, "", 1);
+       if (POP3->num_msgs > 0) {
+               deletemsgs = malloc(POP3->num_msgs * sizeof(long));
+               for (i=0; i<POP3->num_msgs; ++i) {
+                       if (POP3->msgs[i].deleted) {
+                               deletemsgs[num_deletemsgs++] = POP3->msgs[i].msgnum;
+                       }
                }
+               if (num_deletemsgs > 0) {
+                       CtdlDeleteMessages(MAILROOM, deletemsgs, num_deletemsgs, "");
+               }
+               free(deletemsgs);
        }
 
        /* Set last read pointer */
@@ -514,6 +523,23 @@ void pop3_last(char *argbuf) {
 }
 
 
+/*
+ * CAPA is a command which tells the client which POP3 extensions
+ * are supported.
+ */
+void pop3_capa(void) {
+       cprintf("+OK Capability list follows\r\n"
+               "TOP\r\n"
+               "USER\r\n"
+               "UIDL\r\n"
+               "IMPLEMENTATION %s\r\n"
+               ".\r\n"
+               ,
+               CITADEL
+       );
+}
+
+
 
 /*
  * UIDL (Universal IDentifier Listing) is easy.  Our 'unique' message
@@ -611,6 +637,10 @@ void pop3_command_loop(void) {
                cprintf("+OK No operation.\r\n");
        }
 
+       else if (!strncasecmp(cmdbuf, "CAPA", 4)) {
+               pop3_capa();
+       }
+
        else if (!strncasecmp(cmdbuf, "QUIT", 4)) {
                cprintf("+OK Goodbye...\r\n");
                pop3_update();
@@ -681,7 +711,7 @@ void pop3_command_loop(void) {
 
 
 
-char *serv_pop3_init(void)
+CTDL_MODULE_INIT(pop3)
 {
        CtdlRegisterServiceHook(config.c_pop3_port,
                                NULL,
@@ -696,5 +726,7 @@ char *serv_pop3_init(void)
                                NULL);
 #endif
        CtdlRegisterSessionHook(pop3_cleanup_function, EVT_STOP);
+
+       /* return our Subversion id for the Log */
        return "$Id$";
 }