--- orig/rsync.c 2004-07-23 17:16:13 +++ rsync.c 2004-07-26 06:27:27 @@ -246,6 +246,9 @@ void finish_transfer(char *fname, char * goto do_set_perms; } + /* Change permissions before putting the file into place. */ + set_perms(fnametmp, file, NULL, ok_to_set_time ? 0 : PERMS_SKIP_MTIME); + /* move tmp file over real file */ if (verbose > 2) rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname); @@ -257,6 +260,10 @@ void finish_transfer(char *fname, char * do_unlink(fnametmp); return; } + if (ret == 0) { + /* The file was moved into place (not copied), so it's done. */ + return; + } do_set_perms: set_perms(fname, file, NULL, ok_to_set_time ? 0 : PERMS_SKIP_MTIME); } --- orig/t_stub.c 2004-05-15 20:10:13 +++ t_stub.c 2004-07-03 20:17:55 @@ -26,6 +26,7 @@ * functions, so that module test harnesses can run standalone. **/ +int am_root = 0; int modify_window = 0; int module_id = -1; struct exclude_list_struct server_exclude_list; --- orig/util.c 2004-06-09 21:54:47 +++ util.c 2004-07-03 20:17:55 @@ -29,6 +29,7 @@ extern int verbose; extern int dry_run; +extern int am_root; extern int module_id; extern int modify_window; extern struct exclude_list_struct server_exclude_list; @@ -263,6 +264,8 @@ int copy_file(char *source, char *dest, return -1; } + if (!am_root && !(mode & S_IWUSR)) + mode |= S_IWUSR; ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode); if (ofd == -1) { rsyserr(FERROR, errno, "open %s", full_fname(dest)); @@ -361,8 +364,8 @@ int robust_unlink(char *fname) #endif } -/* Returns 0 on success, -1 on most errors, and -2 if we got an error - * trying to copy the file across file systems. */ +/* Returns 0 on successful rename, 1 if we successfully copied the file + * across filesystems, -2 if copy_file() failed, and -1 on other errors. */ int robust_rename(char *from, char *to, int mode) { int tries = 4; @@ -379,10 +382,12 @@ int robust_rename(char *from, char *to, break; #endif case EXDEV: + if (!am_root && !(mode & S_IRUSR)) + do_chmod(from, (mode & CHMOD_BITS) | S_IRUSR); if (copy_file(from, to, mode) != 0) return -2; do_unlink(from); - return 0; + return 1; default: return -1; }