return POP3_GETAUTH_APOP_SEND;
else
return POP3_GETAUTH_USER_SEND;
- } else
+ } else {
+ state->inc_state = INC_ERROR;
return -1;
+ }
}
#if USE_SSL
gint ok;
if ((ok = pop3_ok(sock, NULL)) == PS_SUCCESS) {
- if (!ssl_init_socket_with_method(sock, SSL_METHOD_TLSv1))
+ if (!ssl_init_socket_with_method(sock, SSL_METHOD_TLSv1)) {
+ state->error_val = PS_SOCKET;
+ state->inc_state = INC_ERROR;
return -1;
+ }
if (state->ac_prefs->protocol == A_APOP)
return POP3_GETAUTH_APOP_SEND;
else
state->error_val = PS_PROTOCOL;
state->inc_state = INC_ERROR;
return POP3_LOGOUT_SEND;
- } else
+ } else {
+ state->inc_state = INC_ERROR;
return -1;
+ }
}
#endif /* USE_SSL */
if ((start = strchr(state->greeting, '<')) == NULL) {
log_warning(_("Required APOP timestamp not found "
"in greeting\n"));
+ state->error_val = PS_PROTOCOL;
+ state->inc_state = INC_ERROR;
return -1;
}
if ((end = strchr(start, '>')) == NULL || end == start + 1) {
log_warning(_("Timestamp syntax error in greeting\n"));
+ state->error_val = PS_PROTOCOL;
+ state->inc_state = INC_ERROR;
return -1;
}
if (sscanf(buf, "%d %d", &state->count, &state->total_bytes)
!= 2) {
log_warning(_("POP3 protocol error\n"));
+ state->error_val = PS_PROTOCOL;
+ state->inc_state = INC_ERROR;
return -1;
} else {
if (state->count == 0) {
return POP3_GETRANGE_UIDL_SEND;
}
}
- } else if (ok == PS_PROTOCOL)
+ } else if (ok == PS_PROTOCOL) {
return POP3_LOGOUT_SEND;
- else
+ } else {
+ state->inc_state = INC_ERROR;
return -1;
+ }
}
gint pop3_getrange_last_send(SockInfo *sock, gpointer data)
if (sscanf(buf, "%d", &last) == 0) {
log_warning(_("POP3 protocol error\n"));
+ state->error_val = PS_PROTOCOL;
+ state->inc_state = INC_ERROR;
return -1;
} else {
if (state->count == last)
gboolean get_all = FALSE;
gchar buf[POPBUFSIZE];
gchar id[IDLEN + 1];
+ gint len;
gint next_state;
if (!state->uidl_table) new = TRUE;
return POP3_GETSIZE_LIST_SEND;
}
- while (sock_gets(sock, buf, sizeof(buf)) >= 0) {
+ while ((len = sock_gets(sock, buf, sizeof(buf))) > 0) {
gint num;
time_t recv_time;
}
}
- state->uidl_is_valid = TRUE;
+ if (len < 0) {
+ log_error(_("Socket error\n"));
+ state->error_val = PS_SOCKET;
+ state->inc_state = INC_ERROR;
+ return -1;
+ }
+ state->uidl_is_valid = TRUE;
if (pop3_sd_state(state, POP3_GETRANGE_UIDL_RECV, &next_state))
return next_state;
{
Pop3State *state = (Pop3State *)data;
gchar buf[POPBUFSIZE];
+ gint len;
gint next_state;
if (pop3_ok(sock, NULL) != PS_SUCCESS) return POP3_LOGOUT_SEND;
state->cur_total_bytes = 0;
- while (sock_gets(sock, buf, sizeof(buf)) >= 0) {
+ while ((len = sock_gets(sock, buf, sizeof(buf))) > 0) {
guint num, size;
if (buf[0] == '.') break;
- if (sscanf(buf, "%u %u", &num, &size) != 2)
+ if (sscanf(buf, "%u %u", &num, &size) != 2) {
+ state->error_val = PS_PROTOCOL;
+ state->inc_state = INC_ERROR;
return -1;
+ }
if (num > 0 && num <= state->count)
state->msg[num].size = size;
state->cur_total_bytes += size;
}
+ if (len < 0) {
+ log_error(_("Socket error\n"));
+ state->error_val = PS_SOCKET;
+ state->inc_state = INC_ERROR;
+ return -1;
+ }
+
if (pop3_sd_state(state, POP3_GETSIZE_LIST_RECV, &next_state))
return next_state;
- LOOKUP_NEXT_MSG();
+ LOOKUP_NEXT_MSG();
return POP3_RETR_SEND;
}
return POP3_RETR_SEND;
} else
return POP3_LOGOUT_SEND;
- } else if (ok == PS_PROTOCOL)
+ } else if (ok == PS_PROTOCOL) {
return POP3_LOGOUT_SEND;
- else
+ } else {
+ state->inc_state = INC_ERROR;
return -1;
+ }
}
gint pop3_delete_send(SockInfo *sock, gpointer data)
gint ok;
if ((ok = pop3_ok(sock, NULL)) == PS_SUCCESS) {
-
state->msg[state->cur_msg].deleted = TRUE;
if (pop3_sd_state(state, POP3_DELETE_RECV, &next_state))
return POP3_RETR_SEND;
} else
return POP3_LOGOUT_SEND;
- } else if (ok == PS_PROTOCOL)
+ } else if (ok == PS_PROTOCOL) {
return POP3_LOGOUT_SEND;
- else
+ } else {
+ state->inc_state = INC_ERROR;
return -1;
+ }
}
gint pop3_logout_send(SockInfo *sock, gpointer data)
gint pop3_logout_recv(SockInfo *sock, gpointer data)
{
- if (pop3_ok(sock, NULL) == PS_SUCCESS)
- return -1;
- else
- return -1;
+ Pop3State *state = (Pop3State *)data;
+
+ if (pop3_ok(sock, NULL) != PS_SUCCESS)
+ state->inc_state = INC_ERROR;
+
+ return -1;
}
static gint pop3_ok(SockInfo *sock, gchar *argbuf)
#include <errno.h>
#include <signal.h>
#include <setjmp.h>
+#if HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
#include "socket.h"
#include "utils.h"
#endif
#define BUFFSIZE 8192
+#define IO_TIMEOUT 60
static gint sock_connect_with_timeout (gint sock,
const struct sockaddr *serv_addr,
return is_nonblocking_mode(sock->sock);
}
+static gint fd_check_io(gint fd, GIOCondition cond)
+{
+ struct timeval timeout;
+ fd_set fds;
+
+ timeout.tv_sec = IO_TIMEOUT;
+ timeout.tv_usec = 0;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ if (cond == G_IO_IN) {
+ select(fd + 1, &fds, NULL, NULL, &timeout);
+ } else {
+ select(fd + 1, NULL, &fds, NULL, &timeout);
+ }
+
+ if (FD_ISSET(fd, &fds)) {
+ return 0;
+ } else {
+ g_warning("Socket IO timeout\n");
+ return -1;
+ }
+}
+
static sigjmp_buf jmpenv;
static void timeout_handler(gint sig)
{
struct hostent *hp;
struct sockaddr_in ad;
- guint timeout_secs = 30;
+ guint timeout_secs = IO_TIMEOUT;
memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;
{
gint sock = -1, gai_error;
struct addrinfo hints, *res, *ai;
- guint timeout_secs = 30;
+ guint timeout_secs = IO_TIMEOUT;
gchar port_str[6];
memset(&hints, 0, sizeof(hints));
gint fd_read(gint fd, gchar *buf, gint len)
{
+ if (fd_check_io(fd, G_IO_IN) < 0)
+ return -1;
+
return read(fd, buf, len);
}
gint n, wrlen = 0;
while (len) {
+ if (fd_check_io(fd, G_IO_OUT) < 0)
+ return -1;
signal(SIGPIPE, SIG_IGN);
n = write(fd, buf, len);
if (n <= 0) {
}
#endif
+gint fd_recv(gint fd, gchar *buf, gint len, gint flags)
+{
+ if (fd_check_io(fd, G_IO_IN) < 0)
+ return -1;
+
+ return recv(fd, buf, len, flags);
+}
+
gint fd_gets(gint fd, gchar *buf, gint len)
{
gchar *newline, *bp = buf;
if (--len < 1)
return -1;
do {
- if ((n = recv(fd, bp, len, MSG_PEEK)) <= 0)
+ if ((n = fd_recv(fd, bp, len, MSG_PEEK)) <= 0)
return -1;
if ((newline = memchr(bp, '\n', n)) != NULL)
n = newline - bp + 1;
- if ((n = read(fd, bp, n)) < 0)
+ if ((n = fd_read(fd, bp, n)) < 0)
return -1;
bp += n;
len -= n;