Fix warnings all over citserver; handle function replies; remove unused code.
[citadel.git] / citadel / modules / imap / serv_imap.c
index 753396213d9b5a3f8ea0997f5ff1b574c82ec55a..eab1e8571803cc11f754321e9a565d27781d8bd1 100644 (file)
@@ -1,13 +1,14 @@
 /*
  * IMAP server for the Citadel system
- * Copyright (C) 2000-2009 by Art Cancro and others.
+ *
+ * Copyright (C) 2000-2011 by Art Cancro and others.
  * This code is released under the terms of the GNU General Public License.
  *
  * WARNING: the IMAP protocol is badly designed.  No implementation of it
  * is perfect.  Indeed, with so much gratuitous complexity, *all* IMAP
  * implementations have bugs.
  *
- * This program is free software; you can redistribute it and/or modify
+ * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
@@ -94,6 +95,11 @@ void registerImapCMD(const char *First, long FLen,
        }
 }
 
+void imap_cleanup(void)
+{
+       DeleteHash(&ImapCmds);
+}
+
 const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params)
 {
        void *v;
@@ -106,33 +112,33 @@ const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params)
        StrBufPlain(Imap->Reply, CKEY(Params[1]));
        StrBufUpCase(Imap->Reply);
 
-       CtdlLogPrintf(CTDL_DEBUG, "---- Looking up [%s] -----", 
+       syslog(LOG_DEBUG, "---- Looking up [%s] -----", 
                      ChrPtr(Imap->Reply));
        if (GetHash(ImapCmds, SKEY(Imap->Reply), &v))
        {
-               CtdlLogPrintf(CTDL_DEBUG, "Found. \n"); 
+               syslog(LOG_DEBUG, "Found."); 
                FlushStrBuf(Imap->Reply);
                return (imap_handler_hook *) v;
        }
 
        if (num_parms == 1)
        {
-               CtdlLogPrintf(CTDL_DEBUG, "NOT Found. \n"); 
+               syslog(LOG_DEBUG, "NOT Found."); 
                FlushStrBuf(Imap->Reply);
                return NULL;
        }
        
-       CtdlLogPrintf(CTDL_DEBUG, "---- Looking up [%s] -----", 
+       syslog(LOG_DEBUG, "---- Looking up [%s] -----", 
                      ChrPtr(Imap->Reply));
        StrBufAppendBufPlain(Imap->Reply, CKEY(Params[2]), 0);
        StrBufUpCase(Imap->Reply);
        if (GetHash(ImapCmds, SKEY(Imap->Reply), &v))
        {
-               CtdlLogPrintf(CTDL_DEBUG, "Found. \n"); 
+               syslog(LOG_DEBUG, "Found."); 
                FlushStrBuf(Imap->Reply);
                return (imap_handler_hook *) v;
        }
-       CtdlLogPrintf(CTDL_DEBUG, "NOT Found. \n"); 
+       syslog(LOG_DEBUG, "NOT Found."); 
        FlushStrBuf(Imap->Reply);
                return NULL;
 }
@@ -301,8 +307,7 @@ void imap_load_msgids(void)
        citimap *Imap = IMAP;
 
        if (Imap->selected == 0) {
-               CtdlLogPrintf(CTDL_ERR,
-                       "imap_load_msgids() can't run; no room selected\n");
+               syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected");
                return;
        }
 
@@ -343,7 +348,7 @@ void imap_rescan_msgids(void)
        int num_recent = 0;
 
        if (Imap->selected == 0) {
-               CtdlLogPrintf(CTDL_ERR, "imap_load_msgids() can't run; no room selected\n");
+               syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected");
                return;
        }
 
@@ -363,8 +368,9 @@ void imap_rescan_msgids(void)
        if (cdbfr != NULL) {
                msglist = malloc(cdbfr->len);
                if (msglist == NULL) {
-                       CtdlLogPrintf(CTDL_CRIT, "malloc() failed\n");
-                       abort();
+                       syslog(LOG_CRIT, "IMAP: malloc() failed");
+                       CC->kill_me = KILLME_MALLOC_FAILED;
+                       return;
                }
                memcpy(msglist, cdbfr->ptr, (size_t)cdbfr->len);
                num_msgs = cdbfr->len / sizeof(long);
@@ -478,7 +484,7 @@ void imap_cleanup_function(void)
                imap_do_expunge();
        }
 
-       CtdlLogPrintf(CTDL_DEBUG, "Performing IMAP cleanup hook\n");
+       syslog(LOG_DEBUG, "Performing IMAP cleanup hook");
        imap_free_msgids();
        imap_free_transmitted_message();
 
@@ -498,7 +504,7 @@ void imap_cleanup_function(void)
        FreeStrBuf(&Imap->Reply);
        if (Imap->Cmd.Params != NULL) free(Imap->Cmd.Params);
        free(Imap);
-       CtdlLogPrintf(CTDL_DEBUG, "Finished IMAP cleanup hook\n");
+       syslog(LOG_DEBUG, "Finished IMAP cleanup hook");
 }
 
 
@@ -584,7 +590,7 @@ void imap_greeting(void)
        if (CCC->nologin)
        {
                IAPuts("* BYE; Server busy, try later\r\n");
-               CCC->kill_me = 1;
+               CCC->kill_me = KILLME_NOLOGIN;
                IUnbuffer();
                return;
        }
@@ -602,7 +608,7 @@ void imap_greeting(void)
 void imaps_greeting(void) {
        CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
 #ifdef HAVE_OPENSSL
-       if (!CC->redirect_ssl) CC->kill_me = 1;         /* kill session if no crypto */
+       if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO;          /* kill session if no crypto */
 #endif
        imap_greeting();
 }
