#include "idle.h" #include #include #include "mailimap_sender.h" #include "mailimap_parser.h" #include "mailimap.h" static int mailimap_idle_send(mailimap * session) { int r; r = mailimap_token_send(session->imap_stream, "IDLE"); if (r != MAILIMAP_NO_ERROR) return r; return MAILIMAP_NO_ERROR; } static int mailimap_done_send(mailimap * session) { int r; r = mailimap_token_send(session->imap_stream, "DONE"); if (r != MAILIMAP_NO_ERROR) return r; return MAILIMAP_NO_ERROR; } LIBETPAN_EXPORT int mailimap_idle(mailimap * session) { int r; size_t index; struct mailimap_continue_req * cont_req; struct mailimap_response * response; session->imap_idle_timestamp = time(NULL); r = mailimap_send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_idle_send(session); 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 (mailimap_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 = mailimap_parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; mailimap_response_free(response); return MAILIMAP_ERROR_EXTENSION; } return MAILIMAP_NO_ERROR; } LIBETPAN_EXPORT int mailimap_idle_done(mailimap * session) { int r; int error_code; struct mailimap_response * response; r = mailimap_done_send(session); 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 (mailimap_read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = mailimap_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_EXTENSION; } } LIBETPAN_EXPORT int mailimap_idle_get_fd(mailimap * session) { mailstream_low * low; low = mailstream_get_low(session->imap_stream); return mailstream_low_get_fd(low); } LIBETPAN_EXPORT void mailimap_idle_set_delay(mailimap * session, long delay) { session->imap_idle_maxdelay = delay; } LIBETPAN_EXPORT long mailimap_idle_get_done_date(mailimap * session) { time_t current_time; time_t next_date; current_time = time(NULL); next_date = session->imap_idle_timestamp + session->imap_idle_maxdelay; if (current_time >= next_date) return 0; return next_date - current_time; } LIBETPAN_EXPORT int mailimap_check_idle(mailimap * session) { int send_done; int r; send_done = 0; if (mailimap_idle_get_done_date(session) == 0) { send_done = 1; } else { int fd; fd_set fd_read; struct timeval timeout; fd = mailimap_idle_get_fd(session); if (fd < 0) return MAILIMAP_ERROR_STREAM; timeout.tv_sec = 0; timeout.tv_usec = 0; FD_ZERO(&fd_read); FD_SET(fd, &fd_read); r = select(fd + 1, &fd_read, NULL, NULL, &timeout); if (r > 0) send_done = 1; } if (send_done) { r = mailimap_idle_done(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_idle(session); if (r != MAILIMAP_NO_ERROR) return r; } return MAILIMAP_NO_ERROR; } LIBETPAN_EXPORT int mailimap_has_idle(mailimap * session) { return mailimap_has_extension(session, "IDLE"); }