Made omit_dir_times a static variable in options.c by encoding
[rsync/rsync.git] / generator.c
index 1064ff5..e91e3a6 100644 (file)
@@ -43,7 +43,6 @@ extern int preserve_specials;
 extern int preserve_hard_links;
 extern int preserve_perms;
 extern int preserve_times;
-extern int omit_dir_times;
 extern int uid_ndx;
 extern int gid_ndx;
 extern int delete_mode;
@@ -554,7 +553,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
 {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
                int keep_time = !preserve_times ? 0
-                   : S_ISDIR(file->mode) ? !omit_dir_times
+                   : S_ISDIR(file->mode) ? preserve_times > 1
                    : !S_ISLNK(file->mode);
 
                if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
@@ -1092,6 +1091,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 {
        static int missing_below = -1, excluded_below = -1;
        static const char *parent_dirname = "";
+       static struct file_struct *missing_dir = NULL, *excluded_dir = NULL;
        static struct file_list *fuzzy_dirlist = NULL;
        static int need_fuzzy_dirlist = 0;
        struct file_struct *fuzzy_file = NULL;
@@ -1113,14 +1113,17 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 
        if (server_filter_list.head) {
                if (excluded_below >= 0) {
-                       if (F_DEPTH(file) > excluded_below)
+                       if (F_DEPTH(file) > excluded_below
+                        && (implied_dirs || f_name_has_prefix(file, excluded_dir)))
                                goto skipping;
                        excluded_below = -1;
                }
                if (check_filter(&server_filter_list, fname,
                                 S_ISDIR(file->mode)) < 0) {
-                       if (S_ISDIR(file->mode))
+                       if (S_ISDIR(file->mode)) {
                                excluded_below = F_DEPTH(file);
+                               excluded_dir = file;
+                       }
                  skipping:
                        if (verbose) {
                                rprintf(FINFO,
@@ -1132,7 +1135,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        }
 
        if (missing_below >= 0) {
-               if (F_DEPTH(file) <= missing_below) {
+               if (F_DEPTH(file) <= missing_below
+                || (!implied_dirs && !f_name_has_prefix(file, missing_dir))) {
                        if (dry_run)
                                dry_run--;
                        missing_below = -1;
@@ -1201,6 +1205,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                if (dry_run)
                                        dry_run++;
                                missing_below = F_DEPTH(file);
+                               missing_dir = file;
                        }
                        file->flags |= FLAG_MISSING_DIR;
                }
@@ -1215,11 +1220,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                 * (perhaps recursively) create it. */
                if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
                        if (delete_item(fname, sx.st.st_mode, "directory", del_opts) != 0)
-                               return;
+                               goto skipping_dir_contents;
                        statret = -1;
                }
                if (dry_run && statret != 0 && missing_below < 0) {
                        missing_below = F_DEPTH(file);
+                       missing_dir = file;
                        dry_run++;
                }
                real_ret = statret;
@@ -1253,9 +1259,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                rsyserr(FERROR, errno,
                                        "recv_generator: mkdir %s failed",
                                        full_fname(fname));
+                         skipping_dir_contents:
                                rprintf(FERROR,
                                    "*** Skipping any contents from this failed directory ***\n");
                                missing_below = F_DEPTH(file);
+                               missing_dir = file;
                                file->flags |= FLAG_MISSING_DIR;
                                goto cleanup;
                        }
@@ -1569,7 +1577,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
 
-       if (append_mode > 0 && sx.st.st_size > F_LENGTH(file))
+       if (append_mode > 0 && sx.st.st_size >= F_LENGTH(file))
                goto cleanup;
 
        if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
@@ -1752,15 +1760,15 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
         * transfer and/or re-set any tweaked modified-time values. */
        for (i = start; i <= end; i++, counter++) {
                file = flist->files[i];
+               if (!S_ISDIR(file->mode))
+                       continue;
                if (verbose > 3) {
                        fname = f_name(file, NULL);
                        rprintf(FINFO, "touch_up_dirs: %s (%d)\n",
                                NS(fname), i);
                }
-               if (!F_IS_ACTIVE(file) || !S_ISDIR(file->mode)
-                || file->flags & FLAG_MISSING_DIR)
-                       continue;
-               if (!need_retouch_dir_times && file->mode & S_IWUSR)
+               if (!F_IS_ACTIVE(file) || file->flags & FLAG_MISSING_DIR
+                || (!need_retouch_dir_times && file->mode & S_IWUSR))
                        continue;
                fname = f_name(file, NULL);
                if (!(file->mode & S_IWUSR))
@@ -1870,7 +1878,7 @@ void generate_files(int f_out, const char *local_name)
        }
        solo_file = local_name;
        dir_tweaking = !(list_only || solo_file || dry_run);
-       need_retouch_dir_times = preserve_times && !omit_dir_times;
+       need_retouch_dir_times = preserve_times > 1;
        lull_mod = allowed_lull * 5;
 
        if (verbose > 2)
@@ -1909,7 +1917,7 @@ void generate_files(int f_out, const char *local_name)
                        f_name(fp, fbuf);
                        ndx = cur_flist->ndx_start - 1;
                        recv_generator(fbuf, fp, ndx, itemizing, code, f_out);
-                       if (delete_during) {
+                       if (delete_during && dry_run < 2) {
                                if (BITS_SETnUNSET(fp->flags, FLAG_XFER_DIR, FLAG_MISSING_DIR)) {
                                        dev_t dirdev;
                                        if (one_file_system) {