- Incremental recursion mode does not process the dirs while scanning a
authorWayne Davison <wayned@samba.org>
Sun, 8 Jul 2007 06:25:51 +0000 (06:25 +0000)
committerWayne Davison <wayned@samba.org>
Sun, 8 Jul 2007 06:25:51 +0000 (06:25 +0000)
  file list's contents.  Instead, it handles a parent dir prior to each
  extra file list.  This makes the dir-processing order the same in
  protocol 30 as it is in earlier protocols.
- Moved the permission-fudging code for dirs into recv_generator() to
  make the new protocol-30 dir-handling logic easier.

generator.c

index c15e20f..f4ecbbd 100644 (file)
@@ -112,6 +112,7 @@ static int deldelay_fd = -1;
 static int lull_mod;
 static int dir_tweaking;
 static int need_retouch_dir_times;
 static int lull_mod;
 static int dir_tweaking;
 static int need_retouch_dir_times;
+static int need_retouch_dir_perms;
 static const char *solo_file = NULL;
 
 /* For calling delete_item() and delete_dir_contents(). */
 static const char *solo_file = NULL;
 
 /* For calling delete_item() and delete_dir_contents(). */
@@ -1261,6 +1262,22 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, NULL, 0)
                    && verbose && code != FNONE && f_out != -1)
                        rprintf(code, "%s/\n", fname);
                if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, NULL, 0)
                    && verbose && code != FNONE && f_out != -1)
                        rprintf(code, "%s/\n", fname);
+
+               /* We need to ensure that the dirs in the transfer have writable
+                * permissions during the time we are putting files within them.
+                * This is then fixed after the transfer is done. */
+#ifdef HAVE_CHMOD
+               if (!am_root && !(file->mode & S_IWUSR) && dir_tweaking) {
+                       mode_t mode = file->mode | S_IWUSR;
+                       if (do_chmod(fname, mode) < 0) {
+                               rsyserr(FERROR, errno,
+                                       "failed to modify permissions on %s",
+                                       full_fname(fname));
+                       }
+                       need_retouch_dir_perms = 1;
+               }
+#endif
+
                if (real_ret != 0 && one_file_system)
                        real_sx.st.st_dev = filesystem_dev;
                if (inc_recurse) {
                if (real_ret != 0 && one_file_system)
                        real_sx.st.st_dev = filesystem_dev;
                if (inc_recurse) {
@@ -1838,7 +1855,6 @@ void generate_files(int f_out, const char *local_name)
        char fbuf[MAXPATHLEN];
        int itemizing;
        enum logcode code;
        char fbuf[MAXPATHLEN];
        int itemizing;
        enum logcode code;
-       int need_retouch_dir_perms = 0;
        int save_do_progress = do_progress;
 
        if (protocol_version >= 29) {
        int save_do_progress = do_progress;
 
        if (protocol_version >= 29) {
@@ -1894,16 +1910,21 @@ void generate_files(int f_out, const char *local_name)
        dflt_perms = (ACCESSPERMS & ~orig_umask);
 
        do {
        dflt_perms = (ACCESSPERMS & ~orig_umask);
 
        do {
-               if (inc_recurse && delete_during && cur_flist->ndx_start) {
+               if (inc_recurse && cur_flist->ndx_start) {
                        struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx];
                        struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx];
-                       if (BITS_SETnUNSET(fp->flags, FLAG_XFER_DIR, FLAG_MISSING_DIR)) {
-                               dev_t dirdev;
-                               if (one_file_system) {
-                                       uint32 *devp = F_DIRDEV_P(fp);
-                                       dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
-                               } else
-                                       dirdev = MAKEDEV(0, 0);
-                               delete_in_dir(f_name(fp, fbuf), fp, &dirdev);
+                       f_name(fp, fbuf);
+                       ndx = cur_flist->ndx_start - 1;
+                       recv_generator(fbuf, fp, ndx, itemizing, code, f_out);
+                       if (delete_during) {
+                               if (BITS_SETnUNSET(fp->flags, FLAG_XFER_DIR, FLAG_MISSING_DIR)) {
+                                       dev_t dirdev;
+                                       if (one_file_system) {
+                                               uint32 *devp = F_DIRDEV_P(fp);
+                                               dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
+                                       } else
+                                               dirdev = MAKEDEV(0, 0);
+                                       delete_in_dir(f_name(fp, fbuf), fp, &dirdev);
+                               }
                        }
                }
                for (i = cur_flist->low; i <= cur_flist->high; i++) {
                        }
                }
                for (i = cur_flist->low; i <= cur_flist->high; i++) {
@@ -1912,6 +1933,14 @@ void generate_files(int f_out, const char *local_name)
                        if (!F_IS_ACTIVE(file))
                                continue;
 
                        if (!F_IS_ACTIVE(file))
                                continue;
 
+                       if (inc_recurse && S_ISDIR(file->mode)) {
+                               /* Regular dirs are at the end, so we can stop. */
+                               if (F_DEPTH(file))
+                                       break;
+                               /* A dot-dir is at the start, so just skip it. */
+                               continue;
+                       }
+
 #ifdef ICONV_OPTION
                        if (ic_ndx)
                                ndx = F_NDX(file);
 #ifdef ICONV_OPTION
                        if (ic_ndx)
                                ndx = F_NDX(file);
@@ -1925,24 +1954,6 @@ void generate_files(int f_out, const char *local_name)
                                f_name(file, fbuf);
                        recv_generator(fbuf, file, ndx, itemizing, code, f_out);
 
                                f_name(file, fbuf);
                        recv_generator(fbuf, file, ndx, itemizing, code, f_out);
 
-                       /* We need to ensure that any dirs we create have
-                        * writeable permissions during the time we are putting
-                        * files within them.  This is then fixed after the
-                        * transfer is done. */
-#ifdef HAVE_CHMOD
-                       if (!am_root && S_ISDIR(file->mode)
-                        && !(file->mode & S_IWUSR) && dir_tweaking) {
-                               mode_t mode = file->mode | S_IWUSR;
-                               const char *fname = solo_file ? solo_file : fbuf;
-                               if (do_chmod(fname, mode) < 0) {
-                                       rsyserr(FERROR, errno,
-                                           "failed to modify permissions on %s",
-                                           full_fname(fname));
-                               }
-                               need_retouch_dir_perms = 1;
-                       }
-#endif
-
                        check_for_finished_files(itemizing, code, 0);
 
                        if (allowed_lull && !(i % lull_mod))
                        check_for_finished_files(itemizing, code, 0);
 
                        if (allowed_lull && !(i % lull_mod))