Skip to content

Commit

Permalink
imapd.c: remove support for SCAN command
Browse files Browse the repository at this point in the history
  • Loading branch information
ksmurchison committed May 21, 2024
1 parent a8637b1 commit 1a4ab79
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 187 deletions.
99 changes: 9 additions & 90 deletions imap/imapd.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,6 @@ static struct capa_struct base_capabilities[] = {
{ "MUPDATE=", CAPA_OMNIAUTH|CAPA_VALUE, /* CY */
{ .value = { "mupdate://%1$s/", .strp = &config_mupdate_server } } },
{ "NO_ATOMIC_RENAME", CAPA_POSTAUTH, { 0 } }, /* CY */
{ "SCAN", CAPA_POSTAUTH, { 0 } }, /* NS */
{ "SORT=MODSEQ", CAPA_POSTAUTH, { 0 } }, /* NS */
{ "SORT=UID", CAPA_POSTAUTH, { 0 } }, /* NS */
{ "THREAD=REFS", CAPA_POSTAUTH, { 0 } }, /* draft-ietf-morg-inthread */
Expand Down Expand Up @@ -902,7 +901,7 @@ static void imapd_log_client_behavior(void)
"%s%s%s%s"
"%s%s%s%s"
"%s%s%s"
"%s%s%s",
"%s%s",

session_id(),
imapd_userid ? imapd_userid : "",
Expand Down Expand Up @@ -932,7 +931,6 @@ static void imapd_log_client_behavior(void)
client_behavior.did_uidonly ? " uidonly=<1>" : "",
client_behavior.did_utf8_accept ? " utf8_accept=<1>" : "",

client_behavior.did_scan ? " scan=<1>" : "",
client_behavior.did_xlist ? " xlist=<1>" : "",
client_behavior.did_xmove ? " xmove=<1>" : "");
}
Expand Down Expand Up @@ -2399,25 +2397,6 @@ static void cmdloop(void)

