Changed F_ROOTDIR() to F_PATHNAME().
[rsync/rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index eda6d99..a4f3ca2 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -30,6 +30,7 @@ extern int am_root;
 extern int am_server;
 extern int am_daemon;
 extern int am_sender;
+extern int am_generator;
 extern int inc_recurse;
 extern int do_progress;
 extern int always_checksum;
@@ -196,12 +197,12 @@ static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf)
                                rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
                                        path, linkbuf);
                        }
-                       return do_stat(path, stp);
+                       return x_stat(path, stp, NULL);
                }
        }
        return 0;
 #else
-       return do_stat(path, stp);
+       return x_stat(path, stp, NULL);
 #endif
 }
 
@@ -209,17 +210,17 @@ int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
 {
 #ifdef SUPPORT_LINKS
        if (copy_links)
-               return do_stat(path, stp);
-       if (do_lstat(path, stp) < 0)
+               return x_stat(path, stp, NULL);
+       if (x_lstat(path, stp, NULL) < 0)
                return -1;
        if (follow_dirlinks && S_ISLNK(stp->st_mode)) {
                STRUCT_STAT st;
-               if (do_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
+               if (x_stat(path, &st, NULL) == 0 && S_ISDIR(st.st_mode))
                        *stp = st;
        }
        return 0;
 #else
-       return do_stat(path, stp);
+       return x_stat(path, stp, NULL);
 #endif
 }
 
@@ -254,31 +255,11 @@ static int is_excluded(char *fname, int is_dir, int filter_level)
        return 0;
 }
 
-static int to_wire_mode(mode_t mode)
-{
-#ifdef SUPPORT_LINKS
-#if _S_IFLNK != 0120000
-       if (S_ISLNK(mode))
-               return (mode & ~(_S_IFMT)) | 0120000;
-#endif
-#endif
-       return mode;
-}
-
-static mode_t from_wire_mode(int mode)
-{
-#if _S_IFLNK != 0120000
-       if ((mode & (_S_IFMT)) == 0120000)
-               return (mode & ~(_S_IFMT)) | _S_IFLNK;
-#endif
-       return mode;
-}
-
 static void send_directory(int f, struct file_list *flist, int ndx,
                           char *fbuf, int len, int flags);
 
-static const char *flist_dir, *orig_dir;
-static int flist_dir_len;
+static const char *pathname, *orig_dir;
+static int pathname_len;
 
 
 /**
@@ -322,15 +303,15 @@ void flist_expand(struct file_list *flist)
                out_of_memory("flist_expand");
 }
 
-int push_flist_dir(const char *dir, int len)
+int push_pathname(const char *dir, int len)
 {
-       if (dir == flist_dir)
+       if (dir == pathname)
                return 1;
 
        if (!orig_dir)
                orig_dir = strdup(curr_dir);
 
-       if (flist_dir && !pop_dir(orig_dir)) {
+       if (pathname && !pop_dir(orig_dir)) {
                rsyserr(FERROR, errno, "pop_dir %s failed",
                        full_fname(orig_dir));
                exit_cleanup(RERR_FILESELECT);
@@ -343,8 +324,8 @@ int push_flist_dir(const char *dir, int len)
                return 0;
        }
 
-       flist_dir = dir;
-       flist_dir_len = len >= 0 ? len : dir ? (int)strlen(dir) : 0;
+       pathname = dir;
+       pathname_len = len >= 0 ? len : dir ? (int)strlen(dir) : 0;
 
        return 1;
 }
@@ -576,7 +557,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx)
 static struct file_struct *recv_file_entry(struct file_list *flist,
                                           int flags, int f)
 {
-       static time_t modtime;
+       static int64 modtime;
        static mode_t mode;
        static int64 dev;
        static dev_t rdev;
@@ -594,8 +575,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
        int first_hlink_ndx = -1;
        OFF_T file_length;
        const char *basename;
-       char *bp;
        struct file_struct *file;
+       alloc_pool_t *pool;
+       char *bp;
 
        if (flags & XMIT_SAME_NAME)
                l1 = read_byte(f);
@@ -671,10 +653,17 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
 
        file_length = read_varlong30(f, 3);
        if (!(flags & XMIT_SAME_TIME)) {
-               if (protocol_version >= 30)
-                       modtime = (time_t)read_varlong(f, 4);
-               else
-                       modtime = (time_t)read_int(f);
+               if (protocol_version >= 30) {
+                       modtime = read_varlong(f, 4);
+#if SIZEOF_TIME_T < SIZEOF_INT64
+                       if ((modtime > INT_MAX || modtime < INT_MIN) && !am_generator) {
+                               rprintf(FERROR,
+                                   "Time value of %s truncated on receiver.\n",
+                                   lastname);
+                       }
+#endif
+               } else
+                       modtime = read_int(f);
        }
        if (!(flags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
@@ -772,12 +761,13 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
                        /* Room to save the dir's device for -x */
                        extra_len += 2 * EXTRA_LEN;
                }
