sync with sylpheed 0.6.3 release
[claws.git] / src / pop.c
index e20d70d36621e084c3975b8b441dc99786facb04..ab4de2562b1a97a94287c56b7ede35af9be67a4c 100644 (file)
--- a/src/pop.c
+++ b/src/pop.c
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,10 +71,16 @@ gint pop3_getauth_user_send(SockInfo *sock, gpointer data)
 
 gint pop3_getauth_user_recv(SockInfo *sock, gpointer data)
 {
+       Pop3State *state = (Pop3State *)data;
+
        if (pop3_ok(sock, NULL) == PS_SUCCESS)
                return POP3_GETAUTH_PASS_SEND;
-       else
+       else {
+               log_warning(_("error occurred on authentication\n"));
+               state->error_val = PS_AUTHFAIL;
+               state->inc_state = INC_AUTH_FAILED;
                return -1;
+       }
 }
 
 gint pop3_getauth_pass_send(SockInfo *sock, gpointer data)
@@ -95,8 +101,9 @@ gint pop3_getauth_pass_recv(SockInfo *sock, gpointer data)
        if (pop3_ok(sock, NULL) == PS_SUCCESS)
                return POP3_GETRANGE_STAT_SEND;
        else {
-               log_warning(_("error occurred on authorization\n"));
+               log_warning(_("error occurred on authentication\n"));
                state->error_val = PS_AUTHFAIL;
+               state->inc_state = INC_AUTH_FAILED;
                return -1;
        }
 }
@@ -142,8 +149,9 @@ gint pop3_getauth_apop_recv(SockInfo *sock, gpointer data)
        if (pop3_ok(sock, NULL) == PS_SUCCESS)
                return POP3_GETRANGE_STAT_SEND;
        else {
-               log_warning(_("error occurred on authorization\n"));
+               log_warning(_("error occurred on authentication\n"));
                state->error_val = PS_AUTHFAIL;
+               state->inc_state = INC_AUTH_FAILED;
                return -1;
        }
 }
