c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef IMAP_FETCH_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define IMAP_FETCH_H
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenstruct imap_fetch_context;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenenum imap_fetch_handler_flags {
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen IMAP_FETCH_HANDLER_FLAG_BUFFERED = 0x01,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT = 0x02
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen};
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen/* Returns 1 = ok, 0 = client output buffer full, call again, -1 = error.
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen mail = NULL for deinit. */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainentypedef int imap_fetch_handler_t(struct imap_fetch_context *ctx,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct mail *mail, void *context);
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenstruct imap_fetch_init_context {
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen struct imap_fetch_context *fetch_ctx;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen pool_t pool;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen const char *name;
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen const struct imap_arg *args;
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen const char *error;
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen};
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenstruct imap_fetch_handler {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const char *name;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen /* Returns FALSE and sets ctx->error if arg is invalid */
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen bool (*init)(struct imap_fetch_init_context *ctx);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen};
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenstruct imap_fetch_context_handler {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen imap_fetch_handler_t *handler;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen void *context;
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen const char *name;
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen const char *nil_reply;
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool buffered:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool want_deinit:1;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen};
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenstruct imap_fetch_qresync_args {
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen const ARRAY_TYPE(uint32_t) *qresync_sample_seqset;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen const ARRAY_TYPE(uint32_t) *qresync_sample_uidset;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen};
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainenstruct imap_fetch_state {
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct mailbox_transaction_context *trans;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct mail_search_context *search_ctx;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct mail *cur_mail;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen unsigned int cur_handler;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen const char *cur_human_name;
f339a8e73beea7684ea634941ea82593dea522eeTimo Sirainen uoff_t cur_size;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen enum mail_fetch_field cur_size_field;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen string_t *cur_str;
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen size_t cur_str_prefix_size;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct istream *cur_input;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen bool skip_cr;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen int (*cont_handler)(struct imap_fetch_context *ctx);
defeb23b40f1c1af0535a84529383825e5ef8dfeTimo Sirainen uint64_t *cur_stats_sizep;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool fetching:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool seen_flags_changed:1;
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen /* TRUE if the first FETCH parameter result hasn't yet been sent to
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen the IMAP client. Note that this doesn't affect buffered content in
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen cur_str until it gets flushed out. */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool cur_first:1;
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen /* TRUE if the cur_str prefix has been flushed. More data may still
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen be added to it. */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool line_partial:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool skipped_expunged_msgs:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool failed:1;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen};
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainenstruct imap_fetch_context {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct client *client;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen pool_t ctx_pool;
cddfd1355db6b60c71d7ee3c0b4f23b3efcc9ad1Timo Sirainen const char *reason;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen enum mail_fetch_field fetch_data;
a342a31752dd71ac444259ca57ad33ea6b79a572Timo Sirainen ARRAY_TYPE(const_string) all_headers;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct imap_fetch_context_handler) handlers;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen unsigned int buffered_handlers_count;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen ARRAY_TYPE(keywords) tmp_keywords;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct imap_fetch_state state;
704a96fa677763eef7ae62466e14e83a2f535427Timo Sirainen ARRAY_TYPE(seq_range) fetch_failed_uids;
f32c6ed9db6f4c535f97a2020401572efc8abf86Timo Sirainen unsigned int fetched_mails_count;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
289bd999f282a307b05e6f8beef33155a50fb837Timo Sirainen enum mail_error error;
289bd999f282a307b05e6f8beef33155a50fb837Timo Sirainen const char *errstr;
289bd999f282a307b05e6f8beef33155a50fb837Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool initialized:1;
704a96fa677763eef7ae62466e14e83a2f535427Timo Sirainen bool failures:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool flags_have_handler:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool flags_update_seen:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool flags_show_only_seen_changes:1;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen};
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenvoid imap_fetch_handlers_register(const struct imap_fetch_handler *handlers,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen size_t count);
67c25cb4af273aff7384d5028d459cc9afdf8712Timo Sirainenvoid imap_fetch_handler_unregister(const char *name);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenvoid imap_fetch_add_handler(struct imap_fetch_init_context *ctx,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen enum imap_fetch_handler_flags flags,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen const char *nil_reply,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen imap_fetch_handler_t *handler, void *context)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen ATTR_NULL(3, 5);
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen#define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen imap_fetch_add_handler(ctx, flags, nil_reply + \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen CALLBACK_TYPECHECK(handler, int (*)( \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen struct imap_fetch_context *, struct mail *, \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen typeof(context))), \
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen (imap_fetch_handler_t *)handler, context)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenint imap_fetch_att_list_parse(struct client *client, pool_t pool,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen const struct imap_arg *list,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct imap_fetch_context **fetch_ctx_r,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen const char **error_r);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainenstruct imap_fetch_context *
cddfd1355db6b60c71d7ee3c0b4f23b3efcc9ad1Timo Sirainenimap_fetch_alloc(struct client *client, pool_t pool, const char *reason);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenvoid imap_fetch_free(struct imap_fetch_context **ctx);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenbool imap_fetch_init_handler(struct imap_fetch_init_context *init_ctx);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenvoid imap_fetch_init_nofail_handler(struct imap_fetch_context *ctx,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen bool (*init)(struct imap_fetch_init_context *));
67c25cb4af273aff7384d5028d459cc9afdf8712Timo Sirainenconst struct imap_fetch_handler *imap_fetch_handler_lookup(const char *name);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvoid imap_fetch_begin(struct imap_fetch_context *ctx, struct mailbox *box,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct mail_search_args *search_args);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenint imap_fetch_send_vanished(struct client *client, struct mailbox *box,
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen const struct mail_search_args *search_args,
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen const struct imap_fetch_qresync_args *qresync_args);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen/* Returns 1 if finished, 0 if more data is needed, -1 if error.
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen When 0 is returned, line_partial=TRUE if literal is open and must be
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen finished before anything else to client. */
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenint imap_fetch_more(struct imap_fetch_context *ctx,
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen struct client_command_context *cmd);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen/* Like imap_fetch_more(), but don't check/update output_lock.
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen The caller must handle this itself. */
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenint imap_fetch_more_no_lock_update(struct imap_fetch_context *ctx);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenint imap_fetch_end(struct imap_fetch_context *ctx);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenint imap_fetch_more(struct imap_fetch_context *ctx,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen struct client_command_context *cmd);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenbool imap_fetch_flags_init(struct imap_fetch_init_context *ctx);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenbool imap_fetch_modseq_init(struct imap_fetch_init_context *ctx);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenbool imap_fetch_uid_init(struct imap_fetch_init_context *ctx);
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenbool imap_fetch_body_section_init(struct imap_fetch_init_context *ctx);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainenbool imap_fetch_rfc822_init(struct imap_fetch_init_context *ctx);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenbool imap_fetch_binary_init(struct imap_fetch_init_context *ctx);
c1f8d7ab0d8b15f27bbf33324000fc39751d8564Josef 'Jeff' Sipekbool imap_fetch_snippet_init(struct imap_fetch_init_context *ctx);
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen
16834f18f903048c772112838c015051642a0e77Timo Sirainenvoid imap_fetch_handlers_init(void);
16834f18f903048c772112838c015051642a0e77Timo Sirainenvoid imap_fetch_handlers_deinit(void);
16834f18f903048c772112838c015051642a0e77Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#endif