/* * Process the data that server sent due to IMAP IDLE client request. */ int response_idle(session *ssn, int tag) { regexp *re; if (tag == -1) return -1; re = &responses[RESPONSE_IDLE]; do { buffer_reset(&ibuf); switch (receive_response(ssn, ibuf.data, get_option_number("keepalive") * 60, 0)) { case -1: return -1; break; /* NOTREACHED */ case 0: return STATUS_TIMEOUT; break; /* NOTREACHED */ } verbose("S (%d): %s", ssn->socket, ibuf.data); if (check_bye(ibuf.data)) return STATUS_BYE; } while (regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0)); return STATUS_UNTAGGED; }
/* * Get server data and make sure there is a continuation response inside them. */ int response_continuation(session *ssn, int tag) { int r; ssize_t n; buffer_reset(&ibuf); do { buffer_check(&ibuf, ibuf.len + INPUT_BUF); if ((n = receive_response(ssn, ibuf.data + ibuf.len, 0, 1)) == -1) return -1; ibuf.len += n; if (check_bye(ibuf.data)) return STATUS_BYE; } while ((r = check_tag(ibuf.data, ssn, tag)) == STATUS_NONE && !check_continuation(ibuf.data)); if (r == STATUS_NO && (check_trycreate(ibuf.data) || get_option_boolean("create"))) return STATUS_TRYCREATE; if (r == STATUS_NONE) return STATUS_CONTINUE; return r; }
/* * Process the data that server sent due to IMAP FETCH BODY[] client request, * ie. FETCH BODY[HEADER], FETCH BODY[TEXT], FETCH BODY[HEADER.FIELDS * (<fields>)], FETCH BODY[<part>]. */ int response_fetchbody(session *ssn, int tag, char **body, size_t *len) { int r, match; unsigned int offset; ssize_t n; regexp *re; if (tag == -1) return -1; buffer_reset(&ibuf); match = -1; offset = 0; re = &responses[RESPONSE_FETCH_BODY]; do { buffer_check(&ibuf, ibuf.len + INPUT_BUF); if ((n = receive_response(ssn, ibuf.data + ibuf.len, 0, 1)) == -1) return -1; ibuf.len += n; if (match != 0) { match = regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0); if (match == 0 && re->pmatch[2].rm_so != -1 && re->pmatch[2].rm_eo != -1) { *len = strtoul(ibuf.data + re->pmatch[2].rm_so, NULL, 10); offset = re->pmatch[0].rm_eo + *len; } } if (offset != 0 && ibuf.len >= offset) { if (check_bye(ibuf.data + offset)) return STATUS_BYE; } } while (ibuf.len < offset || (r = check_tag(ibuf.data + offset, ssn, tag)) == STATUS_NONE); if (match == 0) { if (re->pmatch[2].rm_so != -1 && re->pmatch[2].rm_eo != -1) { *body = ibuf.data + re->pmatch[0].rm_eo; } else { *body = ibuf.data + re->pmatch[3].rm_so; *len = re->pmatch[3].rm_eo - re->pmatch[3].rm_so; } } return r; }
/* * Process the greeting that server sends during connection. */ int response_greeting(session *ssn) { buffer_reset(&ibuf); if (receive_response(ssn, ibuf.data, 0, 1) == -1) return -1; verbose("S (%d): %s", ssn->socket, ibuf.data); if (check_bye(ibuf.data)) return STATUS_BYE; if (check_preauth(ibuf.data)) return STATUS_PREAUTH; return STATUS_NONE; }
/* * Process the greeting that server sends during connection. */ int response_greeting(session *ssn) { buffer_reset(&ibuf); if (receive_response(ssn, ibuf.data) == -1) return -1; if (check_bye(ibuf.data)) return -1; verbose("S (%d): %s", ssn->socket, ibuf.data); if (xstrcasestr(ibuf.data, "* PREAUTH")) return STATUS_RESPONSE_PREAUTH; return STATUS_RESPONSE_NONE; }