*/
#define FDELIM '\\'
-void imap_strout(char *buf);
-int imap_parameterize(char **args, char *buf);
+typedef struct __citimap_command {
+ StrBuf *CmdBuf; /* our current commandline; gets chopped into: */
+ ConstStr *Params; /* Commandline tokens */
+ int num_parms; /* Number of Commandline tokens available */
+ int avail_parms; /* Number of ConstStr args is big */
+} citimap_command;
+
+/*
+ * since we work with shifted pointers to ConstStrs in some places,
+ * we can't just say we want to cut the n'th of Cmd, we have to pass it in
+ * and rely on that CutMe references Cmd->CmdBuf; else peek won't work out
+ * and len will differ.
+ */
+void TokenCutRight(citimap_command *Cmd,
+ ConstStr *CutMe,
+ int n);
+/*
+ * since we just move Key around here, Cmd is just here so the syntax is identical.
+ */
+void TokenCutLeft(citimap_command *Cmd,
+ ConstStr *CutMe,
+ int n);
+
+
+void imap_strout(ConstStr *args);
+void plain_imap_strout(char *buf);
+int imap_parameterize(citimap_command *Cmd);
+int old_imap_parameterize(char** args, char *n);
void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf);
void imap_ial_out(struct internet_address_list *ialist);
-int imap_roomname(char *buf, int bufsize, char *foldername);
-int imap_is_message_set(char *);
+int imap_roomname(char *buf, int bufsize, const char *foldername);
+int imap_is_message_set(const char *);
int imap_mailbox_matches_pattern(char *pattern, char *mailboxname);
-int imap_datecmp(char *datestr, time_t msgtime);
+int imap_datecmp(const char *datestr, time_t msgtime);
/*
* Flags that may be returned by imap_roomname()
void CtdlRegisterMaintenanceThread(char *name, void *(*thread_proc) (void *arg));
-void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name);
+void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name);
/*
/*
* API declarations from serv_extensions.h
*/
-void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, char *search_string, char *func_name);
+void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name);
/*
* Global system configuration. Don't change anything here. It's all in dtds/config-defs.h now.
*/
* The caller is responsible for freeing the returned buffer. If the requested
* field is not present, or anything else goes wrong, it returns NULL.
*/
-char *rfc822_fetch_field(char *rfc822, char *fieldname) {
+char *rfc822_fetch_field(char *rfc822, const char *fieldname) {
char *fieldbuf = NULL;
- char *end_of_headers;
- char *field_start;
- char *ptr;
+ const char *end_of_headers;
+ const char *field_start;
+ const char *ptr;
char *cont;
char fieldhdr[SIZ];
int fuzzy_match(struct ctdluser *us, char *matchstring);
void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name);
-char *rfc822_fetch_field(char *rfc822, char *fieldname);
+char *rfc822_fetch_field(char *rfc822, const char *fieldname);
int IsDirectory(char *addr, int allow_masq_domains);
void CtdlDirectoryInit(void);
}
-void wordbreaker(char *text, int *num_tokens, int **tokens) {
+void wordbreaker(const char *text, int *num_tokens, int **tokens) {
int wb_num_tokens = 0;
int wb_num_alloc = 0;
int *wb_tokens = NULL;
- char *ptr;
- char *word_start;
- char *word_end;
+ const char *ptr;
+ const char *word_start;
+ const char *word_end;
char ch;
int word_len;
char word[256];
#define WB_MIN 4 // nothing with 3 or less chars
#define WB_MAX 40
-void wordbreaker(char *text, int *num_tokens, int **tokens);
+void wordbreaker(const char *text, int *num_tokens, int **tokens);
void initialize_noise_words(void);
void noise_word_cleanup(void);
* (This one does the "all of these words" search.)
* Caller is responsible for freeing the message list.
*/
-void ft_search(int *fts_num_msgs, long **fts_msgs, char *search_string) {
+void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string) {
int num_tokens = 0;
int *tokens = NULL;
int i, j;
*/
void ft_index_message(long msgnum, int op);
-void ft_search(int *fts_num_msgs, long **fts_msgs, char *search_string);
+void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string);
void *indexer_thread(void *arg);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "imap_misc.h"
#include "genstamp.h"
/*
* Implements the SETACL command.
*/
-void imap_setacl(int num_parms, char *parms[]) {
+void imap_setacl(int num_parms, ConstStr *Params) {
- cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
+ cprintf("%s BAD not yet implemented FIXME\r\n", Params[0].Key);
return;
}
/*
* Implements the DELETEACL command.
*/
-void imap_deleteacl(int num_parms, char *parms[]) {
+void imap_deleteacl(int num_parms, ConstStr *Params) {
- cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
+ cprintf("%s BAD not yet implemented FIXME\r\n", Params[0].Key);
return;
}
/*
* Implements the GETACL command.
*/
-void imap_getacl(int num_parms, char *parms[]) {
+void imap_getacl(int num_parms, ConstStr *Params) {
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
char rights[32];
if (num_parms != 3) {
- cprintf("%s BAD usage error\r\n", parms[0]);
+ cprintf("%s BAD usage error\r\n", Params[0].Key);
return;
}
/*
* Search for the specified room or folder
*/
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
- cprintf("%s NO Invalid mailbox name or access denied\r\n", parms[0]);
+ cprintf("%s NO Invalid mailbox name or access denied\r\n", Params[0].Key);
return;
}
cprintf("* ACL");
cprintf(" ");
- imap_strout(parms[2]);
+ imap_strout(&Params[2]);
/*
* Traverse the userlist
imap_acl_flags(rights, ra);
if (!IsEmptyStr(rights)) {
cprintf(" ");
- imap_strout(temp.fullname);
+ plain_imap_strout(temp.fullname);
cprintf(" %s", rights);
}
}
CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
}
- cprintf("%s OK GETACL completed\r\n", parms[0]);
+ cprintf("%s OK GETACL completed\r\n", Params[0].Key);
}
/*
* Implements the LISTRIGHTS command.
*/
-void imap_listrights(int num_parms, char *parms[]) {
+void imap_listrights(int num_parms, ConstStr *Params) {
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
struct ctdluser temp;
if (num_parms != 4) {
- cprintf("%s BAD usage error\r\n", parms[0]);
+ cprintf("%s BAD usage error\r\n", Params[0].Key);
return;
}
/*
* Search for the specified room/folder
*/
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
- cprintf("%s NO Invalid mailbox name or access denied\r\n", parms[0]);
+ cprintf("%s NO Invalid mailbox name or access denied\r\n", Params[0].Key);
return;
}
* Search for the specified user
*/
ret = (-1);
- valid = validate_recipients(parms[3], NULL, 0);
+ valid = validate_recipients(Params[3].Key, NULL, 0);
if (valid != NULL) {
if (valid->num_local == 1) {
ret = CtdlGetUser(&temp, valid->recp_local);
free_recipients(valid);
}
if (ret != 0) {
- cprintf("%s NO Invalid user name or access denied\r\n", parms[0]);
+ cprintf("%s NO Invalid user name or access denied\r\n", Params[0].Key);
return;
}
* Now output the list of rights
*/
cprintf("* LISTRIGHTS ");
- imap_strout(parms[2]);
+ imap_strout(&Params[2]);
cprintf(" ");
- imap_strout(parms[3]);
+ imap_strout(&Params[3]);
cprintf(" ");
- imap_strout(""); /* FIXME ... do something here */
+ plain_imap_strout(""); /* FIXME ... do something here */
cprintf("\r\n");
/*
CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
}
- cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
+ cprintf("%s OK LISTRIGHTS completed\r\n", Params[0].Key);
return;
}
/*
* Implements the MYRIGHTS command.
*/
-void imap_myrights(int num_parms, char *parms[]) {
+void imap_myrights(int num_parms, ConstStr *Params) {
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
char rights[32];
if (num_parms != 3) {
- cprintf("%s BAD usage error\r\n", parms[0]);
+ cprintf("%s BAD usage error\r\n", Params[0].Key);
return;
}
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
- cprintf("%s NO Invalid mailbox name or access denied\r\n", parms[0]);
+ cprintf("%s NO Invalid mailbox name or access denied\r\n", Params[0].Key);
return;
}
imap_acl_flags(rights, ra);
cprintf("* MYRIGHTS ");
- imap_strout(parms[2]);
+ imap_strout(&Params[2]);
cprintf(" %s\r\n", rights);
/*
CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
}
- cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);
+ cprintf("%s OK MYRIGHTS completed\r\n", Params[0].Key);
return;
}
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void imap_setacl(int num_parms, char *parms[]);
-void imap_deleteacl(int num_parms, char *parms[]);
-void imap_getacl(int num_parms, char *parms[]);
-void imap_listrights(int num_parms, char *parms[]);
-void imap_myrights(int num_parms, char *parms[]);
+void imap_setacl(int num_parms, ConstStr *Params);
+void imap_deleteacl(int num_parms, ConstStr *Params);
+void imap_getacl(int num_parms, ConstStr *Params);
+void imap_listrights(int num_parms, ConstStr *Params);
+void imap_myrights(int num_parms, ConstStr *Params);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "genstamp.h"
#include "ctdl_module.h"
*/
void imap_fetch_rfc822(long msgnum, char *whichfmt) {
char buf[SIZ];
- char *ptr = NULL;
+ const char *ptr = NULL;
size_t headers_size, text_size, total_size;
size_t bytes_to_send = 0;
struct MetaData smi;
/* For everything else, we do stuff. */
cprintf("(("); /* open double-parens */
- imap_strout(msg->cm_fields['A']); /* personal name */
+ plain_imap_strout(msg->cm_fields['A']); /* personal name */
cprintf(" NIL "); /* source route (not used) */
if (msg->cm_fields['F'] != NULL) {
process_rfc822_addr(msg->cm_fields['F'], user, node, name);
- imap_strout(user); /* mailbox name (user id) */
+ plain_imap_strout(user); /* mailbox name (user id) */
cprintf(" ");
if (!strcasecmp(node, config.c_nodename)) {
- imap_strout(config.c_fqdn);
+ plain_imap_strout(config.c_fqdn);
}
else {
- imap_strout(node); /* host name */
+ plain_imap_strout(node); /* host name */
}
}
else {
- imap_strout(msg->cm_fields['A']); /* mailbox name (user id) */
+ plain_imap_strout(msg->cm_fields['A']); /* mailbox name (user id) */
cprintf(" ");
- imap_strout(msg->cm_fields['N']); /* host name */
+ plain_imap_strout(msg->cm_fields['N']); /* host name */
}
cprintf(")) "); /* close double-parens */
striplt(individual_addr);
process_rfc822_addr(individual_addr, user, node, name);
cprintf("(");
- imap_strout(name);
+ plain_imap_strout(name);
cprintf(" NIL ");
- imap_strout(user);
+ plain_imap_strout(user);
cprintf(" ");
- imap_strout(node);
+ plain_imap_strout(node);
cprintf(")");
if (i < (num_addrs-1)) cprintf(" ");
}
cprintf("ENVELOPE (");
/* Date */
- imap_strout(datestringbuf);
+ plain_imap_strout(datestringbuf);
cprintf(" ");
/* Subject */
- imap_strout(msg->cm_fields['U']);
+ plain_imap_strout(msg->cm_fields['U']);
cprintf(" ");
/* From */
/* In-reply-to */
fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "In-reply-to");
- imap_strout(fieldptr);
+ plain_imap_strout(fieldptr);
cprintf(" ");
if (fieldptr != NULL) free(fieldptr);
/* message ID */
- imap_strout(msg->cm_fields['I']);
+ plain_imap_strout(msg->cm_fields['I']);
cprintf(")");
}
char *boiled_headers = NULL;
int ok = 0;
int done_headers = 0;
- char *ptr = NULL;
+ const char *ptr = NULL;
if (CC->redirect_buffer == NULL) return;
break;
}
}
- num_parms = imap_parameterize(parms, which_fields);
+ num_parms = old_imap_parameterize(parms, which_fields);
boiled_headers = malloc(CC->redirect_alloc);
strcpy(boiled_headers, "");
/* disposition */
extract_token(subtype, cbtype, 1, '/', sizeof subtype);
- imap_strout(subtype);
+ plain_imap_strout(subtype);
/* body language */
/* cprintf(" NIL"); We thought we needed this at one point, but maybe we don't... */
}
cprintf("(");
- imap_strout(cbmaintype); /* body type */
+ plain_imap_strout(cbmaintype); /* body type */
cprintf(" ");
- imap_strout(cbsubtype); /* body subtype */
+ plain_imap_strout(cbsubtype); /* body subtype */
cprintf(" ");
cprintf("("); /* begin body parameter list */
*/
if (name != NULL) if (!IsEmptyStr(name)) {
cprintf("\"NAME\" ");
- imap_strout(name);
+ plain_imap_strout(name);
cprintf(" ");
}
cprintf("\"CHARSET\" ");
if (cbcharset == NULL) {
- imap_strout("US-ASCII");
+ plain_imap_strout("US-ASCII");
}
else if (cbcharset[0] == 0) {
- imap_strout("US-ASCII");
+ plain_imap_strout("US-ASCII");
}
else {
- imap_strout(cbcharset);
+ plain_imap_strout(cbcharset);
}
cprintf(") "); /* end body parameter list */
if (encoding != NULL) if (encoding[0] != 0) have_encoding = 1;
if (have_encoding) {
- imap_strout(encoding);
+ plain_imap_strout(encoding);
}
else {
- imap_strout("7BIT");
+ plain_imap_strout("7BIT");
}
cprintf(" ");
}
else {
cprintf("(");
- imap_strout(disp);
+ plain_imap_strout(disp);
if (filename != NULL) if (!IsEmptyStr(filename)) {
cprintf(" (\"FILENAME\" ");
- imap_strout(filename);
+ plain_imap_strout(filename);
cprintf(")");
}
cprintf(")");
*/
void imap_fetch_bodystructure (long msgnum, char *item,
struct CtdlMessage *msg) {
- char *rfc822 = NULL;
- char *rfc822_body = NULL;
+ const char *rfc822 = NULL;
+ const char *rfc822_body = NULL;
size_t rfc822_len;
size_t rfc822_headers_len;
size_t rfc822_body_len;
- char *ptr = NULL;
+ const char *ptr = NULL;
+ char *pch;
char buf[SIZ];
int lines = 0;
CC->redirect_len = 0;
CC->redirect_alloc = SIZ;
CtdlOutputPreLoadedMsg(msg, MT_RFC822, 0, 0, 1, SUPPRESS_ENV_TO);
- rfc822 = CC->redirect_buffer;
+ rfc822 = pch = CC->redirect_buffer;
rfc822_len = CC->redirect_len;
CC->redirect_buffer = NULL;
CC->redirect_len = 0;
rfc822_headers_len = rfc822_body - rfc822;
rfc822_body_len = rfc822_len - rfc822_headers_len;
- free(rfc822);
+ free(pch);
cprintf("BODYSTRUCTURE (\"TEXT\" \"PLAIN\" "
"(\"CHARSET\" \"US-ASCII\") NIL NIL "
*
* Set is_uid to 1 to fetch by UID instead of sequence number.
*/
-void imap_pick_range(char *supplied_range, int is_uid) {
+void imap_pick_range(const char *supplied_range, int is_uid) {
int i;
int num_sets;
int s;
char setstr[SIZ], lostr[SIZ], histr[SIZ];
long lo, hi;
char actual_range[SIZ];
- struct citimap *Imap;
+ citimap *Imap;
/*
* Handle the "ALL" macro
/*
* This function is called by the main command loop.
*/
-void imap_fetch(int num_parms, char *parms[]) {
+void imap_fetch(int num_parms, ConstStr *Params) {
char items[SIZ];
char *itemlist[512];
int num_items;
int i;
if (num_parms < 4) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- imap_pick_range(parms[2], 0);
+ imap_pick_range(Params[2].Key, 0);
strcpy(items, "");
for (i=3; i<num_parms; ++i) {
- strcat(items, parms[i]);
+ strcat(items, Params[i].Key);
if (i < (num_parms-1)) strcat(items, " ");
}
num_items = imap_extract_data_items(itemlist, items);
if (num_items < 1) {
- cprintf("%s BAD invalid data item list\r\n", parms[0]);
+ cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
return;
}
imap_do_fetch(num_items, itemlist);
- cprintf("%s OK FETCH completed\r\n", parms[0]);
+ cprintf("%s OK FETCH completed\r\n", Params[0].Key);
}
/*
* This function is called by the main command loop.
*/
-void imap_uidfetch(int num_parms, char *parms[]) {
+void imap_uidfetch(int num_parms, ConstStr *Params) {
char items[SIZ];
char *itemlist[512];
int num_items;
int have_uid_item = 0;
if (num_parms < 5) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- imap_pick_range(parms[3], 1);
+ imap_pick_range(Params[3].Key, 1);
strcpy(items, "");
for (i=4; i<num_parms; ++i) {
- strcat(items, parms[i]);
+ strcat(items, Params[i].Key);
if (i < (num_parms-1)) strcat(items, " ");
}
num_items = imap_extract_data_items(itemlist, items);
if (num_items < 1) {
- cprintf("%s BAD invalid data item list\r\n", parms[0]);
+ cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
return;
}
}
imap_do_fetch(num_items, itemlist);
- cprintf("%s OK UID FETCH completed\r\n", parms[0]);
+ cprintf("%s OK UID FETCH completed\r\n", Params[0].Key);
}
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void imap_pick_range(char *range, int is_uid);
-void imap_fetch(int num_parms, char *parms[]);
-void imap_uidfetch(int num_parms, char *parms[]);
+void imap_pick_range(const char *range, int is_uid);
+void imap_fetch(int num_parms, ConstStr *Params);
+void imap_uidfetch(int num_parms, ConstStr *Params);
void imap_fetch_flags(int seq);
int imap_extract_data_items(char **argv, char *items);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "imap_search.h"
#include "imap_store.h"
}
if (match) {
cprintf("* %s (\\NoSelect \\HasChildren) \"/\" ", verb);
- imap_strout(fl->f_name);
+ plain_imap_strout(fl->f_name);
cprintf("\r\n");
}
}
}
if (match) {
cprintf("* %s (%s) \"/\" ", verb, return_options);
- imap_strout(buf);
+ plain_imap_strout(buf);
cprintf("\r\n");
}
}
/*
* Implements the LIST and LSUB commands
*/
-void imap_list(int num_parms, char *parms[])
+void imap_list(int num_parms, ConstStr *Params)
{
int subscribed_rooms_only = 0;
char verb[16];
int return_children = 0;
if (num_parms < 4) {
- cprintf("%s BAD arguments invalid\r\n", parms[0]);
+ cprintf("%s BAD arguments invalid\r\n", Params[0].Key);
return;
}
/* parms[1] is the IMAP verb being used (e.g. LIST or LSUB)
* This tells us how to behave, and what verb to return back to the caller
*/
- safestrncpy(verb, parms[1], sizeof verb);
- j = strlen(verb);
+ safestrncpy(verb, Params[1].Key, sizeof verb);
+ j = Params[1].len;
for (i=0; i<j; ++i) {
verb[i] = toupper(verb[i]);
}
* selection options. Extract their exact position, and then modify our
* expectation of where the root folder will be specified.
*/
- if (parms[2][0] == '(') {
+ if (Params[2].Key[0] == '(') {
extended_list_in_use = 1;
selection_left = 2;
paren_nest = 0;
for (i=2; i<num_parms; ++i) {
- for (j=0; parms[i][j]; ++j) {
- if (parms[i][j] == '(') ++paren_nest;
- if (parms[i][j] == ')') --paren_nest;
+ for (j=0; Params[i].Key[j]; ++j) {
+ if (Params[i].Key[j] == '(') ++paren_nest;
+ if (Params[i].Key[j] == ')') --paren_nest;
}
if (paren_nest == 0) {
selection_right = i; /* found end of selection options */
if ((selection_left > 0) && (selection_right >= selection_left)) {
/* Strip off the outer parentheses */
- if (parms[selection_left][0] == '(') {
- strcpy(parms[selection_left], &parms[selection_left][1]);
+ if (Params[selection_left].Key[0] == '(') {
+ TokenCutLeft(&IMAP->Cmd,
+ &Params[selection_left],
+ 1);
}
- if (parms[selection_right][strlen(parms[selection_right])-1] == ')') {
- parms[selection_right][strlen(parms[selection_right])-1] = 0;
+ if (Params[selection_right].Key[Params[selection_right].len-1] == ')') {
+ TokenCutRight(&IMAP->Cmd,
+ &Params[selection_right],
+ 1);
}
for (i=selection_left; i<=selection_right; ++i) {
- if (!strcasecmp(parms[i], "SUBSCRIBED")) {
+ if (!strcasecmp(Params[i].Key, "SUBSCRIBED")) {
subscribed_rooms_only = 1;
}
- else if (!strcasecmp(parms[i], "RECURSIVEMATCH")) {
+ else if (!strcasecmp(Params[i].Key, "RECURSIVEMATCH")) {
/* FIXME - do this! */
}
patterns_left = root_pos + 1;
patterns_right = root_pos + 1;
- if (parms[patterns_left][0] == '(') {
+ if (Params[patterns_left].Key[0] == '(') {
extended_list_in_use = 1;
paren_nest = 0;
for (i=patterns_left; i<num_parms; ++i) {
- for (j=0; &parms[i][j]; ++j) {
- if (parms[i][j] == '(') ++paren_nest;
- if (parms[i][j] == ')') --paren_nest;
+ for (j=0; &Params[i].Key[j]; ++j) {
+ if (Params[i].Key[j] == '(') ++paren_nest;
+ if (Params[i].Key[j] == ')') --paren_nest;
}
if (paren_nest == 0) {
patterns_right = i; /* found end of patterns */
for (i=0; i<num_patterns; ++i) {
if (i < MAX_PATTERNS) {
patterns[i] = malloc(512);
- snprintf(patterns[i], 512, "%s%s", parms[root_pos], parms[patterns_left+i]);
+ snprintf(patterns[i], 512, "%s%s", Params[root_pos].Key, Params[patterns_left+i].Key);
if (i == 0) {
strcpy(patterns[i], &patterns[i][1]);
}
else {
num_patterns = 1;
patterns[0] = malloc(512);
- snprintf(patterns[0], 512, "%s%s", parms[root_pos], parms[patterns_left]);
+ snprintf(patterns[0], 512, "%s%s",
+ Params[root_pos].Key,
+ Params[patterns_left].Key);
}
/* If the word "RETURN" appears after the folder pattern list, then the client
* is specifying return options.
*/
- if (num_parms - patterns_right > 2) if (!strcasecmp(parms[patterns_right+1], "RETURN")) {
+ if (num_parms - patterns_right > 2) if (!strcasecmp(Params[patterns_right+1].Key, "RETURN")) {
return_left = patterns_right + 2;
extended_list_in_use = 1;
paren_nest = 0;
for (i=return_left; i<num_parms; ++i) {
- for (j=0; parms[i][j]; ++j) {
- if (parms[i][j] == '(') ++paren_nest;
- if (parms[i][j] == ')') --paren_nest;
+ for (j=0; Params[i].Key[j]; ++j) {
+ if (Params[i].Key[j] == '(') ++paren_nest;
+ if (Params[i].Key[j] == ')') --paren_nest;
}
/* Might as well look for these while we're in here... */
- if (parms[i][0] == '(') strcpy(parms[i], &parms[i][1]);
- if (parms[i][strlen(parms[i])-1] == ')') parms[i][strlen(parms[i])-1] = 0;
- CtdlLogPrintf(9, "evaluating <%s>\n", parms[i]);
-
- if (!strcasecmp(parms[i], "SUBSCRIBED")) {
+ if (Params[i].Key[0] == '(')
+ TokenCutLeft(&IMAP->Cmd,
+ &Params[i],
+ 1);
+ if (Params[i].Key[Params[i].len-1] == ')')
+ TokenCutRight(&IMAP->Cmd,
+ &Params[i],
+ 1);
+
+ CtdlLogPrintf(9, "evaluating <%s>\n", Params[i].Key);
+
+ if (!strcasecmp(Params[i].Key, "SUBSCRIBED")) {
return_subscribed = 1;
}
- else if (!strcasecmp(parms[i], "CHILDREN")) {
+ else if (!strcasecmp(Params[i].Key, "CHILDREN")) {
return_children = 1;
}
free(patterns[i]);
}
- cprintf("%s OK %s completed\r\n", parms[0], verb);
+ cprintf("%s OK %s completed\r\n", Params[0].Key, verb);
}
*/
#define MAX_PATTERNS 20
-void imap_list(int num_parms, char *parms[]);
+void imap_list(int num_parms, ConstStr *Params);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "imap_misc.h"
#include "genstamp.h"
* Attempting to set anything else calls a stub which fools the client into
* thinking that there is no remaining space available to store annotations.
*/
-void imap_setmetadata(int num_parms, char *parms[]) {
+void imap_setmetadata(int num_parms, ConstStr *Params) {
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
struct visit vbuf;
if (num_parms != 6) {
- cprintf("%s BAD usage error\r\n", parms[0]);
+ cprintf("%s BAD usage error\r\n", Params[0].Key);
return;
}
/*
* Don't allow other types of metadata to be set
*/
- if (strcasecmp(parms[3], "/vendor/kolab/folder-type")) {
- cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
+ if (strcasecmp(Params[3].Key, "/vendor/kolab/folder-type")) {
+ cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", Params[0].Key);
return;
}
- if (!strcasecmp(parms[4], "(value.shared")) {
+ if (!strcasecmp(Params[4].Key, "(value.shared")) {
setting_user_value = 0; /* global view */
}
- else if (!strcasecmp(parms[4], "(value.priv")) {
+ else if (!strcasecmp(Params[4].Key, "(value.priv")) {
setting_user_value = 1; /* per-user view */
}
else {
- cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
+ cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", Params[0].Key);
return;
}
* Extract the folder type without any parentheses. Then learn
* the Citadel view type based on the supplied folder type.
*/
- extract_token(set_value, parms[5], 0, ')', sizeof set_value);
+ extract_token(set_value, Params[5].Key, 0, ')', sizeof set_value);
if (!strncasecmp(set_value, "mail", 4)) {
set_view = VIEW_MAILBOX;
}
set_view = VIEW_MAILBOX;
}
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf("%s NO Invalid mailbox name or access denied\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
if (setting_user_value)
{
- cprintf("%s OK SETANNOTATION complete\r\n", parms[0]);
+ cprintf("%s OK SETANNOTATION complete\r\n", Params[0].Key);
}
/* If this is a "value.shared" set operation, we are allowed to perform it
CtdlGetRoomLock(&CC->room, CC->room.QRname);
CC->room.QRdefaultview = set_view;
CtdlPutRoomLock(&CC->room);
- cprintf("%s OK SETANNOTATION complete\r\n", parms[0]);
+ cprintf("%s OK SETANNOTATION complete\r\n", Params[0].Key);
}
/* If we got to this point, we don't have permission to set the default view. */
else {
- cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
+ cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", Params[0].Key);
}
/*
* Regardless of what the client asked for, we are going to supply them with
* the folder type. It's the only metadata we have anyway.
*/
-void imap_getmetadata(int num_parms, char *parms[]) {
+void imap_getmetadata(int num_parms, ConstStr *Params) {
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
int ret;
if (num_parms > 5) {
- cprintf("%s BAD usage error\r\n", parms[0]);
+ cprintf("%s BAD usage error\r\n", Params[0].Key);
return;
}
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf("%s NO Invalid mailbox name or access denied\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
CtdlUserGoto(roomname, 0, 0, &msgs, &new);
cprintf("* METADATA ");
- imap_strout(parms[2]);
+ imap_strout(&Params[2]);
cprintf(" \"/vendor/kolab/folder-type\" (\"value.shared\" \"");
/* If it's one of our hard-coded default rooms, we know what to do... */
CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
}
- cprintf("%s OK GETMETADATA complete\r\n", parms[0]);
+ cprintf("%s OK GETMETADATA complete\r\n", Params[0].Key);
return;
}
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void imap_getmetadata(int num_parms, char *parms[]);
-void imap_setmetadata(int num_parms, char *parms[]);
+void imap_getmetadata(int num_parms, ConstStr *Params);
+void imap_setmetadata(int num_parms, ConstStr *Params);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "imap_misc.h"
#include "genstamp.h"
* imap_copy() calls imap_do_copy() to do its actual work, once it's
* validated and boiled down the request a bit. (returns 0 on success)
*/
-int imap_do_copy(char *destination_folder) {
+int imap_do_copy(const char *destination_folder) {
int i;
char roomname[ROOMNAMELEN];
struct ctdlroom qrbuf;
/*
* This function is called by the main command loop.
*/
-void imap_copy(int num_parms, char *parms[]) {
+void imap_copy(int num_parms, ConstStr *Params) {
int ret;
if (num_parms != 4) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- if (imap_is_message_set(parms[2])) {
- imap_pick_range(parms[2], 0);
+ if (imap_is_message_set(Params[2].Key)) {
+ imap_pick_range(Params[2].Key, 0);
}
else {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- ret = imap_do_copy(parms[3]);
+ ret = imap_do_copy(Params[3].Key);
if (!ret) {
- cprintf("%s OK ", parms[0]);
+ cprintf("%s OK ", Params[0].Key);
imap_output_copyuid_response();
cprintf("COPY completed\r\n");
}
else {
- cprintf("%s NO COPY failed (error %d)\r\n", parms[0], ret);
+ cprintf("%s NO COPY failed (error %d)\r\n", Params[0].Key, ret);
}
}
/*
* This function is called by the main command loop.
*/
-void imap_uidcopy(int num_parms, char *parms[]) {
+void imap_uidcopy(int num_parms, ConstStr *Params) {
if (num_parms != 5) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- if (imap_is_message_set(parms[3])) {
- imap_pick_range(parms[3], 1);
+ if (imap_is_message_set(Params[3].Key)) {
+ imap_pick_range(Params[3].Key, 1);
}
else {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- if (imap_do_copy(parms[4]) == 0) {
- cprintf("%s OK ", parms[0]);
+ if (imap_do_copy(Params[4].Key) == 0) {
+ cprintf("%s OK ", Params[0].Key);
imap_output_copyuid_response();
cprintf("UID COPY completed\r\n");
}
else {
- cprintf("%s NO UID COPY failed\r\n", parms[0]);
+ cprintf("%s NO UID COPY failed\r\n", Params[0].Key);
}
}
/*
* This function is called by the main command loop.
*/
-void imap_append(int num_parms, char *parms[]) {
+void imap_append(int num_parms, ConstStr *Params) {
long literal_length;
long bytes_transferred;
struct CtdlMessage *msg = NULL;
int msgs, new;
int i;
char new_message_flags[SIZ];
- struct citimap *Imap;
+ citimap *Imap;
if (num_parms < 4) {
- cprintf("%s BAD usage error\r\n", parms[0]);
+ cprintf("%s BAD usage error\r\n", Params[0].Key);
return;
}
- if ( (parms[num_parms-1][0] != '{')
- || (parms[num_parms-1][strlen(parms[num_parms-1])-1] != '}') ) {
- cprintf("%s BAD no message literal supplied\r\n", parms[0]);
+ if ( (Params[num_parms-1].Key[0] != '{')
+ || (Params[num_parms-1].Key[Params[num_parms-1].len-1] != '}') ) {
+ cprintf("%s BAD no message literal supplied\r\n", Params[0].Key);
return;
}
strcpy(new_message_flags, "");
if (num_parms >= 5) {
for (i=3; i<num_parms; ++i) {
- strcat(new_message_flags, parms[i]);
+ strcat(new_message_flags, Params[i].Key);
strcat(new_message_flags, " ");
}
stripallbut(new_message_flags, '(', ')');
* }
*/
- literal_length = atol(&parms[num_parms-1][1]);
+ literal_length = atol(&Params[num_parms-1].Key[1]);
if (literal_length < 1) {
cprintf("%s BAD Message length must be at least 1.\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
Imap->TransmittedMessage = NewStrBufPlain(NULL, literal_length);
if (Imap->TransmittedMessage == NULL) {
- cprintf("%s NO Cannot allocate memory.\r\n", parms[0]);
+ cprintf("%s NO Cannot allocate memory.\r\n", Params[0].Key);
return;
}
client_read_blob(Imap->TransmittedMessage, literal_length, config.c_sleeping);
if ((ret < 0) || (StrLength(Imap->TransmittedMessage) < literal_length)) {
- cprintf("%s NO Read failed.\r\n", parms[0]);
+ cprintf("%s NO Read failed.\r\n", Params[0].Key);
return;
}
CtdlLogPrintf(CTDL_DEBUG, "Converting message format\n");
msg = convert_internet_message_buf(&Imap->TransmittedMessage);
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf("%s NO Invalid mailbox name or access denied\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
if (ret) {
/* Nope ... print an error message */
- cprintf("%s NO %s\r\n", parms[0], buf);
+ cprintf("%s NO %s\r\n", Params[0].Key, buf);
}
else {
}
if (new_msgnum >= 0L) {
cprintf("%s OK [APPENDUID %ld %ld] APPEND completed\r\n",
- parms[0], GLOBAL_UIDVALIDITY_VALUE, new_msgnum);
+ Params[0].Key, GLOBAL_UIDVALIDITY_VALUE, new_msgnum);
}
else {
cprintf("%s BAD Error %ld saving message to disk.\r\n",
- parms[0], new_msgnum);
+ Params[0].Key, new_msgnum);
}
}
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void imap_copy(int num_parms, char *parms[]);
-void imap_uidcopy(int num_parms, char *parms[]);
-void imap_append(int num_parms, char *parms[]);
+void imap_copy(int num_parms, ConstStr *Params);
+void imap_uidcopy(int num_parms, ConstStr *Params);
+void imap_append(int num_parms, ConstStr *Params);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "imap_search.h"
#include "genstamp.h"
* be loaded only if one or more search criteria require it.
*/
int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
- int num_items, char **itemlist, int is_uid) {
+ int num_items, ConstStr *itemlist, int is_uid) {
int match = 0;
int is_not = 0;
pos = 0;
/* Check for the dreaded NOT criterion. */
- if (!strcasecmp(itemlist[0], "NOT")) {
+ if (!strcasecmp(itemlist[0].Key, "NOT")) {
is_not = 1;
pos = 1;
}
/* Check for the dreaded OR criterion. */
- if (!strcasecmp(itemlist[0], "OR")) {
+ if (!strcasecmp(itemlist[0].Key, "OR")) {
is_or = 1;
pos = 1;
}
/* Now look for criteria. */
- if (!strcasecmp(itemlist[pos], "ALL")) {
+ if (!strcasecmp(itemlist[pos].Key, "ALL")) {
match = 1;
++pos;
}
- else if (!strcasecmp(itemlist[pos], "ANSWERED")) {
+ else if (!strcasecmp(itemlist[pos].Key, "ANSWERED")) {
if (IMAP->flags[seq-1] & IMAP_ANSWERED) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "BCC")) {
+ else if (!strcasecmp(itemlist[pos].Key, "BCC")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
if (msg != NULL) {
fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Bcc");
if (fieldptr != NULL) {
- if (bmstrcasestr(fieldptr, itemlist[pos+1])) {
+ if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
match = 1;
}
free(fieldptr);
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "BEFORE")) {
+ else if (!strcasecmp(itemlist[pos].Key, "BEFORE")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
if (msg->cm_fields['T'] != NULL) {
- if (imap_datecmp(itemlist[pos+1],
+ if (imap_datecmp(itemlist[pos+1].Key,
atol(msg->cm_fields['T'])) < 0) {
match = 1;
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "BODY")) {
+ else if (!strcasecmp(itemlist[pos].Key, "BODY")) {
/* If fulltext indexing is active, on this server,
* all messages have already been qualified.
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (bmstrcasestr(msg->cm_fields['M'], itemlist[pos+1])) {
+ if (bmstrcasestr(msg->cm_fields['M'], itemlist[pos+1].Key)) {
match = 1;
}
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "CC")) {
+ else if (!strcasecmp(itemlist[pos].Key, "CC")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
if (msg != NULL) {
fieldptr = msg->cm_fields['Y'];
if (fieldptr != NULL) {
- if (bmstrcasestr(fieldptr, itemlist[pos+1])) {
+ if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
match = 1;
}
}
else {
fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Cc");
if (fieldptr != NULL) {
- if (bmstrcasestr(fieldptr, itemlist[pos+1])) {
+ if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
match = 1;
}
free(fieldptr);
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "DELETED")) {
+ else if (!strcasecmp(itemlist[pos].Key, "DELETED")) {
if (IMAP->flags[seq-1] & IMAP_DELETED) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "DRAFT")) {
+ else if (!strcasecmp(itemlist[pos].Key, "DRAFT")) {
if (IMAP->flags[seq-1] & IMAP_DRAFT) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "FLAGGED")) {
+ else if (!strcasecmp(itemlist[pos].Key, "FLAGGED")) {
if (IMAP->flags[seq-1] & IMAP_FLAGGED) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "FROM")) {
+ else if (!strcasecmp(itemlist[pos].Key, "FROM")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (bmstrcasestr(msg->cm_fields['A'], itemlist[pos+1])) {
+ if (bmstrcasestr(msg->cm_fields['A'], itemlist[pos+1].Key)) {
match = 1;
}
- if (bmstrcasestr(msg->cm_fields['F'], itemlist[pos+1])) {
+ if (bmstrcasestr(msg->cm_fields['F'], itemlist[pos+1].Key)) {
match = 1;
}
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "HEADER")) {
+ else if (!strcasecmp(itemlist[pos].Key, "HEADER")) {
/* We've got to do a slow search for this because the client
* might be asking for an RFC822 header field that has not been
CC->redirect_alloc = SIZ;
CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_FAST, 0, 1, 0);
- fieldptr = rfc822_fetch_field(CC->redirect_buffer, itemlist[pos+1]);
+ fieldptr = rfc822_fetch_field(CC->redirect_buffer, itemlist[pos+1].Key);
if (fieldptr != NULL) {
- if (bmstrcasestr(fieldptr, itemlist[pos+2])) {
+ if (bmstrcasestr(fieldptr, itemlist[pos+2].Key)) {
match = 1;
}
free(fieldptr);
pos += 3; /* Yes, three */
}
- else if (!strcasecmp(itemlist[pos], "KEYWORD")) {
+ else if (!strcasecmp(itemlist[pos].Key, "KEYWORD")) {
/* not implemented */
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "LARGER")) {
+ else if (!strcasecmp(itemlist[pos].Key, "LARGER")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (strlen(msg->cm_fields['M']) > atoi(itemlist[pos+1])) {
+ if (strlen(msg->cm_fields['M']) > atoi(itemlist[pos+1].Key)) {
match = 1;
}
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "NEW")) {
+ else if (!strcasecmp(itemlist[pos].Key, "NEW")) {
if ( (IMAP->flags[seq-1] & IMAP_RECENT) && (!(IMAP->flags[seq-1] & IMAP_SEEN))) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "OLD")) {
+ else if (!strcasecmp(itemlist[pos].Key, "OLD")) {
if (!(IMAP->flags[seq-1] & IMAP_RECENT)) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "ON")) {
+ else if (!strcasecmp(itemlist[pos].Key, "ON")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
if (msg->cm_fields['T'] != NULL) {
- if (imap_datecmp(itemlist[pos+1],
+ if (imap_datecmp(itemlist[pos+1].Key,
atol(msg->cm_fields['T'])) == 0) {
match = 1;
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "RECENT")) {
+ else if (!strcasecmp(itemlist[pos].Key, "RECENT")) {
if (IMAP->flags[seq-1] & IMAP_RECENT) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "SEEN")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SEEN")) {
if (IMAP->flags[seq-1] & IMAP_SEEN) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "SENTBEFORE")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SENTBEFORE")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
if (msg->cm_fields['T'] != NULL) {
- if (imap_datecmp(itemlist[pos+1],
+ if (imap_datecmp(itemlist[pos+1].Key,
atol(msg->cm_fields['T'])) < 0) {
match = 1;
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "SENTON")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SENTON")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
if (msg->cm_fields['T'] != NULL) {
- if (imap_datecmp(itemlist[pos+1],
+ if (imap_datecmp(itemlist[pos+1].Key,
atol(msg->cm_fields['T'])) == 0) {
match = 1;
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "SENTSINCE")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SENTSINCE")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
if (msg->cm_fields['T'] != NULL) {
- if (imap_datecmp(itemlist[pos+1],
+ if (imap_datecmp(itemlist[pos+1].Key,
atol(msg->cm_fields['T'])) >= 0) {
match = 1;
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "SINCE")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SINCE")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
if (msg->cm_fields['T'] != NULL) {
- if (imap_datecmp(itemlist[pos+1],
+ if (imap_datecmp(itemlist[pos+1].Key,
atol(msg->cm_fields['T'])) >= 0) {
match = 1;
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "SMALLER")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SMALLER")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (strlen(msg->cm_fields['M']) < atoi(itemlist[pos+1])) {
+ if (strlen(msg->cm_fields['M']) < atoi(itemlist[pos+1].Key)) {
match = 1;
}
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "SUBJECT")) {
+ else if (!strcasecmp(itemlist[pos].Key, "SUBJECT")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (bmstrcasestr(msg->cm_fields['U'], itemlist[pos+1])) {
+ if (bmstrcasestr(msg->cm_fields['U'], itemlist[pos+1].Key)) {
match = 1;
}
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "TEXT")) {
+ else if (!strcasecmp(itemlist[pos].Key, "TEXT")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
for (i='A'; i<='Z'; ++i) {
- if (bmstrcasestr(msg->cm_fields[i], itemlist[pos+1])) {
+ if (bmstrcasestr(msg->cm_fields[i], itemlist[pos+1].Key)) {
match = 1;
}
}
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "TO")) {
+ else if (!strcasecmp(itemlist[pos].Key, "TO")) {
if (msg == NULL) {
msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (bmstrcasestr(msg->cm_fields['R'], itemlist[pos+1])) {
+ if (bmstrcasestr(msg->cm_fields['R'], itemlist[pos+1].Key)) {
match = 1;
}
}
}
/* FIXME this is b0rken. fix it. */
- else if (imap_is_message_set(itemlist[pos])) {
- if (is_msg_in_sequence_set(itemlist[pos], seq)) {
+ else if (imap_is_message_set(itemlist[pos].Key)) {
+ if (is_msg_in_sequence_set(itemlist[pos].Key, seq)) {
match = 1;
}
pos += 1;
}
/* FIXME this is b0rken. fix it. */
- else if (!strcasecmp(itemlist[pos], "UID")) {
- if (is_msg_in_sequence_set(itemlist[pos+1], IMAP->msgids[seq-1])) {
+ else if (!strcasecmp(itemlist[pos].Key, "UID")) {
+ if (is_msg_in_sequence_set(itemlist[pos+1].Key, IMAP->msgids[seq-1])) {
match = 1;
}
pos += 2;
* can't there be *one* way to do things? More gratuitous complexity.
*/
- else if (!strcasecmp(itemlist[pos], "UNANSWERED")) {
+ else if (!strcasecmp(itemlist[pos].Key, "UNANSWERED")) {
if ((IMAP->flags[seq-1] & IMAP_ANSWERED) == 0) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "UNDELETED")) {
+ else if (!strcasecmp(itemlist[pos].Key, "UNDELETED")) {
if ((IMAP->flags[seq-1] & IMAP_DELETED) == 0) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "UNDRAFT")) {
+ else if (!strcasecmp(itemlist[pos].Key, "UNDRAFT")) {
if ((IMAP->flags[seq-1] & IMAP_DRAFT) == 0) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "UNFLAGGED")) {
+ else if (!strcasecmp(itemlist[pos].Key, "UNFLAGGED")) {
if ((IMAP->flags[seq-1] & IMAP_FLAGGED) == 0) {
match = 1;
}
++pos;
}
- else if (!strcasecmp(itemlist[pos], "UNKEYWORD")) {
+ else if (!strcasecmp(itemlist[pos].Key, "UNKEYWORD")) {
/* FIXME */
pos += 2;
}
- else if (!strcasecmp(itemlist[pos], "UNSEEN")) {
+ else if (!strcasecmp(itemlist[pos].Key, "UNSEEN")) {
if ((IMAP->flags[seq-1] & IMAP_SEEN) == 0) {
match = 1;
}
* imap_search() calls imap_do_search() to do its actual work, once it's
* validated and boiled down the request a bit.
*/
-void imap_do_search(int num_items, char **itemlist, int is_uid) {
+void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) {
int i, j, k;
int fts_num_msgs = 0;
long *fts_msgs = NULL;
* client software. Revisit later...
*/
for (i=0; i<num_items; ++i) {
- if (itemlist[i][0] == '(') {
- strcpy(&itemlist[i][0], &itemlist[i][1]);
+ if (itemlist[i].Key[0] == '(') {
+
+ TokenCutLeft(&IMAP->Cmd,
+ &itemlist[i],
+ 1);
}
- if (itemlist[i][strlen(itemlist[i])-1] == ')') {
- itemlist[i][strlen(itemlist[i])-1] = 0;
+ if (itemlist[i].Key[itemlist[i].len-1] == ')') {
+ TokenCutRight(&IMAP->Cmd,
+ &itemlist[i],
+ 1);
}
}
* matching. (Only do this if the index is enabled!!)
*/
if (config.c_enable_fulltext) for (i=0; i<(num_items-1); ++i) {
- if (!strcasecmp(itemlist[i], "BODY")) {
- CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1], "fulltext");
+ if (!strcasecmp(itemlist[i].Key, "BODY")) {
+ CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1].Key, "fulltext");
if (fts_num_msgs > 0) {
for (j=0; j < IMAP->num_msgs; ++j) {
if (IMAP->flags[j] & IMAP_SELECTED) {
/*
* This function is called by the main command loop.
*/
-void imap_search(int num_parms, char *parms[]) {
+void imap_search(int num_parms, ConstStr *Params) {
int i;
if (num_parms < 3) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
IMAP->flags[i] |= IMAP_SELECTED;
}
- imap_do_search(num_parms-2, &parms[2], 0);
- cprintf("%s OK SEARCH completed\r\n", parms[0]);
+ imap_do_search(num_parms-2, &Params[2], 0);
+ cprintf("%s OK SEARCH completed\r\n", Params[0].Key);
}
/*
* This function is called by the main command loop.
*/
-void imap_uidsearch(int num_parms, char *parms[]) {
+void imap_uidsearch(int num_parms, ConstStr *Params) {
int i;
if (num_parms < 4) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
IMAP->flags[i] |= IMAP_SELECTED;
}
- imap_do_search(num_parms-3, &parms[3], 1);
- cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
+ imap_do_search(num_parms-3, &Params[3], 1);
+ cprintf("%s OK UID SEARCH completed\r\n", Params[0].Key);
}
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void imap_search(int num_parms, char *parms[]);
-void imap_uidsearch(int num_parms, char *parms[]);
+void imap_search(int num_parms, ConstStr *Params);
+void imap_uidsearch(int num_parms, ConstStr *Params);
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_fetch.h"
#include "imap_store.h"
#include "genstamp.h"
/*
* This function is called by the main command loop.
*/
-void imap_store(int num_parms, char *parms[]) {
+void imap_store(int num_parms, ConstStr *Params) {
char items[1024];
char *itemlist[256];
int num_items;
int i;
if (num_parms < 3) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- if (imap_is_message_set(parms[2])) {
- imap_pick_range(parms[2], 0);
+ if (imap_is_message_set(Params[2].Key)) {
+ imap_pick_range(Params[2].Key, 0);
}
else {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
strcpy(items, "");
for (i=3; i<num_parms; ++i) {
- strcat(items, parms[i]);
+ strcat(items, Params[i].Key);
if (i < (num_parms-1)) strcat(items, " ");
}
num_items = imap_extract_data_items(itemlist, items);
if (num_items < 1) {
- cprintf("%s BAD invalid data item list\r\n", parms[0]);
+ cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
return;
}
imap_do_store(num_items, itemlist);
- cprintf("%s OK STORE completed\r\n", parms[0]);
+ cprintf("%s OK STORE completed\r\n", Params[0].Key);
}
/*
* This function is called by the main command loop.
*/
-void imap_uidstore(int num_parms, char *parms[]) {
+void imap_uidstore(int num_parms, ConstStr *Params) {
char items[1024];
char *itemlist[256];
int num_items;
int i;
if (num_parms < 4) {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
- if (imap_is_message_set(parms[3])) {
- imap_pick_range(parms[3], 1);
+ if (imap_is_message_set(Params[3].Key)) {
+ imap_pick_range(Params[3].Key, 1);
}
else {
- cprintf("%s BAD invalid parameters\r\n", parms[0]);
+ cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
return;
}
strcpy(items, "");
for (i=4; i<num_parms; ++i) {
- strcat(items, parms[i]);
+ strcat(items, Params[i].Key);
if (i < (num_parms-1)) strcat(items, " ");
}
num_items = imap_extract_data_items(itemlist, items);
if (num_items < 1) {
- cprintf("%s BAD invalid data item list\r\n", parms[0]);
+ cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
return;
}
imap_do_store(num_items, itemlist);
- cprintf("%s OK UID STORE completed\r\n", parms[0]);
+ cprintf("%s OK UID STORE completed\r\n", Params[0].Key);
}
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void imap_store(int num_parms, char *parms[]);
-void imap_uidstore(int num_parms, char *parms[]);
+void imap_store(int num_parms, ConstStr *Params);
+void imap_uidstore(int num_parms, ConstStr *Params);
#include "sysdep_decls.h"
#include "internet_addressing.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "ctdl_module.h"
#ifndef HAVE_SNPRINTF
/* Convert from an IMAP-safe name back into a Citadel name. Returns the end of the destination. */
static int cfrommap(int c);
-static char* fromimap(char* destp, char* destend, char* src)
+static char* fromimap(char* destp, char* destend, const char* src)
{
struct string dest;
- unsigned char *p = (unsigned char*) src;
+ unsigned const char *p = (unsigned const char*) src;
int v = 0;
int i = 0;
int state = 0;
/* Output a string to the IMAP client, either as a literal or quoted.
* (We do a literal if it has any double-quotes or backslashes.) */
-void imap_strout(char *buf)
+void plain_imap_strout(char *buf)
{
int i;
int is_literal = 0;
}
}
+/* Output a string to the IMAP client, either as a literal or quoted.
+ * (We do a literal if it has any double-quotes or backslashes.) */
+
+void imap_strout(ConstStr *args)
+{
+ int i;
+ int is_literal = 0;
+
+ if ((args == NULL) || (args->len == 0))
+ { /* yeah, we handle this */
+ cprintf("NIL");
+ return;
+ }
+
+ for (i = 0; i < args->len; ++i) {
+ if ((args->Key[i] == '\"') || (args->Key[i] == '\\'))
+ is_literal = 1;
+ }
+
+ if (is_literal) {
+ cprintf("{%ld}\r\n%s", args->len, args->Key);
+ } else {
+ cprintf("\"%s\"", args->Key);
+ }
+}
+
/* Break a command down into tokens, unquoting any escaped characters. */
-int imap_parameterize(char** args, char* in)
+
+void TokenCutRight(citimap_command *Cmd,
+ ConstStr *CutMe,
+ int n)
+{
+ const char *CutAt;
+
+ if (CutMe->len < n) {
+ CutAt = CutMe->Key;
+ CutMe->len = 0;
+ }
+ else {
+ CutAt = CutMe->Key + CutMe->len - n;
+ CutMe->len -= n;
+ }
+ StrBufPeek(Cmd->CmdBuf, CutAt, -1, '\0');
+}
+
+void TokenCutLeft(citimap_command *Cmd,
+ ConstStr *CutMe,
+ int n)
+{
+ if (CutMe->len < n) {
+ CutMe->Key += CutMe->len;
+ CutMe->len = 0;
+ }
+ else {
+ CutMe->Key += n;
+ CutMe->len -= n;
+ }
+}
+
+
+
+int CmdAdjust(citimap_command *Cmd,
+ int nArgs,
+ int Realloc)
+{
+ ConstStr *Params;
+ if (nArgs > Cmd->avail_parms) {
+ Params = (ConstStr*) malloc(sizeof(ConstStr) * nArgs);
+ if (Realloc) {
+ memcpy(Params,
+ Cmd->Params,
+ sizeof(ConstStr) * Cmd->avail_parms);
+
+ memset(Cmd->Params +
+ sizeof(ConstStr) * Cmd->avail_parms,
+ 0,
+ sizeof(ConstStr) * nArgs -
+ sizeof(ConstStr) * Cmd->avail_parms
+ );
+ }
+ else
+ Cmd->num_parms = 0;
+ Cmd->avail_parms = nArgs;
+ if (Cmd->Params != NULL)
+ free (Cmd->Params);
+ Cmd->Params = Params;
+ }
+ else {
+ if (!Realloc) {
+ memset(Cmd->Params,
+ 0,
+ sizeof(ConstStr) * Cmd->avail_parms);
+ Cmd->num_parms = 0;
+ }
+ }
+ return Cmd->num_parms;
+}
+
+int imap_parameterize(citimap_command *Cmd)
+{
+ int nArgs;
+ const char *In, *End;
+
+ In = ChrPtr(Cmd->CmdBuf);
+ End = In + StrLength(Cmd->CmdBuf);
+
+ /* we start with 10 chars per arg, maybe we need to realloc later. */
+ nArgs = StrLength(Cmd->CmdBuf) / 10 + 10;
+ nArgs = CmdAdjust(Cmd, nArgs, 0);
+ while (In < End)
+ {
+ /* Skip whitespace. */
+ while (isspace(*In))
+ In++;
+ if (*In == '\0')
+ break;
+
+ /* Found the start of a token. */
+
+ Cmd->Params[Cmd->num_parms].Key = In;
+
+ /* Read in the token. */
+
+ for (;;)
+ {
+ if (isspace(*In))
+ break;
+
+ if (*In == '\"')
+ {
+ /* Found a quoted section. */
+
+ Cmd->Params[Cmd->num_parms].Key++;
+ //In++;
+ for (;;)
+ {
+ In++;
+ if (*In == '\"') {
+ StrBufPeek(Cmd->CmdBuf, In, -1, '\0');
+ break;
+ }
+ else if (*In == '\\')
+ In++;
+
+ if (*In == '\0') {
+ Cmd->Params[Cmd->num_parms].len =
+ In - Cmd->Params[Cmd->num_parms].Key;
+ Cmd->num_parms++;
+ return Cmd->num_parms;
+ }
+ }
+ break;
+ }
+ else if (*In == '\\')
+ {
+ In++;
+ }
+
+ if (*In == '\0') {
+ Cmd->Params[Cmd->num_parms].len =
+ In - Cmd->Params[Cmd->num_parms].Key;
+ Cmd->num_parms++;
+ return Cmd->num_parms;
+ }
+ In++;
+ }
+ StrBufPeek(Cmd->CmdBuf, In, -1, '\0');
+ Cmd->Params[Cmd->num_parms].len =
+ In - Cmd->Params[Cmd->num_parms].Key;
+ Cmd->num_parms ++;
+ if (Cmd->num_parms >= Cmd->avail_parms) {
+ nArgs = CmdAdjust(Cmd, nArgs * 2, 1);
+ }
+ In++;
+ }
+ return Cmd->num_parms;
+}
+
+int old_imap_parameterize(char** args, char *in)
{
char* out = in;
int num = 0;
*
*/
-int imap_roomname(char *rbuf, int bufsize, char *foldername)
+int imap_roomname(char *rbuf, int bufsize, const char *foldername)
{
int levels;
char floorname[256];
for (iptr = ialist; iptr != NULL; iptr = iptr->next) {
cprintf("(");
- imap_strout(iptr->ial_name);
+ plain_imap_strout(iptr->ial_name);
cprintf(" NIL ");
- imap_strout(iptr->ial_user);
+ plain_imap_strout(iptr->ial_user);
cprintf(" ");
- imap_strout(iptr->ial_node);
+ plain_imap_strout(iptr->ial_node);
cprintf(")");
}
* return 1 for a valid message set. If any other character is found,
* return 0.
*/
-int imap_is_message_set(char *buf)
+int imap_is_message_set(const char *buf)
{
int i;
char lcase_text[SIZ], lcase_p[SIZ];
char *text = lcase_text;
char *p = lcase_p;
+ long len;
/* Copy both strings and lowercase them, in order to
* make this entire operation case-insensitive.
*/
- for (i=0; i<=strlen(supplied_text); ++i)
+ len = strlen(supplied_text);
+ for (i=0; i<=len; ++i)
lcase_text[i] = tolower(supplied_text[i]);
- for (i=0; i<=strlen(supplied_p); ++i)
+ len = strlen(supplied_p);
+ for (i=0; i<=len; ++i)
p[i] = tolower(supplied_p[i]);
/* Start matching */
* Compare an IMAP date string (date only, no time) to the date found in
* a Unix timestamp.
*/
-int imap_datecmp(char *datestr, time_t msgtime) {
+int imap_datecmp(const char *datestr, time_t msgtime) {
char daystr[256];
char monthstr[256];
char yearstr[256];
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
-#include "serv_imap.h"
#include "imap_tools.h"
+#include "serv_imap.h"
#include "imap_list.h"
#include "imap_fetch.h"
#include "imap_search.h"
/*
* implements the CAPABILITY command
*/
-void imap_capability(int num_parms, char *parms[])
+void imap_capability(int num_parms, ConstStr *Params)
{
cprintf("* ");
imap_output_capability_string();
cprintf("\r\n");
- cprintf("%s OK CAPABILITY completed\r\n", parms[0]);
+ cprintf("%s OK CAPABILITY completed\r\n", Params[0].Key);
}
* making use of this extension.
*
*/
-void imap_id(int num_parms, char *parms[])
+void imap_id(int num_parms, ConstStr *Params)
{
cprintf("* ID NIL\r\n");
- cprintf("%s OK ID completed\r\n", parms[0]);
+ cprintf("%s OK ID completed\r\n", Params[0].Key);
}
{
strcpy(CC->cs_clientname, "IMAP session");
- CC->session_specific_data = malloc(sizeof(struct citimap));
- memset(IMAP, 0, sizeof(struct citimap));
+ CC->session_specific_data = malloc(sizeof(citimap));
+ memset(IMAP, 0, sizeof(citimap));
IMAP->authstate = imap_as_normal;
IMAP->cached_rfc822_data = NULL;
IMAP->cached_rfc822_msgnum = (-1);
/*
* implements the LOGIN command (ordinary username/password login)
*/
-void imap_login(int num_parms, char *parms[])
+void imap_login(int num_parms, ConstStr *Params)
{
switch (num_parms) {
case 3:
- if (parms[2][0] == '{') {
+ if (Params[2].Key[0] == '{') {
cprintf("+ go ahead\r\n");
IMAP->authstate = imap_as_expecting_multilineusername;
- strcpy(IMAP->authseq, parms[0]);
+ strcpy(IMAP->authseq, Params[0].Key);
return;
}
else {
- cprintf("%s BAD incorrect number of parameters\r\n", parms[0]);
+ cprintf("%s BAD incorrect number of parameters\r\n", Params[0].Key);
return;
}
case 4:
- if (CtdlLoginExistingUser(NULL, parms[2]) == login_ok) {
- if (CtdlTryPassword(parms[3]) == pass_ok) {
- cprintf("%s OK [", parms[0]);
+ if (CtdlLoginExistingUser(NULL, Params[2].Key) == login_ok) {
+ if (CtdlTryPassword(Params[3].Key) == pass_ok) {
+ cprintf("%s OK [", Params[0].Key);
imap_output_capability_string();
cprintf("] Hello, %s\r\n", CC->user.fullname);
return;
}
}
- cprintf("%s BAD Login incorrect\r\n", parms[0]);
+ cprintf("%s BAD Login incorrect\r\n", Params[0].Key);
default:
- cprintf("%s BAD incorrect number of parameters\r\n", parms[0]);
+ cprintf("%s BAD incorrect number of parameters\r\n", Params[0].Key);
return;
}
/*
* Implements the AUTHENTICATE command
*/
-void imap_authenticate(int num_parms, char *parms[])
+void imap_authenticate(int num_parms, ConstStr *Params)
{
char buf[SIZ];
if (num_parms != 3) {
cprintf("%s BAD incorrect number of parameters\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
if (CC->logged_in) {
- cprintf("%s BAD Already logged in.\r\n", parms[0]);
+ cprintf("%s BAD Already logged in.\r\n", Params[0].Key);
return;
}
- if (!strcasecmp(parms[2], "LOGIN")) {
+ if (!strcasecmp(Params[2].Key, "LOGIN")) {
CtdlEncodeBase64(buf, "Username:", 9, 0);
cprintf("+ %s\r\n", buf);
IMAP->authstate = imap_as_expecting_username;
- strcpy(IMAP->authseq, parms[0]);
+ strcpy(IMAP->authseq, Params[0].Key);
return;
}
- if (!strcasecmp(parms[2], "PLAIN")) {
+ if (!strcasecmp(Params[2].Key, "PLAIN")) {
// CtdlEncodeBase64(buf, "Username:", 9, 0);
// cprintf("+ %s\r\n", buf);
cprintf("+ \r\n");
IMAP->authstate = imap_as_expecting_plainauth;
- strcpy(IMAP->authseq, parms[0]);
+ strcpy(IMAP->authseq, Params[0].Key);
return;
}
else {
cprintf("%s NO AUTHENTICATE %s failed\r\n",
- parms[0], parms[1]);
+ Params[0].Key, Params[1].Key);
}
}
-void imap_auth_plain(char *cmd)
+void imap_auth_plain(void)
{
- char decoded_authstring[1024];
+ const char *decoded_authstring;
char ident[256];
char user[256];
char pass[256];
int result;
memset(pass, 0, sizeof(pass));
- CtdlDecodeBase64(decoded_authstring, cmd, strlen(cmd));
+ StrBufDecodeBase64(IMAP->Cmd.CmdBuf);
+
+ decoded_authstring = ChrPtr(IMAP->Cmd.CmdBuf);
safestrncpy(ident, decoded_authstring, sizeof ident);
safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
}
-void imap_auth_login_user(char *cmd, long state)
+void imap_auth_login_user(long state)
{
char buf[SIZ];
+ citimap *Imap = IMAP;
switch (state){
case imap_as_expecting_username:
- CtdlDecodeBase64(buf, cmd, SIZ);
- CtdlLoginExistingUser(NULL, buf);
+ StrBufDecodeBase64(Imap->Cmd.CmdBuf);
+ CtdlLoginExistingUser(NULL, ChrPtr(Imap->Cmd.CmdBuf));
CtdlEncodeBase64(buf, "Password:", 9, 0);
cprintf("+ %s\r\n", buf);
- IMAP->authstate = imap_as_expecting_password;
+ Imap->authstate = imap_as_expecting_password;
return;
case imap_as_expecting_multilineusername:
- extract_token(buf, cmd, 1, ' ', sizeof(buf));
- CtdlLoginExistingUser(NULL, cmd);
+ extract_token(buf, ChrPtr(Imap->Cmd.CmdBuf), 1, ' ', sizeof(buf));
+ CtdlLoginExistingUser(NULL, ChrPtr(Imap->Cmd.CmdBuf));
cprintf("+ go ahead\r\n");
IMAP->authstate = imap_as_expecting_multilinepassword;
return;
}
-void imap_auth_login_pass(char *cmd, long state)
+void imap_auth_login_pass(long state)
{
- char *pass = NULL;
+ citimap *Imap = IMAP;
+ const char *pass = NULL;
char buf[SIZ];
switch (state) {
default:
case imap_as_expecting_password:
- memset(buf, 0, sizeof(buf));
- CtdlDecodeBase64(buf, cmd, SIZ);
+ StrBufDecodeBase64(Imap->Cmd.CmdBuf);
pass = buf;
break;
case imap_as_expecting_multilinepassword:
- pass = cmd;
+ pass = ChrPtr(Imap->Cmd.CmdBuf);
break;
}
if (CtdlTryPassword(pass) == pass_ok) {
/*
* implements the STARTTLS command (Citadel API version)
*/
-void imap_starttls(int num_parms, char *parms[])
+void imap_starttls(int num_parms, ConstStr *Params)
{
char ok_response[SIZ];
char nosup_response[SIZ];
char error_response[SIZ];
- sprintf(ok_response, "%s OK begin TLS negotiation now\r\n", parms[0]);
- sprintf(nosup_response, "%s NO TLS not supported here\r\n", parms[0]);
- sprintf(error_response, "%s BAD Internal error\r\n", parms[0]);
+ sprintf(ok_response, "%s OK begin TLS negotiation now\r\n", Params[0].Key);
+ sprintf(nosup_response, "%s NO TLS not supported here\r\n", Params[0].Key);
+ sprintf(error_response, "%s BAD Internal error\r\n", Params[0].Key);
CtdlModuleStartCryptoMsgs(ok_response, nosup_response, error_response);
}
/*
* implements the SELECT command
*/
-void imap_select(int num_parms, char *parms[])
+void imap_select(int num_parms, ConstStr *Params)
{
char towhere[SIZ];
char augmented_roomname[ROOMNAMELEN];
int i;
/* Convert the supplied folder name to a roomname */
- i = imap_roomname(towhere, sizeof towhere, parms[2]);
+ i = imap_roomname(towhere, sizeof towhere, Params[2].Key);
if (i < 0) {
- cprintf("%s NO Invalid mailbox name.\r\n", parms[0]);
+ cprintf("%s NO Invalid mailbox name.\r\n", Params[0].Key);
IMAP->selected = 0;
return;
}
/* Fail here if no such room */
if (!ok) {
- cprintf("%s NO ... no such room, or access denied\r\n", parms[0]);
+ cprintf("%s NO ... no such room, or access denied\r\n", Params[0].Key);
return;
}
CtdlUserGoto(NULL, 0, 0, &msgs, &new);
IMAP->selected = 1;
- if (!strcasecmp(parms[1], "EXAMINE")) {
+ if (!strcasecmp(Params[1].Key, "EXAMINE")) {
IMAP->readonly = 1;
} else {
IMAP->readonly = 0;
cprintf("* OK [PERMANENTFLAGS (\\Deleted \\Seen \\Answered)] permanent flags\r\n");
cprintf("%s OK [%s] %s completed\r\n",
- parms[0],
- (IMAP->readonly ? "READ-ONLY" : "READ-WRITE"), parms[1]
+ Params[0].Key,
+ (IMAP->readonly ? "READ-ONLY" : "READ-WRITE"), Params[1].Key
);
}
/*
* implements the EXPUNGE command syntax
*/
-void imap_expunge(int num_parms, char *parms[])
+void imap_expunge(int num_parms, ConstStr *Params)
{
int num_expunged = 0;
num_expunged = imap_do_expunge();
- cprintf("%s OK expunged %d messages.\r\n", parms[0], num_expunged);
+ cprintf("%s OK expunged %d messages.\r\n", Params[0].Key, num_expunged);
}
/*
* implements the CLOSE command
*/
-void imap_close(int num_parms, char *parms[])
+void imap_close(int num_parms, ConstStr *Params)
{
/* Yes, we always expunge on close. */
IMAP->selected = 0;
IMAP->readonly = 0;
imap_free_msgids();
- cprintf("%s OK CLOSE completed\r\n", parms[0]);
+ cprintf("%s OK CLOSE completed\r\n", Params[0].Key);
}
/*
* Implements the NAMESPACE command.
*/
-void imap_namespace(int num_parms, char *parms[])
+void imap_namespace(int num_parms, ConstStr *Params)
{
int i;
struct floor *fl;
if (floors > 0) cprintf(" ");
cprintf("(");
sprintf(buf, "%s/", fl->f_name);
- imap_strout(buf);
+ plain_imap_strout(buf);
cprintf(" \"/\")");
++floors;
}
/* Wind it up with a newline and a completion message. */
cprintf("\r\n");
- cprintf("%s OK NAMESPACE completed\r\n", parms[0]);
+ cprintf("%s OK NAMESPACE completed\r\n", Params[0].Key);
}
* Implements the CREATE command
*
*/
-void imap_create(int num_parms, char *parms[])
+void imap_create(int num_parms, ConstStr *Params)
{
int ret;
char roomname[ROOMNAMELEN];
char *notification_message = NULL;
if (num_parms < 3) {
- cprintf("%s NO A foder name must be specified\r\n", parms[0]);
+ cprintf("%s NO A foder name must be specified\r\n", Params[0].Key);
return;
}
- if (strchr(parms[2], '\\') != NULL) {
- cprintf("%s NO Invalid character in folder name\r\n", parms[0]);
+ if (strchr(Params[2].Key, '\\') != NULL) {
+ cprintf("%s NO Invalid character in folder name\r\n", Params[0].Key);
CtdlLogPrintf(CTDL_DEBUG, "invalid character in folder name\n");
return;
}
- ret = imap_roomname(roomname, sizeof roomname, parms[2]);
+ ret = imap_roomname(roomname, sizeof roomname, Params[2].Key);
if (ret < 0) {
cprintf("%s NO Invalid mailbox name or location\r\n",
- parms[0]);
+ Params[0].Key);
CtdlLogPrintf(CTDL_DEBUG, "invalid mailbox name or location\n");
return;
}
flags = (ret & 0xff00); /* upper 8 bits = flags */
if (flags & IR_MAILBOX) {
- if (strncasecmp(parms[2], "INBOX/", 6)) {
- cprintf("%s NO Personal folders must be created under INBOX\r\n", parms[0]);
+ if (strncasecmp(Params[2].Key, "INBOX/", 6)) {
+ cprintf("%s NO Personal folders must be created under INBOX\r\n", Params[0].Key);
CtdlLogPrintf(CTDL_DEBUG, "not subordinate to inbox\n");
return;
}
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! ***/
- cprintf("%s NO Mailbox already exists, or create failed\r\n", parms[0]);
+ cprintf("%s NO Mailbox already exists, or create failed\r\n", Params[0].Key);
} else {
- cprintf("%s OK CREATE completed\r\n", parms[0]);
+ cprintf("%s OK CREATE completed\r\n", Params[0].Key);
/* post a message in Aide> describing the new room */
notification_message = malloc(1024);
snprintf(notification_message, 1024,
* 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, char *foldername, int zapped_ok)
+int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok)
{
int ret;
char augmented_roomname[ROOMNAMELEN];
* Implements the STATUS command (sort of)
*
*/
-void imap_status(int num_parms, char *parms[])
+void imap_status(int num_parms, ConstStr *Params)
{
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf
("%s NO Invalid mailbox name or location, or access denied\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
*/
imap_mailboxname(buf, sizeof buf, &CC->room);
cprintf("* STATUS ");
- imap_strout(buf);
+ plain_imap_strout(buf);
cprintf(" (MESSAGES %d ", msgs);
cprintf("RECENT %d ", new); /* Initially, new==recent */
cprintf("UIDNEXT %ld ", CitControl.MMhighest + 1);
/*
* Oooh, look, we're done!
*/
- cprintf("%s OK STATUS completed\r\n", parms[0]);
+ cprintf("%s OK STATUS completed\r\n", Params[0].Key);
}
* Implements the SUBSCRIBE command
*
*/
-void imap_subscribe(int num_parms, char *parms[])
+void imap_subscribe(int num_parms, ConstStr *Params)
{
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf(
"%s NO Error %d: invalid mailbox name or location, or access denied\r\n",
- parms[0],
+ Params[0].Key,
ret
);
return;
CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
}
- cprintf("%s OK SUBSCRIBE completed\r\n", parms[0]);
+ cprintf("%s OK SUBSCRIBE completed\r\n", Params[0].Key);
}
* Implements the UNSUBSCRIBE command
*
*/
-void imap_unsubscribe(int num_parms, char *parms[])
+void imap_unsubscribe(int num_parms, ConstStr *Params)
{
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf
("%s NO Invalid mailbox name or location, or access denied\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
* Now make the API call to zap the room
*/
if (CtdlForgetThisRoom() == 0) {
- cprintf("%s OK UNSUBSCRIBE completed\r\n", parms[0]);
+ cprintf("%s OK UNSUBSCRIBE completed\r\n", Params[0].Key);
} else {
cprintf
("%s NO You may not unsubscribe from this folder.\r\n",
- parms[0]);
+ Params[0].Key);
}
/*
* Implements the DELETE command
*
*/
-void imap_delete(int num_parms, char *parms[])
+void imap_delete(int num_parms, ConstStr *Params)
{
int ret;
char roomname[ROOMNAMELEN];
char savedroom[ROOMNAMELEN];
int msgs, new;
- ret = imap_grabroom(roomname, parms[2], 1);
+ ret = imap_grabroom(roomname, Params[2].Key, 1);
if (ret != 0) {
cprintf("%s NO Invalid mailbox name, or access denied\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
*/
if (CtdlDoIHavePermissionToDeleteThisRoom(&CC->room)) {
CtdlScheduleRoomForDeletion(&CC->room);
- cprintf("%s OK DELETE completed\r\n", parms[0]);
+ cprintf("%s OK DELETE completed\r\n", Params[0].Key);
} else {
- cprintf("%s NO Can't delete this folder.\r\n", parms[0]);
+ cprintf("%s NO Can't delete this folder.\r\n", Params[0].Key);
}
/*
* Implements the RENAME command
*
*/
-void imap_rename(int num_parms, char *parms[])
+void imap_rename(int num_parms, ConstStr *Params)
{
char old_room[ROOMNAMELEN];
char new_room[ROOMNAMELEN];
struct irlparms irlparms;
char buf[1024];
- if (strchr(parms[3], '\\') != NULL) {
+ if (strchr(Params[3].Key, '\\') != NULL) {
cprintf("%s NO Invalid character in folder name\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
- oldr = imap_roomname(old_room, sizeof old_room, parms[2]);
- newr = imap_roomname(new_room, sizeof new_room, parms[3]);
+ oldr = 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);
r = CtdlRenameRoom(old_room, new_room, new_floor);
if (r == crr_room_not_found) {
cprintf("%s NO Could not locate this folder\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
if (r == crr_already_exists) {
- cprintf("%s NO '%s' already exists.\r\n", parms[0], parms[2]);
+ cprintf("%s NO '%s' already exists.\r\n", Params[0].Key, Params[2].Key);
return;
}
if (r == crr_noneditable) {
- cprintf("%s NO This folder is not editable.\r\n", parms[0]);
+ cprintf("%s NO This folder is not editable.\r\n", Params[0].Key);
return;
}
if (r == crr_invalid_floor) {
- cprintf("%s NO Folder root does not exist.\r\n", parms[0]);
+ cprintf("%s NO Folder root does not exist.\r\n", Params[0].Key);
return;
}
if (r == crr_access_denied) {
cprintf("%s NO You do not have permission to edit this folder.\r\n",
- parms[0]);
+ Params[0].Key);
return;
}
if (r != crr_ok) {
cprintf("%s NO Rename failed - undefined error %d\r\n",
- parms[0], r);
+ Params[0].Key, r);
return;
}
* contents. In a Citadel environment it's easier to rename the room
* (already did that) and create a new inbox.
*/
- if (!strcasecmp(parms[2], "INBOX")) {
+ if (!strcasecmp(Params[2].Key, "INBOX")) {
CtdlCreateRoom(MAILROOM, 4, "", 0, 1, 0, VIEW_MAILBOX);
}
/* Otherwise, do the subfolders. Build a list of rooms to rename... */
else {
- irlparms.oldname = parms[2];
- irlparms.newname = parms[3];
+ irlparms.oldname = Params[2].Key;
+ irlparms.newname = Params[3].Key;
irlparms.irl = &irl;
CtdlForEachRoom(imap_rename_backend, (void *) &irlparms);
}
snprintf(buf, sizeof buf, "IMAP folder \"%s\" renamed to \"%s\" by %s\n",
- parms[2],
- parms[3],
+ Params[2].Key,
+ Params[3].Key,
CC->curr_user
);
CtdlAideMessage(buf, "IMAP folder rename");
- cprintf("%s OK RENAME completed\r\n", parms[0]);
+ cprintf("%s OK RENAME completed\r\n", Params[0].Key);
}
*/
void imap_command_loop(void)
{
- char cmdbuf[SIZ];
- char *parms[SIZ];
- int num_parms;
struct timeval tv1, tv2;
suseconds_t total_time = 0;
int untagged_ok = 1;
+ citimap *Imap;
+ const char *pchs, *pche;
gettimeofday(&tv1, NULL);
CC->lastcmd = time(NULL);
- memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
+ Imap = IMAP;
+
flush_output();
- if (client_getln(cmdbuf, sizeof cmdbuf) < 1) {
+ if (Imap->Cmd.CmdBuf == NULL)
+ Imap->Cmd.CmdBuf = NewStrBufPlain(NULL, SIZ);
+ else
+ FlushStrBuf(Imap->Cmd.CmdBuf);
+
+ if (CtdlClientGetLine(Imap->Cmd.CmdBuf) < 1) {
CtdlLogPrintf(CTDL_ERR, "Client disconnected: ending session.\r\n");
CC->kill_me = 1;
return;
}
- if (IMAP->authstate == imap_as_expecting_password) {
+ if (Imap->authstate == imap_as_expecting_password) {
CtdlLogPrintf(CTDL_INFO, "IMAP: <password>\n");
}
- else if (IMAP->authstate == imap_as_expecting_plainauth) {
+ else if (Imap->authstate == imap_as_expecting_plainauth) {
CtdlLogPrintf(CTDL_INFO, "IMAP: <plain_auth>\n");
}
- else if ((IMAP->authstate == imap_as_expecting_multilineusername) ||
- bmstrcasestr(cmdbuf, " LOGIN ")) {
+ else if ((Imap->authstate == imap_as_expecting_multilineusername) ||
+ bmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
CtdlLogPrintf(CTDL_INFO, "IMAP: LOGIN...\n");
}
else {
- CtdlLogPrintf(CTDL_INFO, "IMAP: %s\n", cmdbuf);
+ CtdlLogPrintf(CTDL_INFO, "IMAP: %s\n", ChrPtr(Imap->Cmd.CmdBuf));
}
- while (strlen(cmdbuf) < 5)
- strcat(cmdbuf, " ");
+ pchs = ChrPtr(Imap->Cmd.CmdBuf);
+ pche = pchs + StrLength(Imap->Cmd.CmdBuf);
- /* strip off l/t whitespace and CRLF */
- if (cmdbuf[strlen(cmdbuf) - 1] == '\n')
- cmdbuf[strlen(cmdbuf) - 1] = 0;
- if (cmdbuf[strlen(cmdbuf) - 1] == '\r')
- cmdbuf[strlen(cmdbuf) - 1] = 0;
- striplt(cmdbuf);
+ while ((pche > pchs) &&
+ ((*pche == '\n') ||
+ (*pche == '\r')))
+ {
+ pche --;
+ StrBufCutRight(Imap->Cmd.CmdBuf, 1);
+ }
+ StrBufTrim(Imap->Cmd.CmdBuf);
/* If we're in the middle of a multi-line command, handle that */
- if (IMAP->authstate == imap_as_expecting_username) {
- imap_auth_login_user(cmdbuf, imap_as_expecting_username);
+ switch (Imap->authstate){
+ case imap_as_expecting_username:
+ imap_auth_login_user(imap_as_expecting_username);
return;
- }
- if (IMAP->authstate == imap_as_expecting_multilineusername) {
- imap_auth_login_user(cmdbuf, imap_as_expecting_multilineusername);
+ case imap_as_expecting_multilineusername:
+ imap_auth_login_user(imap_as_expecting_multilineusername);
return;
- }
- if (IMAP->authstate == imap_as_expecting_plainauth) {
- imap_auth_plain(cmdbuf);
+ case imap_as_expecting_plainauth:
+ imap_auth_plain();
return;
- }
- if (IMAP->authstate == imap_as_expecting_password) {
- imap_auth_login_pass(cmdbuf, imap_as_expecting_password);
+ case imap_as_expecting_password:
+ imap_auth_login_pass(imap_as_expecting_password);
return;
- }
- if (IMAP->authstate == imap_as_expecting_multilinepassword) {
- imap_auth_login_pass(cmdbuf, imap_as_expecting_multilinepassword);
+ case imap_as_expecting_multilinepassword:
+ imap_auth_login_pass(imap_as_expecting_multilinepassword);
return;
+ default:
+ break;
}
* If the command just submitted does not contain a literal, we
* might think about delivering some untagged stuff...
*/
- if (cmdbuf[strlen(cmdbuf)-1] == '}') {
+ if (*(ChrPtr(Imap->Cmd.CmdBuf) + StrLength(Imap->Cmd.CmdBuf) - 1)
+ == '}') {
untagged_ok = 0;
}
/* Grab the tag, command, and parameters. */
- num_parms = imap_parameterize(parms, cmdbuf);
+ imap_parameterize(&Imap->Cmd);
+#if 0
+/* debug output the parsed vector */
+ {
+ int i;
+ CtdlLogPrintf(CTDL_DEBUG, "----- %ld params \n",
+ 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",
+ Imap->Cmd.Params[i].len,
+ strlen(Imap->Cmd.Params[i].Key),
+ Imap->Cmd.Params[i].Key);
+ else
+ CtdlLogPrintf(CTDL_DEBUG, "%ld : %s\n",
+ Imap->Cmd.Params[i].len,
+ Imap->Cmd.Params[i].Key);
+ }}
+#endif
/* RFC3501 says that we cannot output untagged data during these commands */
- if (num_parms >= 2) {
- if ( (!strcasecmp(parms[1], "FETCH"))
- || (!strcasecmp(parms[1], "STORE"))
- || (!strcasecmp(parms[1], "SEARCH"))
+ if (Imap->Cmd.num_parms >= 2) {
+ if ( (!strcasecmp(Imap->Cmd.Params[1].Key, "FETCH"))
+ || (!strcasecmp(Imap->Cmd.Params[1].Key, "STORE"))
+ || (!strcasecmp(Imap->Cmd.Params[1].Key, "SEARCH"))
) {
untagged_ok = 0;
}
* messages, and for deletions/changes of existing messages. This
* could probably be optimized better with some deep thought...
*/
- if (IMAP->selected) {
+ if (Imap->selected) {
imap_rescan_msgids();
}
}
/* Now for the command set. */
- if (num_parms < 2) {
+ if (Imap->Cmd.num_parms < 2) {
cprintf("BAD syntax error\r\n");
}
/* The commands below may be executed in any state */
- else if ((!strcasecmp(parms[1], "NOOP"))
- || (!strcasecmp(parms[1], "CHECK"))) {
+ else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "NOOP"))
+ || (!strcasecmp(Imap->Cmd.Params[1].Key, "CHECK"))) {
cprintf("%s OK No operation\r\n",
- parms[0]);
+ Imap->Cmd.Params[0].Key);
}
- else if (!strcasecmp(parms[1], "ID")) {
- imap_id(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "ID")) {
+ imap_id(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "LOGOUT")) {
- if (IMAP->selected) {
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LOGOUT")) {
+ if (Imap->selected) {
imap_do_expunge(); /* yes, we auto-expunge at logout */
}
cprintf("* BYE %s logging out\r\n", config.c_fqdn);
cprintf("%s OK Citadel IMAP session ended.\r\n",
- parms[0]);
+ Imap->Cmd.Params[0].Key);
CC->kill_me = 1;
return;
}
- else if (!strcasecmp(parms[1], "LOGIN")) {
- imap_login(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LOGIN")) {
+ imap_login(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "AUTHENTICATE")) {
- imap_authenticate(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "AUTHENTICATE")) {
+ imap_authenticate(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "CAPABILITY")) {
- imap_capability(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "CAPABILITY")) {
+ imap_capability(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
#ifdef HAVE_OPENSSL
- else if (!strcasecmp(parms[1], "STARTTLS")) {
- imap_starttls(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "STARTTLS")) {
+ imap_starttls(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
#endif
else if (!CC->logged_in) {
- cprintf("%s BAD Not logged in.\r\n", parms[0]);
+ cprintf("%s BAD Not logged in.\r\n", Imap->Cmd.Params[0].Key);
}
/* The commans below require a logged-in state */
- else if (!strcasecmp(parms[1], "SELECT")) {
- imap_select(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SELECT")) {
+ imap_select(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "EXAMINE")) {
- imap_select(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "EXAMINE")) {
+ imap_select(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "LSUB")) {
- imap_list(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LSUB")) {
+ imap_list(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "LIST")) {
- imap_list(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LIST")) {
+ imap_list(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "CREATE")) {
- imap_create(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "CREATE")) {
+ imap_create(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "DELETE")) {
- imap_delete(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "DELETE")) {
+ imap_delete(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "RENAME")) {
- imap_rename(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "RENAME")) {
+ imap_rename(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "STATUS")) {
- imap_status(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "STATUS")) {
+ imap_status(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "SUBSCRIBE")) {
- imap_subscribe(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SUBSCRIBE")) {
+ imap_subscribe(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "UNSUBSCRIBE")) {
- imap_unsubscribe(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "UNSUBSCRIBE")) {
+ imap_unsubscribe(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "APPEND")) {
- imap_append(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "APPEND")) {
+ imap_append(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "NAMESPACE")) {
- imap_namespace(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "NAMESPACE")) {
+ imap_namespace(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "SETACL")) {
- imap_setacl(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SETACL")) {
+ imap_setacl(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "DELETEACL")) {
- imap_deleteacl(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "DELETEACL")) {
+ imap_deleteacl(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "GETACL")) {
- imap_getacl(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "GETACL")) {
+ imap_getacl(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "LISTRIGHTS")) {
- imap_listrights(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LISTRIGHTS")) {
+ imap_listrights(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "MYRIGHTS")) {
- imap_myrights(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "MYRIGHTS")) {
+ imap_myrights(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "GETMETADATA")) {
- imap_getmetadata(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "GETMETADATA")) {
+ imap_getmetadata(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "SETMETADATA")) {
- imap_setmetadata(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SETMETADATA")) {
+ imap_setmetadata(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (IMAP->selected == 0) {
- cprintf("%s BAD no folder selected\r\n", parms[0]);
+ else if (Imap->selected == 0) {
+ cprintf("%s BAD no folder selected\r\n", Imap->Cmd.Params[0].Key);
}
/* The commands below require the SELECT state on a mailbox */
- else if (!strcasecmp(parms[1], "FETCH")) {
- imap_fetch(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "FETCH")) {
+ imap_fetch(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if ((!strcasecmp(parms[1], "UID"))
- && (!strcasecmp(parms[2], "FETCH"))) {
- imap_uidfetch(num_parms, parms);
+ else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID"))
+ && (!strcasecmp(Imap->Cmd.Params[2].Key, "FETCH"))) {
+ imap_uidfetch(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "SEARCH")) {
- imap_search(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SEARCH")) {
+ imap_search(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if ((!strcasecmp(parms[1], "UID"))
- && (!strcasecmp(parms[2], "SEARCH"))) {
- imap_uidsearch(num_parms, parms);
+ else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID"))
+ && (!strcasecmp(Imap->Cmd.Params[2].Key, "SEARCH"))) {
+ imap_uidsearch(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "STORE")) {
- imap_store(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "STORE")) {
+ imap_store(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if ((!strcasecmp(parms[1], "UID"))
- && (!strcasecmp(parms[2], "STORE"))) {
- imap_uidstore(num_parms, parms);
+ else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID"))
+ && (!strcasecmp(Imap->Cmd.Params[2].Key, "STORE"))) {
+ imap_uidstore(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "COPY")) {
- imap_copy(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "COPY")) {
+ imap_copy(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if ((!strcasecmp(parms[1], "UID")) && (!strcasecmp(parms[2], "COPY"))) {
- imap_uidcopy(num_parms, parms);
+ else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID")) && (!strcasecmp(Imap->Cmd.Params[2].Key, "COPY"))) {
+ imap_uidcopy(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "EXPUNGE")) {
- imap_expunge(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "EXPUNGE")) {
+ imap_expunge(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if ((!strcasecmp(parms[1], "UID")) && (!strcasecmp(parms[2], "EXPUNGE"))) {
- imap_expunge(num_parms, parms);
+ else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID")) && (!strcasecmp(Imap->Cmd.Params[2].Key, "EXPUNGE"))) {
+ imap_expunge(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
- else if (!strcasecmp(parms[1], "CLOSE")) {
- imap_close(num_parms, parms);
+ else if (!strcasecmp(Imap->Cmd.Params[1].Key, "CLOSE")) {
+ imap_close(Imap->Cmd.num_parms, Imap->Cmd.Params);
}
/* End of commands. If we get here, the command is either invalid
*/
else {
- cprintf("%s BAD command unrecognized\r\n", parms[0]);
+ cprintf("%s BAD command unrecognized\r\n", Imap->Cmd.Params[0].Key);
}
/* If the client transmitted a message we can free it now */
void imap_cleanup_function(void);
void imap_greeting(void);
void imap_command_loop(void);
-int imap_grabroom(char *returned_roomname, char *foldername, int zapped_ok);
+int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok);
void imap_free_transmitted_message(void);
int imap_do_expunge(void);
void imap_rescan_msgids(void);
-struct citimap {
+
+typedef struct __citimap {
int authstate;
char authseq[SIZ];
int selected; /* set to 1 if in the SELECTED state */
unsigned int *flags;
StrBuf *TransmittedMessage; /* for APPEND command... */
+ citimap_command Cmd; /* our current commandline */
+
/* Cache most recent RFC822 FETCH because client might load in pieces */
char *cached_rfc822_data;
long cached_rfc822_msgnum;
char cached_bodypart[SIZ];
long cached_bodymsgnum;
char cached_body_withbody; /* 1 = body cached; 0 = only headers cached */
-};
+} citimap;
/*
* values of 'authstate'
#define IMAP_RECENT 64 /* reportable but not setable */
-#define IMAP ((struct citimap *)CC->session_specific_data)
+#define IMAP ((citimap *)CC->session_specific_data)
/*
* When loading arrays of message ID's into memory, increase the buffer to
memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
length = client_getln(cmdbuf, sizeof cmdbuf);
if (length >= 1) {
- num_parms = imap_parameterize(parms, cmdbuf);
+ num_parms = old_imap_parameterize(parms, cmdbuf);
if (num_parms == 0) return;
length = strlen(parms[0]);
}
*/
void extract_link(char *target_buf, int target_size, char *rel, char *source_buf)
{
- char *ptr = source_buf;
+ const char *ptr = source_buf;
if (!target_buf) return;
if (!rel) return;
if (len > sizeof work_buffer) len = sizeof work_buffer;
memcpy(work_buffer, link_tag_start, len);
- char *rel_start = NULL;
+ const char *rel_start = NULL;
char *rel_end = NULL;
rel_start = bmstrcasestr(work_buffer, "rel=");
if (rel_start) {
int lines_dumped = 0;
char buf[1024];
char *msgtext;
- char *ptr;
+ const char *ptr;
int in_body = 0;
int done = 0;
char mx_port[256];
int lp, rp;
char *msgtext;
- char *ptr;
+ const char *ptr;
size_t msg_size;
int scan_done;
CitContext *CCC=CC;
int nbytes = 0;
char *diffbuf = NULL;
size_t diffbuf_len = 0;
- char *ptr = NULL;
+ const char *ptr = NULL;
if (!CCC->logged_in) return(0); /* Only do this if logged in. */
char content_type[SIZ]; /* We have to learn this */
char recipient[SIZ];
long newmsgid;
- char *mptr = NULL;
+ const char *mptr = NULL;
struct ctdluser userbuf;
int a, i;
struct MetaData smi;
*
* Caller needs to free the result using free_recipients()
*/
-struct recptypes *validate_recipients(char *supplied_recipients,
+struct recptypes *validate_recipients(const char *supplied_recipients,
const char *RemoteIdentifier,
int Flags) {
struct recptypes *ret;
struct ctdluser *which_user, struct ctdlroom *which_room);
void CtdlGetSeen(char *buf, int which_set);
-struct recptypes *validate_recipients(char *recipients,
+struct recptypes *validate_recipients(const char *recipients,
const char *RemoteIdentifier,
int Flags);
ServiceHookTable = NULL;
}
-void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name)
+void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
{
struct SearchFunctionHook *newfcn;
CtdlLogPrintf(CTDL_INFO, "Registered a new search function (%s)\n", name);
}
-void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name)
+void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
{
struct SearchFunctionHook *cur, *p;
}
}
-void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, char *search_string, char *func_name)
+void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
{
struct SearchFunctionHook *fcn = NULL;
struct SearchFunctionHook {
struct SearchFunctionHook *next;
- void (*fcn_ptr) (int *, long **, char *);
+ void (*fcn_ptr) (int *, long **, const char *);
char *name;
};
extern struct SearchFunctionHook *SearchFunctionHookTable;
* In here we were called by the current thread because it is exiting
* NB. WE ARE THE CURRENT THREAD
*/
- CtdlLogPrintf(CTDL_NOTICE, "Thread \"%s\" (0x%08lx) exited.\n", CT->name, CT->tid);
+ if (CT)
+ {
+ const char *name = CT->name;
+ const pid_t tid = CT->tid;
+
+ CtdlLogPrintf(CTDL_NOTICE, "Thread \"%s\" (0x%08lx) exited.\n", name, tid);
+ }
+ else
+ {
+ CtdlLogPrintf(CTDL_NOTICE, "some ((unknown ? ? ?) Thread exited.\n");
+ }
#ifdef HAVE_BACKTRACE
- eCrash_UnregisterThread();
+/// eCrash_UnregisterThread();
#endif
citthread_mutex_lock(&CT->ThreadMutex);
// Register for tracing
#ifdef HAVE_BACKTRACE
- eCrash_RegisterThread(this_thread->name, 0);
+/// eCrash_RegisterThread(this_thread->name, 0);
#endif
// Tell the world we are here