int mailstream_wait_idle(mailstream * s, int max_idle_delay) { int fd; int idle_fd; int cancel_fd; int maxfd; fd_set readfds; struct timeval delay; int r; if (s->low->driver == mailstream_cfstream_driver) { return mailstream_cfstream_wait_idle(s, max_idle_delay); } fd = mailstream_low_get_fd(mailstream_get_low(s)); idle_fd = mailstream_cancel_get_fd(s->idle); cancel_fd = mailstream_cancel_get_fd(mailstream_low_get_cancel(mailstream_get_low(s))); FD_ZERO(&readfds); FD_SET(fd, &readfds); FD_SET(idle_fd, &readfds); FD_SET(cancel_fd, &readfds); maxfd = fd; if (idle_fd > maxfd) { maxfd = idle_fd; } if (cancel_fd > maxfd) { maxfd = cancel_fd; } delay.tv_sec = max_idle_delay; delay.tv_usec = 0; r = select(maxfd + 1, &readfds, NULL, NULL, &delay); if (r == 0) { // timeout return MAILSTREAM_IDLE_TIMEOUT; } else if (r == -1) { // do nothing return MAILSTREAM_IDLE_ERROR; } else { if (FD_ISSET(fd, &readfds)) { // has something on socket return MAILSTREAM_IDLE_HASDATA; } if (FD_ISSET(idle_fd, &readfds)) { // idle interrupted mailstream_cancel_ack(s->idle); return MAILSTREAM_IDLE_INTERRUPTED; } if (FD_ISSET(cancel_fd, &readfds)) { // idle cancelled mailstream_cancel_ack(mailstream_low_get_cancel(mailstream_get_low(s))); return MAILSTREAM_IDLE_CANCELLED; } return MAILSTREAM_IDLE_ERROR; } }
LIBETPAN_EXPORT int mailpop3_socket_starttls_with_callback(mailpop3 * f, void (* callback)(struct mailstream_ssl_context * ssl_context, void * data), void * data) { int r; int fd; mailstream_low * low; mailstream_low * new_low; r = mailpop3_stls(f); switch (r) { case MAILPOP3_NO_ERROR: break; default: return r; } low = mailstream_get_low(f->pop3_stream); fd = mailstream_low_get_fd(low); if (fd == -1) return MAILPOP3_ERROR_STREAM; new_low = mailstream_low_tls_open_with_callback(fd, callback, data); if (new_low == NULL) return MAILPOP3_ERROR_SSL; mailstream_low_free(low); mailstream_set_low(f->pop3_stream, new_low); return MAILPOP3_NO_ERROR; }
static int get_hostname(mailsmtp * session, int useip, char * buf, int len) { int r; char hostname[HOSTNAME_SIZE]; struct sockaddr addr; socklen_t addr_len = sizeof(addr); int socket = -1; if (!useip) { r = gethostname(hostname, HOSTNAME_SIZE); if (r != 0) return MAILSMTP_ERROR_HOSTNAME; if (snprintf(buf, len, "%s", hostname) >= len) return MAILSMTP_ERROR_HOSTNAME; } else { socket = mailstream_low_get_fd(mailstream_get_low(session->stream)); if (socket < 0) return MAILSMTP_ERROR_HOSTNAME; r = getsockname(socket, &addr, &addr_len ); if (r != 0) return MAILSMTP_ERROR_HOSTNAME; r = getnameinfo(&addr, addr.sa_len, hostname, HOSTNAME_SIZE, NULL, 0, NI_NUMERICHOST); if (r != 0) return MAILSMTP_ERROR_HOSTNAME; if (snprintf(buf, len, "[%s]", hostname) >= len) return MAILSMTP_ERROR_HOSTNAME; } return MAILSMTP_NO_ERROR; }
int mailsmtp_socket_starttls_with_callback(mailsmtp * session, void (* callback)(struct mailstream_ssl_context * ssl_context, void * data), void * data) { int r; int fd; mailstream_low * low; mailstream_low * new_low; low = mailstream_get_low(session->stream); if (low->driver == mailstream_cfstream_driver) { // won't use callback return mailsmtp_cfsocket_starttls(session); } r = mailesmtp_starttls(session); if (r != MAILSMTP_NO_ERROR) return r; fd = mailstream_low_get_fd(low); if (fd == -1) return MAILSMTP_ERROR_STREAM; new_low = mailstream_low_tls_open_with_callback_timeout(fd, session->smtp_timeout, callback, data); if (new_low == NULL) return MAILSMTP_ERROR_SSL; mailstream_low_free(low); mailstream_set_low(session->stream, new_low); return MAILSMTP_NO_ERROR; }
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); }
void mailstream_socket_set_use_read(mailstream * stream, int use_read) { struct mailstream_socket_data * socket_data; mailstream_low * low; low = mailstream_get_low(stream); socket_data = (struct mailstream_socket_data *) low->data; socket_data->use_read = use_read; }
int mailimap_socket_starttls_with_callback(mailimap * f, void (* callback)(struct mailstream_ssl_context * ssl_context, void * data), void * data) { mailstream_low * low; mailstream_low * new_low; int r; int fd; low = mailstream_get_low(f->imap_stream); if (low->driver == mailstream_cfstream_driver) { // won't use callback return mailimap_cfsocket_starttls(f); } r = mailimap_starttls(f); switch (r) { case MAILIMAP_NO_ERROR: break; default: return r; } fd = mailstream_low_get_fd(low); if (fd == -1) return MAILIMAP_ERROR_STREAM; new_low = mailstream_low_tls_open_with_callback_timeout(fd, f->imap_timeout, callback, data); if (new_low == NULL) return MAILIMAP_ERROR_STREAM; mailstream_low_free(low); mailstream_set_low(f->imap_stream, new_low); return MAILIMAP_NO_ERROR; }