@@ -166,7 +174,8 @@ gint pop3_getrange_stat_recv(SockInfo *sock, gpointer data)
        gint ok;
 
        if ((ok = pop3_ok(sock, buf)) == PS_SUCCESS) {
-               if (sscanf(buf, "%d %d", &state->count, &state->bytes) != 2) {
+               if (sscanf(buf, "%d %d", &state->count, &state->total_bytes)
+                   != 2) {
                        log_warning(_("POP3 protocol error\n"));
                        return -1;
                } else {
@@ -177,7 +186,7 @@ gint pop3_getrange_stat_recv(SockInfo *sock, gpointer data)
                                state->new = state->count;
                                if (state->ac_prefs->rmmail ||
                                    state->ac_prefs->getall)
-                                       return POP3_RETR_SEND;
+                                       return POP3_GETSIZE_LIST_SEND;
                                else
                                        return POP3_GETRANGE_UIDL_SEND;
                        }
@@ -190,6 +199,10 @@ gint pop3_getrange_stat_recv(SockInfo *sock, gpointer data)
 
 gint pop3_getrange_last_send(SockInfo *sock, gpointer data)
 {
+       Pop3State *state = (Pop3State *)data;
+
+       inc_progress_update(state, POP3_GETRANGE_LAST_SEND);
+
        pop3_gen_send(sock, "LAST");
 
        return POP3_GETRANGE_LAST_RECV;
@@ -212,15 +225,19 @@ gint pop3_getrange_last_recv(SockInfo *sock, gpointer data)
                        else {
                                state->new = state->count - last;
                                state->cur_msg = last + 1;
-                               return POP3_RETR_SEND;
+                               return POP3_GETSIZE_LIST_SEND;
                        }
                }
        } else
-               return POP3_RETR_SEND;
+               return POP3_GETSIZE_LIST_SEND;
 }
 
 gint pop3_getrange_uidl_send(SockInfo *sock, gpointer data)
 {
+       Pop3State *state = (Pop3State *)data;
+
+       inc_progress_update(state, POP3_GETRANGE_UIDL_SEND);
+
        pop3_gen_send(sock, "UIDL");
 
        return POP3_GETRANGE_UIDL_RECV;
@@ -229,7 +246,6 @@ gint pop3_getrange_uidl_send(SockInfo *sock, gpointer data)
 gint pop3_getrange_uidl_recv(SockInfo *sock, gpointer data)
 {
        Pop3State *state = (Pop3State *)data;
-       gboolean nb;
        gboolean new = FALSE;
        gchar buf[POPBUFSIZE];
        gchar id[IDLEN + 1];
@@ -238,10 +254,7 @@ gint pop3_getrange_uidl_recv(SockInfo *sock, gpointer data)
 
        if (!state->id_table) new = TRUE;
 
-       nb = sock_is_nonblocking_mode(sock);
-       if (nb && (sock_set_nonblocking_mode(sock, FALSE) < 0)) return -1;
-
-       while (sock_read(sock, buf, sizeof(buf)) >= 0) {
+       while (sock_gets(sock, buf, sizeof(buf)) >= 0) {
                gint num;
 
                if (buf[0] == '.') break;
@@ -263,14 +276,56 @@ gint pop3_getrange_uidl_recv(SockInfo *sock, gpointer data)
                                (state->id_list, g_strdup(id));
        }
 
-       if (nb && (sock_set_nonblocking_mode(sock, TRUE) < 0)) return -1;
-
        if (new == TRUE)
-               return POP3_RETR_SEND;
+               return POP3_GETSIZE_LIST_SEND;
        else
                return POP3_LOGOUT_SEND;
 }
 
+gint pop3_getsize_list_send(SockInfo *sock, gpointer data)
+{
+       Pop3State *state = (Pop3State *)data;
+
+       inc_progress_update(state, POP3_GETSIZE_LIST_SEND);
+
+       pop3_gen_send(sock, "LIST");
+
+       return POP3_GETSIZE_LIST_RECV;
+}
+
+gint pop3_getsize_list_recv(SockInfo *sock, gpointer data)
+{
+       Pop3State *state = (Pop3State *)data;
+       gchar buf[POPBUFSIZE];
+
+       if (pop3_ok(sock, NULL) != PS_SUCCESS) return POP3_LOGOUT_SEND;
+
+       state->sizes = g_new0(gint, state->count + 1);
+       state->cur_total_bytes = 0;
+
+       while (sock_gets(sock, buf, sizeof(buf)) >= 0) {
+               guint num, size;
+
+               if (buf[0] == '.') break;
+               if (sscanf(buf, "%u %u", &num, &size) != 2)
+                       return -1;
+
+               if (num > 0 && num <= state->count)
+                       state->sizes[num] = size;
+               if (num > 0 && num < state->cur_msg)
+                       state->cur_total_bytes += size;
+       }
+
+       while (state->sizes[state->cur_msg] == 0) {
+               if (state->cur_msg == state->count)
+                       return POP3_LOGOUT_SEND;
+               else
+                       state->cur_msg++;
+       }
+
+       return POP3_RETR_SEND;
+}
+
 gint pop3_retr_send(SockInfo *sock, gpointer data)
 {
        Pop3State *state = (Pop3State *)data;
@@ -293,10 +348,15 @@ gint pop3_retr_recv(SockInfo *sock, gpointer data)
                        state->inc_state = INC_NOSPACE;
                        return -1;
                }
+
                if ((drop_ok = inc_drop_message(file, state)) < 0) {
                        state->inc_state = INC_ERROR;
                        return -1;
                }
+
+               state->cur_total_bytes += state->sizes[state->cur_msg];
+               state->cur_total_num++;
+
                if (drop_ok == 0 && state->ac_prefs->rmmail)
                        return POP3_DELETE_SEND;
 
@@ -310,6 +370,12 @@ gint pop3_retr_recv(SockInfo *sock, gpointer data)
 
                if (state->cur_msg < state->count) {
                        state->cur_msg++;
+                       while (state->sizes[state->cur_msg] == 0) {
+                               if (state->cur_msg == state->count)
+                                       return POP3_LOGOUT_SEND;
+                               else
+                                       state->cur_msg++;
+                       }
                        return POP3_RETR_SEND;
                } else
                        return POP3_LOGOUT_SEND;
@@ -323,7 +389,7 @@ gint pop3_delete_send(SockInfo *sock, gpointer data)
 {
        Pop3State *state = (Pop3State *)data;
 
-       //inc_progress_update(state, POP3_DELETE_SEND);
+       /*inc_progress_update(state, POP3_DELETE_SEND);*/
 
        pop3_gen_send(sock, "DELE %d", state->cur_msg);
 
@@ -338,6 +404,12 @@ gint pop3_delete_recv(SockInfo *sock, gpointer data)
        if ((ok = pop3_ok(sock, NULL)) == PS_SUCCESS) {
                if (state->cur_msg < state->count) {
                        state->cur_msg++;
+                       while (state->sizes[state->cur_msg] == 0) {
+                               if (state->cur_msg == state->count)
+                                       return POP3_LOGOUT_SEND;
+                               else
+                                       state->cur_msg++;
+                       }
                        return POP3_RETR_SEND;
                } else
                        return POP3_LOGOUT_SEND;
@@ -428,19 +500,11 @@ static void pop3_gen_send(SockInfo *sock, const gchar *format, ...)
 
 static gint pop3_gen_recv(SockInfo *sock, gchar *buf, gint size)
 {
-       gboolean nb;
-
-       nb = sock_is_nonblocking_mode(sock);
-
-       if (nb && (sock_set_nonblocking_mode(sock, FALSE) < 0))
-               return PS_SOCKET;
-       if (sock_read(sock, buf, size) < 0) {
+       if (sock_gets(sock, buf, size) < 0) {
                return PS_SOCKET;
        } else {
                strretchomp(buf);
                log_print("POP3< %s\n", buf);
-               if (nb && (sock_set_nonblocking_mode(sock, TRUE) < 0))
-                       return PS_SOCKET;
 
                return PS_SUCCESS;
        }