Properly handle a failure to create a partial directory, which is
[rsync/rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index 2cf72b1..fe6d0b9 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -66,6 +66,7 @@ extern int sanitize_paths;
 extern int munge_symlinks;
 extern int need_unsorted_flist;
 extern int output_needs_newline;
+extern int sender_keeps_checksum;
 extern int unsort_ndx;
 extern struct stats stats;
 extern char *filesfrom_host;
@@ -375,7 +376,7 @@ int change_pathname(struct file_struct *file, const char *dir, int dirlen)
        if (!change_dir(dir, CD_NORMAL)) {
          chdir_error:
                io_error |= IOERR_GENERAL;
-               rsyserr(FERROR, errno, "change_dir %s failed", full_fname(dir));
+               rsyserr(FERROR_XFER, errno, "change_dir %s failed", full_fname(dir));
                if (dir != orig_dir)
                        change_dir(orig_dir, CD_NORMAL);
                pathname = NULL;
@@ -399,7 +400,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
        static gid_t gid;
        static const char *user_name, *group_name;
        static char lastname[MAXPATHLEN];
+#ifdef SUPPORT_HARD_LINKS
        int first_hlink_ndx = -1;
+#endif
        int l1, l2;
        int xflags;
 
@@ -472,6 +475,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                                np->data = (void*)(long)(first_ndx + ndx + 1);
                                xflags |= XMIT_HLINK_FIRST;
                        }
+                       if (DEBUG_GTE(HLINK, 1)) {
+                               if (first_hlink_ndx >= 0) {
+                                       rprintf(FINFO, "[%s] #%d hard-links #%d (%sabbrev)\n",
+                                               who_am_i(), first_ndx + ndx, first_hlink_ndx,
+                                               first_hlink_ndx >= first_ndx ? "" : "un");
+                               } else if (DEBUG_GTE(HLINK, 3)) {
+                                       rprintf(FINFO, "[%s] dev:inode for #%d is %s:%s\n",
+                                               who_am_i(), first_ndx + ndx,
+                                               big_num(tmp_dev, 0), big_num(tmp_ino, 0));
+                               }
+                       }
                } else {
                        if (tmp_dev == dev) {
                                if (protocol_version >= 28)
@@ -518,11 +532,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                write_byte(f, l2);
        write_buf(f, fname + l1, l2);
 
+#ifdef SUPPORT_HARD_LINKS
        if (first_hlink_ndx >= 0) {
                write_varint(f, first_hlink_ndx);
                if (first_hlink_ndx >= first_ndx)
                        goto the_end;
        }
+#endif
 
        write_varlong30(f, F_LENGTH(file), 3);
        if (!(xflags & XMIT_SAME_TIME)) {
@@ -609,7 +625,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                write_buf(f, sum, checksum_len);
        }
 
+#ifdef SUPPORT_HARD_LINKS
   the_end:
+#endif
        strlcpy(lastname, fname, MAXPATHLEN);
 
        if (S_ISREG(mode) || S_ISLNK(mode))
@@ -671,11 +689,11 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
                xbuf outbuf, inbuf;
 
                INIT_CONST_XBUF(outbuf, thisname);
-               INIT_XBUF(inbuf, lastname, basename_len, -1);
+               INIT_XBUF(inbuf, lastname, basename_len, (size_t)-1);
 
                if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
                        io_error |= IOERR_GENERAL;
-                       rprintf(FINFO,
+                       rprintf(FERROR_XFER,
                            "[%s] cannot convert filename: %s (%s)\n",
                            who_am_i(), lastname, strerror(errno));
                        outbuf.len = 0;
@@ -713,6 +731,11 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
                                first_hlink_ndx, flist->ndx_start + flist->used);
                        exit_cleanup(RERR_PROTOCOL);
                }
+               if (DEBUG_GTE(HLINK, 1)) {
+                       rprintf(FINFO, "[%s] #%d hard-links #%d (%sabbrev)\n",
+                               who_am_i(), flist->used+flist->ndx_start, first_hlink_ndx,
+                               first_hlink_ndx >= flist->ndx_start ? "" : "un");
+               }
                if (first_hlink_ndx >= flist->ndx_start) {
                        struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
                        file_length = F_LENGTH(first);
@@ -1045,7 +1068,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
 
        if (strlcpy(thisname, fname, sizeof thisname) >= sizeof thisname) {
                io_error |= IOERR_GENERAL;
-               rprintf(FINFO, "skipping overly long name: %s\n", fname);
+               rprintf(FERROR_XFER, "skipping overly long name: %s\n", fname);
                return NULL;
        }
        clean_fname(thisname, 0);
@@ -1187,6 +1210,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                extra_len += EXTRA_LEN;
 #endif
 
+       if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
+               file_checksum(thisname, tmp_sum, st.st_size);
+               if (sender_keeps_checksum)
+                       extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
+       }
+
 #if EXTRA_ROUNDING > 0
        if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
                extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
@@ -1213,8 +1242,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                if (protocol_version >= 28
                 ? (!S_ISDIR(st.st_mode) && st.st_nlink > 1)
                 : S_ISREG(st.st_mode)) {
-                       tmp_dev = st.st_dev;
-                       tmp_ino = st.st_ino;
+                       tmp_dev = (int64)st.st_dev + 1;
+                       tmp_ino = (int64)st.st_ino;
                } else
                        tmp_dev = 0;
        }
