When using --iconv, if a server-side receiver can't convert a filename,
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index ce675d2..2756b14 100644 (file)
--- a/io.c
+++ b/io.c
@@ -36,7 +36,6 @@
 extern int bwlimit;
 extern size_t bwlimit_writemax;
 extern int io_timeout;
-extern int allowed_lull;
 extern int am_server;
 extern int am_daemon;
 extern int am_sender;
@@ -47,7 +46,6 @@ extern int eol_nulls;
 extern int flist_eof;
 extern int list_only;
 extern int read_batch;
-extern int csum_length;
 extern int protect_args;
 extern int checksum_seed;
 extern int protocol_version;
@@ -60,10 +58,12 @@ extern int filesfrom_convert;
 extern iconv_t ic_send, ic_recv;
 #endif
 
-const char phase_unknown[] = "unknown";
+int csum_length = SHORT_SUM_LENGTH; /* initial value */
+int allowed_lull = 0;
 int ignore_timeout = 0;
 int batch_fd = -1;
 int msgdone_cnt = 0;
+int check_for_io_err = 0;
 
 /* Ignore an EOF error if non-zero. See whine_about_eof(). */
 int kluge_around_eof = 0;
@@ -352,8 +352,7 @@ static void check_for_d_option_error(const char *msg)
 
        if (saw_d) {
                rprintf(FWARNING,
-                       "*** Try adding \"-r --exclude='/*/*'\" "
-                       "if remote rsync is <= 2.6.3 ***\n");
+                   "*** Try using \"--old-d\" if remote rsync is <= 2.6.3 ***\n");
        }
 }
 
@@ -381,6 +380,8 @@ static void read_msg_fd(void)
        len = tag & 0xFFFFFF;
        tag = (tag >> 24) - MPLEX_BASE;
 
+       check_for_io_err = 0;
+
        switch (tag) {
        case MSG_DONE:
                if (len < 0 || len > 1 || !am_generator) {
@@ -409,12 +410,15 @@ static void read_msg_fd(void)
                /* Read extra file list from receiver. */
                assert(iobuf_in != NULL);
                assert(iobuf_f_in == fd);
-               if (verbose > 3) {
+               if (DEBUG_GTE(FLIST, 2)) {
                        rprintf(FINFO, "[%s] receiving flist for dir %d\n",
                                who_am_i(), IVAL(buf,0));
                }
                flist = recv_file_list(fd);
                flist->parent_ndx = IVAL(buf,0);
+               /* If the sender is going to send us an MSG_IO_ERROR value, it
+                * will always be the very next message following MSG_FLIST. */
+               check_for_io_err = 1;
 #ifdef SUPPORT_HARD_LINKS
                if (preserve_hard_links)
                        match_hard_links(flist);
@@ -450,6 +454,7 @@ static void read_msg_fd(void)
                got_flist_entry_status(FES_NO_SEND, buf);
                break;
        case MSG_ERROR_SOCKET:
+       case MSG_ERROR_UTF8:
        case MSG_CLIENT:
                if (!am_generator)
                        goto invalid_msg;
@@ -513,7 +518,7 @@ static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len,
                xbuf outbuf, inbuf;
 
                INIT_XBUF(outbuf, buffer + 4, 0, sizeof buffer - 4);
-               INIT_XBUF(inbuf, (char*)buf, len, -1);
+               INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1);
 
                iconvbufs(ic_send, &inbuf, &outbuf,
                          ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
@@ -630,8 +635,8 @@ static void whine_about_eof(int fd)
        }
 
        rprintf(FERROR, RSYNC_NAME ": connection unexpectedly closed "
-               "(%.0f bytes received so far) [%s]\n",
-               (double)stats.total_read, who_am_i());
+               "(%s bytes received so far) [%s]\n",
+               big_num(stats.total_read, 0), who_am_i());
 
        exit_cleanup(RERR_STREAMIO);
 }
@@ -874,8 +879,8 @@ int read_line(int fd, char *buf, size_t bufsiz, int flags)
        return s - buf;
 }
 
-int read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
-             char ***argv_p, int *argc_p, char **request_p)
+void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
+              char ***argv_p, int *argc_p, char **request_p)
 {
        int maxargs = MAX_ARGS;
        int dot_pos = 0;
@@ -889,14 +894,14 @@ int read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
 
        if (!(argv = new_array(char *, maxargs)))
                out_of_memory("read_args");
-       if (mod_name)
+       if (mod_name && !protect_args)
                argv[argc++] = "rsyncd";
 
        while (1) {
                if (read_line(f_in, buf, bufsiz, rl_flags) == 0)
                        break;
 
-               if (argc == maxargs) {
+               if (argc == maxargs-1) {
                        maxargs += MAX_ARGS;
                        if (!(argv = realloc_array(argv, char *, maxargs)))
                                out_of_memory("read_args");
@@ -919,11 +924,12 @@ int read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
                                dot_pos = argc;
                }
        }
+       argv[argc] = NULL;
+
+       glob_expand(NULL, NULL, NULL, NULL);
 
        *argc_p = argc;
        *argv_p = argv;
-
-       return dot_pos ? dot_pos : argc;
 }
 
 int io_start_buffering_out(int f_out)
@@ -1061,6 +1067,8 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
                msg_bytes = tag & 0xFFFFFF;
                tag = (tag >> 24) - MPLEX_BASE;
 
+               check_for_io_err = 0;
+
                switch (tag) {
                case MSG_DATA:
                        if (msg_bytes > iobuf_in_siz) {
@@ -1092,10 +1100,9 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
                                xbuf outbuf, inbuf;
                                char ibuf[512];
                                int add_null = 0;
-                               int pos = 0;
 
                                INIT_CONST_XBUF(outbuf, line);
-                               INIT_XBUF(inbuf, ibuf, 0, -1);
+                               INIT_XBUF(inbuf, ibuf, 0, (size_t)-1);
 
                                while (msg_bytes) {
                                        inbuf.len = msg_bytes > sizeof ibuf
@@ -1107,7 +1114,6 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
                                        if (iconvbufs(ic_send, &inbuf, &outbuf,
                                            ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE) < 0)
                                                goto overflow;
-                                       pos = -1;
                                }
                                if (add_null) {
                                        if (outbuf.len == outbuf.size)
@@ -1354,6 +1360,7 @@ int read_vstring(int f, char *buf, int bufsize)
  * called by both the sender and the receiver. */
 void read_sum_head(int f, struct sum_struct *sum)
 {
+       int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
        sum->count = read_int(f);
        if (sum->count < 0) {
                rprintf(FERROR, "Invalid checksum count %ld [%s]\n",
@@ -1361,7 +1368,7 @@ void read_sum_head(int f, struct sum_struct *sum)
                exit_cleanup(RERR_PROTOCOL);
        }
        sum->blength = read_int(f);
-       if (sum->blength < 0 || sum->blength > MAX_BLOCK_SIZE) {
+       if (sum->blength < 0 || sum->blength > max_blength) {
                rprintf(FERROR, "Invalid block length %ld [%s]\n",
                        (long)sum->blength, who_am_i());
                exit_cleanup(RERR_PROTOCOL);