static size_t gettok (struct imap4d_tokbuf *tok, size_t off) { char *buf = tok->buffer; while (off < tok->level && mu_isblank (buf[off])) off++; if (tok->argc == tok->argmax) { if (tok->argmax == 0) tok->argmax = 16; else tok->argmax *= 2; tok->argp = realloc (tok->argp, tok->argmax * sizeof (tok->argp[0])); if (!tok->argp) imap4d_bye (ERR_NO_MEM); } if (buf[off] == '"') { char *start = buf + off + 1; char *p = NULL; while (*start && (p = strchr (start, '"'))) { if (p == start || p[-1] != '\\') break; start = p + 1; } if (p) { size_t len; off++; len = unquote (buf + off, p - (buf + off)); buf[off + len] = 0; tok->argp[tok->argc++] = off; return p - buf + 1; } } tok->argp[tok->argc++] = off; if (ISDELIM (buf[off])) return insert_nul (tok, off + 1); while (off < tok->level && !mu_isblank (buf[off])) { if (ISDELIM (buf[off])) return insert_nul (tok, off); off++; } insert_nul (tok, off); return off + 1; }
static size_t imap4d_tokbuf_getline (struct imap4d_tokbuf *tok) { char buffer[512]; size_t level = tok->level; do { size_t len; int rc; rc = mu_stream_readline (iostream, buffer, sizeof (buffer), &len); check_input_err (rc, len); imap4d_tokbuf_expand (tok, len); memcpy (tok->buffer + tok->level, buffer, len); tok->level += len; } while (tok->level && tok->buffer[tok->level - 1] != '\n'); tok->buffer[--tok->level] = 0; if (tok->buffer[tok->level - 1] == '\r') tok->buffer[--tok->level] = 0; while (tok->level > 0 && mu_isblank (tok->buffer[tok->level-1])) tok->buffer[--tok->level] = 0; return level; }
static int initial_parse (struct _mu_imapio *io) { int rc, type; int eat_rest = 0; if ((rc = mu_wordsplit_len (io->_imap_buf_base, io->_imap_buf_level, &io->_imap_ws, io->_imap_ws_flags | (io->_imap_server ? 0 : MU_WRDSF_INCREMENTAL)))) { if (rc == MU_WRDSE_NOINPUT) return IMAPIO_OK; return IMAPIO_ERR; } io->_imap_ws_flags |= MU_WRDSF_REUSE; if (io->_imap_server) return IMAPIO_OK; if ((rc = mu_wordsplit (NULL, &io->_imap_ws, MU_WRDSF_INCREMENTAL))) { if (rc == MU_WRDSE_NOINPUT) return IMAPIO_OK; return IMAPIO_ERR; } if (strcmp (io->_imap_ws.ws_wordv[0], "+") == 0) eat_rest = 1; else if ((type = is_status_response (io->_imap_ws.ws_wordv[1])) && (type == STATUS_RESPONSE || strcmp (io->_imap_ws.ws_wordv[0], "*") == 0)) { rc = get_response_code (io); if (rc) return IMAPIO_ERR; eat_rest = 1; } if (eat_rest) { while (io->_imap_ws.ws_endp < io->_imap_ws.ws_len && mu_isblank (io->_imap_ws.ws_input[io->_imap_ws.ws_endp])) io->_imap_ws.ws_endp++; io->_imap_ws.ws_flags |= MU_WRDSF_NOSPLIT; rc = mu_wordsplit (NULL, &io->_imap_ws, MU_WRDSF_INCREMENTAL); io->_imap_ws.ws_flags &= ~MU_WRDSF_NOSPLIT; if (rc) { if (rc != MU_WRDSE_NOINPUT) return IMAPIO_ERR; } return IMAPIO_RESP; } return IMAPIO_OK; }