X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fimap%2Fserv_imap.c;h=1290276e27fec9c17980cf8fe112fce2d33efc21;hb=dc1d15a3a02aadae3c441f22d9db1601295f1f47;hp=5c831deb26cd64e28289bae905fef5f2647bb248;hpb=43e4f82efcc5cc0130d1b2712fd73ceb84d074eb;p=citadel.git diff --git a/citadel/modules/imap/serv_imap.c b/citadel/modules/imap/serv_imap.c index 5c831deb2..1290276e2 100644 --- a/citadel/modules/imap/serv_imap.c +++ b/citadel/modules/imap/serv_imap.c @@ -69,7 +69,7 @@ #include "imap_misc.h" #include "ctdl_module.h" - +int IMAPDebugEnabled = 0; HashList *ImapCmds = NULL; void registerImapCMD(const char *First, long FLen, const char *Second, long SLen, @@ -102,8 +102,9 @@ void imap_cleanup(void) const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params) { + struct CitContext *CCC = CC; void *v; - citimap *Imap = IMAP; + citimap *Imap = CCCIMAP; if (num_parms < 1) return NULL; @@ -112,33 +113,33 @@ const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params) StrBufPlain(Imap->Reply, CKEY(Params[1])); StrBufUpCase(Imap->Reply); - syslog(LOG_DEBUG, "---- Looking up [%s] -----", + IMAP_syslog(LOG_DEBUG, "---- Looking up [%s] -----", ChrPtr(Imap->Reply)); if (GetHash(ImapCmds, SKEY(Imap->Reply), &v)) { - syslog(LOG_DEBUG, "Found."); + IMAPM_syslog(LOG_DEBUG, "Found."); FlushStrBuf(Imap->Reply); return (imap_handler_hook *) v; } if (num_parms == 1) { - syslog(LOG_DEBUG, "NOT Found."); + IMAPM_syslog(LOG_DEBUG, "NOT Found."); FlushStrBuf(Imap->Reply); return NULL; } - syslog(LOG_DEBUG, "---- Looking up [%s] -----", + IMAP_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)) { - syslog(LOG_DEBUG, "Found."); + IMAPM_syslog(LOG_DEBUG, "Found."); FlushStrBuf(Imap->Reply); return (imap_handler_hook *) v; } - syslog(LOG_DEBUG, "NOT Found."); + IMAPM_syslog(LOG_DEBUG, "NOT Found."); FlushStrBuf(Imap->Reply); return NULL; } @@ -152,11 +153,13 @@ struct irl { }; /* Data which is passed between imap_rename() and imap_rename_backend() */ -struct irlparms { - char *oldname; - char *newname; +typedef struct __irlparms { + const char *oldname; + long oldnamelen; + const char *newname; + long newnamelen; struct irl **irl; -}; +}irlparms; /* @@ -290,7 +293,7 @@ void imap_add_single_msgid(long msgnum, void *userdata) if (Imap->num_msgs > Imap->num_alloc) { Imap->num_alloc += REALLOC_INCREMENT; Imap->msgids = realloc(Imap->msgids, (Imap->num_alloc * sizeof(long)) ); - Imap->flags = realloc(Imap->flags, (Imap->num_alloc * sizeof(long)) ); + Imap->flags = realloc(Imap->flags, (Imap->num_alloc * sizeof(unsigned int)) ); } Imap->msgids[Imap->num_msgs - 1] = msgnum; Imap->flags[Imap->num_msgs - 1] = 0; @@ -303,11 +306,12 @@ void imap_add_single_msgid(long msgnum, void *userdata) */ void imap_load_msgids(void) { + struct CitContext *CCC = CC; struct cdbdata *cdbfr; - citimap *Imap = IMAP; + citimap *Imap = CCCIMAP; if (Imap->selected == 0) { - syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected"); + IMAPM_syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected"); return; } @@ -316,16 +320,17 @@ void imap_load_msgids(void) /* Load the message list */ cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long)); if (cdbfr != NULL) { - Imap->msgids = malloc(cdbfr->len); - memcpy(Imap->msgids, cdbfr->ptr, cdbfr->len); + Imap->msgids = (long*)cdbfr->ptr; Imap->num_msgs = cdbfr->len / sizeof(long); Imap->num_alloc = cdbfr->len / sizeof(long); + cdbfr->ptr = NULL; + cdbfr->len = 0; cdb_free(cdbfr); } if (Imap->num_msgs) { - Imap->flags = malloc(Imap->num_alloc * sizeof(long)); - memset(Imap->flags, 0, (Imap->num_alloc * sizeof(long)) ); + Imap->flags = malloc(Imap->num_alloc * sizeof(unsigned int)); + memset(Imap->flags, 0, (Imap->num_alloc * sizeof(unsigned int)) ); } imap_set_seen_flags(0); @@ -337,7 +342,8 @@ void imap_load_msgids(void) */ void imap_rescan_msgids(void) { - citimap *Imap = IMAP; + struct CitContext *CCC = CC; + citimap *Imap = CCCIMAP; int original_num_msgs = 0; long original_highest = 0L; int i, j, jstart; @@ -348,7 +354,7 @@ void imap_rescan_msgids(void) int num_recent = 0; if (Imap->selected == 0) { - syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected"); + IMAPM_syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected"); return; } @@ -366,14 +372,10 @@ void imap_rescan_msgids(void) */ cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long)); if (cdbfr != NULL) { - msglist = malloc(cdbfr->len + 1); - if (msglist == NULL) { - syslog(LOG_CRIT, "IMAP: malloc() failed"); - CC->kill_me = KILLME_MALLOC_FAILED; - return; - } - memcpy(msglist, cdbfr->ptr, (size_t)cdbfr->len); + msglist = (long*)cdbfr->ptr; + cdbfr->ptr = NULL; num_msgs = cdbfr->len / sizeof(long); + cdbfr->len = 0; cdb_free(cdbfr); } else { num_msgs = 0; @@ -412,9 +414,8 @@ void imap_rescan_msgids(void) (Imap->num_msgs - i))); memmove(&Imap->flags[i], &Imap->flags[i + 1], - (sizeof(long) * + (sizeof(unsigned int) * (Imap->num_msgs - i))); - --i; } @@ -473,7 +474,8 @@ void imap_rescan_msgids(void) */ void imap_cleanup_function(void) { - citimap *Imap = IMAP; + struct CitContext *CCC = CC; + citimap *Imap = CCCIMAP; /* Don't do this stuff if this is not a Imap session! */ if (CC->h_command_function != imap_command_loop) @@ -484,7 +486,7 @@ void imap_cleanup_function(void) imap_do_expunge(); } - syslog(LOG_DEBUG, "Performing IMAP cleanup hook"); + IMAPM_syslog(LOG_DEBUG, "Performing IMAP cleanup hook"); imap_free_msgids(); imap_free_transmitted_message(); @@ -504,7 +506,7 @@ void imap_cleanup_function(void) FreeStrBuf(&Imap->Reply); if (Imap->Cmd.Params != NULL) free(Imap->Cmd.Params); free(Imap); - syslog(LOG_DEBUG, "Finished IMAP cleanup hook"); + IMAPM_syslog(LOG_DEBUG, "Finished IMAP cleanup hook"); } @@ -909,13 +911,14 @@ void imap_select(int num_parms, ConstStr *Params) */ int imap_do_expunge(void) { - citimap *Imap = IMAP; + struct CitContext *CCC = CC; + citimap *Imap = CCCIMAP; int i; int num_expunged = 0; long *delmsgs = NULL; int num_delmsgs = 0; - syslog(LOG_DEBUG, "imap_do_expunge() called"); + IMAPM_syslog(LOG_DEBUG, "imap_do_expunge() called"); if (Imap->selected == 0) { return (0); } @@ -938,7 +941,7 @@ int imap_do_expunge(void) imap_rescan_msgids(); } - syslog(LOG_DEBUG, "Expunged %d messages from <%s>", num_expunged, CC->room.QRname); + IMAP_syslog(LOG_DEBUG, "Expunged %d messages from <%s>", num_expunged, CC->room.QRname); return (num_expunged); } @@ -978,6 +981,7 @@ void imap_close(int num_parms, ConstStr *Params) */ void imap_namespace(int num_parms, ConstStr *Params) { + long len; int i; struct floor *fl; int floors = 0; @@ -998,8 +1002,8 @@ void imap_namespace(int num_parms, ConstStr *Params) if (fl->f_flags & F_INUSE) { /* if (floors > 0) IAPuts(" "); samjam says this confuses javamail */ IAPuts("("); - snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name); - plain_imap_strout(Namespace); + len = snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name); + IPutStr(Namespace, len); IAPuts(" \"/\")"); ++floors; } @@ -1018,6 +1022,7 @@ void imap_namespace(int num_parms, ConstStr *Params) */ void imap_create(int num_parms, ConstStr *Params) { + struct CitContext *CCC = CC; int ret; char roomname[ROOMNAMELEN]; int floornum; @@ -1033,14 +1038,14 @@ void imap_create(int num_parms, ConstStr *Params) if (strchr(Params[2].Key, '\\') != NULL) { IReply("NO Invalid character in folder name"); - syslog(LOG_DEBUG, "invalid character in folder name"); + IMAPM_syslog(LOG_ERR, "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"); - syslog(LOG_DEBUG, "invalid mailbox name or location"); + IMAPM_syslog(LOG_ERR, "invalid mailbox name or location"); return; } floornum = (ret & 0x00ff); /* lower 8 bits = floor number */ @@ -1049,7 +1054,7 @@ void imap_create(int num_parms, ConstStr *Params) if (flags & IR_MAILBOX) { if (strncasecmp(Params[2].Key, "INBOX/", 6)) { IReply("NO Personal folders must be created under INBOX"); - syslog(LOG_DEBUG, "not subordinate to inbox"); + IMAPM_syslog(LOG_ERR, "not subordinate to inbox"); return; } } @@ -1062,8 +1067,8 @@ void imap_create(int num_parms, ConstStr *Params) newroomview = VIEW_BBS; } - syslog(LOG_INFO, "IMAP: Create new room <%s> on floor <%d> with type <%d>", - roomname, floornum, newroomtype); + IMAP_syslog(LOG_INFO, "Create new room <%s> on floor <%d> with type <%d>", + roomname, floornum, newroomtype); ret = CtdlCreateRoom(roomname, newroomtype, "", floornum, 1, 0, newroomview); if (ret == 0) { @@ -1084,7 +1089,7 @@ void imap_create(int num_parms, ConstStr *Params) CtdlAideMessage(notification_message, "Room Creation Message"); free(notification_message); } - syslog(LOG_DEBUG, "imap_create() completed"); + IMAPM_syslog(LOG_DEBUG, "imap_create() completed"); } @@ -1150,6 +1155,7 @@ int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok */ void imap_status(int num_parms, ConstStr *Params) { + long len; int ret; char roomname[ROOMNAMELEN]; char imaproomname[SIZ]; @@ -1178,9 +1184,9 @@ void imap_status(int num_parms, ConstStr *Params) * names and simply spew all possible data items. It's far easier to * code and probably saves us some processing time too. */ - imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room); + len = imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room); IAPuts("* STATUS "); - plain_imap_strout(imaproomname); + IPutStr(imaproomname, len); IAPrintf(" (MESSAGES %d ", msgs); IAPrintf("RECENT %d ", new); /* Initially, new==recent */ IAPrintf("UIDNEXT %ld ", CitControl.MMhighest + 1); @@ -1344,19 +1350,19 @@ void imap_rename_backend(struct ctdlroom *qrbuf, void *data) char newroomname[ROOMNAMELEN]; int newfloor = 0; struct irl *irlp = NULL; /* scratch pointer */ - struct irlparms *irlparms; + irlparms *myirlparms; - irlparms = (struct irlparms *) data; + myirlparms = (irlparms *) data; imap_mailboxname(foldername, sizeof foldername, qrbuf); /* Rename subfolders */ - if ((!strncasecmp(foldername, irlparms->oldname, - strlen(irlparms->oldname)) - && (foldername[strlen(irlparms->oldname)] == '/'))) { + if ((!strncasecmp(foldername, myirlparms->oldname, + myirlparms->oldnamelen) + && (foldername[myirlparms->oldnamelen] == '/'))) { sprintf(newfoldername, "%s/%s", - irlparms->newname, - &foldername[strlen(irlparms->oldname) + 1] + myirlparms->newname, + &foldername[myirlparms->oldnamelen + 1] ); newfloor = imap_roomname(newroomname, @@ -1367,8 +1373,8 @@ void imap_rename_backend(struct ctdlroom *qrbuf, void *data) strcpy(irlp->irl_newroom, newroomname); strcpy(irlp->irl_oldroom, qrbuf->QRname); irlp->irl_newfloor = newfloor; - irlp->next = *(irlparms->irl); - *(irlparms->irl) = irlp; + irlp->next = *(myirlparms->irl); + *(myirlparms->irl) = irlp; } } @@ -1386,7 +1392,7 @@ void imap_rename(int num_parms, ConstStr *Params) int r; struct irl *irl = NULL; /* the list */ struct irl *irlp = NULL; /* scratch pointer */ - struct irlparms irlparms; + irlparms irlparms; char aidemsg[1024]; if (strchr(Params[3].Key, '\\') != NULL) { @@ -1436,7 +1442,9 @@ void imap_rename(int num_parms, ConstStr *Params) /* Otherwise, do the subfolders. Build a list of rooms to rename... */ else { irlparms.oldname = Params[2].Key; + irlparms.oldnamelen = Params[2].len; irlparms.newname = Params[3].Key; + irlparms.newnamelen = Params[3].len; irlparms.irl = &irl; CtdlForEachRoom(imap_rename_backend, (void *) &irlparms); @@ -1446,8 +1454,9 @@ void imap_rename(int num_parms, ConstStr *Params) irl->irl_newroom, irl->irl_newfloor); if (r != crr_ok) { + struct CitContext *CCC = CC; /* FIXME handle error returns better */ - syslog(LOG_ERR, "IMAP: CtdlRenameRoom() error %d", r); + IMAP_syslog(LOG_ERR, "CtdlRenameRoom() error %d", r); } irlp = irl; irl = irl->next; @@ -1471,6 +1480,7 @@ void imap_rename(int num_parms, ConstStr *Params) */ void imap_command_loop(void) { + struct CitContext *CCC = CC; struct timeval tv1, tv2; suseconds_t total_time = 0; citimap *Imap; @@ -1478,8 +1488,8 @@ void imap_command_loop(void) const imap_handler_hook *h; gettimeofday(&tv1, NULL); - CC->lastcmd = time(NULL); - Imap = IMAP; + CCC->lastcmd = time(NULL); + Imap = CCCIMAP; flush_output(); if (Imap->Cmd.CmdBuf == NULL) @@ -1488,23 +1498,23 @@ void imap_command_loop(void) FlushStrBuf(Imap->Cmd.CmdBuf); if (CtdlClientGetLine(Imap->Cmd.CmdBuf) < 1) { - syslog(LOG_ERR, "IMAP: client disconnected: ending session."); + IMAPM_syslog(LOG_ERR, "client disconnected: ending session."); CC->kill_me = KILLME_CLIENT_DISCONNECTED; return; } if (Imap->authstate == imap_as_expecting_password) { - syslog(LOG_INFO, "IMAP: "); + IMAPM_syslog(LOG_INFO, ""); } else if (Imap->authstate == imap_as_expecting_plainauth) { - syslog(LOG_INFO, "IMAP: "); + IMAPM_syslog(LOG_INFO, ""); } else if ((Imap->authstate == imap_as_expecting_multilineusername) || cbmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) { - syslog(LOG_INFO, "IMAP: LOGIN..."); + IMAPM_syslog(LOG_INFO, "LOGIN..."); } else { - syslog(LOG_INFO, "IMAP: %s", ChrPtr(Imap->Cmd.CmdBuf)); + IMAP_syslog(LOG_DEBUG, "%s", ChrPtr(Imap->Cmd.CmdBuf)); } pchs = ChrPtr(Imap->Cmd.CmdBuf); @@ -1556,18 +1566,18 @@ void imap_command_loop(void) /* debug output the parsed vector */ { int i; - syslog(LOG_DEBUG, "----- %ld params", Imap->Cmd.num_parms); + IMAP_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)) - syslog(LOG_DEBUG, "*********** %ld != %ld : %s", - Imap->Cmd.Params[i].len, - strlen(Imap->Cmd.Params[i].Key), + IMAP_syslog(LOG_DEBUG, "*********** %ld != %ld : %s", + Imap->Cmd.Params[i].len, + strlen(Imap->Cmd.Params[i].Key), Imap->Cmd.Params[i].Key); else - syslog(LOG_DEBUG, "%ld : %s", - Imap->Cmd.Params[i].len, - Imap->Cmd.Params[i].Key); + IMAP_syslog(LOG_DEBUG, "%ld : %s", + Imap->Cmd.Params[i].len, + Imap->Cmd.Params[i].Key); }} #endif @@ -1618,10 +1628,10 @@ BAIL: gettimeofday(&tv2, NULL); total_time = (tv2.tv_usec + (tv2.tv_sec * 1000000)) - (tv1.tv_usec + (tv1.tv_sec * 1000000)); - syslog(LOG_DEBUG, "IMAP command completed in %ld.%ld seconds", - (total_time / 1000000), - (total_time % 1000000) - ); + IMAP_syslog(LOG_DEBUG, "IMAP command completed in %ld.%ld seconds", + (total_time / 1000000), + (total_time % 1000000) + ); } void imap_noop (int num_parms, ConstStr *Params) @@ -1643,7 +1653,10 @@ void imap_logout(int num_parms, ConstStr *Params) const char *CitadelServiceIMAP="IMAP"; const char *CitadelServiceIMAPS="IMAPS"; - +void SetIMAPDebugEnabled(const int n) +{ + IMAPDebugEnabled = n; +} /* * This function is called to register the IMAP extension with Citadel. */ @@ -1699,13 +1712,14 @@ CTDL_MODULE_INIT(imap) if (!threading) { + CtdlRegisterDebugFlagHook(HKEY("imapsrv"), SetIMAPDebugEnabled, &IMAPDebugEnabled); CtdlRegisterServiceHook(config.c_imap_port, NULL, imap_greeting, imap_command_loop, NULL, CitadelServiceIMAP); #ifdef HAVE_OPENSSL CtdlRegisterServiceHook(config.c_imaps_port, NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS); #endif - CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP); + CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP, PRIO_STOP + 30); CtdlRegisterCleanupHook(imap_cleanup); }