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