@@ -637,7 +643,7 @@ void imap_login(int num_parms, ConstStr *Params)
                        }
                        else
                        {
-                               IReplyPrintf("NO AUTHENTICATE %s failed\r\n",
+                               IReplyPrintf("NO AUTHENTICATE %s failed",
                                             Params[3].Key);
                        }
                }
@@ -815,8 +821,6 @@ void imap_select(int num_parms, ConstStr *Params)
        int ra = 0;
        struct ctdlroom QRscratch;
        int msgs, new;
-       int floornum;
-       int roomflags;
        int i;
 
        /* Convert the supplied folder name to a roomname */
@@ -826,8 +830,6 @@ void imap_select(int num_parms, ConstStr *Params)
                Imap->selected = 0;
                return;
        }
-       floornum = (i & 0x00ff);
-       roomflags = (i & 0xff00);
 
        /* First try a regular match */
        c = CtdlGetRoom(&QRscratch, towhere);
@@ -913,7 +915,7 @@ int imap_do_expunge(void)
        long *delmsgs = NULL;
        int num_delmsgs = 0;
 
-       CtdlLogPrintf(CTDL_DEBUG, "imap_do_expunge() called\n");
+       syslog(LOG_DEBUG, "imap_do_expunge() called");
        if (Imap->selected == 0) {
                return (0);
        }
@@ -936,7 +938,7 @@ int imap_do_expunge(void)
                imap_rescan_msgids();
        }
 
-       CtdlLogPrintf(CTDL_DEBUG, "Expunged %d messages from <%s>\n", num_expunged, CC->room.QRname);
+       syslog(LOG_DEBUG, "Expunged %d messages from <%s>", num_expunged, CC->room.QRname);
        return (num_expunged);
 }
 
@@ -1031,14 +1033,14 @@ void imap_create(int num_parms, ConstStr *Params)
 
        if (strchr(Params[2].Key, '\\') != NULL) {
                IReply("NO Invalid character in folder name");
-               CtdlLogPrintf(CTDL_DEBUG, "invalid character in folder name\n");
+               syslog(LOG_DEBUG, "invalid character in folder name");
                return;
        }
 
        ret = imap_roomname(roomname, sizeof roomname, Params[2].Key);
        if (ret < 0) {
                IReply("NO Invalid mailbox name or location");
-               CtdlLogPrintf(CTDL_DEBUG, "invalid mailbox name or location\n");
+               syslog(LOG_DEBUG, "invalid mailbox name or location");
                return;
        }
        floornum = (ret & 0x00ff);      /* lower 8 bits = floor number */