prometheus_increment(CYRUS_IMAP_STATUS_TOTAL);
}
else if (!strcmp(cmd.s, "Scan")) {
struct listargs listargs;

c = getastring(imapd_in, imapd_out, &arg1);
if (c != ' ') goto missingargs;
c = getastring(imapd_in, imapd_out, &arg2);
if (c != ' ') goto missingargs;
c = getastring(imapd_in, imapd_out, &arg3);
if (!IS_EOL(c, imapd_in)) goto extraargs;

memset(&listargs, 0, sizeof(struct listargs));
listargs.ref = arg1.s;
strarray_append(&listargs.pat, arg2.s);
listargs.scan = arg3.s;

cmd_list(tag.s, &listargs);

prometheus_increment(CYRUS_IMAP_SCAN_TOTAL);
}
else if (!strcmp(cmd.s, "Syncapply")) {
if (!imapd_userisadmin) goto badcmd;

Expand Down Expand Up @@ -4175,7 +4154,7 @@ static int cmd_append(char *tag, char *name, const char *cur_name, int isreplace
const char *origname = name;
struct listargs listargs = {
LIST_CMD_EXTENDED, 0, LIST_RET_CHILDREN | LIST_RET_SPECIALUSE,
"", STRARRAY_INITIALIZER, NULL, 0, {0}, STRARRAY_INITIALIZER, NULL
"", STRARRAY_INITIALIZER, 0, {0}, STRARRAY_INITIALIZER, NULL
};

if (client_capa & CAPA_IMAP4REV2) {
Expand Down Expand Up @@ -4658,7 +4637,7 @@ static void cmd_select(char *tag, char *cmd, char *name)
const char *origname = name;
struct listargs listargs = {
LIST_CMD_EXTENDED, 0, LIST_RET_CHILDREN | LIST_RET_SPECIALUSE,
"", STRARRAY_INITIALIZER, NULL, 0, {0}, STRARRAY_INITIALIZER, NULL
"", STRARRAY_INITIALIZER, 0, {0}, STRARRAY_INITIALIZER, NULL
};

memset(&init, 0, sizeof(struct index_init));
Expand Down Expand Up @@ -7619,7 +7598,7 @@ static void cmd_create(char *tag, char *name, struct dlist *extargs, int localon
const char *origname = name;
struct listargs listargs = {
LIST_CMD_EXTENDED, 0, LIST_RET_CHILDREN | LIST_RET_SPECIALUSE,
"", STRARRAY_INITIALIZER, NULL, 0, {0}, STRARRAY_INITIALIZER, NULL
"", STRARRAY_INITIALIZER, 0, {0}, STRARRAY_INITIALIZER, NULL
};

/* We don't care about trailing hierarchy delimiters. */
Expand Down Expand Up @@ -8398,7 +8377,7 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *location,
const char *orig_newname = newname;
struct listargs listargs = {
LIST_CMD_EXTENDED, 0, LIST_RET_CHILDREN | LIST_RET_SPECIALUSE,
"", STRARRAY_INITIALIZER, NULL, 0, {0}, STRARRAY_INITIALIZER, NULL
"", STRARRAY_INITIALIZER, 0, {0}, STRARRAY_INITIALIZER, NULL
};

if (location && !imapd_userisadmin) {
Expand Down Expand Up @@ -9134,8 +9113,6 @@ static void cmd_list(char *tag, struct listargs *listargs)

if (listargs->cmd == LIST_CMD_XLIST)
client_behavior.did_xlist = 1;
else if (listargs->scan)
client_behavior.did_scan = 1;

if (listargs->sel & LIST_SEL_REMOTE) {
if (!config_getswitch(IMAPOPT_PROXYD_DISABLE_MAILBOX_REFERRALS)) {
Expand Down Expand Up @@ -13894,50 +13871,6 @@ static void list_response(const char *extname, const mbentry_t *mbentry,
}
}

else if (listargs->scan) {
/* SCAN mailbox for content */

if (!strcmpsafe(mbentry->name, index_mboxname(imapd_index))) {
/* currently selected mailbox */
if (index_refresh(imapd_index) ||
!index_scan(imapd_index, listargs->scan)) {
return; /* no matching messages */
}
}
else {
/* other local mailbox */
struct index_state *state;
struct index_init init;
int doclose = 0;

memset(&init, 0, sizeof(struct index_init));
init.userid = imapd_userid;
init.authstate = imapd_authstate;
init.out = imapd_out;
init.examine_mode = 1;

r = index_open(mbentry->name, &init, &state);

if (!r)
doclose = 1;

if (!r && !index_hasrights(state, ACL_READ)) {
r = (imapd_userisadmin || index_hasrights(state, ACL_LOOKUP)) ?
IMAP_PERMISSION_DENIED : IMAP_MAILBOX_NONEXISTENT;
}

if (!r) {
if (!index_scan(state, listargs->scan)) {
r = -1; /* no matching messages */
}
}

if (doclose) index_close(&state);

if (r) return;
}
}

/* figure out \Has(No)Children if necessary
This is mainly used for LIST (SUBSCRIBED) RETURN (CHILDREN)
*/
Expand Down Expand Up @@ -14141,9 +14074,8 @@ static int perform_output(const char *extname, const mbentry_t *mbentry, struct
/* already proxied to this backend server */
return 0;
}
if (listargs->scan ||
(listargs->ret &
(LIST_RET_SPECIALUSE | LIST_RET_STATUS | LIST_RET_METADATA))) {
if (listargs->ret &
(LIST_RET_SPECIALUSE | LIST_RET_STATUS | LIST_RET_METADATA)) {
/* remote mailbox that we need to fetch metadata from */
struct backend *s;

Expand All @@ -14157,21 +14089,8 @@ static int perform_output(const char *extname, const mbentry_t *mbentry, struct

proxy_gentag(mytag, sizeof(mytag));

if (listargs->scan) {
/* Send SCAN command to backend */
prot_printf(s->out, "%s Scan {%tu+}\r\n%s {%tu+}\r\n%s"
" {%tu+}\r\n%s\r\n",
mytag, strlen(listargs->ref), listargs->ref,
strlen(listargs->pat.data[0]),
listargs->pat.data[0],
strlen(listargs->scan), listargs->scan);

pipe_until_tag(s, mytag, 0);
}
else {
/* Send LIST command to backend */
list_data_remote(s, mytag, listargs, rock->subs);
}
/* Send LIST command to backend */
list_data_remote(s, mytag, listargs, rock->subs);
}

return 0;
Expand Down
2 changes: 0 additions & 2 deletions imap/imapd.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ struct listargs {
unsigned ret; /* Return options */
const char *ref; /* Reference name */
strarray_t pat; /* Mailbox pattern(s) */
const char *scan; /* SCAN content */
unsigned statusitems; /* for RETURN STATUS */
struct getmetadata_options metaopts; /* for RETURN METADATA */
strarray_t metaitems; /* for RETURN METADATA */
Expand Down Expand Up @@ -468,7 +467,6 @@ struct client_behavior_registry {
uint32_t did_utf8_accept : 1; /* used ENABLE UTF8=ACCEPT */

/* non-standard - track for possible deprecation */
uint32_t did_scan : 1; /* used SCAN */
uint32_t did_xlist : 1; /* used XLIST */
uint32_t did_xmove : 1; /* used XMOVE */
};
Expand Down
93 changes: 0 additions & 93 deletions imap/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,99 +1742,6 @@ static void build_query(search_builder_t *bx,
}
}

static int index_prefilter_messages(unsigned* msg_list,
struct index_state *state,
struct searchargs *searchargs __attribute((unused)))
{
unsigned int msgno;

xstats_inc(SEARCH_TRIVIAL);

/* Just put in all possible messages. This falls back to Cyrus' default
* search. */

for (msgno = 1; msgno <= state->exists; msgno++)
msg_list[msgno-1] = msgno;

return state->exists;
}

static int index_scan_work(const char *s, unsigned long len,
const char *match, unsigned long min)
{
while (len > min) {
if (!strncasecmp(s, match, min)) return(1);
s++;
len--;
}
return(0);
}

/*
* Guts of the SCAN command, lifted from _index_search()
*
* Returns 1 if we get a hit, otherwise returns 0.
*/
EXPORTED int index_scan(struct index_state *state, const char *contents)
{
unsigned *msgno_list = NULL;
uint32_t msgno;
int n = 0;
int listindex;
int listcount;
struct searchargs searchargs = {0};
unsigned long length;
struct mailbox *mailbox = state->mailbox;
charset_t ascii = charset_lookupname("US-ASCII");

if (!(contents && contents[0]))
goto done;

if (state->exists <= 0)
goto done;

length = strlen(contents);

memset(&searchargs, 0, sizeof(struct searchargs));
searchargs.root = search_expr_new(NULL, SEOP_MATCH);
searchargs.root->attr = search_attr_find("text");

/* Use US-ASCII to emulate fgrep */

searchargs.root->value.s = charset_convert(contents, ascii, charset_flags);

search_expr_internalise(state, searchargs.root);

msgno_list = (unsigned *) xmalloc(state->exists * sizeof(unsigned));

listcount = index_prefilter_messages(msgno_list, state, &searchargs);

for (listindex = 0; !n && listindex < listcount; listindex++) {
if (!(listindex % 128) && cmd_cancelled(/*insearch*/1))
break;
struct buf buf = BUF_INITIALIZER;
struct index_record record;
msgno = msgno_list[listindex];

if (index_reload_record(state, msgno, &record))
continue;

if (mailbox_map_record(mailbox, &record, &buf))
continue;

n += index_scan_work(buf.s, buf.len, contents, length);

buf_free(&buf);
}

done:
charset_free(&ascii);
search_expr_free(searchargs.root);
free(msgno_list);

return n;
}

EXPORTED uint32_t index_getuid(struct index_state *state, uint32_t msgno)
{
assert(msgno <= state->exists);
Expand Down
2 changes: 0 additions & 2 deletions imap/index.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,6 @@ extern int index_thread(struct index_state *state, int algorithm,
extern int index_search(struct index_state *state,
struct searchargs *searchargs, int usinguid,
struct progress_rock *prock);
extern int index_scan(struct index_state *state,
const char *contents);
extern int index_copy(struct index_state *state,
char *sequence,
int usinguid,
Expand Down

0 comments on commit 1a4ab79

Please sign in to comment.