Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

imapd.c: remove support for SCAN command #4925

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 0 additions & 52 deletions cassandane/tiny-tests/List/scan

This file was deleted.

99 changes: 9 additions & 90 deletions imap/imapd.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,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 @@ -896,7 +895,7 @@ static void imapd_log_client_behavior(void)
"%s%s%s%s"
"%s%s%s%s"
"%s%s%s"
"%s%s",
"%s",

session_id(),
imapd_userid ? imapd_userid : "",
Expand Down Expand Up @@ -926,7 +925,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>" : "");
}

Expand Down Expand Up @@ -2424,25 +2422,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 @@ -4195,7 +4174,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 @@ -4693,7 +4672,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 @@ -6987,7 +6966,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 @@ -7767,7 +7746,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 @@ -8511,8 +8490,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 @@ -13169,50 +13146,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 @@ -13416,9 +13349,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 @@ -13432,21 +13364,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 @@ -356,7 +356,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 @@ -469,7 +468,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 */
};

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