@@ -1046,8 +1048,8 @@ void imap_create(int num_parms, ConstStr *Params)
 
        if (flags & IR_MAILBOX) {
                if (strncasecmp(Params[2].Key, "INBOX/", 6)) {
-                       IReply("%s NO Personal folders must be created under INBOX");
-                       CtdlLogPrintf(CTDL_DEBUG, "not subordinate to inbox\n");
+                       IReply("NO Personal folders must be created under INBOX");
+                       syslog(LOG_DEBUG, "not subordinate to inbox");
                        return;
                }
        }
@@ -1060,7 +1062,7 @@ void imap_create(int num_parms, ConstStr *Params)
                newroomview = VIEW_BBS;
        }
 
-       CtdlLogPrintf(CTDL_INFO, "Create new room <%s> on floor <%d> with type <%d>\n",
+       syslog(LOG_INFO, "IMAP: Create new room <%s> on floor <%d> with type <%d>",
                roomname, floornum, newroomtype);
 
        ret = CtdlCreateRoom(roomname, newroomtype, "", floornum, 1, 0, newroomview);
@@ -1068,7 +1070,7 @@ void imap_create(int num_parms, ConstStr *Params)
                /*** DO NOT CHANGE THIS ERROR MESSAGE IN ANY WAY!  BYNARI CONNECTOR DEPENDS ON IT! ***/
                IReply("NO Mailbox already exists, or create failed");
        } else {
-               IReply("%s OK CREATE completed");
+               IReply("OK CREATE completed");
                /* post a message in Aide> describing the new room */
                notification_message = malloc(1024);
                snprintf(notification_message, 1024,
@@ -1082,7 +1084,7 @@ void imap_create(int num_parms, ConstStr *Params)
                CtdlAideMessage(notification_message, "Room Creation Message");
                free(notification_message);
        }
-       CtdlLogPrintf(CTDL_DEBUG, "imap_create() completed\n");
+       syslog(LOG_DEBUG, "imap_create() completed");
 }
 
 
@@ -1379,7 +1381,7 @@ void imap_rename(int num_parms, ConstStr *Params)
 {
        char old_room[ROOMNAMELEN];
        char new_room[ROOMNAMELEN];
-       int oldr, newr;
+       int newr;
        int new_floor;
        int r;
        struct irl *irl = NULL; /* the list */
@@ -1392,7 +1394,7 @@ void imap_rename(int num_parms, ConstStr *Params)
                return;
        }
 
-       oldr = imap_roomname(old_room, sizeof old_room, Params[2].Key);
+       imap_roomname(old_room, sizeof old_room, Params[2].Key);
        newr = imap_roomname(new_room, sizeof new_room, Params[3].Key);
        new_floor = (newr & 0xFF);
 
@@ -1445,7 +1447,7 @@ void imap_rename(int num_parms, ConstStr *Params)
                                           irl->irl_newfloor);
                        if (r != crr_ok) {
                                /* FIXME handle error returns better */
-                               CtdlLogPrintf(CTDL_ERR, "CtdlRenameRoom() error %d\n", r);
+                               syslog(LOG_ERR, "IMAP: CtdlRenameRoom() error %d", r);
                        }
                        irlp = irl;
                        irl = irl->next;
