2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* this file contains code used by more than one part of the rsync
27 extern int daemon_log_format_has_i
;
28 extern int preserve_times
;
29 extern int omit_dir_times
;
33 extern int am_generator
;
34 extern int am_starting_up
;
35 extern int preserve_uid
;
36 extern int preserve_gid
;
38 extern int keep_dirlinks
;
39 extern int make_backups
;
40 extern struct stats stats
;
46 void free_sums(struct sum_struct
*s
)
48 if (s
->sums
) free(s
->sums
);
53 int set_perms(char *fname
,struct file_struct
*file
,STRUCT_STAT
*st
,
58 int change_uid
, change_gid
;
63 if (link_stat(fname
, &st2
, 0) < 0) {
64 rsyserr(FERROR
, errno
, "stat %s failed",
71 if (!preserve_times
|| S_ISLNK(st
->st_mode
)
72 || (S_ISDIR(st
->st_mode
) && omit_dir_times
))
73 flags
|= PERMS_SKIP_MTIME
;
74 if (!(flags
& PERMS_SKIP_MTIME
)
75 && cmp_modtime(st
->st_mtime
, file
->modtime
) != 0) {
76 if (set_modtime(fname
,file
->modtime
) != 0) {
77 rsyserr(FERROR
, errno
, "failed to set times on %s",
84 change_uid
= am_root
&& preserve_uid
&& st
->st_uid
!= file
->uid
;
85 change_gid
= preserve_gid
&& file
->gid
!= GID_NONE
86 && st
->st_gid
!= file
->gid
;
87 #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
88 if (S_ISLNK(st
->st_mode
))
92 if (change_uid
|| change_gid
) {
96 "set uid of %s from %ld to %ld\n",
98 (long)st
->st_uid
, (long)file
->uid
);
102 "set gid of %s from %ld to %ld\n",
104 (long)st
->st_gid
, (long)file
->gid
);
108 change_uid
? file
->uid
: st
->st_uid
,
109 change_gid
? file
->gid
: st
->st_gid
) != 0) {
110 /* shouldn't have attempted to change uid or gid
111 * unless have the privilege */
112 rsyserr(FERROR
, errno
, "%s %s failed",
113 change_uid
? "chown" : "chgrp",
117 /* a lchown had been done - we have to re-stat if the
118 * destination had the setuid or setgid bits set due
119 * to the side effect of the chown call */
120 if (st
->st_mode
& (S_ISUID
| S_ISGID
)) {
122 keep_dirlinks
&& S_ISDIR(st
->st_mode
));
128 if (!S_ISLNK(st
->st_mode
)) {
129 if ((st
->st_mode
& CHMOD_BITS
) != (file
->mode
& CHMOD_BITS
)) {
131 if (do_chmod(fname
,(file
->mode
& CHMOD_BITS
)) != 0) {
132 rsyserr(FERROR
, errno
, "failed to set permissions on %s",
140 if (verbose
> 1 && flags
& PERMS_REPORT
) {
141 enum logcode code
= daemon_log_format_has_i
|| dry_run
144 rprintf(code
, "%s\n", safe_fname(fname
));
146 rprintf(code
, "%s is uptodate\n", safe_fname(fname
));
154 /* KLUGE: if the user hits Ctrl-C while ssh is prompting
155 * for a password, then our cleanup's sending of a SIGUSR1
156 * signal to all our children may kill ssh before it has a
157 * chance to restore the tty settings (i.e. turn echo back
158 * on). By sleeping for a short time, ssh gets a bigger
159 * chance to do the right thing. If child processes are
160 * not ssh waiting for a password, then this tiny delay
161 * shouldn't hurt anything. */
163 exit_cleanup(RERR_SIGNAL
);
167 /* finish off a file transfer, renaming the file and setting the permissions
169 void finish_transfer(char *fname
, char *fnametmp
, struct file_struct
*file
,
170 int ok_to_set_time
, int overwriting_basis
)
176 rprintf(FINFO
, "finishing %s\n", safe_fname(fname
));
180 if (make_backups
&& overwriting_basis
&& !make_backup(fname
))
183 /* Change permissions before putting the file into place. */
184 set_perms(fnametmp
, file
, NULL
, ok_to_set_time
? 0 : PERMS_SKIP_MTIME
);
186 /* move tmp file over real file */
188 rprintf(FINFO
, "renaming %s to %s\n",
189 safe_fname(fnametmp
), safe_fname(fname
));
191 ret
= robust_rename(fnametmp
, fname
, file
->mode
& INITACCESSPERMS
);
193 rsyserr(FERROR
, errno
, "%s %s -> \"%s\"",
194 ret
== -2 ? "copy" : "rename",
195 full_fname(fnametmp
), safe_fname(fname
));
200 /* The file was moved into place (not copied), so it's done. */
204 set_perms(fname
, file
, NULL
, ok_to_set_time
? 0 : PERMS_SKIP_MTIME
);
207 const char *who_am_i(void)
210 return am_server
? "server" : "client";
211 return am_sender
? "sender" : am_generator
? "generator" : "receiver";