- detect presence of remsh and use it instead of rsh
[rsync/rsync.git] / main.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
22int verbose = 0;
23int always_checksum = 0;
24time_t starttime;
25off_t total_size = 0;
26int block_size=BLOCK_SIZE;
27
28char *backup_suffix = BACKUP_SUFFIX;
29
30static char *rsync_path = RSYNC_NAME;
31
32int make_backups = 0;
33int preserve_links = 0;
dc5ddbcc 34int preserve_hard_links = 0;
c627d613
AT
35int preserve_perms = 0;
36int preserve_devices = 0;
37int preserve_uid = 0;
38int preserve_gid = 0;
39int preserve_times = 0;
40int update_only = 0;
41int cvs_exclude = 0;
42int dry_run=0;
43int local_server=0;
44int ignore_times=0;
45int delete_mode=0;
46int one_file_system=0;
4fe159a8 47int remote_version=0;
dc5ddbcc 48int sparse_files=0;
70d794dc 49int do_compression=0;
7b8356d0
AT
50int am_root=0;
51int orig_umask=0;
70d794dc 52
34ccb63e 53extern int csum_length;
c627d613
AT
54
55int am_server = 0;
56static int sender = 0;
57int recurse = 0;
58
59static void usage(FILE *f);
60
61static void report(int f)
62{
63 int in,out,tsize;
64 time_t t = time(NULL);
65
66 if (!verbose) return;
67
68 if (am_server && sender) {
69 write_int(f,read_total());
70 write_int(f,write_total());
71 write_int(f,total_size);
72 write_flush(f);
73 return;
74 }
75
76 if (sender) {
77 in = read_total();
78 out = write_total();
79 tsize = (int)total_size;
80 } else {
81 in = read_int(f);
82 out = read_int(f);
83 tsize = read_int(f);
84 }
85
86 printf("wrote %d bytes read %d bytes %g bytes/sec\n",
87 out,in,(in+out)/(0.5 + (t-starttime)));
88 printf("total size is %d speedup is %g\n",
89 tsize,(1.0*tsize)/(in+out));
90}
91
92
93static void server_options(char **args,int *argc)
94{
95 int ac = *argc;
96 static char argstr[50];
97 static char bsize[30];
98 int i, x;
99
100 args[ac++] = "--server";
101
102 if (!sender)
103 args[ac++] = "--sender";
104
105 x = 1;
106 argstr[0] = '-';
107 for (i=0;i<verbose;i++)
108 argstr[x++] = 'v';
109 if (make_backups)
110 argstr[x++] = 'b';
111 if (update_only)
112 argstr[x++] = 'u';
113 if (dry_run)
114 argstr[x++] = 'n';
115 if (preserve_links)
116 argstr[x++] = 'l';
dc5ddbcc
AT
117 if (preserve_hard_links)
118 argstr[x++] = 'H';
c627d613
AT
119 if (preserve_uid)
120 argstr[x++] = 'o';
121 if (preserve_gid)
122 argstr[x++] = 'g';
123 if (preserve_devices)
124 argstr[x++] = 'D';
125 if (preserve_times)
126 argstr[x++] = 't';
127 if (preserve_perms)
128 argstr[x++] = 'p';
129 if (recurse)
130 argstr[x++] = 'r';
131 if (always_checksum)
132 argstr[x++] = 'c';
133 if (cvs_exclude)
134 argstr[x++] = 'C';
135 if (ignore_times)
136 argstr[x++] = 'I';
137 if (one_file_system)
138 argstr[x++] = 'x';
dc5ddbcc
AT
139 if (sparse_files)
140 argstr[x++] = 'S';
861c20b4
PM
141 if (do_compression)
142 argstr[x++] = 'z';
c627d613
AT
143 argstr[x] = 0;
144
145 if (x != 1) args[ac++] = argstr;
146
147 if (block_size != BLOCK_SIZE) {
148 sprintf(bsize,"-B%d",block_size);
149 args[ac++] = bsize;
150 }
43a481dc 151
c627d613
AT
152 if (delete_mode)
153 args[ac++] = "--delete";
154
155 *argc = ac;
156}
157
158
159
160int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
161{
162 char *args[100];
163 int i,argc=0;
164 char *tok,*p;
165
166 if (!local_server) {
167 if (!cmd)
168 cmd = getenv(RSYNC_RSH_ENV);
169 if (!cmd)
170 cmd = RSYNC_RSH;
171 cmd = strdup(cmd);
172 if (!cmd)
173 goto oom;
174
175 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
176 args[argc++] = tok;
177 }
178
7b8356d0
AT
179#if HAVE_REMSH
180 /* remsh (on HPUX) takes the arguments the other way around */
181 args[argc++] = machine;
182 if (user) {
183 args[argc++] = "-l";
184 args[argc++] = user;
185 }
186#else
c627d613
AT
187 if (user) {
188 args[argc++] = "-l";
189 args[argc++] = user;
190 }
191 args[argc++] = machine;
7b8356d0 192#endif
c627d613
AT
193 }
194
195 args[argc++] = rsync_path;
196
197 server_options(args,&argc);
198
199 if (path && *path) {
200 char *dir = strdup(path);
201 p = strrchr(dir,'/');
202 if (p) {
203 *p = 0;
7b8356d0
AT
204 if (!dir[0])
205 args[argc++] = "/";
206 else
207 args[argc++] = dir;
c627d613
AT
208 p++;
209 } else {
210 args[argc++] = ".";
211 p = dir;
212 }
213 if (p[0])
214 args[argc++] = path;
215 }
216
217 args[argc] = NULL;
218
219 if (verbose > 3) {
dc5ddbcc 220 fprintf(FERROR,"cmd=");
c627d613 221 for (i=0;i<argc;i++)
dc5ddbcc
AT
222 fprintf(FERROR,"%s ",args[i]);
223 fprintf(FERROR,"\n");
c627d613
AT
224 }
225
226 return piped_child(args,f_in,f_out);
227
228oom:
229 out_of_memory("do_cmd");
230 return 0; /* not reached */
231}
232
233
234
235
236static char *get_local_name(struct file_list *flist,char *name)
237{
238 struct stat st;
239
240 if (stat(name,&st) == 0) {
241 if (S_ISDIR(st.st_mode)) {
242 if (chdir(name) != 0) {
dc5ddbcc 243 fprintf(FERROR,"chdir %s : %s\n",name,strerror(errno));
34ccb63e 244 exit_cleanup(1);
c627d613
AT
245 }
246 return NULL;
247 }
248 if (flist->count > 1) {
dc5ddbcc 249 fprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
34ccb63e 250 exit_cleanup(1);
c627d613
AT
251 }
252 return name;
253 }
254
255 if (flist->count == 1)
256 return name;
257
258 if (!name)
259 return NULL;
260
7b8356d0 261 if (mkdir(name,0777 & ~orig_umask) != 0) {
dc5ddbcc 262 fprintf(FERROR,"mkdir %s : %s\n",name,strerror(errno));
34ccb63e 263 exit_cleanup(1);
94481d91 264 } else {
dc5ddbcc 265 fprintf(FINFO,"created directory %s\n",name);
c627d613
AT
266 }
267
268 if (chdir(name) != 0) {
dc5ddbcc 269 fprintf(FERROR,"chdir %s : %s\n",name,strerror(errno));
34ccb63e 270 exit_cleanup(1);
c627d613
AT
271 }
272
273 return NULL;
274}
275
276
277
278
279void do_server_sender(int argc,char *argv[])
280{
281 int i;
282 char *dir = argv[0];
283 struct file_list *flist;
284
285 if (verbose > 2)
dc5ddbcc 286 fprintf(FERROR,"server_sender starting pid=%d\n",(int)getpid());
c627d613
AT
287
288 if (chdir(dir) != 0) {
dc5ddbcc 289 fprintf(FERROR,"chdir %s: %s\n",dir,strerror(errno));
34ccb63e 290 exit_cleanup(1);
c627d613
AT
291 }
292 argc--;
293 argv++;
294
295 if (strcmp(dir,".")) {
296 int l = strlen(dir);
297 for (i=0;i<argc;i++)
298 argv[i] += l+1;
299 }
300
301 if (argc == 0 && recurse) {
302 argc=1;
303 argv--;
304 argv[0] = ".";
305 }
306
307
a06d19e3 308 flist = send_file_list(STDOUT_FILENO,argc,argv);
c627d613
AT
309 send_files(flist,STDOUT_FILENO,STDIN_FILENO);
310 report(STDOUT_FILENO);
34ccb63e 311 exit_cleanup(0);
c627d613
AT
312}
313
314
dc5ddbcc
AT
315static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
316{
317 int pid;
318 int status=0;
c6e7fcb4 319 int recv_pipe[2];
dc5ddbcc
AT
320
321 if (preserve_hard_links)
322 init_hard_links(flist);
323
c6e7fcb4
AT
324 if (pipe(recv_pipe) < 0) {
325 fprintf(FERROR,"pipe failed in do_recv\n");
326 exit(1);
327 }
328
329
dc5ddbcc 330 if ((pid=fork()) == 0) {
c6e7fcb4 331 recv_files(f_in,flist,local_name,recv_pipe[1]);
dc5ddbcc
AT
332 if (preserve_hard_links)
333 do_hard_links(flist);
334 if (verbose > 2)
335 fprintf(FERROR,"receiver read %d\n",read_total());
336 exit_cleanup(0);
337 }
338
c6e7fcb4 339 generate_files(f_out,flist,local_name,recv_pipe[0]);
dc5ddbcc
AT
340
341 waitpid(pid, &status, 0);
342
343 return status;
344}
345
c627d613
AT
346
347void do_server_recv(int argc,char *argv[])
348{
dc5ddbcc 349 int status;
c627d613
AT
350 char *dir = NULL;
351 struct file_list *flist;
352 char *local_name=NULL;
353
354 if (verbose > 2)
dc5ddbcc 355 fprintf(FERROR,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
c627d613
AT
356
357 if (argc > 0) {
358 dir = argv[0];
359 argc--;
360 argv++;
361 if (chdir(dir) != 0) {
dc5ddbcc 362 fprintf(FERROR,"chdir %s : %s\n",dir,strerror(errno));
34ccb63e 363 exit_cleanup(1);
c627d613
AT
364 }
365 }
366
367 if (delete_mode)
368 recv_exclude_list(STDIN_FILENO);
369
370 flist = recv_file_list(STDIN_FILENO);
371 if (!flist || flist->count == 0) {
dc5ddbcc 372 fprintf(FERROR,"nothing to do\n");
34ccb63e 373 exit_cleanup(1);
c627d613
AT
374 }
375
376 if (argc > 0) {
377 if (strcmp(dir,".")) {
378 argv[0] += strlen(dir);
379 if (argv[0][0] == '/') argv[0]++;
380 }
381 local_name = get_local_name(flist,argv[0]);
382 }
383
dc5ddbcc 384 status = do_recv(STDIN_FILENO,STDOUT_FILENO,flist,local_name);
34ccb63e 385 exit_cleanup(status);
c627d613
AT
386}
387
388
389static void usage(FILE *f)
390{
391 fprintf(f,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
392 VERSION);
393 fprintf(f,"Usage:\t%s [options] src user@host:dest\nOR",RSYNC_NAME);
394 fprintf(f,"\t%s [options] user@host:src dest\n\n",RSYNC_NAME);
395 fprintf(f,"Options:\n");
396 fprintf(f,"-v, --verbose increase verbosity\n");
397 fprintf(f,"-c, --checksum always checksum\n");
398 fprintf(f,"-a, --archive archive mode (same as -rlptDog)\n");
399 fprintf(f,"-r, --recursive recurse into directories\n");
400 fprintf(f,"-b, --backup make backups (default ~ extension)\n");
401 fprintf(f,"-u, --update update only (don't overwrite newer files)\n");
402 fprintf(f,"-l, --links preserve soft links\n");
dc5ddbcc 403 fprintf(f,"-H, --hard-links preserve hard links\n");
c627d613
AT
404 fprintf(f,"-p, --perms preserve permissions\n");
405 fprintf(f,"-o, --owner preserve owner (root only)\n");
406 fprintf(f,"-g, --group preserve group\n");
407 fprintf(f,"-D, --devices preserve devices (root only)\n");
408 fprintf(f,"-t, --times preserve times\n");
dc5ddbcc 409 fprintf(f,"-S, --sparse handle sparse files efficiently\n");
c627d613
AT
410 fprintf(f,"-n, --dry-run show what would have been transferred\n");
411 fprintf(f,"-x, --one-file-system don't cross filesystem boundaries\n");
412 fprintf(f,"-B, --block-size SIZE checksum blocking size\n");
413 fprintf(f,"-e, --rsh COMMAND specify rsh replacement\n");
414 fprintf(f," --rsync-path PATH specify path to rsync on the remote machine\n");
415 fprintf(f,"-C, --cvs-exclude auto ignore files in the same way CVS does\n");
416 fprintf(f," --delete delete files that don't exist on the sending side\n");
417 fprintf(f,"-I, --ignore-times don't exclude files that match length and time\n");
861c20b4 418 fprintf(f,"-z, --compress compress file data\n");
c627d613
AT
419 fprintf(f," --exclude FILE exclude file FILE\n");
420 fprintf(f," --exclude-from FILE exclude files listed in FILE\n");
421 fprintf(f," --suffix SUFFIX override backup suffix\n");
422 fprintf(f," --version print version number\n");
423
424 fprintf(f,"\n");
425 fprintf(f,"the backup suffix defaults to %s\n",BACKUP_SUFFIX);
426 fprintf(f,"the block size defaults to %d\n",BLOCK_SIZE);
427}
428
429enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
b98c7b81 430 OPT_EXCLUDE_FROM,OPT_DELETE,OPT_RSYNC_PATH};
c627d613 431
861c20b4 432static char *short_options = "oblHpguDCtcahvrIxnSe:B:z";
c627d613
AT
433
434static struct option long_options[] = {
435 {"version", 0, 0, OPT_VERSION},
436 {"server", 0, 0, OPT_SERVER},
437 {"sender", 0, 0, OPT_SENDER},
438 {"delete", 0, 0, OPT_DELETE},
439 {"exclude", 1, 0, OPT_EXCLUDE},
440 {"exclude-from",1, 0, OPT_EXCLUDE_FROM},
441 {"rsync-path", 1, 0, OPT_RSYNC_PATH},
442 {"one-file-system",0, 0, 'x'},
443 {"ignore-times",0, 0, 'I'},
444 {"help", 0, 0, 'h'},
445 {"dry-run", 0, 0, 'n'},
dc5ddbcc 446 {"sparse", 0, 0, 'S'},
c627d613
AT
447 {"cvs-exclude", 0, 0, 'C'},
448 {"archive", 0, 0, 'a'},
449 {"checksum", 0, 0, 'c'},
450 {"backup", 0, 0, 'b'},
451 {"update", 0, 0, 'u'},
452 {"verbose", 0, 0, 'v'},
453 {"recursive", 0, 0, 'r'},
454 {"devices", 0, 0, 'D'},
455 {"perms", 0, 0, 'p'},
456 {"links", 0, 0, 'l'},
dc5ddbcc 457 {"hard-links", 0, 0, 'H'},
c627d613
AT
458 {"owner", 0, 0, 'o'},
459 {"group", 0, 0, 'g'},
460 {"times", 0, 0, 't'},
461 {"rsh", 1, 0, 'e'},
462 {"suffix", 1, 0, OPT_SUFFIX},
463 {"block-size", 1, 0, 'B'},
861c20b4 464 {"compress", 0, 0, 'z'},
c627d613
AT
465 {0,0,0,0}};
466
467int main(int argc,char *argv[])
468{
dc5ddbcc 469 int pid, status, status2;
c627d613
AT
470 int opt;
471 int option_index;
472 char *shell_cmd = NULL;
473 char *shell_machine = NULL;
474 char *shell_path = NULL;
475 char *shell_user = NULL;
476 char *p;
477 int f_in,f_out;
478 struct file_list *flist;
479 char *local_name = NULL;
480
481 starttime = time(NULL);
7b8356d0
AT
482 am_root = (getuid() == 0);
483
484 /* we set a 0 umask so that correct file permissions can be
485 carried across */
486 orig_umask = umask(0);
c627d613
AT
487
488 while ((opt = getopt_long(argc, argv,
489 short_options, long_options, &option_index))
490 != -1) {
491 switch (opt)
492 {
493 case OPT_VERSION:
494 printf("rsync version %s protocol version %d\n",
495 VERSION,PROTOCOL_VERSION);
34ccb63e 496 exit_cleanup(0);
c627d613
AT
497
498 case OPT_SUFFIX:
499 backup_suffix = optarg;
500 break;
501
502 case OPT_RSYNC_PATH:
503 rsync_path = optarg;
504 break;
505
506 case 'I':
507 ignore_times = 1;
508 break;
509
510 case 'x':
511 one_file_system=1;
512 break;
513
514 case OPT_DELETE:
515 delete_mode = 1;
516 break;
517
518 case OPT_EXCLUDE:
519 add_exclude(optarg);
520 break;
521
522 case OPT_EXCLUDE_FROM:
523 add_exclude_file(optarg,1);
524 break;
525
526 case 'h':
dc5ddbcc 527 usage(FINFO);
34ccb63e 528 exit_cleanup(0);
c627d613
AT
529
530 case 'b':
531 make_backups=1;
532 break;
533
534 case 'n':
535 dry_run=1;
536 break;
537
dc5ddbcc
AT
538 case 'S':
539 sparse_files=1;
540 break;
541
c627d613
AT
542 case 'C':
543 cvs_exclude=1;
544 break;
545
546 case 'u':
547 update_only=1;
548 break;
549
c627d613 550 case 'l':
dc5ddbcc 551#if SUPPORT_LINKS
c627d613 552 preserve_links=1;
dc5ddbcc 553#endif
c627d613 554 break;
dc5ddbcc
AT
555
556 case 'H':
557#if SUPPORT_HARD_LINKS
558 preserve_hard_links=1;
c627d613 559#endif
dc5ddbcc 560 break;
c627d613
AT
561
562 case 'p':
563 preserve_perms=1;
564 break;
565
566 case 'o':
7b8356d0 567 preserve_uid=1;
c627d613
AT
568 break;
569
570 case 'g':
571 preserve_gid=1;
572 break;
573
574 case 'D':
7b8356d0 575 preserve_devices=1;
c627d613
AT
576 break;
577
578 case 't':
579 preserve_times=1;
580 break;
581
582 case 'c':
583 always_checksum=1;
584 break;
585
586 case 'v':
587 verbose++;
588 break;
589
590 case 'a':
591 recurse=1;
592#if SUPPORT_LINKS
593 preserve_links=1;
594#endif
595 preserve_perms=1;
596 preserve_times=1;
597 preserve_gid=1;
7b8356d0 598 if (am_root) {
c627d613
AT
599 preserve_devices=1;
600 preserve_uid=1;
7b8356d0 601 }
c627d613
AT
602 break;
603
604 case OPT_SERVER:
605 am_server = 1;
606 break;
607
608 case OPT_SENDER:
609 if (!am_server) {
dc5ddbcc 610 usage(FERROR);
34ccb63e 611 exit_cleanup(1);
c627d613
AT
612 }
613 sender = 1;
614 break;
615
616 case 'r':
617 recurse = 1;
618 break;
619
620 case 'e':
621 shell_cmd = optarg;
622 break;
623
624 case 'B':
625 block_size = atoi(optarg);
626 break;
627
861c20b4
PM
628 case 'z':
629 do_compression = 1;
630 break;
631
c627d613 632 default:
861c20b4 633 /* fprintf(FERROR,"bad option -%c\n",opt); */
34ccb63e 634 exit_cleanup(1);
c627d613
AT
635 }
636 }
637
638 while (optind--) {
639 argc--;
640 argv++;
641 }
642
6b83141d
AT
643 signal(SIGCHLD,SIG_IGN);
644 signal(SIGINT,SIGNAL_CAST sig_int);
645 signal(SIGPIPE,SIGNAL_CAST sig_int);
646 signal(SIGHUP,SIGNAL_CAST sig_int);
647
c627d613
AT
648 if (dry_run)
649 verbose = MAX(verbose,1);
650
651 if (am_server) {
aae43eb3 652 setup_protocol(STDOUT_FILENO,STDIN_FILENO);
c627d613
AT
653
654 if (sender) {
655 recv_exclude_list(STDIN_FILENO);
656 if (cvs_exclude)
657 add_cvs_excludes();
658 do_server_sender(argc,argv);
659 } else {
660 do_server_recv(argc,argv);
661 }
34ccb63e 662 exit_cleanup(0);
c627d613
AT
663 }
664
665 if (argc < 2) {
dc5ddbcc 666 usage(FERROR);
34ccb63e 667 exit_cleanup(1);
c627d613
AT
668 }
669
670 p = strchr(argv[0],':');
671
672 if (p) {
673 sender = 0;
674 *p = 0;
675 shell_machine = argv[0];
676 shell_path = p+1;
677 argc--;
678 argv++;
679 } else {
680 sender = 1;
681
682 p = strchr(argv[argc-1],':');
683 if (!p) {
684 local_server = 1;
685 }
686
687 if (local_server) {
688 shell_machine = NULL;
689 shell_path = argv[argc-1];
690 } else {
691 *p = 0;
692 shell_machine = argv[argc-1];
693 shell_path = p+1;
694 }
695 argc--;
696 }
697
698 if (shell_machine) {
699 p = strchr(shell_machine,'@');
700 if (p) {
701 *p = 0;
702 shell_user = shell_machine;
703 shell_machine = p+1;
704 }
705 }
706
707 if (verbose > 3) {
dc5ddbcc 708 fprintf(FERROR,"cmd=%s machine=%s user=%s path=%s\n",
c627d613
AT
709 shell_cmd?shell_cmd:"",
710 shell_machine?shell_machine:"",
711 shell_user?shell_user:"",
712 shell_path?shell_path:"");
713 }
714
c627d613 715 if (!sender && argc != 1) {
dc5ddbcc 716 usage(FERROR);
34ccb63e 717 exit_cleanup(1);
c627d613
AT
718 }
719
720 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
721
aae43eb3 722 setup_protocol(f_out,f_in);
4fe159a8 723
c627d613 724 if (verbose > 3)
dc5ddbcc 725 fprintf(FERROR,"parent=%d child=%d sender=%d recurse=%d\n",
c627d613
AT
726 (int)getpid(),pid,sender,recurse);
727
728 if (sender) {
729 if (cvs_exclude)
730 add_cvs_excludes();
731 if (delete_mode)
732 send_exclude_list(f_out);
a06d19e3 733 flist = send_file_list(f_out,argc,argv);
c627d613 734 if (verbose > 3)
dc5ddbcc 735 fprintf(FERROR,"file list sent\n");
c627d613
AT
736 send_files(flist,f_out,f_in);
737 if (verbose > 3)
dc5ddbcc 738 fprintf(FERROR,"waiting on %d\n",pid);
c627d613
AT
739 waitpid(pid, &status, 0);
740 report(-1);
34ccb63e 741 exit_cleanup(status);
c627d613
AT
742 }
743
744 send_exclude_list(f_out);
745
746 flist = recv_file_list(f_in);
747 if (!flist || flist->count == 0) {
dc5ddbcc 748 fprintf(FERROR,"nothing to do\n");
34ccb63e 749 exit_cleanup(0);
c627d613
AT
750 }
751
752 local_name = get_local_name(flist,argv[0]);
753
dc5ddbcc 754 status2 = do_recv(f_in,f_out,flist,local_name);
c627d613
AT
755
756 report(f_in);
757
758 waitpid(pid, &status, 0);
759
760 return status | status2;
761}