sync with sylpheed 0.4.66cvs6
[claws.git] / src / recv.c
index 9d27fb7f3647dc3e0cc422c7e149b38f491a9833..1a0e6b471f9c9d14349cd6d128f6df72af8f1ed0 100644 (file)
@@ -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
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/time.h>
 
 #include "intl.h"
 #include "recv.h"
@@ -100,20 +101,35 @@ gint recv_write(SockInfo *sock, FILE *fp)
 {
        gchar buf[BUFFSIZE];
        gint len;
-       gboolean nb;
+       gint bytes = 0;
+       struct timeval tv_prev, tv_cur;
 
-       nb = sock_is_nonblocking_mode(sock);
-       if (nb) sock_set_nonblocking_mode(sock, FALSE);
+       gettimeofday(&tv_prev, NULL);
 
        for (;;) {
-               if (sock_read(sock, buf, sizeof(buf)) < 0) {
+               if (sock_gets(sock, buf, sizeof(buf)) < 0) {
                        g_warning(_("error occurred while retrieving data.\n"));
-                       if (nb) sock_set_nonblocking_mode(sock, TRUE);
                        return -1;
                }
 
                len = strlen(buf);
-               if (len > 1 && buf[0] == '.' && buf[1] == '\r') break;
+               if (len > 1 && buf[0] == '.' && buf[1] == '\r') {
+                       if (recv_ui_func)
+                               recv_ui_func(sock, bytes, recv_ui_func_data);
+                       break;
+               }
+               bytes += len;
+
+               if (recv_ui_func) {
+                       gettimeofday(&tv_cur, NULL);
+                       /* if elapsed time from previous update is greater
+                          than 300 usec, update UI */
+                       if (tv_cur.tv_sec - tv_prev.tv_sec > 0 ||
+                           tv_cur.tv_usec - tv_prev.tv_usec > 500) {
+                               recv_ui_func(sock, bytes, recv_ui_func_data);
+                               gettimeofday(&tv_prev, NULL);
+                       }
+               }
 
                if (len > 1 && buf[len - 1] == '\n' && buf[len - 2] == '\r') {
                        buf[len - 2] = '\n';
@@ -127,9 +143,6 @@ gint recv_write(SockInfo *sock, FILE *fp)
                if (!strncmp(buf, ">From ", 6))
                        memmove(buf, buf + 1, len--);
 
-               if (recv_ui_func)
-                       recv_ui_func(sock, len, recv_ui_func_data);
-
                if (fp && fputs(buf, fp) == EOF) {
                        perror("fputs");
                        g_warning(_("Can't write to file.\n"));
@@ -137,8 +150,6 @@ gint recv_write(SockInfo *sock, FILE *fp)
                }
        }
 
-       if (nb) sock_set_nonblocking_mode(sock, TRUE);
-
        if (!fp) return -1;
 
        return 0;
@@ -147,51 +158,49 @@ gint recv_write(SockInfo *sock, FILE *fp)
 gint recv_bytes_write(SockInfo *sock, glong size, FILE *fp)
 {
        gchar *buf;
-       gboolean nb;
        glong count = 0;
        gchar *prev, *cur;
 
-       nb = sock_is_nonblocking_mode(sock);
-       if (nb) sock_set_nonblocking_mode(sock, FALSE);
-
        Xalloca(buf, size, return -1);
 
        do {
-               size_t read_count;
+               gint read_count;
 
-               /* FIXME: put this into socket.c :WK: */
-               read_count = fd_read(sock->sock, buf + count, size - count);
-               if (read_count < 0) {
-                       if (nb) sock_set_nonblocking_mode(sock, TRUE);
+               read_count = sock_read(sock, buf + count, size - count);
+               if (read_count < 0)
                        return -1;
-               }
                count += read_count;
        } while (count < size);
 
+       /* +------------------+----------------+--------------------------+ *
+        * ^buf               ^prev            ^cur             buf+size-1^ */
+
        prev = buf;
-       while ((cur = memchr(prev, '\r', size)) != NULL) {
-               if (cur - buf + 1 < size && *(cur + 1) == '\n') {
-                       if (fwrite(prev, sizeof(gchar), cur - prev, fp) == EOF ||
-                           fwrite("\n", sizeof(gchar), 1, fp) == EOF) {
-                               perror("fwrite");
-                               g_warning(_("Can't write to file.\n"));
-                               if (nb) sock_set_nonblocking_mode(sock, TRUE);
-                               return -1;
-                       }
-                       prev = cur + 2;
-                       if (prev - buf >= size) break;
+       while ((cur = memchr(prev, '\r', size - (prev - buf))) != NULL) {
+               if (cur == buf + size - 1) break;
+
+               if (fwrite(prev, sizeof(gchar), cur - prev, fp) == EOF ||
+                   fwrite("\n", sizeof(gchar), 1, fp) == EOF) {
+                       perror("fwrite");
+                       g_warning(_("Can't write to file.\n"));
+                       return -1;
                }
+
+               if (*(cur + 1) == '\n')
+                       prev = cur + 2;
+               else
+                       prev = cur + 1;
+
+               if (prev - buf >= size) break;
        }
 
        if (prev - buf < size && fwrite(buf, sizeof(gchar),
                                        size - (prev - buf), fp) == EOF) {
                perror("fwrite");
                g_warning(_("Can't write to file.\n"));
-               if (nb) sock_set_nonblocking_mode(sock, TRUE);
                return -1;
        }
 
-       if (nb) sock_set_nonblocking_mode(sock, TRUE);
        return 0;
 }