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; }
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 mailimap_idle_get_fd(mailimap * session) { mailstream_low * low; low = mailstream_get_low(session->imap_stream); return mailstream_low_get_fd(low); }
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; }
int mailstream_low_wait_idle(mailstream_low * low, struct mailstream_cancel * idle, int max_idle_delay) { int fd; int idle_fd; int cancel_fd; int maxfd; fd_set readfds; struct timeval delay; int r; if (low->driver == mailstream_cfstream_driver) { return mailstream_low_cfstream_wait_idle(low, max_idle_delay); } else if (low->driver == mailstream_compress_driver) { return mailstream_low_compress_wait_idle(low, idle, max_idle_delay); } if (idle == NULL) { return MAILSTREAM_IDLE_ERROR; } if (mailstream_low_get_cancel(low) == NULL) { return MAILSTREAM_IDLE_ERROR; } fd = mailstream_low_get_fd(low); idle_fd = mailstream_cancel_get_fd(idle); cancel_fd = mailstream_cancel_get_fd(mailstream_low_get_cancel(low)); FD_ZERO(&readfds); #ifdef WIN32 HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); WSAEventSelect(fd, event, FD_READ | FD_CLOSE); FD_SET(event, &readfds); FD_SET(idle_fd, &readfds); FD_SET(cancel_fd, &readfds); r = WaitForMultipleObjects(readfds.fd_count, readfds.fd_array, FALSE, max_idle_delay * 1000); WSAEventSelect(fd, event, 0); CloseHandle(event); if (r == WAIT_TIMEOUT) { return MAILSTREAM_IDLE_TIMEOUT; } else if (r == WAIT_OBJECT_0){ return MAILSTREAM_IDLE_HASDATA; } else if (r == WAIT_OBJECT_0 + 1){ return MAILSTREAM_IDLE_INTERRUPTED; } else if (r == WAIT_OBJECT_0 + 2){ return MAILSTREAM_IDLE_CANCELLED; } DWORD i = GetLastError(); return MAILSTREAM_IDLE_ERROR; #else 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(idle); return MAILSTREAM_IDLE_INTERRUPTED; } if (FD_ISSET(cancel_fd, &readfds)) { // idle cancelled mailstream_cancel_ack(mailstream_low_get_cancel(low)); return MAILSTREAM_IDLE_CANCELLED; } return MAILSTREAM_IDLE_ERROR; } #endif }