Switch over to Matt's idea of using FLAG_OWNED_BY_US.
[rsync.git] / generator.c
index c2fbc065057c01aa1ae3a91c980dc879d89603f4..0c3060458deba2d6ba9aeec9ac97c5d4ac2dbe88 100644 (file)
@@ -44,8 +44,6 @@ extern int preserve_hard_links;
 extern int preserve_executability;
 extern int preserve_perms;
 extern int preserve_times;
-extern int uid_ndx;
-extern int gid_ndx;
 extern int delete_mode;
 extern int delete_before;
 extern int delete_during;
@@ -169,19 +167,12 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                do_chmod(fbuf, mode | S_IWUSR);
 
        if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
-               int save_uid_ndx = uid_ndx;
                /* This only happens on the first call to delete_item() since
                 * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
-               if (!uid_ndx)
-                       uid_ndx = ++file_extra_cnt;
                ignore_perishable = 1;
                /* If DEL_RECURSE is not set, this just reports emptiness. */
                ret = delete_dir_contents(fbuf, flags);
                ignore_perishable = 0;
-               if (!save_uid_ndx) {
-                       --file_extra_cnt;
-                       uid_ndx = 0;
-               }
                if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
                        goto check_ret;
                /* OK: try to delete the directory. */
@@ -294,7 +285,7 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
                }
 
                strlcpy(p, fp->basename, remainder);
-               if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
+               if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
                        do_chmod(fname, fp->mode | S_IWUSR);
                /* Save stack by recursing to ourself directly. */
                if (S_ISDIR(fp->mode)) {
@@ -472,7 +463,6 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
        struct file_list *dirlist;
        char delbuf[MAXPATHLEN];
        int dlen, i;
-       int save_uid_ndx = uid_ndx;
 
        if (!fbuf) {
                change_local_filter_dir(NULL, 0, 0);
@@ -504,9 +494,6 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                        return;
        }
 
-       if (!uid_ndx)
-               uid_ndx = ++file_extra_cnt;
-
        dirlist = get_dirlist(fbuf, dlen, 0);
 
        /* If an item in dirlist is not found in flist, delete it
@@ -526,7 +513,7 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                 * a delete_item call with a DEL_MAKE_ROOM flag. */
                if (flist_find_ignore_dirness(cur_flist, fp) < 0) {
                        int flags = DEL_RECURSE;
-                       if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
+                       if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
                                flags |= DEL_NO_UID_WRITE;
                        f_name(fp, delbuf);
                        if (delete_during == 2) {
@@ -538,11 +525,6 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
        }
 
        flist_free(dirlist);
-
-       if (!save_uid_ndx) {
-               --file_extra_cnt;
-               uid_ndx = 0;
-       }
 }
 
 /* This deletes any files on the receiving side that are not present on the
@@ -1367,7 +1349,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 
                if (need_fuzzy_dirlist && S_ISREG(file->mode)) {
                        strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf);
-                       fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
+                       fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, GDL_IGNORE_FILTER_RULES);
                        need_fuzzy_dirlist = 0;
                }
 
@@ -1411,8 +1393,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        fnamecmp = fname;
 
        if (is_dir) {
+               mode_t added_perms;
                if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
                        goto cleanup;
+               if (am_root < 0) {
+                       /* For --fake-super, the dir must be useable by the copying
+                        * user, just like it would be for root. */
+                       added_perms = S_IRUSR|S_IWUSR|S_IXUSR;
+               } else
+                       added_perms = 0;
                if (is_dir < 0) {
                        /* In inc_recurse mode we want to make sure any missing
                         * directories get created while we're still processing
@@ -1423,7 +1412,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                         && (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)
+                       if (do_mkdir(fname, (file->mode|added_perms) & 0700) == 0)
                                file->flags |= FLAG_DIR_CREATED;
                        goto cleanup;
                }
@@ -1466,10 +1455,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        itemize(fnamecmp, file, ndx, statret, &sx,
                                statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
                }
-               if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
+               if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) {
                        if (!relative_paths || errno != ENOENT
-                           || create_directory_path(fname) < 0
-                           || (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
+                        || create_directory_path(fname) < 0
+                        || (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) {
                                rsyserr(FERROR_XFER, errno,
                                        "recv_generator: mkdir %s failed",
                                        full_fname(fname));