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 whole_file;
36 extern int block_size;
37 extern int csum_length;
38 extern int ignore_times;
40 extern int io_timeout;
41 extern int remote_version;
42 extern int always_checksum;
43 extern int modify_window;
44 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 /* if always checksum is set then we use the checksum instead
56 of the file time to determine whether to sync */
57 if (always_checksum && S_ISREG(st->st_mode)) {
58 char sum[MD4_SUM_LENGTH];
59 char fnamecmpdest[MAXPATHLEN];
61 if (compare_dest != NULL) {
62 if (access(fname, 0) != 0) {
63 snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
68 file_checksum(fname,sum,st->st_size);
69 if (remote_version < 21) {
70 return (memcmp(sum,file->sum,2) == 0);
72 return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
84 return (cmp_modtime(st->st_mtime,file->modtime) == 0);
88 /* use a larger block size for really big files */
89 static int adapt_block_size(struct file_struct *file, int bsize)
93 if (bsize != BLOCK_SIZE) return bsize;
95 ret = file->length / (10000); /* rough heuristic */
96 ret = ret & ~15; /* multiple of 16 */
97 if (ret < bsize) ret = bsize;
98 if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
104 send a sums struct down a fd
106 static void send_sums(struct sum_struct *s, int f_out)
111 /* tell the other guy how many we are going to be
112 doing and how many bytes there are in the last
114 write_int(f_out, s->count);
115 write_int(f_out, s->n);
116 write_int(f_out, s->remainder);
118 for (i = 0; i < s->count; i++) {
119 write_int(f_out, s->sums[i].sum1);
120 write_buf(f_out, s->sums[i].sum2, csum_length);
123 /* we don't have checksums */
125 write_int(f_out, block_size);
131 generate a stream of signatures/checksums that describe a buffer
133 generate approximately one checksum every n bytes
135 static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
138 struct sum_struct *s;
141 int remainder = (len%block_len);
144 count = (len+(block_len-1))/block_len;
146 s = (struct sum_struct *)malloc(sizeof(*s));
147 if (!s) out_of_memory("generate_sums");
150 s->remainder = remainder;
160 rprintf(FINFO,"count=%d rem=%d n=%d flength=%.0f\n",
161 s->count,s->remainder,s->n,(double)s->flength);
163 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
164 if (!s->sums) out_of_memory("generate_sums");
166 for (i=0;i<count;i++) {
168 char *map = map_ptr(buf,offset,n1);
170 s->sums[i].sum1 = get_checksum1(map,n1);
171 get_checksum2(map,n1,s->sums[i].sum2);
173 s->sums[i].offset = offset;
178 rprintf(FINFO,"chunk[%d] offset=%.0f len=%d sum1=%08x\n",
179 i,(double)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
191 * Acts on file number I from FLIST, whose name is fname.
193 * First fixes up permissions, then generates checksums for the file.
195 * (This comment was added later by mbp who was trying to work it out;
196 * it might be wrong.)
198 void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
202 struct map_struct *buf;
203 struct sum_struct *s;
205 struct file_struct *file = flist->files[i];
207 char fnamecmpbuf[MAXPATHLEN];
208 extern char *compare_dest;
209 extern int list_only;
210 extern int preserve_perms;
211 extern int only_existing;
213 if (list_only) return;
216 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
218 statret = link_stat(fname,&st);
220 if (only_existing && statret == -1 && errno == ENOENT) {
221 /* we only want to update existing files */
222 if (verbose > 1) rprintf(FINFO, RSYNC_NAME
223 ": not creating new file \"%s\"\n",fname);
229 (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
230 /* if the file exists already and we aren't perserving
231 presmissions then act as though the remote end sent
232 us the file permissions we already have */
233 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
236 if (S_ISDIR(file->mode)) {
237 /* The file to be received is a directory, so we need
238 * to prepare appropriately. If there is already a
239 * file of that name and it is *not* a directory, then
240 * we need to delete it. If it doesn't exist, then
241 * recursively create it. */
243 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
244 if (statret == 0 && !S_ISDIR(st.st_mode)) {
245 if (robust_unlink(fname) != 0) {
246 rprintf(FERROR, RSYNC_NAME
247 ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
248 fname,strerror(errno));
253 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
254 if (!(relative_paths && errno==ENOENT &&
255 create_directory_path(fname)==0 &&
256 do_mkdir(fname,file->mode)==0)) {
257 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
258 fname,strerror(errno));
261 /* f_out is set to -1 when doing final directory
262 permission and modification time repair */
263 if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
264 rprintf(FINFO,"%s/\n",fname);
268 if (preserve_links && S_ISLNK(file->mode)) {
270 char lnk[MAXPATHLEN];
272 extern int safe_symlinks;
274 if (safe_symlinks && unsafe_symlink(file->link, fname)) {
276 rprintf(FINFO,RSYNC_NAME ": ignoring unsafe symlink \"%s\" -> \"%s\"\n",
282 l = readlink(fname,lnk,MAXPATHLEN-1);
285 /* A link already pointing to the
286 * right place -- no further action
288 if (strcmp(lnk,file->link) == 0) {
289 set_perms(fname,file,&st,1);
293 /* Not a symlink, so delete whatever's
294 * already there and put a new symlink
298 if (do_symlink(file->link,fname) != 0) {
299 rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
300 fname,file->link,strerror(errno));
302 set_perms(fname,file,NULL,0);
304 rprintf(FINFO,RSYNC_NAME": %s -> %s\n",
313 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
315 st.st_mode != file->mode ||
316 st.st_rdev != file->rdev) {
319 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
320 fname,(int)file->mode,(int)file->rdev);
321 if (do_mknod(fname,file->mode,file->rdev) != 0) {
322 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
324 set_perms(fname,file,NULL,0);
326 rprintf(FINFO,"%s\n",fname);
329 set_perms(fname,file,&st,1);
335 if (preserve_hard_links && check_hard_link(file)) {
337 rprintf(FINFO, RSYNC_NAME
338 ": \"%s\" is a hard link\n",f_name(file));
342 if (!S_ISREG(file->mode)) {
343 rprintf(FINFO, RSYNC_NAME
344 ": skipping non-regular file \"%s\"\n",fname);
350 if ((statret == -1) && (compare_dest != NULL)) {
351 /* try the file at compare_dest instead */
352 int saveerrno = errno;
353 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
354 statret = link_stat(fnamecmpbuf,&st);
355 if (!S_ISREG(st.st_mode))
360 fnamecmp = fnamecmpbuf;
364 if (errno == ENOENT) {
366 if (!dry_run) send_sums(NULL,f_out);
369 rprintf(FERROR, RSYNC_NAME
370 ": recv_generator failed to open \"%s\": %s\n",
371 fname, strerror(errno));
376 if (!S_ISREG(st.st_mode)) {
377 if (delete_file(fname) != 0) {
381 /* now pretend the file didn't exist */
383 if (!dry_run) send_sums(NULL,f_out);
387 if (opt_ignore_existing && fnamecmp == fname) {
389 rprintf(FINFO,"%s exists\n",fname);
393 if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
395 rprintf(FINFO,"%s is newer\n",fname);
399 if (skip_file(fname, file, &st)) {
400 if (fnamecmp == fname)
401 set_perms(fname,file,&st,1);
412 send_sums(NULL,f_out);
417 fd = do_open(fnamecmp, O_RDONLY, 0);
420 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
421 /* pretend the file didn't exist */
423 send_sums(NULL,f_out);
427 if (st.st_size > 0) {
428 buf = map_file(fd,st.st_size);
434 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
436 s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
439 rprintf(FINFO,"sending sums for %d\n",i);
445 if (buf) unmap_file(buf);
452 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
458 rprintf(FINFO,"generator starting pid=%d count=%d\n",
459 (int)getpid(),flist->count);
461 /* we expect to just sit around now, so don't exit on a
462 timeout. If we really get a timeout then the other process should
466 for (i = 0; i < flist->count; i++) {
467 struct file_struct *file = flist->files[i];
468 mode_t saved_mode = file->mode;
469 if (!file->basename) continue;
471 /* we need to ensure that any directories we create have writeable
472 permissions initially so that we can create the files within
473 them. This is then fixed after the files are transferred */
474 if (!am_root && S_ISDIR(file->mode)) {
475 file->mode |= S_IWUSR; /* user write */
476 /* XXX: Could this be causing a problem on SCO? Perhaps their
477 * handling of permissions is strange? */
480 recv_generator(local_name?local_name:f_name(file),
483 file->mode = saved_mode;
487 csum_length = SUM_LENGTH;
491 rprintf(FINFO,"generate_files phase=%d\n",phase);
495 if (remote_version >= 13) {
496 /* in newer versions of the protocol the files can cycle through
497 the system more than once to catch initial checksum errors */
498 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
499 struct file_struct *file = flist->files[i];
500 recv_generator(local_name?local_name:f_name(file),
506 rprintf(FINFO,"generate_files phase=%d\n",phase);