// IMAP server for the Citadel system
//
-// Copyright (c) 1987-2022 by the citadel.org team
+// 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 <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"
const imap_handler_hook *imap_lookup(int num_parms, ConstStr *Params) {
- struct CitContext *CCC = CC;
void *v;
- citimap *Imap = CCCIMAP;
+ citimap *Imap = IMAP;
if (num_parms < 1)
return NULL;
*/
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) {
* 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;
+ 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;
+ 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
IAPrintf("* %d RECENT\r\n", num_recent);
}
- if (msglist != NULL) {
- free(msglist);
- }
+ free(msglist);
Imap->last_mtime = CC->room.QRmtime;
}
* the IMAP server.
*/
void imap_cleanup_function(void) {
- struct CitContext *CCC = CC;
- citimap *Imap = CCCIMAP;
+ citimap *Imap = IMAP;
/* Don't do this stuff if this is not a Imap session! */
if (CC->h_command_function != imap_command_loop)
*/
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;
}
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);
* Does the real work for expunge.
*/
int imap_do_expunge(void) {
- struct CitContext *CCC = CC;
- citimap *Imap = CCCIMAP;
+ citimap *Imap = IMAP;
int i;
int num_expunged = 0;
long *delmsgs = NULL;
* Main command loop for IMAP sessions.
*/
void imap_command_loop(void) {
- struct CitContext *CCC = CC;
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)