+ if (statret == 0 && sx.st.st_uid == our_uid)
+ del_opts |= DEL_OWNED_BY_US;
+
+ if (is_dir) {
+ if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
+ goto cleanup;
+ if (is_dir < 0) {
+ /* In inc_recurse mode we want to make sure any missing
+ * directories get created while we're still processing
+ * the parent dir (which allows us to touch the parent
+ * dir's mtime right away). We will handle the dir in
+ * full later (right before we handle its contents). */
+ if (statret == 0
+ && (S_ISDIR(sx.st.st_mode)
+ || delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0))
+ goto cleanup; /* Any errors get reported later. */
+ if (do_mkdir(fname, file->mode & 0700) == 0)
+ file->flags |= FLAG_DIR_CREATED;
+ goto cleanup;
+ }
+ /* The file to be received is a directory, so we need
+ * to prepare appropriately. If there is already a
+ * file of that name and it is *not* a directory, then
+ * we need to delete it. If it doesn't exist, then
+ * (perhaps recursively) create it. */
+ if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
+ if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0)
+ 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;
+ real_sx = sx;
+ if (file->flags & FLAG_DIR_CREATED)
+ statret = -1;
+ if (!preserve_perms) { /* See comment in non-dir code below. */
+ file->mode = dest_mode(file->mode, sx.st.st_mode,
+ dflt_perms, statret == 0);
+ }
+ if (statret != 0 && basis_dir[0] != NULL) {
+ int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
+ itemizing, code);
+ if (j == -2) {
+ itemizing = 0;
+ code = FNONE;
+ } else if (j >= 0)
+ statret = 1;
+ }
+ if (itemizing && f_out != -1) {
+ itemize(fname, file, ndx, statret, &sx,
+ statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
+ }
+ if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
+ if (!relative_paths || errno != ENOENT
+ || create_directory_path(fname) < 0
+ || (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
+ rsyserr(FERROR_XFER, 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;
+ }
+ }
+ 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_XFER, 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_DIR_DEV_P(file);
+ DEV_MAJOR(devp) = major(real_sx.st.st_dev);
+ DEV_MINOR(devp) = minor(real_sx.st.st_dev);
+ }
+ }
+ else if (delete_during && f_out != -1 && !phase && dry_run < 2
+ && (file->flags & FLAG_CONTENT_DIR))
+ delete_in_dir(fname, file, &real_sx.st.st_dev);
+ goto cleanup;
+ }
+
+ /* If we're not preserving permissions, change the file-list's
+ * mode based on the local permissions and some heuristics. */
+ if (!preserve_perms) {
+ int exists = statret == 0 && !S_ISDIR(sx.st.st_mode);
+ file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms,
+ exists);
+ }
+
+#ifdef SUPPORT_HARD_LINKS
+ if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
+ && hard_link_check(file, ndx, fname, statret, &sx, itemizing, code))
+ goto cleanup;
+#endif
+