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 * NULL sum_struct means we have no checksums
122 void write_sum_head(int f, struct sum_struct *sum)
124 static struct sum_struct null_sum;
126 if (sum == (struct sum_struct *)NULL)
129 write_int(f, sum->count);
130 write_int(f, sum->blength);
131 if (remote_version >= 27)
132 write_int(f, sum->s2length);
133 write_int(f, sum->remainder);
139 * Perhaps we want to just send an empty checksum set for this file,
140 * which will force the whole thing to be literally transferred.
142 * When do we do this? If the user's explicitly said they
143 * want the whole thing, or if { they haven't explicitly
144 * requested a delta, and it's local but not batch mode.}
147 static BOOL disable_deltas_p(void)
149 extern int whole_file;
150 extern int local_server;
151 extern int write_batch;
155 if (whole_file == 0 || write_batch)
162 * Generate and send a stream of signatures/checksums that describe a buffer
164 * Generate approximately one checksum every block_len bytes.
166 static void generate_and_send_sums(struct map_struct *buf, OFF_T len,
167 int block_len, int f_out)
170 struct sum_struct sum;
173 sum.count = (len + (block_len - 1)) / block_len;
174 sum.remainder = (len % block_len);
175 sum.blength = block_len;
177 sum.s2length = csum_length;
178 /* not needed here sum.sums = NULL; */
180 if (sum.count && verbose > 3) {
181 rprintf(FINFO, "count=%ld rem=%ld n=%ld flength=%.0f\n",
182 (long) sum.count, (long) sum.remainder,
183 (long) sum.blength, (double) sum.flength);
186 write_sum_head(f_out, &sum);
188 for (i = 0; i < sum.count; i++) {
189 int n1 = MIN(len, block_len);
190 char *map = map_ptr(buf, offset, n1);
191 uint32 sum1 = get_checksum1(map, n1);
192 char sum2[SUM_LENGTH];
194 get_checksum2(map, n1, sum2);
198 "chunk[%d] offset=%.0f len=%d sum1=%08lx\n",
199 i, (double) offset, n1, (unsigned long) sum1);
201 write_int(f_out, sum1);
202 write_buf(f_out, sum2, sum.s2length);
211 * Acts on file number @p i from @p flist, whose name is @p fname.
213 * First fixes up permissions, then generates checksums for the file.
215 * @note This comment was added later by mbp who was trying to work it
216 * out. It might be wrong.
218 void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
222 struct map_struct *buf;
224 struct file_struct *file = flist->files[i];
226 char fnamecmpbuf[MAXPATHLEN];
227 extern char *compare_dest;
228 extern int list_only;
229 extern int preserve_perms;
230 extern int only_existing;
231 extern int orig_umask;
233 if (list_only) return;
236 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
238 statret = link_stat(fname,&st);
240 if (only_existing && statret == -1 && errno == ENOENT) {
241 /* we only want to update existing files */
242 if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
248 (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
249 /* if the file exists already and we aren't perserving
250 * permissions then act as though the remote end sent
251 * us the file permissions we already have */
252 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
255 if (S_ISDIR(file->mode)) {
256 /* The file to be received is a directory, so we need
257 * to prepare appropriately. If there is already a
258 * file of that name and it is *not* a directory, then
259 * we need to delete it. If it doesn't exist, then
260 * recursively create it. */
262 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
263 if (statret == 0 && !S_ISDIR(st.st_mode)) {
264 if (robust_unlink(fname) != 0) {
265 rprintf(FERROR, RSYNC_NAME
266 ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
267 fname,strerror(errno));
272 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
273 if (!(relative_paths && errno==ENOENT &&
274 create_directory_path(fname, orig_umask)==0 &&
275 do_mkdir(fname,file->mode)==0)) {
276 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
277 fname,strerror(errno));
280 /* f_out is set to -1 when doing final directory
281 permission and modification time repair */
282 if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
283 rprintf(FINFO,"%s/\n",fname);
287 if (preserve_links && S_ISLNK(file->mode)) {
289 char lnk[MAXPATHLEN];
291 extern int safe_symlinks;
293 if (safe_symlinks && unsafe_symlink(file->link, fname)) {
295 rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
301 l = readlink(fname,lnk,MAXPATHLEN-1);
304 /* A link already pointing to the
305 * right place -- no further action
307 if (strcmp(lnk,file->link) == 0) {
308 set_perms(fname,file,&st,1);
312 /* Not a symlink, so delete whatever's
313 * already there and put a new symlink
317 if (do_symlink(file->link,fname) != 0) {
318 rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
319 fname,file->link,strerror(errno));
321 set_perms(fname,file,NULL,0);
323 rprintf(FINFO,"%s -> %s\n", fname,file->link);
331 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
333 st.st_mode != file->mode ||
334 st.st_rdev != file->rdev) {
337 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
338 fname,(int)file->mode,(int)file->rdev);
339 if (do_mknod(fname,file->mode,file->rdev) != 0) {
340 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
342 set_perms(fname,file,NULL,0);
344 rprintf(FINFO,"%s\n",fname);
347 set_perms(fname,file,&st,1);
353 if (preserve_hard_links && check_hard_link(file)) {
355 rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
359 if (!S_ISREG(file->mode)) {
360 rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
366 if ((statret == -1) && (compare_dest != NULL)) {
367 /* try the file at compare_dest instead */
368 int saveerrno = errno;
369 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
370 statret = link_stat(fnamecmpbuf,&st);
371 if (!S_ISREG(st.st_mode))
376 else if (link_dest && !dry_run) {
377 if (do_link(fnamecmpbuf, fname) != 0) {
379 rprintf(FINFO,"link %s => %s : %s\n",
384 fnamecmp = fnamecmpbuf;
388 fnamecmp = fnamecmpbuf;
392 if (errno == ENOENT) {
394 if (!dry_run) write_sum_head(f_out, NULL);
397 rprintf(FERROR, RSYNC_NAME
398 ": recv_generator failed to open \"%s\": %s\n",
399 fname, strerror(errno));
404 if (!S_ISREG(st.st_mode)) {
405 if (delete_file(fname) != 0) {
409 /* now pretend the file didn't exist */
411 if (!dry_run) write_sum_head(f_out, NULL);
415 if (opt_ignore_existing && fnamecmp == fname) {
417 rprintf(FINFO,"%s exists\n",fname);
421 if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
423 rprintf(FINFO,"%s is newer\n",fname);
427 if (skip_file(fname, file, &st)) {
428 if (fnamecmp == fname)
429 set_perms(fname,file,&st,1);
438 if (disable_deltas_p()) {
440 write_sum_head(f_out, NULL);
445 fd = do_open(fnamecmp, O_RDONLY, 0);
448 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
449 /* pretend the file didn't exist */
451 write_sum_head(f_out, NULL);
455 if (st.st_size > 0) {
456 buf = map_file(fd,st.st_size);
462 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
465 rprintf(FINFO, "generating and sending sums for %d\n", i);
468 generate_and_send_sums(buf, st.st_size,
469 adapt_block_size(file, block_size), f_out);
472 if (buf) unmap_file(buf);
477 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
483 rprintf(FINFO,"generator starting pid=%d count=%d\n",
484 (int)getpid(),flist->count);
489 ? "delta-transmission disabled for local transfer or --whole-file\n"
490 : "delta transmission enabled\n");
493 /* we expect to just sit around now, so don't exit on a
494 timeout. If we really get a timeout then the other process should
498 for (i = 0; i < flist->count; i++) {
499 struct file_struct *file = flist->files[i];
500 mode_t saved_mode = file->mode;
501 if (!file->basename) continue;
503 /* we need to ensure that any directories we create have writeable
504 permissions initially so that we can create the files within
505 them. This is then fixed after the files are transferred */
506 if (!am_root && S_ISDIR(file->mode)) {
507 file->mode |= S_IWUSR; /* user write */
508 /* XXX: Could this be causing a problem on SCO? Perhaps their
509 * handling of permissions is strange? */
512 recv_generator(local_name?local_name:f_name(file), flist,i,f);
514 file->mode = saved_mode;
518 csum_length = SUM_LENGTH;
522 rprintf(FINFO,"generate_files phase=%d\n",phase);
526 /* files can cycle through the system more than once
527 * to catch initial checksum errors */
528 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
529 struct file_struct *file = flist->files[i];
530 recv_generator(local_name?local_name:f_name(file), flist,i,f);
535 rprintf(FINFO,"generate_files phase=%d\n",phase);