Diffstat (limited to 'kmicromail/libetpan/imap/mailimap.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/imap/mailimap.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/kmicromail/libetpan/imap/mailimap.c b/kmicromail/libetpan/imap/mailimap.c index c8fbfee..76d9454 100644 --- a/kmicromail/libetpan/imap/mailimap.c +++ b/kmicromail/libetpan/imap/mailimap.c @@ -374,1788 +374,1788 @@ message_data_store(mailimap * session, } } static void cont_req_or_resp_data_store(mailimap * session, struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data) { if (cont_req_or_resp_data->rsp_type == MAILIMAP_RESP_RESP_DATA) { struct mailimap_response_data * resp_data; resp_data = cont_req_or_resp_data->rsp_data.rsp_resp_data; switch (resp_data->rsp_type) { case MAILIMAP_RESP_DATA_TYPE_COND_STATE: resp_cond_state_store(session, resp_data->rsp_data.rsp_cond_state); break; case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA: mailbox_data_store(session, resp_data->rsp_data.rsp_mailbox_data); break; case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA: message_data_store(session, resp_data->rsp_data.rsp_message_data); break; case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA: if (session->imap_connection_info) { if (session->imap_connection_info->imap_capability != NULL) mailimap_capability_data_free(session->imap_connection_info->imap_capability); session->imap_connection_info->imap_capability = resp_data->rsp_data.rsp_capability_data; resp_data->rsp_data.rsp_capability_data = NULL; } break; } } } static void response_tagged_store(mailimap * session, struct mailimap_response_tagged * tagged) { resp_cond_state_store(session, tagged->rsp_cond_state); } static void resp_cond_bye_store(mailimap * session, struct mailimap_resp_cond_bye * resp_cond_bye) { resp_text_store(session, resp_cond_bye->rsp_text); } static void response_fatal_store(mailimap * session, struct mailimap_response_fatal * fatal) { resp_cond_bye_store(session, fatal->rsp_bye); } static void response_done_store(mailimap * session, struct mailimap_response_done * resp_done) { switch(resp_done->rsp_type) { case MAILIMAP_RESP_DONE_TYPE_TAGGED: response_tagged_store(session, resp_done->rsp_data.rsp_tagged); break; case MAILIMAP_RESP_DONE_TYPE_FATAL: response_fatal_store(session, resp_done->rsp_data.rsp_fatal); break; } } static void response_store(mailimap * session, struct mailimap_response * response) { clistiter * cur; if (session->imap_response_info) { mailimap_response_info_free(session->imap_response_info); session->imap_response_info = NULL; } session->imap_response_info = mailimap_response_info_new(); if (session->imap_response_info == NULL) { /* ignored error */ return; } if (response->rsp_cont_req_or_resp_data_list != NULL) { for(cur = clist_begin(response->rsp_cont_req_or_resp_data_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data; cont_req_or_resp_data = clist_content(cur); cont_req_or_resp_data_store(session, cont_req_or_resp_data); } } response_done_store(session, response->rsp_resp_done); } static void resp_cond_auth_store(mailimap * session, struct mailimap_resp_cond_auth * cond_auth) { resp_text_store(session, cond_auth->rsp_text); } static void greeting_store(mailimap * session, struct mailimap_greeting * greeting) { switch (greeting->gr_type) { case MAILIMAP_GREETING_RESP_COND_AUTH: resp_cond_auth_store(session, greeting->gr_data.gr_auth); break; case MAILIMAP_GREETING_RESP_COND_BYE: resp_cond_bye_store(session, greeting->gr_data.gr_bye); break; } } int mailimap_connect(mailimap * session, mailstream * s) { struct mailimap_greeting * greeting; int r; int auth_type; struct mailimap_connection_info * connection_info; if (session->imap_state != MAILIMAP_STATE_DISCONNECTED) return MAILIMAP_ERROR_BAD_STATE; session->imap_stream = s; if (session->imap_connection_info) mailimap_connection_info_free(session->imap_connection_info); connection_info = mailimap_connection_info_new(); if (connection_info != NULL) session->imap_connection_info = connection_info; if (read_line(session) == NULL) { return MAILIMAP_ERROR_STREAM; } r = parse_greeting(session, &greeting); if (r != MAILIMAP_NO_ERROR) { return r; } auth_type = greeting->gr_data.gr_auth->rsp_type; mailimap_greeting_free(greeting); switch (auth_type) { case MAILIMAP_RESP_COND_AUTH_PREAUTH: session->imap_state = MAILIMAP_STATE_AUTHENTICATED; return MAILIMAP_NO_ERROR_AUTHENTICATED; default: session->imap_state = MAILIMAP_STATE_NON_AUTHENTICATED; return MAILIMAP_NO_ERROR_NON_AUTHENTICATED; } } /* ********************************************************************** */ int mailimap_append(mailimap * session, const char * mailbox, struct mailimap_flag_list * flag_list, struct mailimap_date_time * date_time, const char * literal, size_t literal_size) { struct mailimap_response * response; int r; int error_code; struct mailimap_continue_req * cont_req; size_t index; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_append_send(session->imap_stream, mailbox, flag_list, date_time, literal_size); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; index = 0; r = mailimap_continue_req_parse(session->imap_stream, session->imap_stream_buffer, &index, &cont_req, session->imap_progr_rate, session->imap_progr_fun); if (r == MAILIMAP_NO_ERROR) mailimap_continue_req_free(cont_req); if (r == MAILIMAP_ERROR_PARSE) { r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; mailimap_response_free(response); return MAILIMAP_ERROR_APPEND; } r = mailimap_literal_data_send(session->imap_stream, literal, literal_size, session->imap_progr_rate, session->imap_progr_fun); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_APPEND; } } /* gboolean mailimap_authenticate(mailimap * session, gchar * auth_type) { } gboolean mailimap_authenticate_resp_send(mailimap * session, gchar * base64) { } */ int mailimap_noop(mailimap * session) { struct mailimap_response * response; int r; int error_code; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_noop_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_NOOP; } } int mailimap_logout(mailimap * session) { struct mailimap_response * response; int r; int error_code; int res; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) { res = r; goto close; } r = mailimap_logout_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) { res = r; goto close; } r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) { res = r; goto close; } if (mailstream_flush(session->imap_stream) == -1) { res = MAILIMAP_ERROR_STREAM; goto close; } if (read_line(session) == NULL) { res = MAILIMAP_ERROR_STREAM; goto close; } r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) { res = r; goto close; } error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: if (session->imap_connection_info) { mailimap_connection_info_free(session->imap_connection_info); session->imap_connection_info = NULL; } res = MAILIMAP_NO_ERROR; goto close; default: res = MAILIMAP_ERROR_LOGOUT; goto close; } close: mailstream_close(session->imap_stream); session->imap_stream = NULL; session->imap_state = MAILIMAP_STATE_DISCONNECTED; return res; } /* send the results back to the caller */ /* duplicate the result */ static struct mailimap_capability * mailimap_capability_dup(struct mailimap_capability * orig_cap) { struct mailimap_capability * cap; char * auth_type; char * name; name = NULL; auth_type = NULL; switch (orig_cap->cap_type) { case MAILIMAP_CAPABILITY_NAME: name = strdup(orig_cap->cap_data.cap_name); if (name == NULL) goto err; break; case MAILIMAP_CAPABILITY_AUTH_TYPE: auth_type = strdup(orig_cap->cap_data.cap_auth_type); if (auth_type == NULL) goto err; break; } cap = mailimap_capability_new(orig_cap->cap_type, auth_type, name); if (cap == NULL) goto free; return cap; free: if (name != NULL) free(name); if (auth_type != NULL) free(auth_type); err: return NULL; } static struct mailimap_capability_data * mailimap_capability_data_dup(struct mailimap_capability_data * orig_cap_data) { struct mailimap_capability_data * cap_data; struct mailimap_capability * cap_dup; clist * list; clistiter * cur; int r; list = clist_new(); if (list == NULL) goto err; for(cur = clist_begin(orig_cap_data->cap_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailimap_capability * cap; cap = clist_content(cur); cap_dup = mailimap_capability_dup(cap); if (cap_dup == NULL) goto list; r = clist_append(list, cap_dup); if (r < 0) { mailimap_capability_free(cap_dup); goto list; } } cap_data = mailimap_capability_data_new(list); if (cap_data == NULL) goto list; return cap_data; list: clist_foreach(list, (clist_func) mailimap_capability_free, NULL); clist_free(list); err: return NULL; } int mailimap_capability(mailimap * session, struct mailimap_capability_data ** result) { struct mailimap_response * response; int r; int error_code; struct mailimap_capability_data * cap_data; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_capability_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: cap_data = mailimap_capability_data_dup(session->imap_connection_info->imap_capability); if (cap_data == NULL) return MAILIMAP_ERROR_MEMORY; * result = cap_data; return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_CAPABILITY; } } int mailimap_check(mailimap * session) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_check_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_CHECK; } } int mailimap_close(mailimap * session) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_close_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: /* leave selected state */ mailimap_selection_info_free(session->imap_selection_info); session->imap_selection_info = NULL; session->imap_state = MAILIMAP_STATE_AUTHENTICATED; return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_CLOSE; } } int mailimap_expunge(mailimap * session) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_expunge_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_EXPUNGE; } } int mailimap_copy(mailimap * session, struct mailimap_set * set, const char * mb) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_copy_send(session->imap_stream, set, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_COPY; } } int mailimap_uid_copy(mailimap * session, struct mailimap_set * set, const char * mb) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_uid_copy_send(session->imap_stream, set, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UID_COPY; } } int mailimap_create(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_create_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_CREATE; } } int mailimap_delete(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_delete_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_DELETE; } } int mailimap_examine(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_examine_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; if (session->imap_selection_info != NULL) mailimap_selection_info_free(session->imap_selection_info); session->imap_selection_info = mailimap_selection_info_new(); r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: session->imap_state = MAILIMAP_STATE_SELECTED; return MAILIMAP_NO_ERROR; default: mailimap_selection_info_free(session->imap_selection_info); session->imap_selection_info = NULL; session->imap_state = MAILIMAP_STATE_AUTHENTICATED; return MAILIMAP_ERROR_EXAMINE; } } int mailimap_fetch(mailimap * session, struct mailimap_set * set, struct mailimap_fetch_type * fetch_type, clist ** result) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_fetch_send(session->imap_stream, set, fetch_type); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_fetch_list; session->imap_response_info->rsp_fetch_list = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_FETCH; } } void mailimap_fetch_list_free(clist * fetch_list) { clist_foreach(fetch_list, (clist_func) mailimap_msg_att_free, NULL); clist_free(fetch_list); } int mailimap_uid_fetch(mailimap * session, struct mailimap_set * set, struct mailimap_fetch_type * fetch_type, clist ** result) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_uid_fetch_send(session->imap_stream, set, fetch_type); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_fetch_list; session->imap_response_info->rsp_fetch_list = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UID_FETCH; } } int mailimap_list(mailimap * session, const char * mb, const char * list_mb, clist ** result) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_list_send(session->imap_stream, mb, list_mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_mailbox_list; session->imap_response_info->rsp_mailbox_list = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_LIST; } } int mailimap_login(mailimap * session, const char * userid, const char * password) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_NON_AUTHENTICATED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_login_send(session->imap_stream, userid, password); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: session->imap_state = MAILIMAP_STATE_AUTHENTICATED; return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_LOGIN; } } int mailimap_lsub(mailimap * session, const char * mb, const char * list_mb, clist ** result) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_lsub_send(session->imap_stream, mb, list_mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_mailbox_lsub; session->imap_response_info->rsp_mailbox_lsub = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_LSUB; } } void mailimap_list_result_free(clist * list) { clist_foreach(list, (clist_func) mailimap_mailbox_list_free, NULL); clist_free(list); } int mailimap_rename(mailimap * session, const char * mb, const char * new_name) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_rename_send(session->imap_stream, mb, new_name); if (r != MAILIMAP_NO_ERROR) return r; if (!mailimap_crlf_send(session->imap_stream)) if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_RENAME; } } int mailimap_search(mailimap * session, const char * charset, struct mailimap_search_key * key, clist ** result) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_search_send(session->imap_stream, charset, key); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_search_result; session->imap_response_info->rsp_search_result = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_SEARCH; } } int mailimap_uid_search(mailimap * session, const char * charset, struct mailimap_search_key * key, clist ** result) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_uid_search_send(session->imap_stream, charset, key); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_search_result; session->imap_response_info->rsp_search_result = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UID_SEARCH; } } void mailimap_search_result_free(clist * search_result) { clist_foreach(search_result, (clist_func) free, NULL); clist_free(search_result); } int mailimap_select(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_select_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; if (session->imap_selection_info != NULL) mailimap_selection_info_free(session->imap_selection_info); session->imap_selection_info = mailimap_selection_info_new(); r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: session->imap_state = MAILIMAP_STATE_SELECTED; return MAILIMAP_NO_ERROR; default: mailimap_selection_info_free(session->imap_selection_info); session->imap_selection_info = NULL; session->imap_state = MAILIMAP_STATE_AUTHENTICATED; return MAILIMAP_ERROR_SELECT; } } int mailimap_status(mailimap * session, const char * mb, struct mailimap_status_att_list * status_att_list, struct mailimap_mailbox_data_status ** result) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_status_send(session->imap_stream, mb, status_att_list); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; * result = session->imap_response_info->rsp_status; session->imap_response_info->rsp_status = NULL; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_STATUS; } } int mailimap_store(mailimap * session, struct mailimap_set * set, struct mailimap_store_att_flags * store_att_flags) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_store_send(session->imap_stream, set, store_att_flags); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_STORE; } } int mailimap_uid_store(mailimap * session, struct mailimap_set * set, struct mailimap_store_att_flags * store_att_flags) { struct mailimap_response * response; int r; int error_code; if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_uid_store_send(session->imap_stream, set, store_att_flags); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UID_STORE; } } int mailimap_subscribe(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_subscribe_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_SUBSCRIBE; } } int mailimap_unsubscribe(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; - r = mailimap_subscribe_send(session->imap_stream, mb); + r = mailimap_unsubscribe_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UNSUBSCRIBE; } } int mailimap_starttls(mailimap * session) { struct mailimap_response * response; int r; int error_code; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_starttls_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_STARTTLS; } } static char * read_line(mailimap * session) { return mailstream_read_line(session->imap_stream, session->imap_stream_buffer); } static int send_current_tag(mailimap * session) { char tag_str[15]; int r; session->imap_tag ++; snprintf(tag_str, 15, "%i", session->imap_tag); r = mailimap_tag_send(session->imap_stream, tag_str); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_space_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; return MAILIMAP_NO_ERROR; } static int parse_response(mailimap * session, struct mailimap_response ** result) { size_t index; struct mailimap_response * response; char tag_str[15]; int r; index = 0; session->imap_response = NULL; r = mailimap_response_parse(session->imap_stream, session->imap_stream_buffer, &index, &response, session->imap_progr_rate, session->imap_progr_fun); if (r != MAILIMAP_NO_ERROR) return r; #if 0 mailimap_response_print(response); #endif response_store(session, response); if (mmap_string_assign(session->imap_response_buffer, response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_text->rsp_text) == NULL) return MAILIMAP_ERROR_MEMORY; session->imap_response = session->imap_response_buffer->str; if (response->rsp_resp_done->rsp_type == MAILIMAP_RESP_DONE_TYPE_FATAL) return MAILIMAP_ERROR_FATAL; snprintf(tag_str, 15, "%i", session->imap_tag); if (strcmp(response->rsp_resp_done->rsp_data.rsp_tagged->rsp_tag, tag_str) != 0) return MAILIMAP_ERROR_PROTOCOL; if (response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type == MAILIMAP_RESP_COND_STATE_BAD) return MAILIMAP_ERROR_PROTOCOL; * result = response; return MAILIMAP_NO_ERROR; } static int parse_greeting(mailimap * session, struct mailimap_greeting ** result) { size_t index; struct mailimap_greeting * greeting; int r; index = 0; session->imap_response = NULL; r = mailimap_greeting_parse(session->imap_stream, session->imap_stream_buffer, &index, &greeting, session->imap_progr_rate, session->imap_progr_fun); if (r != MAILIMAP_NO_ERROR) return r; #if 0 mailimap_greeting_print(greeting); #endif greeting_store(session, greeting); if (greeting->gr_type == MAILIMAP_GREETING_RESP_COND_BYE) { if (mmap_string_assign(session->imap_response_buffer, greeting->gr_data.gr_bye->rsp_text->rsp_text) == NULL) return MAILIMAP_ERROR_MEMORY; session->imap_response = session->imap_response_buffer->str; return MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION; } if (mmap_string_assign(session->imap_response_buffer, greeting->gr_data.gr_auth->rsp_text->rsp_text) == NULL) return MAILIMAP_ERROR_MEMORY; session->imap_response = session->imap_response_buffer->str; * result = greeting; return MAILIMAP_NO_ERROR; } mailimap * mailimap_new(size_t imap_progr_rate, progress_function * imap_progr_fun) { mailimap * f; f = malloc(sizeof(* f)); if (f == NULL) goto err; f->imap_response = NULL; f->imap_stream = NULL; f->imap_progr_rate = imap_progr_rate; f->imap_progr_fun = imap_progr_fun; f->imap_stream_buffer = mmap_string_new(""); if (f->imap_stream_buffer == NULL) goto free_f; f->imap_response_buffer = mmap_string_new(""); if (f->imap_response_buffer == NULL) goto free_stream_buffer; f->imap_state = MAILIMAP_STATE_DISCONNECTED; f->imap_tag = 0; f->imap_selection_info = NULL; f->imap_response_info = NULL; f->imap_connection_info = NULL; return f; free_stream_buffer: mmap_string_free(f->imap_stream_buffer); free_f: free(f); err: return NULL; } void mailimap_free(mailimap * session) { if (session->imap_stream) mailimap_logout(session); mmap_string_free(session->imap_response_buffer); mmap_string_free(session->imap_stream_buffer); if (session->imap_response_info) mailimap_response_info_free(session->imap_response_info); if (session->imap_selection_info) mailimap_selection_info_free(session->imap_selection_info); if (session->imap_connection_info) mailimap_connection_info_free(session->imap_connection_info); free(session); } |