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, "not creating new file \"%s\"\n",fname);
228 (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
229 /* if the file exists already and we aren't perserving
230 presmissions then act as though the remote end sent
231 us the file permissions we already have */
232 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
235 if (S_ISDIR(file->mode)) {
236 /* The file to be received is a directory, so we need
237 * to prepare appropriately. If there is already a
238 * file of that name and it is *not* a directory, then
239 * we need to delete it. If it doesn't exist, then
240 * recursively create it. */
242 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
243 if (statret == 0 && !S_ISDIR(st.st_mode)) {
244 if (robust_unlink(fname) != 0) {
245 rprintf(FERROR, RSYNC_NAME
246 ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
247 fname,strerror(errno));
252 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
253 if (!(relative_paths && errno==ENOENT &&
254 create_directory_path(fname)==0 &&
255 do_mkdir(fname,file->mode)==0)) {
256 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
257 fname,strerror(errno));
260 /* f_out is set to -1 when doing final directory
261 permission and modification time repair */
262 if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
263 rprintf(FINFO,"%s/\n",fname);
267 if (preserve_links && S_ISLNK(file->mode)) {
269 char lnk[MAXPATHLEN];
271 extern int safe_symlinks;
273 if (safe_symlinks && unsafe_symlink(file->link, fname)) {
275 rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
281 l = readlink(fname,lnk,MAXPATHLEN-1);
284 /* A link already pointing to the
285 * right place -- no further action
287 if (strcmp(lnk,file->link) == 0) {
288 set_perms(fname,file,&st,1);
292 /* Not a symlink, so delete whatever's
293 * already there and put a new symlink
297 if (do_symlink(file->link,fname) != 0) {
298 rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
299 fname,file->link,strerror(errno));
301 set_perms(fname,file,NULL,0);
303 rprintf(FINFO,"%s -> %s\n", fname,file->link);
311 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
313 st.st_mode != file->mode ||
314 st.st_rdev != file->rdev) {
317 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
318 fname,(int)file->mode,(int)file->rdev);
319 if (do_mknod(fname,file->mode,file->rdev) != 0) {
320 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
322 set_perms(fname,file,NULL,0);
324 rprintf(FINFO,"%s\n",fname);
327 set_perms(fname,file,&st,1);
333 if (preserve_hard_links && check_hard_link(file)) {
335 rprintf(FINFO, "\"%s\" is a hard link\n",f_name(file));
339 if (!S_ISREG(file->mode)) {
340 rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
346 if ((statret == -1) && (compare_dest != NULL)) {
347 /* try the file at compare_dest instead */
348 int saveerrno = errno;
349 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
350 statret = link_stat(fnamecmpbuf,&st);
351 if (!S_ISREG(st.st_mode))
356 fnamecmp = fnamecmpbuf;
360 if (errno == ENOENT) {
362 if (!dry_run) send_sums(NULL,f_out);
365 rprintf(FERROR, RSYNC_NAME
366 ": recv_generator failed to open \"%s\": %s\n",
367 fname, strerror(errno));
372 if (!S_ISREG(st.st_mode)) {
373 if (delete_file(fname) != 0) {
377 /* now pretend the file didn't exist */
379 if (!dry_run) send_sums(NULL,f_out);
383 if (opt_ignore_existing && fnamecmp == fname) {
385 rprintf(FINFO,"%s exists\n",fname);
389 if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
391 rprintf(FINFO,"%s is newer\n",fname);
395 if (skip_file(fname, file, &st)) {
396 if (fnamecmp == fname)
397 set_perms(fname,file,&st,1);
406 assert(whole_file == 0 || whole_file == 1);
407 /* We should have decided by now. */
410 send_sums(NULL,f_out);
415 fd = do_open(fnamecmp, O_RDONLY, 0);
418 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
419 /* pretend the file didn't exist */
421 send_sums(NULL,f_out);
425 if (st.st_size > 0) {
426 buf = map_file(fd,st.st_size);
432 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
434 s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
437 rprintf(FINFO,"sending sums for %d\n",i);
443 if (buf) unmap_file(buf);
450 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
456 rprintf(FINFO,"generator starting pid=%d count=%d\n",
457 (int)getpid(),flist->count);
459 /* we expect to just sit around now, so don't exit on a
460 timeout. If we really get a timeout then the other process should
464 for (i = 0; i < flist->count; i++) {
465 struct file_struct *file = flist->files[i];
466 mode_t saved_mode = file->mode;
467 if (!file->basename) continue;
469 /* we need to ensure that any directories we create have writeable
470 permissions initially so that we can create the files within
471 them. This is then fixed after the files are transferred */
472 if (!am_root && S_ISDIR(file->mode)) {
473 file->mode |= S_IWUSR; /* user write */
474 /* XXX: Could this be causing a problem on SCO? Perhaps their
475 * handling of permissions is strange? */
478 recv_generator(local_name?local_name:f_name(file),
481 file->mode = saved_mode;
485 csum_length = SUM_LENGTH;
489 rprintf(FINFO,"generate_files phase=%d\n",phase);
493 if (remote_version >= 13) {
494 /* in newer versions of the protocol the files can cycle through
495 the system more than once to catch initial checksum errors */
496 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
497 struct file_struct *file = flist->files[i];
498 recv_generator(local_name?local_name:f_name(file),
504 rprintf(FINFO,"generate_files phase=%d\n",phase);