X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ecc7623e7faf75f6ba3dd7b5a416c52e2346ac7d..d521e1c2a1980d241b0ca611d71c78d51bf255f5:/rsync.c diff --git a/rsync.c b/rsync.c index 818f26b4..25b06295 100644 --- a/rsync.c +++ b/rsync.c @@ -32,7 +32,6 @@ extern int verbose; extern int dry_run; -extern int logfile_format_has_i; extern int preserve_perms; extern int preserve_executability; extern int preserve_times; @@ -101,25 +100,27 @@ void free_sums(struct sum_struct *s) /* This is only called when we aren't preserving permissions. Figure out what * the permissions should be and return them merged back into the mode. */ -mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int exists) +mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int exists) { + int new_mode; /* If the file already exists, we'll return the local permissions, * possibly tweaked by the --executability option. */ if (exists) { + new_mode = (flist_mode & ~CHMOD_BITS) | (stat_mode & CHMOD_BITS); if (preserve_executability && S_ISREG(flist_mode)) { /* If the source file is executable, grant execute * rights to everyone who can read, but ONLY if the * file isn't already executable. */ if (!(flist_mode & 0111)) - cur_mode &= ~0111; - else if (!(cur_mode & 0111)) - cur_mode |= (cur_mode & 0444) >> 2; + new_mode &= ~0111; + else if (!(stat_mode & 0111)) + new_mode |= (new_mode & 0444) >> 2; } - } else - cur_mode = flist_mode & ACCESSPERMS & ~orig_umask; - if (daemon_chmod_modes && !S_ISLNK(flist_mode)) - cur_mode = tweak_mode(cur_mode, daemon_chmod_modes); - return (flist_mode & ~CHMOD_BITS) | (cur_mode & CHMOD_BITS); + } else { + /* Apply the umask and turn off special permissions. */ + new_mode = flist_mode & (~CHMOD_BITS | (ACCESSPERMS & ~orig_umask)); + } + return new_mode; } int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st, @@ -128,6 +129,7 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st, int updated = 0; STRUCT_STAT st2; int change_uid, change_gid; + mode_t new_mode = file->mode; if (!st) { if (dry_run) @@ -138,11 +140,11 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st, return 0; } st = &st2; - if (!preserve_perms && S_ISDIR(file->mode) + if (!preserve_perms && S_ISDIR(new_mode) && st->st_mode & S_ISGID) { /* We just created this directory and its setgid * bit is on, so make sure it stays on. */ - file->mode |= S_ISGID; + new_mode |= S_ISGID; } } @@ -203,9 +205,11 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st, updated = 1; } + if (daemon_chmod_modes && !S_ISLNK(new_mode)) + new_mode = tweak_mode(new_mode, daemon_chmod_modes); #ifdef HAVE_CHMOD - if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) { - int ret = do_chmod(fname, file->mode); + if ((st->st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) { + int ret = do_chmod(fname, new_mode); if (ret < 0) { rsyserr(FERROR, errno, "failed to set permissions on %s", @@ -218,12 +222,10 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st, #endif if (verbose > 1 && flags & ATTRS_REPORT) { - enum logcode code = logfile_format_has_i || dry_run - ? FCLIENT : FINFO; if (updated) - rprintf(code, "%s\n", fname); + rprintf(FCLIENT, "%s\n", fname); else - rprintf(code, "%s is uptodate\n", fname); + rprintf(FCLIENT, "%s is uptodate\n", fname); } return updated; }