#include "idle.h"
#include <stdlib.h>
#include <time.h>
#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");
}
syntax highlighted by Code2HTML, v. 0.9.1