-               flist = dir_flist;
-       }
+               pool = dir_flist->file_pool;
+       } else
+               pool = flist->file_pool;
 
        alloc_len = FILE_STRUCT_LEN + extra_len + basename_len
                  + linkname_len;
-       bp = pool_alloc(flist->file_pool, alloc_len, "recv_file_entry");
+       bp = pool_alloc(pool, alloc_len, "recv_file_entry");
 
        memset(bp, 0, extra_len + FILE_STRUCT_LEN);
        bp += extra_len;
@@ -791,7 +781,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
        if (flags & XMIT_HLINKED)
                file->flags |= FLAG_HLINKED;
 #endif
-       file->modtime = modtime;
+       file->modtime = (time_t)modtime;
        file->len32 = (uint32)file_length;
        if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) {
                file->flags |= FLAG_LENGTH64;
@@ -938,7 +928,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        char *bp;
 
        if (strlcpy(thisname, fname, sizeof thisname)
-           >= sizeof thisname - flist_dir_len) {
+           >= sizeof thisname - pathname_len) {
                rprintf(FINFO, "skipping overly long name: %s\n", fname);
                return NULL;
        }
@@ -962,7 +952,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                if (save_errno == ENOENT) {
 #ifdef SUPPORT_LINKS
                        /* Avoid "vanished" error if symlink points nowhere. */
-                       if (copy_links && do_lstat(thisname, &st) == 0
+                       if (copy_links && x_lstat(thisname, &st, NULL) == 0
                            && S_ISLNK(st.st_mode)) {
                                io_error |= IOERR_GENERAL;
                                rprintf(FERROR, "symlink has no referent: %s\n",
@@ -1125,7 +1115,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        if (always_checksum && am_sender && S_ISREG(st.st_mode))
                file_checksum(thisname, tmp_sum, st.st_size);
 
-       F_ROOTDIR(file) = flist_dir;
+       F_PATHNAME(file) = pathname;
 
        /* This code is only used by the receiver when it is building
         * a list of files for a delete pass. */
@@ -1134,7 +1124,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                int save_mode = file->mode;
                file->mode = S_IFDIR; /* Find a directory with our name. */
                if (flist_find(dir_flist, file) >= 0
-                   && do_stat(thisname, &st2) == 0 && S_ISDIR(st2.st_mode)) {
+                   && x_stat(thisname, &st2, NULL) == 0 && S_ISDIR(st2.st_mode)) {
                        file->modtime = st2.st_mtime;
                        file->len32 = 0;
                        file->mode = st2.st_mode;
@@ -1369,8 +1359,8 @@ void send_extra_file_list(int f, int at_least)
         * files in the upcoming file-lists. */
        if (cur_flist->next) {
                flist = first_flist->prev; /* the newest flist */
-               future_cnt = flist->count
-                          + flist->ndx_start - cur_flist->next->ndx_start;
+               future_cnt = flist->count + flist->ndx_start
+                          - cur_flist->next->ndx_start;
        } else
                future_cnt = 0;
        while (future_cnt < at_least) {
@@ -1381,8 +1371,8 @@ void send_extra_file_list(int f, int at_least)
                f_name(file, fbuf);
                dlen = strlen(fbuf);
 
-               if (F_ROOTDIR(file) != flist_dir) {
-                       if (!push_flist_dir(F_ROOTDIR(file), -1))
+               if (F_PATHNAME(file) != pathname) {
+                       if (!push_pathname(F_PATHNAME(file), -1))
                                exit_cleanup(RERR_FILESELECT);
                }
 
@@ -1391,7 +1381,8 @@ void send_extra_file_list(int f, int at_least)
 
                write_ndx(f, NDX_FLIST_OFFSET - send_dir_ndx);
                change_local_filter_dir(fbuf, dlen, send_dir_depth);
-               send_directory(f, flist, send_dir_ndx, fbuf, dlen, FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
+               send_directory(f, flist, send_dir_ndx, fbuf, dlen,
+                              FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
                write_byte(f, 0);
 
                clean_flist(flist, 0, 0);
@@ -1429,7 +1420,9 @@ void send_extra_file_list(int f, int at_least)
 
 struct file_list *send_file_list(int f, int argc, char *argv[])
 {
-       int len;
+       static const char *lastdir;
+       static int lastdir_len = -1;
+       int len, dirlen;
        STRUCT_STAT st;
        char *p, *dir;
        char lastpath[MAXPATHLEN] = "";
@@ -1581,23 +1574,18 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                        fn = ".";
                }
 
-               if (dir && *dir) {
-                       static const char *lastdir;
-                       static int lastdir_len = -1;
-                       int len = strlen(dir);
-
-                       if (len != lastdir_len || memcmp(lastdir, dir, len) != 0) {
-                               if (!push_flist_dir(strdup(dir), len))
-                                       goto push_error;
-                               lastdir = flist_dir;
-                               lastdir_len = flist_dir_len;
-                       } else if (!push_flist_dir(lastdir, lastdir_len)) {
-                         push_error:
-                               io_error |= IOERR_GENERAL;
-                               rsyserr(FERROR, errno, "push_dir %s failed in %s",
-                                       full_fname(dir), curr_dir);
-                               continue;
-                       }
+               dirlen = dir ? strlen(dir) : 0;
+               if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
+                       if (!push_pathname(dir ? strdup(dir) : NULL, dirlen))
+                               goto push_error;
+                       lastdir = pathname;
+                       lastdir_len = pathname_len;
+               } else if (!push_pathname(lastdir, lastdir_len)) {
+                 push_error:
+                       io_error |= IOERR_GENERAL;
+                       rsyserr(FERROR, errno, "push_dir %s failed in %s",
+                               full_fname(dir), curr_dir);
+                       continue;
                }
 
                if (fn != fbuf)
@@ -1652,9 +1640,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
 
                if (recurse || (xfer_dirs && is_dot_dir)) {
                        struct file_struct *file;
-                       int top_flags = FLAG_TOP_DIR | FLAG_XFER_DIR
-                                     | (is_dot_dir ? 0 : flags)
-                                     | (inc_recurse ? FLAG_DIVERT_DIRS : 0);
+                       int top_flags = FLAG_TOP_DIR | FLAG_XFER_DIR | flags;
                        file = send_file_name(f, flist, fbuf, &st,
                                              top_flags, ALL_FILTERS);
                        if (file && !inc_recurse)
@@ -2170,7 +2156,7 @@ static void output_flist(struct file_list *flist)
                if (!am_sender)
                        snprintf(depthbuf, sizeof depthbuf, "%d", F_DEPTH(file));
                if (F_IS_ACTIVE(file)) {
-                       root = am_sender ? NS(F_ROOTDIR(file)) : depthbuf;
+                       root = am_sender ? NS(F_PATHNAME(file)) : depthbuf;
                        if ((dir = file->dirname) == NULL)
                                dir = slash = "";
                        else