@@ -1471,7 +1473,6 @@ void imap_command_loop(void)
 {
        struct timeval tv1, tv2;
        suseconds_t total_time = 0;
-       int untagged_ok = 1;
        citimap *Imap;
        const char *pchs, *pche;
        const imap_handler_hook *h;
@@ -1487,23 +1488,23 @@ void imap_command_loop(void)
                FlushStrBuf(Imap->Cmd.CmdBuf);
 
        if (CtdlClientGetLine(Imap->Cmd.CmdBuf) < 1) {
-               CtdlLogPrintf(CTDL_ERR, "Client disconnected: ending session.\r\n");
-               CC->kill_me = 1;
+               syslog(LOG_ERR, "IMAP: client disconnected: ending session.");
+               CC->kill_me = KILLME_CLIENT_DISCONNECTED;
                return;
        }
 
        if (Imap->authstate == imap_as_expecting_password) {
-               CtdlLogPrintf(CTDL_INFO, "IMAP: <password>\n");
+               syslog(LOG_INFO, "IMAP: <password>");
        }
        else if (Imap->authstate == imap_as_expecting_plainauth) {
-               CtdlLogPrintf(CTDL_INFO, "IMAP: <plain_auth>\n");
+               syslog(LOG_INFO, "IMAP: <plain_auth>");
        }
        else if ((Imap->authstate == imap_as_expecting_multilineusername) || 
                 cbmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
-               CtdlLogPrintf(CTDL_INFO, "IMAP: LOGIN...\n");
+               syslog(LOG_INFO, "IMAP: LOGIN...");
        }
        else {
-               CtdlLogPrintf(CTDL_INFO, "IMAP: %s\n", ChrPtr(Imap->Cmd.CmdBuf));
+               syslog(LOG_INFO, "IMAP: %s", ChrPtr(Imap->Cmd.CmdBuf));
        }
 
        pchs = ChrPtr(Imap->Cmd.CmdBuf);
@@ -1548,10 +1549,6 @@ void imap_command_loop(void)
         * If the command just submitted does not contain a literal, we
         * might think about delivering some untagged stuff...
         */
-       if (*(ChrPtr(Imap->Cmd.CmdBuf) + StrLength(Imap->Cmd.CmdBuf) - 1)
-           == '}') {
-               untagged_ok = 0;
-       }
 
        /* Grab the tag, command, and parameters. */
        imap_parameterize(&Imap->Cmd);
@@ -1559,17 +1556,16 @@ void imap_command_loop(void)
 /* debug output the parsed vector */
        {
                int i;
-               CtdlLogPrintf(CTDL_DEBUG, "----- %ld params \n",
-                             Imap->Cmd.num_parms);
+               syslog(LOG_DEBUG, "----- %ld params", Imap->Cmd.num_parms);
 
        for (i=0; i < Imap->Cmd.num_parms; i++) {
                if (Imap->Cmd.Params[i].len != strlen(Imap->Cmd.Params[i].Key))
-                       CtdlLogPrintf(CTDL_DEBUG, "*********** %ld != %ld : %s\n",
+                       syslog(LOG_DEBUG, "*********** %ld != %ld : %s",
                                      Imap->Cmd.Params[i].len, 
                                      strlen(Imap->Cmd.Params[i].Key),
                                      Imap->Cmd.Params[i].Key);
                else
-                       CtdlLogPrintf(CTDL_DEBUG, "%ld : %s\n",
+                       syslog(LOG_DEBUG, "%ld : %s",
                                      Imap->Cmd.Params[i].len, 
                                      Imap->Cmd.Params[i].Key);
        }}
@@ -1622,7 +1618,7 @@ BAIL:
 
        gettimeofday(&tv2, NULL);
        total_time = (tv2.tv_usec + (tv2.tv_sec * 1000000)) - (tv1.tv_usec + (tv1.tv_sec * 1000000));
-       CtdlLogPrintf(CTDL_DEBUG, "IMAP command completed in %ld.%ld seconds\n",
+       syslog(LOG_DEBUG, "IMAP command completed in %ld.%ld seconds",
                (total_time / 1000000),
                (total_time % 1000000)
        );
@@ -1640,7 +1636,7 @@ void imap_logout(int num_parms, ConstStr *Params)
        }
        IAPrintf("* BYE %s logging out\r\n", config.c_fqdn);
        IReply("OK Citadel IMAP session ended.");
-       CC->kill_me = 1;
+       CC->kill_me = KILLME_CLIENT_LOGGED_OUT;
        return;
 }
 
@@ -1710,8 +1706,9 @@ CTDL_MODULE_INIT(imap)
                                        NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS);
 #endif
                CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP);
+               CtdlRegisterCleanupHook(imap_cleanup);
        }
        
-       /* return our Subversion id for the Log */
+       /* return our module name for the log */
        return "imap";
 }