@@ -1250,9 +1279,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                memcpy(bp + basename_len, linkname, linkname_len);
 #endif
 
-       if (always_checksum && am_sender && S_ISREG(st.st_mode))
-               file_checksum(thisname, tmp_sum, st.st_size);
-
        if (am_sender)
                F_PATHNAME(file) = pathname;
        else if (!pool)
@@ -1283,6 +1309,9 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                return NULL;
        }
 
+       if (sender_keeps_checksum && S_ISREG(st.st_mode))
+               memcpy(F_SUM(file), tmp_sum, checksum_len);
+
        if (unsort_ndx)
                F_NDX(file) = dir_count;
 
@@ -1333,7 +1362,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
                        if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
                          convert_error:
                                io_error |= IOERR_GENERAL;
-                               rprintf(FINFO,
+                               rprintf(FERROR_XFER,
                                    "[%s] cannot convert filename: %s (%s)\n",
                                    who_am_i(), f_name(file, fbuf), strerror(errno));
                                return NULL;
@@ -1558,14 +1587,14 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
                        continue;
                if (strlcpy(p, dname, remainder) >= remainder) {
                        io_error |= IOERR_GENERAL;
-                       rprintf(FINFO,
+                       rprintf(FERROR_XFER,
                                "cannot send long-named file %s\n",
                                full_fname(fbuf));
                        continue;
                }
                if (dname[0] == '\0') {
                        io_error |= IOERR_GENERAL;
-                       rprintf(FINFO,
+                       rprintf(FERROR_XFER,
                                "cannot send file with empty name in %s\n",
                                full_fname(fbuf));
                        continue;
@@ -2188,12 +2217,13 @@ struct file_list *recv_file_list(int f)
        int dstart, flags;
        int64 start_read;
 
-       if (!first_flist)
+       if (!first_flist) {
+               if (show_filelist_p())
+                       start_filelist_progress("receiving file list");
+               else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
+                       rprintf(FCLIENT, "receiving incremental file list\n");
                rprintf(FLOG, "receiving file list\n");
-       if (show_filelist_p())
-               start_filelist_progress("receiving file list");
-       else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server && !first_flist)
-               rprintf(FCLIENT, "receiving incremental file list\n");
+       }
 
        start_read = stats.total_read;
 
@@ -2408,14 +2438,16 @@ struct file_list *flist_new(int flags, char *msg)
 
        if (flags & FLIST_TEMP) {
                if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
-                                               out_of_memory, POOL_INTERN)))
+                                                    out_of_memory,
+                                                    POOL_INTERN)))
                        out_of_memory(msg);
        } else {
                /* This is a doubly linked list with prev looping back to
                 * the end of the list, but the last next pointer is NULL. */
                if (!first_flist) {
                        flist->file_pool = pool_create(NORMAL_EXTENT, 0,
-                                               out_of_memory, POOL_INTERN);
+                                                      out_of_memory,
+                                                      POOL_INTERN);
                        if (!flist->file_pool)
                                out_of_memory(msg);