* Copyright (C) 2003-2007 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
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(). */
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 (one_file_system) {
- uint32 *devp = F_DIRDEV_P(file);
+ uint32 *devp = F_DIR_DEV_P(file);
DEV_MAJOR(devp) = major(real_sx.st.st_dev);
DEV_MINOR(devp) = minor(real_sx.st.st_dev);
}
maybe_flush_socket(1);
}
- if (delete_during == 2 || !dir_tweaking) {
- /* Skip directory touch-up. */
- } else if (first_flist->ndx_start != 0)
- touch_up_dirs(dir_flist, first_flist->parent_ndx);
- else if (relative_paths && implied_dirs)
- touch_up_dirs(first_flist, -1);
-
flist_free(first_flist); /* updates first_flist */
}
}
char fbuf[MAXPATHLEN];
int itemizing;
enum logcode code;
- int need_retouch_dir_perms = 0;
int save_do_progress = do_progress;
if (protocol_version >= 29) {
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];
- 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_DIR_DEV_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++) {
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);
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))
if (delete_after && !solo_file && file_total > 0)
do_delete_pass();
- if ((need_retouch_dir_perms || need_retouch_dir_times)
- && dir_tweaking && (!inc_recurse || delete_during == 2))
+ if ((need_retouch_dir_perms || need_retouch_dir_times) && dir_tweaking)
touch_up_dirs(dir_flist, -1);
if (max_delete >= 0 && deletion_count > max_delete) {