- added info on the mailing list
[rsync/rsync.git] / rsync.c
CommitLineData
c627d613
AT
1/*
2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
4
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.
9
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.
14
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.
18*/
19
20#include "rsync.h"
21
43a481dc
AT
22extern int csum_length;
23
c627d613
AT
24extern int verbose;
25extern int am_server;
26extern int always_checksum;
27extern time_t starttime;
28
c6e7fcb4
AT
29extern int remote_version;
30
c627d613
AT
31extern char *backup_suffix;
32
33extern int block_size;
34extern int update_only;
35extern int make_backups;
36extern int preserve_links;
dc5ddbcc 37extern int preserve_hard_links;
c627d613
AT
38extern int preserve_perms;
39extern int preserve_devices;
40extern int preserve_uid;
41extern int preserve_gid;
42extern int preserve_times;
43extern int dry_run;
44extern int ignore_times;
45extern int recurse;
46extern int delete_mode;
47extern int cvs_exclude;
7b8356d0 48extern int am_root;
c627d613
AT
49
50/*
51 free a sums struct
52 */
53static void free_sums(struct sum_struct *s)
54{
55 if (s->sums) free(s->sums);
56 free(s);
57}
58
59
60
61/*
62 send a sums struct down a fd
63 */
64static void send_sums(struct sum_struct *s,int f_out)
65{
66 int i;
67
68 /* tell the other guy how many we are going to be doing and how many
69 bytes there are in the last chunk */
70 write_int(f_out,s?s->count:0);
71 write_int(f_out,s?s->n:block_size);
72 write_int(f_out,s?s->remainder:0);
73 if (s)
74 for (i=0;i<s->count;i++) {
75 write_int(f_out,s->sums[i].sum1);
43a481dc 76 write_buf(f_out,s->sums[i].sum2,csum_length);
c627d613
AT
77 }
78 write_flush(f_out);
79}
80
81
82/*
83 generate a stream of signatures/checksums that describe a buffer
84
85 generate approximately one checksum every n bytes
86 */
c6e7fcb4 87static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n)
c627d613
AT
88{
89 int i;
90 struct sum_struct *s;
91 int count;
92 int block_len = n;
93 int remainder = (len%block_len);
94 off_t offset = 0;
95
96 count = (len+(block_len-1))/block_len;
97
98 s = (struct sum_struct *)malloc(sizeof(*s));
99 if (!s) out_of_memory("generate_sums");
100
101 s->count = count;
102 s->remainder = remainder;
103 s->n = n;
104 s->flength = len;
105
106 if (count==0) {
107 s->sums = NULL;
108 return s;
109 }
110
111 if (verbose > 3)
dc5ddbcc 112 fprintf(FERROR,"count=%d rem=%d n=%d flength=%d\n",
c627d613
AT
113 s->count,s->remainder,s->n,(int)s->flength);
114
115 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
116 if (!s->sums) out_of_memory("generate_sums");
117
118 for (i=0;i<count;i++) {
119 int n1 = MIN(len,n);
d9bea2dd 120 char *map = map_ptr(buf,offset,n1);
c627d613 121
d9bea2dd
AT
122 s->sums[i].sum1 = get_checksum1(map,n1);
123 get_checksum2(map,n1,s->sums[i].sum2);
c627d613
AT
124
125 s->sums[i].offset = offset;
126 s->sums[i].len = n1;
127 s->sums[i].i = i;
128
129 if (verbose > 3)
dc5ddbcc 130 fprintf(FERROR,"chunk[%d] offset=%d len=%d sum1=%08x\n",
c627d613
AT
131 i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
132
133 len -= n1;
c627d613
AT
134 offset += n1;
135 }
136
137 return s;
138}
139
140
141/*
142 receive the checksums for a buffer
143 */
144static struct sum_struct *receive_sums(int f)
145{
146 struct sum_struct *s;
147 int i;
148 off_t offset = 0;
149 int block_len;
150
151 s = (struct sum_struct *)malloc(sizeof(*s));
152 if (!s) out_of_memory("receive_sums");
153
154 s->count = read_int(f);
155 s->n = read_int(f);
156 s->remainder = read_int(f);
157 s->sums = NULL;
158
159 if (verbose > 3)
dc5ddbcc 160 fprintf(FERROR,"count=%d n=%d rem=%d\n",
c627d613
AT
161 s->count,s->n,s->remainder);
162
163 block_len = s->n;
164
165 if (s->count == 0)
166 return(s);
167
168 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
169 if (!s->sums) out_of_memory("receive_sums");
170
171 for (i=0;i<s->count;i++) {
172 s->sums[i].sum1 = read_int(f);
43a481dc 173 read_buf(f,s->sums[i].sum2,csum_length);
c627d613
AT
174
175 s->sums[i].offset = offset;
176 s->sums[i].i = i;
177
178 if (i == s->count-1 && s->remainder != 0) {
179 s->sums[i].len = s->remainder;
180 } else {
181 s->sums[i].len = s->n;
182 }
183 offset += s->sums[i].len;
184
185 if (verbose > 3)
dc5ddbcc 186 fprintf(FERROR,"chunk[%d] len=%d offset=%d sum1=%08x\n",
c627d613
AT
187 i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
188 }
189
190 s->flength = offset;
191
192 return s;
193}
194
195
7b8356d0
AT
196static int set_perms(char *fname,struct file_struct *file,struct stat *st,
197 int report)
c627d613
AT
198{
199 int updated = 0;
200 struct stat st2;
201
7b8356d0 202 if (dry_run) return 0;
c627d613
AT
203
204 if (!st) {
7b8356d0 205 if (lstat(fname,&st2) != 0) {
dc5ddbcc 206 fprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
7b8356d0 207 return 0;
c627d613
AT
208 }
209 st = &st2;
210 }
211
7bec6a5c
AT
212 if (preserve_times && !S_ISLNK(st->st_mode) &&
213 st->st_mtime != file->modtime) {
c627d613
AT
214 updated = 1;
215 if (set_modtime(fname,file->modtime) != 0) {
dc5ddbcc 216 fprintf(FERROR,"failed to set times on %s : %s\n",
c627d613 217 fname,strerror(errno));
7b8356d0 218 return 0;
c627d613
AT
219 }
220 }
221
222#ifdef HAVE_CHMOD
7bec6a5c
AT
223 if (preserve_perms && !S_ISLNK(st->st_mode) &&
224 st->st_mode != file->mode) {
c627d613
AT
225 updated = 1;
226 if (chmod(fname,file->mode) != 0) {
dc5ddbcc 227 fprintf(FERROR,"failed to set permissions on %s : %s\n",
c627d613 228 fname,strerror(errno));
7b8356d0 229 return 0;
c627d613
AT
230 }
231 }
232#endif
233
7b8356d0 234 if ((am_root && preserve_uid && st->st_uid != file->uid) ||
c627d613
AT
235 (preserve_gid && st->st_gid != file->gid)) {
236 updated = 1;
237 if (chown(fname,
7b8356d0 238 (am_root&&preserve_uid)?file->uid:-1,
c627d613
AT
239 preserve_gid?file->gid:-1) != 0) {
240 if (verbose>1 || preserve_uid)
dc5ddbcc 241 fprintf(FERROR,"chown %s : %s\n",fname,strerror(errno));
7b8356d0 242 return updated;
c627d613
AT
243 }
244 }
245
246 if (verbose > 1 && report) {
247 if (updated)
dc5ddbcc 248 fprintf(FINFO,"%s\n",fname);
c627d613 249 else
dc5ddbcc 250 fprintf(FINFO,"%s is uptodate\n",fname);
c627d613 251 }
7b8356d0 252 return updated;
c627d613
AT
253}
254
255
256void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
257{
258 int fd;
259 struct stat st;
c6e7fcb4 260 struct map_struct *buf;
c627d613 261 struct sum_struct *s;
ebb0a6f6 262 char sum[MD4_SUM_LENGTH];
c627d613 263 int statret;
dc5ddbcc 264 struct file_struct *file = &flist->files[i];
c627d613
AT
265
266 if (verbose > 2)
9e31c482 267 fprintf(FERROR,"recv_generator(%s,%d)\n",fname,i);
c627d613
AT
268
269 statret = lstat(fname,&st);
270
7b8356d0
AT
271 if (S_ISDIR(file->mode)) {
272 if (dry_run) return;
273 if (statret == 0 && !S_ISDIR(st.st_mode)) {
274 if (unlink(fname) != 0) {
275 fprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
276 return;
277 }
278 statret = -1;
279 }
280 if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST)
281 fprintf(FERROR,"mkdir %s : %s\n",fname,strerror(errno));
282 if (set_perms(fname,file,NULL,0) && verbose)
283 fprintf(FINFO,"%s/\n",fname);
284 return;
285 }
286
c627d613 287#if SUPPORT_LINKS
dc5ddbcc 288 if (preserve_links && S_ISLNK(file->mode)) {
c627d613
AT
289 char lnk[MAXPATHLEN];
290 int l;
291 if (statret == 0) {
292 l = readlink(fname,lnk,MAXPATHLEN-1);
293 if (l > 0) {
294 lnk[l] = 0;
dc5ddbcc
AT
295 if (strcmp(lnk,file->link) == 0) {
296 set_perms(fname,file,&st,1);
c627d613
AT
297 return;
298 }
299 }
300 }
301 if (!dry_run) unlink(fname);
dc5ddbcc
AT
302 if (!dry_run && symlink(file->link,fname) != 0) {
303 fprintf(FERROR,"link %s -> %s : %s\n",
304 fname,file->link,strerror(errno));
c627d613 305 } else {
dc5ddbcc 306 set_perms(fname,file,NULL,0);
c627d613 307 if (verbose)
dc5ddbcc
AT
308 fprintf(FINFO,"%s -> %s\n",
309 fname,file->link);
c627d613
AT
310 }
311 return;
312 }
313#endif
314
315#ifdef HAVE_MKNOD
7b8356d0 316 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
c627d613 317 if (statret != 0 ||
dc5ddbcc
AT
318 st.st_mode != file->mode ||
319 st.st_rdev != file->rdev) {
c627d613
AT
320 if (!dry_run) unlink(fname);
321 if (verbose > 2)
dc5ddbcc
AT
322 fprintf(FERROR,"mknod(%s,0%o,0x%x)\n",
323 fname,(int)file->mode,(int)file->rdev);
c627d613 324 if (!dry_run &&
dc5ddbcc
AT
325 mknod(fname,file->mode,file->rdev) != 0) {
326 fprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
c627d613 327 } else {
dc5ddbcc 328 set_perms(fname,file,NULL,0);
c627d613 329 if (verbose)
dc5ddbcc 330 fprintf(FINFO,"%s\n",fname);
c627d613
AT
331 }
332 } else {
dc5ddbcc 333 set_perms(fname,file,&st,1);
c627d613
AT
334 }
335 return;
336 }
337#endif
338
dc5ddbcc
AT
339 if (preserve_hard_links && check_hard_link(file)) {
340 if (verbose > 1)
341 fprintf(FINFO,"%s is a hard link\n",file->name);
342 return;
343 }
344
345 if (!S_ISREG(file->mode)) {
346 fprintf(FERROR,"skipping non-regular file %s\n",fname);
c627d613
AT
347 return;
348 }
349
350 if (statret == -1) {
351 if (errno == ENOENT) {
352 write_int(f_out,i);
353 if (!dry_run) send_sums(NULL,f_out);
354 } else {
355 if (verbose > 1)
dc5ddbcc 356 fprintf(FERROR,"recv_generator failed to open %s\n",fname);
c627d613
AT
357 }
358 return;
359 }
360
361 if (!S_ISREG(st.st_mode)) {
7b8356d0
AT
362 /* its not a regular file on the receiving end, but it is on the
363 sending end. If its a directory then skip it (too dangerous to
364 do a recursive deletion??) otherwise try to unlink it */
365 if (S_ISDIR(st.st_mode)) {
366 fprintf(FERROR,"ERROR: %s is a directory\n",fname);
367 return;
368 }
369 if (unlink(fname) != 0) {
370 fprintf(FERROR,"%s : not a regular file (generator)\n",fname);
371 return;
372 }
373
374 /* now pretend the file didn't exist */
375 write_int(f_out,i);
376 if (!dry_run) send_sums(NULL,f_out);
c627d613
AT
377 return;
378 }
379
dc5ddbcc 380 if (update_only && st.st_mtime >= file->modtime) {
c627d613 381 if (verbose > 1)
dc5ddbcc 382 fprintf(FERROR,"%s is newer\n",fname);
c627d613
AT
383 return;
384 }
385
386 if (always_checksum && S_ISREG(st.st_mode)) {
387 file_checksum(fname,sum,st.st_size);
388 }
389
dc5ddbcc
AT
390 if (st.st_size == file->length &&
391 ((!ignore_times && st.st_mtime == file->modtime) ||
c627d613 392 (always_checksum && S_ISREG(st.st_mode) &&
dc5ddbcc
AT
393 memcmp(sum,file->sum,csum_length) == 0))) {
394 set_perms(fname,file,&st,1);
c627d613
AT
395 return;
396 }
397
398 if (dry_run) {
399 write_int(f_out,i);
400 return;
401 }
402
403 /* open the file */
404 fd = open(fname,O_RDONLY);
405
406 if (fd == -1) {
dc5ddbcc 407 fprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
c627d613
AT
408 return;
409 }
410
411 if (st.st_size > 0) {
412 buf = map_file(fd,st.st_size);
c627d613
AT
413 } else {
414 buf = NULL;
415 }
416
417 if (verbose > 3)
9e31c482 418 fprintf(FERROR,"gen mapped %s of size %d\n",fname,(int)st.st_size);
c627d613
AT
419
420 s = generate_sums(buf,st.st_size,block_size);
421
9e31c482
AT
422 if (verbose > 2)
423 fprintf(FERROR,"sending sums for %d\n",i);
424
c627d613
AT
425 write_int(f_out,i);
426 send_sums(s,f_out);
427 write_flush(f_out);
428
429 close(fd);
1cdc8b50 430 if (buf) unmap_file(buf);
c627d613
AT
431
432 free_sums(s);
433}
434
435
436
9e31c482 437static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
c627d613
AT
438{
439 int i,n,remainder,len,count;
440 off_t offset = 0;
441 off_t offset2;
70d794dc 442 char *data;
ebb0a6f6
AT
443 static char file_sum1[MD4_SUM_LENGTH];
444 static char file_sum2[MD4_SUM_LENGTH];
9e31c482 445 char *map=NULL;
c627d613
AT
446
447 count = read_int(f_in);
448 n = read_int(f_in);
449 remainder = read_int(f_in);
450
9e31c482
AT
451 sum_init();
452
70d794dc 453 for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
c627d613
AT
454 if (i > 0) {
455 if (verbose > 3)
dc5ddbcc 456 fprintf(FERROR,"data recv %d at %d\n",i,(int)offset);
c627d613 457
9e31c482
AT
458 sum_update(data,i);
459
7b8356d0 460 if (fd != -1 && write_sparse(fd,data,i) != i) {
dc5ddbcc 461 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 462 exit_cleanup(1);
c627d613
AT
463 }
464 offset += i;
465 } else {
466 i = -(i+1);
467 offset2 = i*n;
468 len = n;
469 if (i == count-1 && remainder != 0)
470 len = remainder;
471
472 if (verbose > 3)
dc5ddbcc 473 fprintf(FERROR,"chunk[%d] of size %d at %d offset=%d\n",
c627d613
AT
474 i,len,(int)offset2,(int)offset);
475
9e31c482
AT
476 map = map_ptr(buf,offset2,len);
477
861c20b4 478 see_token(map, len);
9e31c482
AT
479 sum_update(map,len);
480
7b8356d0 481 if (fd != -1 && write_sparse(fd,map,len) != len) {
dc5ddbcc 482 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 483 exit_cleanup(1);
c627d613
AT
484 }
485 offset += len;
486 }
487 }
7bec6a5c 488
7b8356d0 489 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
dc5ddbcc 490 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 491 exit_cleanup(1);
7bec6a5c 492 }
9e31c482
AT
493
494 sum_end(file_sum1);
495
496 if (remote_version >= 14) {
ebb0a6f6 497 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
9e31c482
AT
498 if (verbose > 2)
499 fprintf(FERROR,"got file_sum\n");
7b8356d0 500 if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
9e31c482
AT
501 return 0;
502 }
503 return 1;
c627d613
AT
504}
505
506
507static void delete_one(struct file_struct *f)
508{
509 if (!S_ISDIR(f->mode)) {
510 if (!dry_run && unlink(f->name) != 0) {
dc5ddbcc 511 fprintf(FERROR,"unlink %s : %s\n",f->name,strerror(errno));
c627d613 512 } else if (verbose) {
dc5ddbcc 513 fprintf(FERROR,"deleting %s\n",f->name);
c627d613
AT
514 }
515 } else {
516 if (!dry_run && rmdir(f->name) != 0) {
517 if (errno != ENOTEMPTY)
dc5ddbcc 518 fprintf(FERROR,"rmdir %s : %s\n",f->name,strerror(errno));
c627d613 519 } else if (verbose) {
dc5ddbcc 520 fprintf(FERROR,"deleting directory %s\n",f->name);
c627d613
AT
521 }
522 }
523}
524
525
526static void delete_files(struct file_list *flist)
527{
528 struct file_list *local_file_list;
529 char *dot=".";
530 int i;
531
4fe159a8 532 if (cvs_exclude)
79fbb6f5 533 add_cvs_excludes();
4fe159a8 534
a06d19e3 535 if (!(local_file_list = send_file_list(-1,1,&dot)))
c627d613
AT
536 return;
537
538 for (i=local_file_list->count;i>=0;i--) {
539 if (!local_file_list->files[i].name) continue;
540 if (-1 == flist_find(flist,&local_file_list->files[i])) {
541 delete_one(&local_file_list->files[i]);
542 }
543 }
544}
545
546static char *cleanup_fname = NULL;
547
34ccb63e 548void exit_cleanup(int code)
c627d613
AT
549{
550 if (cleanup_fname)
551 unlink(cleanup_fname);
34ccb63e
AT
552 exit(code);
553}
554
555void sig_int(void)
556{
557 exit_cleanup(1);
c627d613
AT
558}
559
560
c6e7fcb4 561int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
c627d613
AT
562{
563 int fd1,fd2;
564 struct stat st;
565 char *fname;
566 char fnametmp[MAXPATHLEN];
c6e7fcb4 567 struct map_struct *buf;
c627d613 568 int i;
dc5ddbcc 569 struct file_struct *file;
c6e7fcb4 570 int phase=0;
9e31c482 571 int recv_ok;
c627d613 572
981791bd 573 if (verbose > 2) {
dc5ddbcc 574 fprintf(FERROR,"recv_files(%d) starting\n",flist->count);
981791bd 575 }
c627d613
AT
576
577 if (recurse && delete_mode && !local_name && flist->count>0) {
578 delete_files(flist);
579 }
580
581 while (1)
9e31c482 582 {
c627d613 583 i = read_int(f_in);
c6e7fcb4
AT
584 if (i == -1) {
585 if (phase==0 && remote_version >= 13) {
586 phase++;
9e31c482
AT
587 csum_length = SUM_LENGTH;
588 if (verbose > 2)
589 fprintf(FERROR,"recv_files phase=%d\n",phase);
c6e7fcb4
AT
590 write_int(f_gen,-1);
591 write_flush(f_gen);
592 continue;
593 }
594 break;
595 }
c627d613 596
dc5ddbcc
AT
597 file = &flist->files[i];
598 fname = file->name;
c627d613
AT
599
600 if (local_name)
601 fname = local_name;
602
603 if (dry_run) {
604 if (!am_server && verbose)
605 printf("%s\n",fname);
606 continue;
607 }
608
609 if (verbose > 2)
dc5ddbcc 610 fprintf(FERROR,"recv_files(%s)\n",fname);
c627d613
AT
611
612 /* open the file */
ac1eb754 613 fd1 = open(fname,O_RDONLY);
c627d613 614
ac1eb754 615 if (fd1 != -1 && fstat(fd1,&st) != 0) {
dc5ddbcc 616 fprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
7b8356d0 617 receive_data(f_in,NULL,-1,NULL);
c627d613 618 close(fd1);
7b8356d0 619 continue;
c627d613
AT
620 }
621
ac1eb754 622 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
7b8356d0
AT
623 fprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
624 receive_data(f_in,NULL,-1,NULL);
c627d613 625 close(fd1);
7b8356d0 626 continue;
c627d613
AT
627 }
628
ac1eb754 629 if (fd1 != -1 && st.st_size > 0) {
c627d613 630 buf = map_file(fd1,st.st_size);
9e31c482
AT
631 if (verbose > 2)
632 fprintf(FERROR,"recv mapped %s of size %d\n",fname,(int)st.st_size);
c627d613
AT
633 } else {
634 buf = NULL;
635 }
636
c627d613
AT
637 /* open tmp file */
638 sprintf(fnametmp,"%s.XXXXXX",fname);
639 if (NULL == mktemp(fnametmp)) {
dc5ddbcc 640 fprintf(FERROR,"mktemp %s failed\n",fnametmp);
7b8356d0
AT
641 receive_data(f_in,buf,-1,NULL);
642 if (buf) unmap_file(buf);
643 close(fd1);
644 continue;
c627d613 645 }
dc5ddbcc 646 fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
c627d613 647 if (fd2 == -1) {
dc5ddbcc 648 fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
7b8356d0
AT
649 receive_data(f_in,buf,-1,NULL);
650 if (buf) unmap_file(buf);
651 close(fd1);
652 continue;
c627d613
AT
653 }
654
655 cleanup_fname = fnametmp;
656
657 if (!am_server && verbose)
658 printf("%s\n",fname);
659
660 /* recv file data */
9e31c482 661 recv_ok = receive_data(f_in,buf,fd2,fname);
c627d613 662
981791bd 663 if (fd1 != -1) {
1cdc8b50 664 if (buf) unmap_file(buf);
981791bd
AT
665 close(fd1);
666 }
c627d613
AT
667 close(fd2);
668
669 if (verbose > 2)
dc5ddbcc 670 fprintf(FERROR,"renaming %s to %s\n",fnametmp,fname);
c627d613
AT
671
672 if (make_backups) {
673 char fnamebak[MAXPATHLEN];
674 sprintf(fnamebak,"%s%s",fname,backup_suffix);
ac1eb754 675 if (rename(fname,fnamebak) != 0 && errno != ENOENT) {
dc5ddbcc 676 fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
7b8356d0 677 continue;
c627d613
AT
678 }
679 }
680
681 /* move tmp file over real file */
682 if (rename(fnametmp,fname) != 0) {
dc5ddbcc 683 fprintf(FERROR,"rename %s -> %s : %s\n",
c627d613 684 fnametmp,fname,strerror(errno));
7b8356d0 685 unlink(fnametmp);
c627d613
AT
686 }
687
688 cleanup_fname = NULL;
689
dc5ddbcc 690 set_perms(fname,file,NULL,0);
9e31c482
AT
691
692 if (!recv_ok) {
693 if (verbose > 1)
694 fprintf(FERROR,"redoing %s(%d)\n",fname,i);
52296954
AT
695 if (csum_length == SUM_LENGTH)
696 fprintf(FERROR,"ERROR: file corruption in %s\n",fname);
9e31c482
AT
697 write_int(f_gen,i);
698 }
c627d613
AT
699 }
700
7b8356d0
AT
701 /* now we need to fix any directory permissions that were
702 modified during the transfer */
703 if (!am_root) {
704 for (i = 0; i < flist->count; i++) {
705 struct file_struct *file = &flist->files[i];
706 if (!file->name || !S_ISDIR(file->mode)) continue;
707 recv_generator(file->name,flist,i,-1);
708 }
709 }
710
711
c627d613 712 if (verbose > 2)
dc5ddbcc 713 fprintf(FERROR,"recv_files finished\n");
c627d613
AT
714
715 return 0;
716}
717
718
719
720off_t send_files(struct file_list *flist,int f_out,int f_in)
721{
722 int fd;
723 struct sum_struct *s;
c6e7fcb4 724 struct map_struct *buf;
c627d613
AT
725 struct stat st;
726 char fname[MAXPATHLEN];
727 off_t total=0;
728 int i;
dc5ddbcc 729 struct file_struct *file;
c6e7fcb4 730 int phase = 0;
c627d613
AT
731
732 if (verbose > 2)
dc5ddbcc 733 fprintf(FERROR,"send_files starting\n");
c627d613 734
720b47f2
AT
735 setup_nonblocking(f_in,f_out);
736
c627d613
AT
737 while (1)
738 {
739 i = read_int(f_in);
c6e7fcb4
AT
740 if (i == -1) {
741 if (phase==0 && remote_version >= 13) {
742 phase++;
9e31c482 743 csum_length = SUM_LENGTH;
c6e7fcb4
AT
744 write_int(f_out,-1);
745 write_flush(f_out);
9e31c482
AT
746 if (verbose > 2)
747 fprintf(FERROR,"send_files phase=%d\n",phase);
c6e7fcb4
AT
748 continue;
749 }
750 break;
751 }
c627d613 752
dc5ddbcc
AT
753 file = &flist->files[i];
754
c627d613 755 fname[0] = 0;
dc5ddbcc
AT
756 if (file->dir) {
757 strcpy(fname,file->dir);
c627d613
AT
758 strcat(fname,"/");
759 }
dc5ddbcc 760 strcat(fname,file->name);
c627d613
AT
761
762 if (verbose > 2)
dc5ddbcc 763 fprintf(FERROR,"send_files(%d,%s)\n",i,fname);
c627d613
AT
764
765 if (dry_run) {
766 if (!am_server && verbose)
767 printf("%s\n",fname);
768 write_int(f_out,i);
769 continue;
770 }
771
772 s = receive_sums(f_in);
773 if (!s) {
dc5ddbcc 774 fprintf(FERROR,"receive_sums failed\n");
c627d613
AT
775 return -1;
776 }
777
778 fd = open(fname,O_RDONLY);
779 if (fd == -1) {
dc5ddbcc 780 fprintf(FERROR,"send_files failed to open %s: %s\n",
c627d613
AT
781 fname,strerror(errno));
782 continue;
783 }
784
785 /* map the local file */
786 if (fstat(fd,&st) != 0) {
dc5ddbcc 787 fprintf(FERROR,"fstat failed : %s\n",strerror(errno));
c627d613
AT
788 return -1;
789 }
790
791 if (st.st_size > 0) {
792 buf = map_file(fd,st.st_size);
c627d613
AT
793 } else {
794 buf = NULL;
795 }
796
797 if (verbose > 2)
dc5ddbcc 798 fprintf(FERROR,"send_files mapped %s of size %d\n",
c627d613
AT
799 fname,(int)st.st_size);
800
801 write_int(f_out,i);
802
803 write_int(f_out,s->count);
804 write_int(f_out,s->n);
805 write_int(f_out,s->remainder);
806
807 if (verbose > 2)
dc5ddbcc 808 fprintf(FERROR,"calling match_sums %s\n",fname);
c627d613
AT
809
810 if (!am_server && verbose)
811 printf("%s\n",fname);
812
720b47f2 813 match_sums(f_out,s,buf,st.st_size);
c627d613
AT
814 write_flush(f_out);
815
1cdc8b50 816 if (buf) unmap_file(buf);
c627d613
AT
817 close(fd);
818
819 free_sums(s);
820
821 if (verbose > 2)
dc5ddbcc 822 fprintf(FERROR,"sender finished %s\n",fname);
c627d613
AT
823
824 total += st.st_size;
825 }
826
dc5ddbcc
AT
827 if (verbose > 2)
828 fprintf(FERROR,"send files finished\n");
829
c627d613
AT
830 match_report();
831
832 write_int(f_out,-1);
833 write_flush(f_out);
834
835 return total;
836}
837
838
839
c6e7fcb4 840void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
c627d613
AT
841{
842 int i;
9e31c482 843 int phase=0;
c627d613
AT
844
845 if (verbose > 2)
dc5ddbcc 846 fprintf(FERROR,"generator starting pid=%d count=%d\n",
c627d613
AT
847 (int)getpid(),flist->count);
848
849 for (i = 0; i < flist->count; i++) {
dc5ddbcc 850 struct file_struct *file = &flist->files[i];
7b8356d0 851 mode_t saved_mode = file->mode;
dc5ddbcc 852 if (!file->name) continue;
7b8356d0
AT
853
854 /* we need to ensure that any directories we create have writeable
855 permissions initially so that we can create the files within
856 them. This is then fixed after the files are transferred */
857 if (!am_root && S_ISDIR(file->mode)) {
858 file->mode |= S_IWUSR; /* user write */
c627d613 859 }
7b8356d0 860
dc5ddbcc 861 recv_generator(local_name?local_name:file->name,
c627d613 862 flist,i,f);
7b8356d0
AT
863
864 file->mode = saved_mode;
c627d613 865 }
c6e7fcb4 866
9e31c482
AT
867 phase++;
868 csum_length = SUM_LENGTH;
869 ignore_times=1;
870
871 if (verbose > 2)
872 fprintf(FERROR,"generate_files phase=%d\n",phase);
873
c627d613
AT
874 write_int(f,-1);
875 write_flush(f);
c6e7fcb4
AT
876
877 if (remote_version >= 13) {
7b8356d0
AT
878 /* in newer versions of the protocol the files can cycle through
879 the system more than once to catch initial checksum errors */
c6e7fcb4
AT
880 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
881 struct file_struct *file = &flist->files[i];
882 recv_generator(local_name?local_name:file->name,
883 flist,i,f);
884 }
885
9e31c482
AT
886 phase++;
887 if (verbose > 2)
888 fprintf(FERROR,"generate_files phase=%d\n",phase);
889
c6e7fcb4
AT
890 write_int(f,-1);
891 write_flush(f);
892 }
893
894
c627d613 895 if (verbose > 2)
dc5ddbcc 896 fprintf(FERROR,"generator wrote %d\n",write_total());
c627d613 897}
dc5ddbcc
AT
898
899