-/*
- * IMAP server for the Citadel system
- *
- * Copyright (C) 2000-2022 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 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
+// IMAP server for the Citadel system
+//
+// Copyright (c) 1987-2023 by the citadel.org team
+//
+// This program is open source software. Use, duplication, or disclosure
+// is subject to the terms of the GNU General Public License, version 3.
#include "../../sysdep.h"
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <time.h>
+#include <sys/time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <libcitadel.h>
-#include "../../citadel.h"
+#include "../../citadel_defs.h"
#include "../../server.h"
#include "../../citserver.h"
#include "../../support.h"
#include "../../config.h"
#include "../../user_ops.h"
+#include "../../room_ops.h"
#include "../../database.h"
#include "../../msgbase.h"
#include "../../internet_addressing.h"
#include "../../ctdl_module.h"
HashList *ImapCmds = NULL;
-void registerImapCMD(const char *First, long FLen,
- const char *Second, long SLen,
- imap_handler H,
- int Flags)
-{
+void registerImapCMD(const char *First, long FLen, const char *Second, long SLen, imap_handler H, int Flags) {
imap_handler_hook *h;
h = (imap_handler_hook*) malloc(sizeof(imap_handler_hook));
}
-const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params)
-{
- struct CitContext *CCC = CC;
+const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params) {
void *v;
- citimap *Imap = CCCIMAP;
+ citimap *Imap = IMAP;
if (num_parms < 1)
return NULL;
StrBufUpCase(Imap->Reply);
syslog(LOG_DEBUG, "---- Looking up [%s] -----", ChrPtr(Imap->Reply));
- if (GetHash(ImapCmds, SKEY(Imap->Reply), &v))
- {
+ if (GetHash(ImapCmds, SKEY(Imap->Reply), &v)) {
syslog(LOG_DEBUG, "Found.");
FlushStrBuf(Imap->Reply);
return (imap_handler_hook *) v;
}
- if (num_parms == 1)
- {
+ if (num_parms == 1) {
syslog(LOG_DEBUG, "NOT Found.");
FlushStrBuf(Imap->Reply);
return NULL;
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))
- {
+ if (GetHash(ImapCmds, SKEY(Imap->Reply), &v)) {
syslog(LOG_DEBUG, "Found.");
FlushStrBuf(Imap->Reply);
return (imap_handler_hook *) v;
return NULL;
}
+
/* imap_rename() uses this struct containing list of rooms to rename */
struct irl {
struct irl *next;
int irl_newfloor;
};
+
/* Data which is passed between imap_rename() and imap_rename_backend() */
typedef struct __irlparms {
const char *oldname;
const char *newname;
long newnamelen;
struct irl **irl;
-}irlparms;
+} irlparms;
/*
* If there is a message ID map in memory, free it
*/
-void imap_free_msgids(void)
-{
+void imap_free_msgids(void) {
citimap *Imap = IMAP;
if (Imap->msgids != NULL) {
free(Imap->msgids);
/*
* If there is a transmitted message in memory, free it
*/
-void imap_free_transmitted_message(void)
-{
+void imap_free_transmitted_message(void) {
FreeStrBuf(&IMAP->TransmittedMessage);
}
* room, or some other value if we're only interested in an incremental
* update.
*/
-void imap_set_seen_flags(int first_msg)
-{
+void imap_set_seen_flags(int first_msg) {
citimap *Imap = IMAP;
- visit vbuf;
+ struct visit vbuf;
int i;
int num_sets;
int s;
char setstr[64], lostr[64], histr[64];
long lo, hi;
- if (Imap->num_msgs < 1) return;
+ if (Imap->num_msgs < 0) return;
CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
for (i = first_msg; i < Imap->num_msgs; ++i) {
}
-
/*
* Back end for imap_load_msgids()
*
* allocate space in the list for REALLOC_INCREMENT messages at a time. This
* allows the mapping to proceed much faster.
*/
-void imap_add_single_msgid(long msgnum, void *userdata)
-{
+void imap_add_single_msgid(long msgnum, void *userdata) {
citimap *Imap = IMAP;
++Imap->num_msgs;
}
-
/*
* Set up a message ID map for the current room (folder)
*/
-void imap_load_msgids(void)
-{
- struct CitContext *CCC = CC;
- struct cdbdata *cdbfr;
- citimap *Imap = CCCIMAP;
+void imap_load_msgids(void) {
+ citimap *Imap = IMAP;
if (Imap->selected == 0) {
syslog(LOG_ERR, "imap_load_msgids() can't run; no room selected");
imap_free_msgids(); /* If there was already a map, free it */
/* Load the message list */
- cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
- if (cdbfr != NULL) {
- 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);
- }
+ Imap->num_msgs = CtdlFetchMsgList(CC->room.QRnumber, &Imap->msgids);
+ Imap->num_alloc = Imap->num_msgs;
if (Imap->num_msgs) {
Imap->flags = malloc(Imap->num_alloc * sizeof(unsigned int));
memset(Imap->flags, 0, (Imap->num_alloc * sizeof(unsigned int)) );
}
-
imap_set_seen_flags(0);
}
/*
* Re-scan the selected room (folder) and see if it's been changed at all
*/
-void imap_rescan_msgids(void)
-{
- struct CitContext *CCC = CC;
- citimap *Imap = CCCIMAP;
+void imap_rescan_msgids(void) {
+ citimap *Imap = IMAP;
int original_num_msgs = 0;
long original_highest = 0L;
int i, j, jstart;
int message_still_exists;
- struct cdbdata *cdbfr;
long *msglist = NULL;
int num_msgs = 0;
int num_recent = 0;
/* Load the *current* message list from disk, so we can compare it
* to what we have in memory.
*/
- cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
- if (cdbfr != NULL) {
- msglist = (long*)cdbfr->ptr;
- cdbfr->ptr = NULL;
- num_msgs = cdbfr->len / sizeof(long);
- cdbfr->len = 0;
- cdb_free(cdbfr);
- } else {
- num_msgs = 0;
- }
+ num_msgs = CtdlFetchMsgList(CC->room.QRnumber, &msglist);
/*
* Check to see if any of the messages we know about have been expunged
if (message_still_exists == 0) {
IAPrintf("* %d EXPUNGE\r\n", i + 1);
- /* Here's some nice stupid nonsense. When a
- * message is expunged, we have to slide all
- * the existing messages up in the message
- * array.
- */
+ // When a message is expunged, we have to slide all the existing messages up in the message array.
--Imap->num_msgs;
- memmove(&Imap->msgids[i],
- &Imap->msgids[i + 1],
- (sizeof(long) *
- (Imap->num_msgs - i)));
- memmove(&Imap->flags[i],
- &Imap->flags[i + 1],
- (sizeof(unsigned int) *
- (Imap->num_msgs - i)));
+ memmove(&Imap->msgids[i], &Imap->msgids[i + 1], (sizeof(long) * (Imap->num_msgs - i)));
+ memmove(&Imap->flags[i], &Imap->flags[i + 1], (sizeof(unsigned int) * (Imap->num_msgs - i)));
--i;
}
}
}
- /*
- * Remember how many messages were here before we re-scanned.
- */
+ // Remember how many messages were here before we re-scanned.
original_num_msgs = Imap->num_msgs;
if (Imap->num_msgs > 0) {
original_highest = Imap->msgids[Imap->num_msgs - 1];
- } else {
+ }
+ else {
original_highest = 0L;
}
- /*
- * Now peruse the room for *new* messages only.
- * This logic is probably the cause of Bug # 368
- * [ http://bugzilla.citadel.org/show_bug.cgi?id=368 ]
- */
+ // Now peruse the room for *new* messages only.
+ // This logic is probably the cause of Bug # 368
+ // [ http://bugzilla.citadel.org/show_bug.cgi?id=368 ]
if (num_msgs > 0) {
for (j = 0; j < num_msgs; ++j) {
if (msglist[j] > original_highest) {
IAPrintf("* %d RECENT\r\n", num_recent);
}
- if (msglist != NULL) {
- free(msglist);
- }
+ free(msglist);
Imap->last_mtime = CC->room.QRmtime;
}
* This cleanup function blows away the temporary memory and files used by
* the IMAP server.
*/
-void imap_cleanup_function(void)
-{
- struct CitContext *CCC = CC;
- citimap *Imap = CCCIMAP;
+void imap_cleanup_function(void) {
+ citimap *Imap = IMAP;
/* Don't do this stuff if this is not a Imap session! */
if (CC->h_command_function != imap_command_loop)
/*
- * Does the actual work of the CAPABILITY command (because we need to
- * output this stuff in other places as well)
+ * Does the actual work of the CAPABILITY command (because we need to output this stuff in other places as well)
*/
void imap_output_capability_string(void) {
IAPuts("CAPABILITY IMAP4REV1 NAMESPACE ID AUTH=PLAIN AUTH=LOGIN UIDPLUS");
/*
* implements the CAPABILITY command
*/
-void imap_capability(int num_parms, ConstStr *Params)
-{
+void imap_capability(int num_parms, ConstStr *Params) {
IAPuts("* ");
imap_output_capability_string();
IAPuts("\r\n");
* making use of this extension.
*
*/
-void imap_id(int num_parms, ConstStr *Params)
-{
+void imap_id(int num_parms, ConstStr *Params) {
IAPuts("* ID NIL\r\n");
IReply("OK ID completed");
}
/*
* Here's where our IMAP session begins its happy day.
*/
-void imap_greeting(void)
-{
+void imap_greeting(void) {
citimap *Imap;
- CitContext *CCC = CC;
- strcpy(CCC->cs_clientname, "IMAP session");
- CCC->session_specific_data = malloc(sizeof(citimap));
- Imap = (citimap *)CCC->session_specific_data;
+ strcpy(CC->cs_clientname, "IMAP session");
+ CC->session_specific_data = malloc(sizeof(citimap));
+ Imap = (citimap *)CC->session_specific_data;
memset(Imap, 0, sizeof(citimap));
Imap->authstate = imap_as_normal;
Imap->cached_rfc822_msgnum = (-1);
Imap->cached_rfc822_withbody = 0;
Imap->Reply = NewStrBufPlain(NULL, SIZ * 10); /* 40k */
- if (CCC->nologin)
- {
+ if (CC->nologin) {
IAPuts("* BYE; Server busy, try later\r\n");
- CCC->kill_me = KILLME_NOLOGIN;
+ CC->kill_me = KILLME_NOLOGIN;
IUnbuffer();
return;
}
/*
* implements the LOGIN command (ordinary username/password login)
*/
-void imap_login(int num_parms, ConstStr *Params)
-{
+void imap_login(int num_parms, ConstStr *Params) {
switch (num_parms) {
case 3:
- if (Params[2].Key[0] == '{') {
+ if (Params[2].len && (Params[2].Key[0] == '{')) {
IAPuts("+ go ahead\r\n");
IMAP->authstate = imap_as_expecting_multilineusername;
strcpy(IMAP->authseq, Params[0].Key);
IAPrintf("] Hello, %s\r\n", CC->user.fullname);
return;
}
- else
- {
+ else {
IReplyPrintf("NO AUTHENTICATE %s failed", Params[3].Key);
return;
}
/*
* Implements the AUTHENTICATE command
*/
-void imap_authenticate(int num_parms, ConstStr *Params)
-{
+void imap_authenticate(int num_parms, ConstStr *Params) {
char UsrBuf[SIZ];
if (num_parms != 3) {
}
if (!strcasecmp(Params[2].Key, "LOGIN")) {
- size_t len = CtdlEncodeBase64(UsrBuf, "Username:", 9, 0);
+ size_t len = CtdlEncodeBase64(UsrBuf, "Username:", 9, BASE64_NO_LINEBREAKS);
if (UsrBuf[len - 1] == '\n') {
UsrBuf[len - 1] = '\0';
}
}
if (!strcasecmp(Params[2].Key, "PLAIN")) {
- // size_t len = CtdlEncodeBase64(UsrBuf, "Username:", 9, 0);
+ // size_t len = CtdlEncodeBase64(UsrBuf, "Username:", 9, BASE64_NO_LINEBREAKS);
// if (UsrBuf[len - 1] == '\n') {
// UsrBuf[len - 1] = '\0';
// }
}
-void imap_auth_plain(void)
-{
+void imap_auth_plain(void) {
citimap *Imap = IMAP;
const char *decoded_authstring;
char ident[256] = "";
memset(pass, 0, sizeof(pass));
decoded_len = StrBufDecodeBase64(Imap->Cmd.CmdBuf);
- if (decoded_len > 0)
- {
+ if (decoded_len > 0) {
decoded_authstring = ChrPtr(Imap->Cmd.CmdBuf);
len = safestrncpy(ident, decoded_authstring, sizeof ident);
decoded_len -= len - 1;
decoded_authstring += len + 1;
- if (decoded_len > 0)
- {
+ if (decoded_len > 0) {
len = safestrncpy(user, decoded_authstring, sizeof user);
decoded_authstring += len + 1;
decoded_len -= len - 1;
}
- if (decoded_len > 0)
- {
+ if (decoded_len > 0) {
plen = safestrncpy(pass, decoded_authstring, sizeof pass);
if (plen < 0)
}
-void imap_auth_login_user(long state)
-{
+void imap_auth_login_user(long state) {
char PWBuf[SIZ];
citimap *Imap = IMAP;
- switch (state){
+ switch (state) {
case imap_as_expecting_username:
StrBufDecodeBase64(Imap->Cmd.CmdBuf);
CtdlLoginExistingUser(ChrPtr(Imap->Cmd.CmdBuf));
- size_t len = CtdlEncodeBase64(PWBuf, "Password:", 9, 0);
+ size_t len = CtdlEncodeBase64(PWBuf, "Password:", 9, BASE64_NO_LINEBREAKS);
if (PWBuf[len - 1] == '\n') {
PWBuf[len - 1] = '\0';
}
}
-void imap_auth_login_pass(long state)
-{
+void imap_auth_login_pass(long state) {
citimap *Imap = IMAP;
const char *pass = NULL;
long len = 0;
if (CtdlTryPassword(pass, len) == pass_ok) {
IAPrintf("%s OK authentication succeeded\r\n", Imap->authseq);
- } else {
+ }
+ else {
IAPrintf("%s NO authentication failed\r\n", Imap->authseq);
}
Imap->authstate = imap_as_normal;
/*
* implements the STARTTLS command (Citadel API version)
*/
-void imap_starttls(int num_parms, ConstStr *Params)
-{
+void imap_starttls(int num_parms, ConstStr *Params) {
char ok_response[SIZ];
char nosup_response[SIZ];
char error_response[SIZ];
/*
* implements the SELECT command
*/
-void imap_select(int num_parms, ConstStr *Params)
-{
+void imap_select(int num_parms, ConstStr *Params) {
citimap *Imap = IMAP;
char towhere[ROOMNAMELEN];
char augmented_roomname[ROOMNAMELEN];
if (!strcasecmp(Params[1].Key, "EXAMINE")) {
Imap->readonly = 1;
- } else {
+ }
+ else {
Imap->readonly = 0;
}
*/
IAPuts("* FLAGS (\\Deleted \\Seen \\Answered)\r\n");
IAPuts("* OK [PERMANENTFLAGS (\\Deleted \\Seen \\Answered)] permanent flags\r\n");
-
- IReplyPrintf("OK [%s] %s completed",
- (Imap->readonly ? "READ-ONLY" : "READ-WRITE"), Params[1].Key
- );
+ IReplyPrintf("OK [%s] %s completed", (Imap->readonly ? "READ-ONLY" : "READ-WRITE"), Params[1].Key);
}
/*
* Does the real work for expunge.
*/
-int imap_do_expunge(void)
-{
- struct CitContext *CCC = CC;
- citimap *Imap = CCCIMAP;
+int imap_do_expunge(void) {
+ citimap *Imap = IMAP;
int i;
int num_expunged = 0;
long *delmsgs = NULL;
/*
* implements the EXPUNGE command syntax
*/
-void imap_expunge(int num_parms, ConstStr *Params)
-{
+void imap_expunge(int num_parms, ConstStr *Params) {
int num_expunged = 0;
num_expunged = imap_do_expunge();
/*
* implements the CLOSE command
*/
-void imap_close(int num_parms, ConstStr *Params)
-{
+void imap_close(int num_parms, ConstStr *Params) {
/* Yes, we always expunge on close. */
if (IMAP->selected) {
/*
* Implements the NAMESPACE command.
*/
-void imap_namespace(int num_parms, ConstStr *Params)
-{
+void imap_namespace(int num_parms, ConstStr *Params) {
long len;
int i;
struct floor *fl;
/* All personal folders are subordinate to INBOX. */
IAPuts("((\"INBOX/\" \"/\")) ");
- /* Other users' folders ... coming soon! FIXME */
+ /* Other users' folders ... eventually? FIXME */
IAPuts("NIL ");
/* Show all floors as shared namespaces. Neato! */
* Implements the CREATE command
*
*/
-void imap_create(int num_parms, ConstStr *Params)
-{
+void imap_create(int num_parms, ConstStr *Params) {
int ret;
char roomname[ROOMNAMELEN];
int floornum;
if (flags & IR_MAILBOX) {
newroomtype = 4; /* private mailbox */
newroomview = VIEW_MAILBOX;
- } else {
+ }
+ else {
newroomtype = 0; /* public folder */
newroomview = VIEW_BBS;
}
ret = CtdlCreateRoom(roomname, newroomtype, "", floornum, 1, 0, newroomview);
if (ret == 0) {
- /*** DO NOT CHANGE THIS ERROR MESSAGE IN ANY WAY! BYNARI CONNECTOR DEPENDS ON IT! ***/
IReply("NO Mailbox already exists, or create failed");
- } else {
+ }
+ else {
IReply("OK CREATE completed");
- /* post a message in Aide> describing the new room */
+ // post a message in Aide> describing the new room
notification_message = malloc(1024);
snprintf(notification_message, 1024,
"A new room called \"%s\" has been created by %s%s%s%s\n",
* Locate a room by its IMAP folder name, and check access to it.
* If zapped_ok is nonzero, we can also look for the room in the zapped list.
*/
-int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok)
-{
+int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok) {
int ret;
char augmented_roomname[ROOMNAMELEN];
char roomname[ROOMNAMELEN];
/* Then try a mailbox name match */
if (c != 0) {
- CtdlMailboxName(augmented_roomname, sizeof augmented_roomname,
- &CC->user, roomname);
+ CtdlMailboxName(augmented_roomname, sizeof augmented_roomname, &CC->user, roomname);
c = CtdlGetRoom(&QRscratch, augmented_roomname);
if (c == 0)
safestrncpy(roomname, augmented_roomname, sizeof(roomname));
if (!ok) {
strcpy(returned_roomname, "");
return (2);
- } else {
+ }
+ else {
safestrncpy(returned_roomname, QRscratch.QRname, ROOMNAMELEN);
return (0);
}
* Implements the STATUS command (sort of)
*
*/
-void imap_status(int num_parms, ConstStr *Params)
-{
+void imap_status(int num_parms, ConstStr *Params) {
long len;
int ret;
char roomname[ROOMNAMELEN];
* Implements the SUBSCRIBE command
*
*/
-void imap_subscribe(int num_parms, ConstStr *Params)
-{
+void imap_subscribe(int num_parms, ConstStr *Params) {
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
* Implements the UNSUBSCRIBE command
*
*/
-void imap_unsubscribe(int num_parms, ConstStr *Params)
-{
+void imap_unsubscribe(int num_parms, ConstStr *Params) {
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
*/
if (CtdlForgetThisRoom() == 0) {
IReply("OK UNSUBSCRIBE completed");
- } else {
+ }
+ else {
IReply("NO You may not unsubscribe from this folder.");
}
* Implements the DELETE command
*
*/
-void imap_delete(int num_parms, ConstStr *Params)
-{
+void imap_delete(int num_parms, ConstStr *Params) {
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
if (CtdlDoIHavePermissionToDeleteThisRoom(&CC->room)) {
CtdlScheduleRoomForDeletion(&CC->room);
IReply("OK DELETE completed");
- } else {
+ }
+ else {
IReply("NO Can't delete this folder.");
}
/*
* Back end function for imap_rename()
*/
-void imap_rename_backend(struct ctdlroom *qrbuf, void *data)
-{
+void imap_rename_backend(struct ctdlroom *qrbuf, void *data) {
char foldername[SIZ];
char newfoldername[SIZ];
char newroomname[ROOMNAMELEN];
* Implements the RENAME command
*
*/
-void imap_rename(int num_parms, ConstStr *Params)
-{
+void imap_rename(int num_parms, ConstStr *Params) {
char old_room[ROOMNAMELEN];
char new_room[ROOMNAMELEN];
int newr;
/* ... and now rename them. */
while (irl != NULL) {
- r = CtdlRenameRoom(irl->irl_oldroom,
- irl->irl_newroom,
- irl->irl_newfloor);
+ r = CtdlRenameRoom(irl->irl_oldroom, irl->irl_newroom, irl->irl_newfloor);
if (r != crr_ok) {
/* FIXME handle error returns better */
syslog(LOG_ERR, "CtdlRenameRoom() error %d", r);
/*
* Main command loop for IMAP sessions.
*/
-void imap_command_loop(void)
-{
- struct CitContext *CCC = CC;
+void imap_command_loop(void) {
struct timeval tv1, tv2;
suseconds_t total_time = 0;
citimap *Imap;
const imap_handler_hook *h;
gettimeofday(&tv1, NULL);
- CCC->lastcmd = time(NULL);
- Imap = CCCIMAP;
+ CC->lastcmd = time(NULL);
+ Imap = IMAP;
flush_output();
if (Imap->Cmd.CmdBuf == NULL)
else if (Imap->authstate == imap_as_expecting_plainauth) {
syslog(LOG_INFO, "<plain_auth>");
}
- else if ((Imap->authstate == imap_as_expecting_multilineusername) ||
- cbmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
+ else if ((Imap->authstate == imap_as_expecting_multilineusername) || cbmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
syslog(LOG_INFO, "LOGIN...");
}
else {
pchs = ChrPtr(Imap->Cmd.CmdBuf);
pche = pchs + StrLength(Imap->Cmd.CmdBuf);
- while ((pche > pchs) &&
- ((*pche == '\n') ||
- (*pche == '\r')))
- {
+ while ((pche > pchs) && ((*pche == '\n') || (*pche == '\r'))) {
pche --;
StrBufCutRight(Imap->Cmd.CmdBuf, 1);
}
/* Grab the tag, command, and parameters. */
imap_parameterize(&Imap->Cmd);
-#if 0
-/* debug output the parsed vector */
- {
- int i;
- 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->Cmd.Params[i].Key);
- else
- syslog(LOG_DEBUG, "%ld : %s",
- Imap->Cmd.Params[i].len,
- Imap->Cmd.Params[i].Key);
- }}
-#endif
/* Now for the command set. */
h = imap_lookup(Imap->Cmd.num_parms, Imap->Cmd.Params);
- if (h == NULL)
- {
+ if (h == NULL) {
IReply("BAD command unrecognized");
goto BAIL;
}
/* RFC3501 says that we cannot output untagged data during these commands */
if ((h->Flags & I_FLAG_UNTAGGED) == 0) {
- /* we can put any additional untagged stuff right here in the future */
+ // we can put any additional untagged stuff right here in the future
- /*
- * Before processing the command that was just entered... if we happen
- * to have a folder selected, we'd like to rescan that folder for new
- * messages, and for deletions/changes of existing messages. This
- * could probably be optimized better with some deep thought...
- */
+ // Before processing the command that was just entered... if we happen
+ // to have a folder selected, we'd like to rescan that folder for new
+ // messages, and for deletions/changes of existing messages. This
+ // could probably be optimized better with some deep thought...
if (Imap->selected) {
imap_rescan_msgids();
}
);
}
-void imap_noop (int num_parms, ConstStr *Params)
-{
+
+void imap_noop(int num_parms, ConstStr *Params) {
IReply("OK No operation");
}
-void imap_logout(int num_parms, ConstStr *Params)
-{
+
+void imap_logout(int num_parms, ConstStr *Params) {
if (IMAP->selected) {
imap_do_expunge(); /* yes, we auto-expunge at logout */
}
return;
}
+
const char *CitadelServiceIMAP="IMAP";
const char *CitadelServiceIMAPS="IMAPS";
-/*
- * This function is called to register the IMAP extension with Citadel.
- */
+
+// Initialization function, called from modules_init.c
char *ctdl_module_init_imap(void) {
if (ImapCmds == NULL) {
ImapCmds = NewHash(1, NULL);
RegisterImapCMD("CLOSE", "", imap_close, I_FLAG_LOGGED_IN | I_FLAG_SELECT);
if (!threading) {
- CtdlRegisterServiceHook(CtdlGetConfigInt("c_imap_port"),
- NULL, imap_greeting, imap_command_loop, NULL, CitadelServiceIMAP);
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_imap_port"), NULL, imap_greeting, imap_command_loop, NULL, CitadelServiceIMAP);
#ifdef HAVE_OPENSSL
- CtdlRegisterServiceHook(CtdlGetConfigInt("c_imaps_port"),
- NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS);
+ CtdlRegisterServiceHook(CtdlGetConfigInt("c_imaps_port"), NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS);
#endif
CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP, PRIO_STOP + 30);
}
- /* return our module name for the log */
+ // return our module name for the log
return "imap";
}