Clean generated files for distclean.
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index 1899cb9..afe837f 100644 (file)
--- a/io.c
+++ b/io.c
@@ -28,6 +28,7 @@
  * io_start_multiplex_out() and io_start_multiplex_in(). */
 
 #include "rsync.h"
+#include "ifuncs.h"
 
 /** If no timeout is specified then use a 60 second select timeout */
 #define SELECT_TIMEOUT 60
@@ -52,7 +53,7 @@ extern int protocol_version;
 extern int remove_source_files;
 extern int preserve_hard_links;
 extern struct stats stats;
-extern struct file_list *cur_flist, *first_flist;
+extern struct file_list *cur_flist;
 #ifdef ICONV_OPTION
 extern int filesfrom_convert;
 extern iconv_t ic_send, ic_recv;
@@ -99,7 +100,7 @@ static char ff_lastchar;
 #ifdef ICONV_OPTION
 static xbuf iconv_buf = EMPTY_XBUF;
 #endif
-static int defer_forwarding_messages = 0;
+static int defer_forwarding_messages = 0, defer_forwarding_keep = 0;
 static int select_timeout = SELECT_TIMEOUT;
 static int active_filecnt = 0;
 static OFF_T active_bytecnt = 0;
@@ -180,7 +181,6 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
        struct file_list *flist = flist_for_ndx(ndx);
 
        assert(flist != NULL);
-       assert(ndx >= flist->ndx_start);
 
        if (remove_source_files) {
                active_filecnt--;
@@ -196,8 +196,10 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
                        send_msg(MSG_SUCCESS, buf, 4, 0);
                if (preserve_hard_links) {
                        struct file_struct *file = flist->files[ndx - flist->ndx_start];
-                       if (F_IS_HLINKED(file))
+                       if (F_IS_HLINKED(file)) {
                                flist_ndx_push(&hlink_list, ndx);
+                               flist->in_progress++;
+                       }
                }
                break;
        case FES_REDO:
@@ -387,6 +389,12 @@ static void read_msg_fd(void)
                        goto invalid_msg;
                flist_eof = 1;
                break;
+       case MSG_IO_ERROR:
+               if (len != 4)
+                       goto invalid_msg;
+               readfd(fd, buf, len);
+               io_error |= IVAL(buf, 0);
+               break;
        case MSG_DELETED:
                if (len >= (int)sizeof buf || !am_generator)
                        goto invalid_msg;
@@ -432,7 +440,7 @@ static void read_msg_fd(void)
 
        no_flush--;
        msg_fd_in = fd;
-       if (!--defer_forwarding_messages)
+       if (!--defer_forwarding_messages && !no_flush)
                msg_flush();
 }
 
@@ -472,7 +480,9 @@ static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len,
        else
                memcpy(buffer + 4, buf, n);
 
+       defer_forwarding_keep = 1; /* defer_forwarding_messages++ on return */
        writefd_unbuffered(fd, buffer, n+4);
+       defer_forwarding_keep = 0;
 
        len -= n;
        buf += n;
@@ -484,22 +494,18 @@ static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len,
                INIT_CONST_XBUF(outbuf, buffer);
                INIT_XBUF(inbuf, (char*)buf, len, -1);
 
-               defer_forwarding_messages++;
                do {
                        iconvbufs(ic_send, &inbuf, &outbuf,
                                  ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
                        writefd_unbuffered(fd, outbuf.buf, outbuf.len);
                } while (inbuf.len);
-               if (!--defer_forwarding_messages)
-                       msg_flush();
        } else
 #endif
-       if (len) {
-               defer_forwarding_messages++;
+       if (len)
                writefd_unbuffered(fd, buf, len);
-               if (!--defer_forwarding_messages)
-                       msg_flush();
-       }
+
+       if (!--defer_forwarding_messages && !no_flush)
+               msg_flush();
 }
 
 int send_msg(enum msgcode code, const char *buf, int len, int convert)
@@ -674,7 +680,11 @@ static int read_timeout(int fd, char *buf, size_t len)
                                }
                        } else if (io_filesfrom_f_in >= 0) {
                                if (FD_ISSET(io_filesfrom_f_in, &r_fds)) {
+#ifdef ICONV_OPTION
                                        xbuf *ibuf = filesfrom_convert ? &iconv_buf : &ff_buf;
+#else
+                                       xbuf *ibuf = &ff_buf;
+#endif
                                        int l = read(io_filesfrom_f_in, ibuf->buf, ibuf->size);
                                        if (l <= 0) {
                                                if (l == 0 || errno != EINTR) {
@@ -685,6 +695,7 @@ static int read_timeout(int fd, char *buf, size_t len)
                                                        io_filesfrom_f_in = -1;
                                                }
                                        } else {
+#ifdef ICONV_OPTION
                                                if (filesfrom_convert) {
                                                        iconv_buf.pos = 0;
                                                        iconv_buf.len = l;
@@ -692,6 +703,7 @@ static int read_timeout(int fd, char *buf, size_t len)
                                                            ICB_EXPAND_OUT|ICB_INCLUDE_BAD|ICB_INCLUDE_INCOMPLETE);
                                                        l = ff_buf.len;
                                                }
+#endif
                                                if (!eol_nulls) {
                                                        char *s = ff_buf.buf + l;
                                                        /* Transform CR and/or LF into '\0' */
@@ -771,7 +783,11 @@ int read_line(int fd, char *buf, size_t bufsiz, int flags)
 #endif
 
   start:
+#ifdef ICONV_OPTION
        s = flags & RL_CONVERT ? iconv_buf.buf : buf;
+#else
+       s = buf;
+#endif
        eob = s + bufsiz - 1;
        while (1) {
                cnt = read(fd, &ch, 1);
@@ -830,8 +846,11 @@ int read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
        int dot_pos = 0;
        int argc = 0;
        char **argv, *p;
-       int rl_flags = (rl_nulls ? RL_EOL_NULLS : 0)
-                    | (protect_args && ic_recv != (iconv_t)-1 ? RL_CONVERT : 0);
+       int rl_flags = (rl_nulls ? RL_EOL_NULLS : 0);
+
+#ifdef ICONV_OPTION
+       rl_flags |= (protect_args && ic_recv != (iconv_t)-1 ? RL_CONVERT : 0);
+#endif
 
        if (!(argv = new_array(char *, maxargs)))
                out_of_memory("read_args");
@@ -1027,6 +1046,7 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
                        if (msg_bytes != 4)
                                goto invalid_msg;
                        read_loop(fd, line, msg_bytes);
+                       send_msg_int(MSG_IO_ERROR, IVAL(line, 0));
                        io_error |= IVAL(line, 0);
                        break;
                case MSG_DELETED:
@@ -1490,7 +1510,8 @@ static void writefd_unbuffered(int fd, const char *buf, size_t len)
        }
 
        no_flush--;
-       if (!(defer_forwarding_messages -= defer_inc))
+       defer_inc -= defer_forwarding_keep;
+       if (!(defer_forwarding_messages -= defer_inc) && !no_flush)
                msg_flush();
 }
 
@@ -1840,6 +1861,8 @@ void start_write_batch(int fd)
         * actual communication so far depends on whether a daemon
         * is involved. */
        write_int(batch_fd, protocol_version);
+       if (protocol_version >= 30)
+               write_byte(batch_fd, inc_recurse);
        write_int(batch_fd, checksum_seed);
 
        if (am_sender)