1 /* -*- c-file-style: "linux" -*-
3 rsync -- fast file replication program
5 Copyright (C) 1996-2000 by Andrew Tridgell
6 Copyright (C) Paul Mackerras 1996
7 Copyright (C) 2002 by Martin Pool <mbp@samba.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern int relative_paths;
29 extern int preserve_links;
31 extern int preserve_devices;
32 extern int preserve_hard_links;
33 extern int update_only;
34 extern int opt_ignore_existing;
35 extern int block_size;
36 extern int csum_length;
37 extern int ignore_times;
39 extern int io_timeout;
40 extern int remote_version;
41 extern int always_checksum;
42 extern int modify_window;
43 extern char *compare_dest;
47 /* choose whether to skip a particular file */
48 static int skip_file(char *fname,
49 struct file_struct *file, STRUCT_STAT *st)
51 if (st->st_size != file->length) {
55 extern int preserve_perms;
56 extern int preserve_uid;
57 extern int preserve_gid;
60 && st->st_mode & ~_S_IFMT) != (file->mode & ~_S_IFMT))
63 if (preserve_uid && st->st_uid != file->uid)
66 if (preserve_gid && st->st_gid != file->gid)
70 /* if always checksum is set then we use the checksum instead
71 of the file time to determine whether to sync */
72 if (always_checksum && S_ISREG(st->st_mode)) {
73 char sum[MD4_SUM_LENGTH];
74 char fnamecmpdest[MAXPATHLEN];
76 if (compare_dest != NULL) {
77 if (access(fname, 0) != 0) {
78 snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
83 file_checksum(fname,sum,st->st_size);
84 if (remote_version < 21) {
85 return (memcmp(sum,file->sum,2) == 0);
87 return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
99 return (cmp_modtime(st->st_mtime,file->modtime) == 0);
103 /* use a larger block size for really big files */
104 static int adapt_block_size(struct file_struct *file, int bsize)
108 if (bsize != BLOCK_SIZE) return bsize;
110 ret = file->length / (10000); /* rough heuristic */
111 ret = ret & ~15; /* multiple of 16 */
112 if (ret < bsize) ret = bsize;
113 if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
119 send a header that says "we have no checksums" down the f_out fd
121 static void send_null_sums(int f_out)
124 write_int(f_out, block_size);
131 * Perhaps we want to just send an empty checksum set for this file,
132 * which will force the whole thing to be literally transferred.
134 * When do we do this? If the user's explicitly said they
135 * want the whole thing, or if { they haven't explicitly
136 * requested a delta, and it's local but not batch mode.}
139 static BOOL disable_deltas_p(void)
141 extern int whole_file;
142 extern int local_server;
143 extern int write_batch;
147 if (whole_file == 0 || write_batch)
154 * Generate and send a stream of signatures/checksums that describe a buffer
156 * Generate approximately one checksum every block_len bytes.
158 static void generate_and_send_sums(struct map_struct *buf, OFF_T len,
159 int block_len, int f_out)
162 struct sum_struct sum;
165 sum.count = (len + (block_len - 1)) / block_len;
166 sum.remainder = (len % block_len);
169 /* not needed here sum.sums = NULL; */
171 if (sum.count && verbose > 3) {
172 rprintf(FINFO, "count=%ld rem=%ld n=%ld flength=%.0f\n",
173 (long) sum.count, (long) sum.remainder,
174 (long) sum.n, (double) sum.flength);
177 write_int(f_out, sum.count);
178 write_int(f_out, sum.n);
179 write_int(f_out, sum.remainder);
181 for (i = 0; i < sum.count; i++) {
182 int n1 = MIN(len, block_len);
183 char *map = map_ptr(buf, offset, n1);
184 uint32 sum1 = get_checksum1(map, n1);
185 char sum2[SUM_LENGTH];
187 get_checksum2(map, n1, sum2);
191 "chunk[%d] offset=%.0f len=%d sum1=%08lx\n",
192 i, (double) offset, n1, (unsigned long) sum1);
194 write_int(f_out, sum1);
195 write_buf(f_out, sum2, csum_length);
204 * Acts on file number @p i from @p flist, whose name is @p fname.
206 * First fixes up permissions, then generates checksums for the file.
208 * @note This comment was added later by mbp who was trying to work it
209 * out. It might be wrong.
211 void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
215 struct map_struct *buf;
217 struct file_struct *file = flist->files[i];
219 char fnamecmpbuf[MAXPATHLEN];
220 extern char *compare_dest;
221 extern int list_only;
222 extern int preserve_perms;
223 extern int only_existing;
224 extern int orig_umask;
226 if (list_only) return;
229 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
231 statret = link_stat(fname,&st);
233 if (only_existing && statret == -1 && errno == ENOENT) {
234 /* we only want to update existing files */
235 if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
241 (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
242 /* if the file exists already and we aren't perserving
243 * permissions then act as though the remote end sent
244 * us the file permissions we already have */
245 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
248 if (S_ISDIR(file->mode)) {
249 /* The file to be received is a directory, so we need
250 * to prepare appropriately. If there is already a
251 * file of that name and it is *not* a directory, then
252 * we need to delete it. If it doesn't exist, then
253 * recursively create it. */
255 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
256 if (statret == 0 && !S_ISDIR(st.st_mode)) {
257 if (robust_unlink(fname) != 0) {
258 rprintf(FERROR, RSYNC_NAME
259 ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
260 fname,strerror(errno));
265 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
266 if (!(relative_paths && errno==ENOENT &&
267 create_directory_path(fname, orig_umask)==0 &&
268 do_mkdir(fname,file->mode)==0)) {
269 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
270 fname,strerror(errno));
273 /* f_out is set to -1 when doing final directory
274 permission and modification time repair */
275 if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
276 rprintf(FINFO,"%s/\n",fname);
280 if (preserve_links && S_ISLNK(file->mode)) {
282 char lnk[MAXPATHLEN];
284 extern int safe_symlinks;
286 if (safe_symlinks && unsafe_symlink(file->link, fname)) {
288 rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
294 l = readlink(fname,lnk,MAXPATHLEN-1);
297 /* A link already pointing to the
298 * right place -- no further action
300 if (strcmp(lnk,file->link) == 0) {
301 set_perms(fname,file,&st,1);
305 /* Not a symlink, so delete whatever's
306 * already there and put a new symlink
310 if (do_symlink(file->link,fname) != 0) {
311 rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
312 fname,file->link,strerror(errno));
314 set_perms(fname,file,NULL,0);
316 rprintf(FINFO,"%s -> %s\n", fname,file->link);
324 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
326 st.st_mode != file->mode ||
327 st.st_rdev != file->rdev) {
330 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
331 fname,(int)file->mode,(int)file->rdev);
332 if (do_mknod(fname,file->mode,file->rdev) != 0) {
333 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
335 set_perms(fname,file,NULL,0);
337 rprintf(FINFO,"%s\n",fname);
340 set_perms(fname,file,&st,1);
346 if (preserve_hard_links && check_hard_link(file)) {
348 rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
352 if (!S_ISREG(file->mode)) {
353 rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
359 if ((statret == -1) && (compare_dest != NULL)) {
360 /* try the file at compare_dest instead */
361 int saveerrno = errno;
362 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
363 statret = link_stat(fnamecmpbuf,&st);
364 if (!S_ISREG(st.st_mode))
369 else if (link_dest && !dry_run) {
370 if (do_link(fnamecmpbuf, fname) != 0) {
372 rprintf(FINFO,"link %s => %s : %s\n",
377 fnamecmp = fnamecmpbuf;
381 fnamecmp = fnamecmpbuf;
385 if (errno == ENOENT) {
387 if (!dry_run) send_null_sums(f_out);
390 rprintf(FERROR, RSYNC_NAME
391 ": recv_generator failed to open \"%s\": %s\n",
392 fname, strerror(errno));
397 if (!S_ISREG(st.st_mode)) {
398 if (delete_file(fname) != 0) {
402 /* now pretend the file didn't exist */
404 if (!dry_run) send_null_sums(f_out);
408 if (opt_ignore_existing && fnamecmp == fname) {
410 rprintf(FINFO,"%s exists\n",fname);
414 if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
416 rprintf(FINFO,"%s is newer\n",fname);
420 if (skip_file(fname, file, &st)) {
421 if (fnamecmp == fname)
422 set_perms(fname,file,&st,1);
431 if (disable_deltas_p()) {
433 send_null_sums(f_out);
438 fd = do_open(fnamecmp, O_RDONLY, 0);
441 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
442 /* pretend the file didn't exist */
444 send_null_sums(f_out);
448 if (st.st_size > 0) {
449 buf = map_file(fd,st.st_size);
455 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
458 rprintf(FINFO, "generating and sending sums for %d\n", i);
461 generate_and_send_sums(buf, st.st_size,
462 adapt_block_size(file, block_size), f_out);
465 if (buf) unmap_file(buf);
470 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
476 rprintf(FINFO,"generator starting pid=%d count=%d\n",
477 (int)getpid(),flist->count);
482 ? "delta-transmission disabled for local transfer or --whole-file\n"
483 : "delta transmission enabled\n");
486 /* we expect to just sit around now, so don't exit on a
487 timeout. If we really get a timeout then the other process should
491 for (i = 0; i < flist->count; i++) {
492 struct file_struct *file = flist->files[i];
493 mode_t saved_mode = file->mode;
494 if (!file->basename) continue;
496 /* we need to ensure that any directories we create have writeable
497 permissions initially so that we can create the files within
498 them. This is then fixed after the files are transferred */
499 if (!am_root && S_ISDIR(file->mode)) {
500 file->mode |= S_IWUSR; /* user write */
501 /* XXX: Could this be causing a problem on SCO? Perhaps their
502 * handling of permissions is strange? */
505 recv_generator(local_name?local_name:f_name(file), flist,i,f);
507 file->mode = saved_mode;
511 csum_length = SUM_LENGTH;
515 rprintf(FINFO,"generate_files phase=%d\n",phase);
519 if (remote_version >= 13) {
520 /* in newer versions of the protocol the files can cycle through
521 the system more than once to catch initial checksum errors */
522 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
523 struct file_struct *file = flist->files[i];
524 recv_generator(local_name?local_name:f_name(file),
530 rprintf(FINFO,"generate_files phase=%d\n",phase);