Annotation of embedaddon/rsync/main.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * The startup routines, including main(), for rsync.
                      3:  *
                      4:  * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
                      5:  * Copyright (C) 1996 Paul Mackerras
                      6:  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
                      7:  * Copyright (C) 2003-2009 Wayne Davison
                      8:  *
                      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 3 of the License, or
                     12:  * (at your option) any later version.
                     13:  *
                     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.
                     18:  *
                     19:  * You should have received a copy of the GNU General Public License along
                     20:  * with this program; if not, visit the http://fsf.org website.
                     21:  */
                     22: 
                     23: #include "rsync.h"
                     24: #include "ifuncs.h"
                     25: #include "io.h"
                     26: #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
                     27: #include <locale.h>
                     28: #endif
                     29: 
                     30: extern int verbose;
                     31: extern int dry_run;
                     32: extern int list_only;
                     33: extern int am_root;
                     34: extern int am_server;
                     35: extern int am_sender;
                     36: extern int am_daemon;
                     37: extern int inc_recurse;
                     38: extern int blocking_io;
                     39: extern int remove_source_files;
                     40: extern int need_messages_from_generator;
                     41: extern int kluge_around_eof;
                     42: extern int do_stats;
                     43: extern int got_xfer_error;
                     44: extern int module_id;
                     45: extern int copy_links;
                     46: extern int copy_dirlinks;
                     47: extern int copy_unsafe_links;
                     48: extern int keep_dirlinks;
                     49: extern int preserve_hard_links;
                     50: extern int protocol_version;
                     51: extern int file_total;
                     52: extern int recurse;
                     53: extern int xfer_dirs;
                     54: extern int protect_args;
                     55: extern int relative_paths;
                     56: extern int sanitize_paths;
                     57: extern int curr_dir_depth;
                     58: extern int curr_dir_len;
                     59: extern int module_id;
                     60: extern int rsync_port;
                     61: extern int whole_file;
                     62: extern int read_batch;
                     63: extern int write_batch;
                     64: extern int batch_fd;
                     65: extern int filesfrom_fd;
                     66: extern int connect_timeout;
                     67: extern dev_t filesystem_dev;
                     68: extern pid_t cleanup_child_pid;
                     69: extern unsigned int module_dirlen;
                     70: extern struct stats stats;
                     71: extern char *filesfrom_host;
                     72: extern char *partial_dir;
                     73: extern char *dest_option;
                     74: extern char *basis_dir[MAX_BASIS_DIRS+1];
                     75: extern char *rsync_path;
                     76: extern char *shell_cmd;
                     77: extern char *batch_name;
                     78: extern char *password_file;
                     79: extern char curr_dir[MAXPATHLEN];
                     80: extern struct file_list *first_flist;
                     81: extern struct filter_list_struct daemon_filter_list;
                     82: 
                     83: uid_t our_uid;
                     84: int am_receiver = 0;  /* Only set to 1 after the receiver/generator fork. */
                     85: int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */
                     86: int local_server = 0;
                     87: int daemon_over_rsh = 0;
                     88: mode_t orig_umask = 0;
                     89: int batch_gen_fd = -1;
                     90: 
                     91: /* There's probably never more than at most 2 outstanding child processes,
                     92:  * but set it higher, just in case. */
                     93: #define MAXCHILDPROCS 7
                     94: 
                     95: #ifdef HAVE_SIGACTION
                     96: # ifdef HAVE_SIGPROCMASK
                     97: #  define SIGACTMASK(n,h) SIGACTION(n,h), sigaddset(&sigmask,(n))
                     98: # else
                     99: #  define SIGACTMASK(n,h) SIGACTION(n,h)
                    100: # endif
                    101: static struct sigaction sigact;
                    102: #endif
                    103: 
                    104: struct pid_status {
                    105:        pid_t pid;
                    106:        int status;
                    107: } pid_stat_table[MAXCHILDPROCS];
                    108: 
                    109: static time_t starttime, endtime;
                    110: static int64 total_read, total_written;
                    111: 
                    112: static void show_malloc_stats(void);
                    113: 
                    114: /* Works like waitpid(), but if we already harvested the child pid in our
                    115:  * remember_children(), we succeed instead of returning an error. */
                    116: pid_t wait_process(pid_t pid, int *status_ptr, int flags)
                    117: {
                    118:        pid_t waited_pid;
                    119:        
                    120:        do {
                    121:                waited_pid = waitpid(pid, status_ptr, flags);
                    122:        } while (waited_pid == -1 && errno == EINTR);
                    123: 
                    124:        if (waited_pid == -1 && errno == ECHILD) {
                    125:                /* Status of requested child no longer available:  check to
                    126:                 * see if it was processed by remember_children(). */
                    127:                int cnt;
                    128:                for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
                    129:                        if (pid == pid_stat_table[cnt].pid) {
                    130:                                *status_ptr = pid_stat_table[cnt].status;
                    131:                                pid_stat_table[cnt].pid = 0;
                    132:                                return pid;
                    133:                        }
                    134:                }
                    135:        }
                    136: 
                    137:        return waited_pid;
                    138: }
                    139: 
                    140: /* Wait for a process to exit, calling io_flush while waiting. */
                    141: static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
                    142: {
                    143:        pid_t waited_pid;
                    144:        int status;
                    145: 
                    146:        while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) {
                    147:                msleep(20);
                    148:                io_flush(FULL_FLUSH);
                    149:        }
                    150: 
                    151:        /* TODO: If the child exited on a signal, then log an
                    152:         * appropriate error message.  Perhaps we should also accept a
                    153:         * message describing the purpose of the child.  Also indicate
                    154:         * this to the caller so that they know something went wrong. */
                    155:        if (waited_pid < 0) {
                    156:                rsyserr(FERROR, errno, "waitpid");
                    157:                *exit_code_ptr = RERR_WAITCHILD;
                    158:        } else if (!WIFEXITED(status)) {
                    159: #ifdef WCOREDUMP
                    160:                if (WCOREDUMP(status))
                    161:                        *exit_code_ptr = RERR_CRASHED;
                    162:                else
                    163: #endif
                    164:                if (WIFSIGNALED(status))
                    165:                        *exit_code_ptr = RERR_TERMINATED;
                    166:                else
                    167:                        *exit_code_ptr = RERR_WAITCHILD;
                    168:        } else
                    169:                *exit_code_ptr = WEXITSTATUS(status);
                    170: }
                    171: 
                    172: /* This function gets called from all 3 processes.  We want the client side
                    173:  * to actually output the text, but the sender is the only process that has
                    174:  * all the stats we need.  So, if we're a client sender, we do the report.
                    175:  * If we're a server sender, we write the stats on the supplied fd.  If
                    176:  * we're the client receiver we read the stats from the supplied fd and do
                    177:  * the report.  All processes might also generate a set of debug stats, if
                    178:  * the verbose level is high enough (this is the only thing that the
                    179:  * generator process and the server receiver ever do here). */
                    180: static void handle_stats(int f)
                    181: {
                    182:        endtime = time(NULL);
                    183: 
                    184:        /* Cache two stats because the read/write code can change it. */
                    185:        total_read = stats.total_read;
                    186:        total_written = stats.total_written;
                    187: 
                    188:        if (do_stats && verbose > 1) {
                    189:                /* These come out from every process */
                    190:                show_malloc_stats();
                    191:                show_flist_stats();
                    192:        }
                    193: 
                    194:        if (am_generator)
                    195:                return;
                    196: 
                    197:        if (am_daemon) {
                    198:                if (f == -1 || !am_sender)
                    199:                        return;
                    200:        }
                    201: 
                    202:        if (am_server) {
                    203:                if (am_sender) {
                    204:                        write_varlong30(f, total_read, 3);
                    205:                        write_varlong30(f, total_written, 3);
                    206:                        write_varlong30(f, stats.total_size, 3);
                    207:                        if (protocol_version >= 29) {
                    208:                                write_varlong30(f, stats.flist_buildtime, 3);
                    209:                                write_varlong30(f, stats.flist_xfertime, 3);
                    210:                        }
                    211:                }
                    212:                return;
                    213:        }
                    214: 
                    215:        /* this is the client */
                    216: 
                    217:        if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */
                    218:                ;
                    219:        else if (!am_sender) {
                    220:                /* Read the first two in opposite order because the meaning of
                    221:                 * read/write swaps when switching from sender to receiver. */
                    222:                total_written = read_varlong30(f, 3);
                    223:                total_read = read_varlong30(f, 3);
                    224:                stats.total_size = read_varlong30(f, 3);
                    225:                if (protocol_version >= 29) {
                    226:                        stats.flist_buildtime = read_varlong30(f, 3);
                    227:                        stats.flist_xfertime = read_varlong30(f, 3);
                    228:                }
                    229:        } else if (write_batch) {
                    230:                /* The --read-batch process is going to be a client
                    231:                 * receiver, so we need to give it the stats. */
                    232:                write_varlong30(batch_fd, total_read, 3);
                    233:                write_varlong30(batch_fd, total_written, 3);
                    234:                write_varlong30(batch_fd, stats.total_size, 3);
                    235:                if (protocol_version >= 29) {
                    236:                        write_varlong30(batch_fd, stats.flist_buildtime, 3);
                    237:                        write_varlong30(batch_fd, stats.flist_xfertime, 3);
                    238:                }
                    239:        }
                    240: }
                    241: 
                    242: static void output_summary(void)
                    243: {
                    244:        if (do_stats) {
                    245:                rprintf(FCLIENT, "\n");
                    246:                rprintf(FINFO,"Number of files: %d\n", stats.num_files);
                    247:                rprintf(FINFO,"Number of files transferred: %d\n",
                    248:                        stats.num_transferred_files);
                    249:                rprintf(FINFO,"Total file size: %s bytes\n",
                    250:                        human_num(stats.total_size));
                    251:                rprintf(FINFO,"Total transferred file size: %s bytes\n",
                    252:                        human_num(stats.total_transferred_size));
                    253:                rprintf(FINFO,"Literal data: %s bytes\n",
                    254:                        human_num(stats.literal_data));
                    255:                rprintf(FINFO,"Matched data: %s bytes\n",
                    256:                        human_num(stats.matched_data));
                    257:                rprintf(FINFO,"File list size: %s\n",
                    258:                        human_num(stats.flist_size));
                    259:                if (stats.flist_buildtime) {
                    260:                        rprintf(FINFO,
                    261:                                "File list generation time: %.3f seconds\n",
                    262:                                (double)stats.flist_buildtime / 1000);
                    263:                        rprintf(FINFO,
                    264:                                "File list transfer time: %.3f seconds\n",
                    265:                                (double)stats.flist_xfertime / 1000);
                    266:                }
                    267:                rprintf(FINFO,"Total bytes sent: %s\n",
                    268:                        human_num(total_written));
                    269:                rprintf(FINFO,"Total bytes received: %s\n",
                    270:                        human_num(total_read));
                    271:        }
                    272: 
                    273:        if (verbose || do_stats) {
                    274:                rprintf(FCLIENT, "\n");
                    275:                rprintf(FINFO,
                    276:                        "sent %s bytes  received %s bytes  %s bytes/sec\n",
                    277:                        human_num(total_written), human_num(total_read),
                    278:                        human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
                    279:                rprintf(FINFO, "total size is %s  speedup is %.2f%s\n",
                    280:                        human_num(stats.total_size),
                    281:                        (double)stats.total_size / (total_written+total_read),
                    282:                        write_batch < 0 ? " (BATCH ONLY)" : dry_run ? " (DRY RUN)" : "");
                    283:        }
                    284: 
                    285:        fflush(stdout);
                    286:        fflush(stderr);
                    287: }
                    288: 
                    289: 
                    290: /**
                    291:  * If our C library can get malloc statistics, then show them to FINFO
                    292:  **/
                    293: static void show_malloc_stats(void)
                    294: {
                    295: #ifdef HAVE_MALLINFO
                    296:        struct mallinfo mi;
                    297: 
                    298:        mi = mallinfo();
                    299: 
                    300:        rprintf(FCLIENT, "\n");
                    301:        rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
                    302:                getpid(), am_server ? "server " : "",
                    303:                am_daemon ? "daemon " : "", who_am_i());
                    304:        rprintf(FINFO, "  arena:     %10ld   (bytes from sbrk)\n",
                    305:                (long)mi.arena);
                    306:        rprintf(FINFO, "  ordblks:   %10ld   (chunks not in use)\n",
                    307:                (long)mi.ordblks);
                    308:        rprintf(FINFO, "  smblks:    %10ld\n",
                    309:                (long)mi.smblks);
                    310:        rprintf(FINFO, "  hblks:     %10ld   (chunks from mmap)\n",
                    311:                (long)mi.hblks);
                    312:        rprintf(FINFO, "  hblkhd:    %10ld   (bytes from mmap)\n",
                    313:                (long)mi.hblkhd);
                    314:        rprintf(FINFO, "  allmem:    %10ld   (bytes from sbrk + mmap)\n",
                    315:                (long)mi.arena + mi.hblkhd);
                    316:        rprintf(FINFO, "  usmblks:   %10ld\n",
                    317:                (long)mi.usmblks);
                    318:        rprintf(FINFO, "  fsmblks:   %10ld\n",
                    319:                (long)mi.fsmblks);
                    320:        rprintf(FINFO, "  uordblks:  %10ld   (bytes used)\n",
                    321:                (long)mi.uordblks);
                    322:        rprintf(FINFO, "  fordblks:  %10ld   (bytes free)\n",
                    323:                (long)mi.fordblks);
                    324:        rprintf(FINFO, "  keepcost:  %10ld   (bytes in releasable chunk)\n",
                    325:                (long)mi.keepcost);
                    326: #endif /* HAVE_MALLINFO */
                    327: }
                    328: 
                    329: 
                    330: /* Start the remote shell.   cmd may be NULL to use the default. */
                    331: static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, int remote_argc,
                    332:                    int *f_in_p, int *f_out_p)
                    333: {
                    334:        int i, argc = 0;
                    335:        char *args[MAX_ARGS];
                    336:        pid_t pid;
                    337:        int dash_l_set = 0;
                    338: 
                    339:        if (!read_batch && !local_server) {
                    340:                char *t, *f, in_quote = '\0';
                    341:                char *rsh_env = getenv(RSYNC_RSH_ENV);
                    342:                if (!cmd)
                    343:                        cmd = rsh_env;
                    344:                if (!cmd)
                    345:                        cmd = RSYNC_RSH;
                    346:                cmd = strdup(cmd); /* MEMORY LEAK */
                    347:                if (!cmd)
                    348:                        goto oom;
                    349: 
                    350:                for (t = f = cmd; *f; f++) {
                    351:                        if (*f == ' ')
                    352:                                continue;
                    353:                        /* Comparison leaves rooms for server_options(). */
                    354:                        if (argc >= MAX_ARGS - MAX_SERVER_ARGS)
                    355:                                goto arg_overflow;
                    356:                        args[argc++] = t;
                    357:                        while (*f != ' ' || in_quote) {
                    358:                                if (!*f) {
                    359:                                        if (in_quote) {
                    360:                                                rprintf(FERROR,
                    361:                                                    "Missing trailing-%c in remote-shell command.\n",
                    362:                                                    in_quote);
                    363:                                                exit_cleanup(RERR_SYNTAX);
                    364:                                        }
                    365:                                        f--;
                    366:                                        break;
                    367:                                }
                    368:                                if (*f == '\'' || *f == '"') {
                    369:                                        if (!in_quote) {
                    370:                                                in_quote = *f++;
                    371:                                                continue;
                    372:                                        }
                    373:                                        if (*f == in_quote && *++f != in_quote) {
                    374:                                                in_quote = '\0';
                    375:                                                continue;
                    376:                                        }
                    377:                                }
                    378:                                *t++ = *f++;
                    379:                        }
                    380:                        *t++ = '\0';
                    381:                }
                    382: 
                    383:                /* check to see if we've already been given '-l user' in
                    384:                 * the remote-shell command */
                    385:                for (i = 0; i < argc-1; i++) {
                    386:                        if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
                    387:                                dash_l_set = 1;
                    388:                }
                    389: 
                    390: #ifdef HAVE_REMSH
                    391:                /* remsh (on HPUX) takes the arguments the other way around */
                    392:                args[argc++] = machine;
                    393:                if (user && !(daemon_over_rsh && dash_l_set)) {
                    394:                        args[argc++] = "-l";
                    395:                        args[argc++] = user;
                    396:                }
                    397: #else
                    398:                if (user && !(daemon_over_rsh && dash_l_set)) {
                    399:                        args[argc++] = "-l";
                    400:                        args[argc++] = user;
                    401:                }
                    402:                args[argc++] = machine;
                    403: #endif
                    404: 
                    405:                args[argc++] = rsync_path;
                    406: 
                    407:                if (blocking_io < 0) {
                    408:                        char *cp;
                    409:                        if ((cp = strrchr(cmd, '/')) != NULL)
                    410:                                cp++;
                    411:                        else
                    412:                                cp = cmd;
                    413:                        if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0)
                    414:                                blocking_io = 1;
                    415:                }
                    416: 
                    417:                server_options(args,&argc);
                    418: 
                    419:                if (argc >= MAX_ARGS - 2)
                    420:                        goto arg_overflow;
                    421:        }
                    422: 
                    423:        args[argc++] = ".";
                    424: 
                    425:        if (!daemon_over_rsh) {
                    426:                while (remote_argc > 0) {
                    427:                        if (argc >= MAX_ARGS - 1) {
                    428:                          arg_overflow:
                    429:                                rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
                    430:                                exit_cleanup(RERR_SYNTAX);
                    431:                        }
                    432:                        if (**remote_argv == '-') {
                    433:                                if (asprintf(args + argc++, "./%s", *remote_argv++) < 0)
                    434:                                        out_of_memory("do_cmd");
                    435:                        } else
                    436:                                args[argc++] = *remote_argv++;
                    437:                        remote_argc--;
                    438:                }
                    439:        }
                    440: 
                    441:        args[argc] = NULL;
                    442: 
                    443:        if (verbose > 3) {
                    444:                for (i = 0; i < argc; i++)
                    445:                        rprintf(FCLIENT, "cmd[%d]=%s ", i, args[i]);
                    446:                rprintf(FCLIENT, "\n");
                    447:        }
                    448: 
                    449:        if (read_batch) {
                    450:                int from_gen_pipe[2];
                    451:                set_allow_inc_recurse();
                    452:                if (fd_pair(from_gen_pipe) < 0) {
                    453:                        rsyserr(FERROR, errno, "pipe");
                    454:                        exit_cleanup(RERR_IPC);
                    455:                }
                    456:                batch_gen_fd = from_gen_pipe[0];
                    457:                *f_out_p = from_gen_pipe[1];
                    458:                *f_in_p = batch_fd;
                    459:                pid = (pid_t)-1; /* no child pid */
                    460: #ifdef ICONV_CONST
                    461:                setup_iconv();
                    462: #endif
                    463:        } else if (local_server) {
                    464:                /* If the user didn't request --[no-]whole-file, force
                    465:                 * it on, but only if we're not batch processing. */
                    466:                if (whole_file < 0 && !write_batch)
                    467:                        whole_file = 1;
                    468:                set_allow_inc_recurse();
                    469:                pid = local_child(argc, args, f_in_p, f_out_p, child_main);
                    470: #ifdef ICONV_CONST
                    471:                setup_iconv();
                    472: #endif
                    473:        } else {
                    474:                pid = piped_child(args, f_in_p, f_out_p);
                    475: #ifdef ICONV_CONST
                    476:                setup_iconv();
                    477: #endif
                    478:                if (protect_args && !daemon_over_rsh)
                    479:                        send_protected_args(*f_out_p, args);
                    480:        }
                    481: 
                    482:        return pid;
                    483: 
                    484:   oom:
                    485:        out_of_memory("do_cmd");
                    486:        return 0; /* not reached */
                    487: }
                    488: 
                    489: /* The receiving side operates in one of two modes:
                    490:  *
                    491:  * 1. it receives any number of files into a destination directory,
                    492:  * placing them according to their names in the file-list.
                    493:  *
                    494:  * 2. it receives a single file and saves it using the name in the
                    495:  * destination path instead of its file-list name.  This requires a
                    496:  * "local name" for writing out the destination file.
                    497:  *
                    498:  * So, our task is to figure out what mode/local-name we need.
                    499:  * For mode 1, we change into the destination directory and return NULL.
                    500:  * For mode 2, we change into the directory containing the destination
                    501:  * file (if we aren't already there) and return the local-name. */
                    502: static char *get_local_name(struct file_list *flist, char *dest_path)
                    503: {
                    504:        STRUCT_STAT st;
                    505:        int statret;
                    506:        char *cp;
                    507: 
                    508:        if (verbose > 2) {
                    509:                rprintf(FINFO, "get_local_name count=%d %s\n",
                    510:                        file_total, NS(dest_path));
                    511:        }
                    512: 
                    513:        if (!dest_path || list_only)
                    514:                return NULL;
                    515: 
                    516:        /* Treat an empty string as a copy into the current directory. */
                    517:        if (!*dest_path)
                    518:            dest_path = ".";
                    519: 
                    520:        if (daemon_filter_list.head) {
                    521:                char *slash = strrchr(dest_path, '/');
                    522:                if (slash && (slash[1] == '\0' || (slash[1] == '.' && slash[2] == '\0')))
                    523:                        *slash = '\0';
                    524:                else
                    525:                        slash = NULL;
                    526:                if ((*dest_path != '.' || dest_path[1] != '\0')
                    527:                 && (check_filter(&daemon_filter_list, FLOG, dest_path, 0) < 0
                    528:                  || check_filter(&daemon_filter_list, FLOG, dest_path, 1) < 0)) {
                    529:                        rprintf(FERROR, "ERROR: daemon has excluded destination \"%s\"\n",
                    530:                                dest_path);
                    531:                        exit_cleanup(RERR_FILESELECT);
                    532:                }
                    533:                if (slash)
                    534:                        *slash = '/';
                    535:        }
                    536: 
                    537:        /* See what currently exists at the destination. */
                    538:        if ((statret = do_stat(dest_path, &st)) == 0) {
                    539:                /* If the destination is a dir, enter it and use mode 1. */
                    540:                if (S_ISDIR(st.st_mode)) {
                    541:                        if (!change_dir(dest_path, CD_NORMAL)) {
                    542:                                rsyserr(FERROR, errno, "change_dir#1 %s failed",
                    543:                                        full_fname(dest_path));
                    544:                                exit_cleanup(RERR_FILESELECT);
                    545:                        }
                    546:                        filesystem_dev = st.st_dev; /* ensures --force works right w/-x */
                    547:                        return NULL;
                    548:                }
                    549:                if (file_total > 1) {
                    550:                        rprintf(FERROR,
                    551:                                "ERROR: destination must be a directory when"
                    552:                                " copying more than 1 file\n");
                    553:                        exit_cleanup(RERR_FILESELECT);
                    554:                }
                    555:                if (file_total == 1 && S_ISDIR(flist->files[0]->mode)) {
                    556:                        rprintf(FERROR,
                    557:                                "ERROR: cannot overwrite non-directory"
                    558:                                " with a directory\n");
                    559:                        exit_cleanup(RERR_FILESELECT);
                    560:                }
                    561:        } else if (errno != ENOENT) {
                    562:                /* If we don't know what's at the destination, fail. */
                    563:                rsyserr(FERROR, errno, "ERROR: cannot stat destination %s",
                    564:                        full_fname(dest_path));
                    565:                exit_cleanup(RERR_FILESELECT);
                    566:        }
                    567: 
                    568:        cp = strrchr(dest_path, '/');
                    569: 
                    570:        /* If we need a destination directory because the transfer is not
                    571:         * of a single non-directory or the user has requested one via a
                    572:         * destination path ending in a slash, create one and use mode 1. */
                    573:        if (file_total > 1 || (cp && !cp[1])) {
                    574:                /* Lop off the final slash (if any). */
                    575:                if (cp && !cp[1])
                    576:                        *cp = '\0';
                    577: 
                    578:                if (statret == 0) {
                    579:                        rprintf(FERROR,
                    580:                            "ERROR: destination path is not a directory\n");
                    581:                        exit_cleanup(RERR_SYNTAX);
                    582:                }
                    583: 
                    584:                if (mkdir_defmode(dest_path) != 0) {
                    585:                        rsyserr(FERROR, errno, "mkdir %s failed",
                    586:                                full_fname(dest_path));
                    587:                        exit_cleanup(RERR_FILEIO);
                    588:                }
                    589: 
                    590:                if (flist->high >= flist->low
                    591:                 && strcmp(flist->files[flist->low]->basename, ".") == 0)
                    592:                        flist->files[0]->flags |= FLAG_DIR_CREATED;
                    593: 
                    594:                if (verbose)
                    595:                        rprintf(FINFO, "created directory %s\n", dest_path);
                    596: 
                    597:                if (dry_run) {
                    598:                        /* Indicate that dest dir doesn't really exist. */
                    599:                        dry_run++;
                    600:                }
                    601: 
                    602:                if (!change_dir(dest_path, dry_run > 1 ? CD_SKIP_CHDIR : CD_NORMAL)) {
                    603:                        rsyserr(FERROR, errno, "change_dir#2 %s failed",
                    604:                                full_fname(dest_path));
                    605:                        exit_cleanup(RERR_FILESELECT);
                    606:                }
                    607: 
                    608:                return NULL;
                    609:        }
                    610: 
                    611:        /* Otherwise, we are writing a single file, possibly on top of an
                    612:         * existing non-directory.  Change to the item's parent directory
                    613:         * (if it has a path component), return the basename of the
                    614:         * destination file as the local name, and use mode 2. */
                    615:        if (!cp)
                    616:                return dest_path;
                    617: 
                    618:        if (cp == dest_path)
                    619:                dest_path = "/";
                    620: 
                    621:        *cp = '\0';
                    622:        if (!change_dir(dest_path, CD_NORMAL)) {
                    623:                rsyserr(FERROR, errno, "change_dir#3 %s failed",
                    624:                        full_fname(dest_path));
                    625:                exit_cleanup(RERR_FILESELECT);
                    626:        }
                    627:        *cp = '/';
                    628: 
                    629:        return cp + 1;
                    630: }
                    631: 
                    632: /* This function checks on our alternate-basis directories.  If we're in
                    633:  * dry-run mode and the destination dir does not yet exist, we'll try to
                    634:  * tweak any dest-relative paths to make them work for a dry-run (the
                    635:  * destination dir must be in curr_dir[] when this function is called).
                    636:  * We also warn about any arg that is non-existent or not a directory. */
                    637: static void check_alt_basis_dirs(void)
                    638: {
                    639:        STRUCT_STAT st;
                    640:        char **dir_p, *slash = strrchr(curr_dir, '/');
                    641: 
                    642:        for (dir_p = basis_dir; *dir_p; dir_p++) {
                    643:                if (dry_run > 1 && **dir_p != '/') {
                    644:                        int len = curr_dir_len + 1 + strlen(*dir_p) + 1;
                    645:                        char *new = new_array(char, len);
                    646:                        if (!new)
                    647:                                out_of_memory("check_alt_basis_dirs");
                    648:                        if (slash && strncmp(*dir_p, "../", 3) == 0) {
                    649:                            /* We want to remove only one leading "../" prefix for
                    650:                             * the directory we couldn't create in dry-run mode:
                    651:                             * this ensures that any other ".." references get
                    652:                             * evaluated the same as they would for a live copy. */
                    653:                            *slash = '\0';
                    654:                            pathjoin(new, len, curr_dir, *dir_p + 3);
                    655:                            *slash = '/';
                    656:                        } else
                    657:                            pathjoin(new, len, curr_dir, *dir_p);
                    658:                        *dir_p = new;
                    659:                }
                    660:                if (do_stat(*dir_p, &st) < 0) {
                    661:                        rprintf(FWARNING, "%s arg does not exist: %s\n",
                    662:                                dest_option, *dir_p);
                    663:                } else if (!S_ISDIR(st.st_mode)) {
                    664:                        rprintf(FWARNING, "%s arg is not a dir: %s\n",
                    665:                                dest_option, *dir_p);
                    666:                }
                    667:        }
                    668: }
                    669: 
                    670: /* This is only called by the sender. */
                    671: static void read_final_goodbye(int f_in)
                    672: {
                    673:        int i, iflags, xlen;
                    674:        uchar fnamecmp_type;
                    675:        char xname[MAXPATHLEN];
                    676: 
                    677:        if (protocol_version < 29)
                    678:                i = read_int(f_in);
                    679:        else {
                    680:                i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
                    681:                                       xname, &xlen);
                    682:        }
                    683: 
                    684:        if (i != NDX_DONE) {
                    685:                rprintf(FERROR, "Invalid packet at end of run (%d) [%s]\n",
                    686:                        i, who_am_i());
                    687:                exit_cleanup(RERR_PROTOCOL);
                    688:        }
                    689: }
                    690: 
                    691: static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
                    692: {
                    693:        struct file_list *flist;
                    694:        char *dir = argv[0];
                    695: 
                    696:        if (verbose > 2) {
                    697:                rprintf(FINFO, "server_sender starting pid=%ld\n",
                    698:                        (long)getpid());
                    699:        }
                    700: 
                    701:        if (am_daemon && lp_write_only(module_id)) {
                    702:                rprintf(FERROR, "ERROR: module is write only\n");
                    703:                exit_cleanup(RERR_SYNTAX);
                    704:                return;
                    705:        }
                    706:        if (am_daemon && lp_read_only(module_id) && remove_source_files) {
                    707:                rprintf(FERROR,
                    708:                    "ERROR: --remove-%s-files cannot be used with a read-only module\n",
                    709:                    remove_source_files == 1 ? "source" : "sent");
                    710:                exit_cleanup(RERR_SYNTAX);
                    711:                return;
                    712:        }
                    713: 
                    714:        if (!relative_paths) {
                    715:                if (!change_dir(dir, CD_NORMAL)) {
                    716:                        rsyserr(FERROR, errno, "change_dir#3 %s failed",
                    717:                                full_fname(dir));
                    718:                        exit_cleanup(RERR_FILESELECT);
                    719:                }
                    720:        }
                    721:        argc--;
                    722:        argv++;
                    723: 
                    724:        if (argc == 0 && (recurse || xfer_dirs || list_only)) {
                    725:                argc = 1;
                    726:                argv--;
                    727:                argv[0] = ".";
                    728:        }
                    729: 
                    730:        flist = send_file_list(f_out,argc,argv);
                    731:        if (!flist || flist->used == 0)
                    732:                exit_cleanup(0);
                    733: 
                    734:        io_start_buffering_in(f_in);
                    735: 
                    736:        send_files(f_in, f_out);
                    737:        io_flush(FULL_FLUSH);
                    738:        handle_stats(f_out);
                    739:        if (protocol_version >= 24)
                    740:                read_final_goodbye(f_in);
                    741:        io_flush(FULL_FLUSH);
                    742:        exit_cleanup(0);
                    743: }
                    744: 
                    745: 
                    746: static int do_recv(int f_in, int f_out, char *local_name)
                    747: {
                    748:        int pid;
                    749:        int exit_code = 0;
                    750:        int error_pipe[2];
                    751: 
                    752:        /* The receiving side mustn't obey this, or an existing symlink that
                    753:         * points to an identical file won't be replaced by the referent. */
                    754:        copy_links = copy_dirlinks = copy_unsafe_links = 0;
                    755: 
                    756: #ifdef SUPPORT_HARD_LINKS
                    757:        if (preserve_hard_links && !inc_recurse)
                    758:                match_hard_links(first_flist);
                    759: #endif
                    760: 
                    761:        if (fd_pair(error_pipe) < 0) {
                    762:                rsyserr(FERROR, errno, "pipe failed in do_recv");
                    763:                exit_cleanup(RERR_IPC);
                    764:        }
                    765: 
                    766:        io_flush(NORMAL_FLUSH);
                    767: 
                    768:        if ((pid = do_fork()) == -1) {
                    769:                rsyserr(FERROR, errno, "fork failed in do_recv");
                    770:                exit_cleanup(RERR_IPC);
                    771:        }
                    772: 
                    773:        if (pid == 0) {
                    774:                am_receiver = 1;
                    775: 
                    776:                close(error_pipe[0]);
                    777:                if (f_in != f_out)
                    778:                        close(f_out);
                    779: 
                    780:                /* we can't let two processes write to the socket at one time */
                    781:                io_end_multiplex_out();
                    782: 
                    783:                /* set place to send errors */
                    784:                set_msg_fd_out(error_pipe[1]);
                    785:                io_start_buffering_out(error_pipe[1]);
                    786: 
                    787:                recv_files(f_in, local_name);
                    788:                io_flush(FULL_FLUSH);
                    789:                handle_stats(f_in);
                    790: 
                    791:                send_msg(MSG_DONE, "", 1, 0);
                    792:                write_varlong(error_pipe[1], stats.total_read, 3);
                    793:                io_flush(FULL_FLUSH);
                    794: 
                    795:                /* Handle any keep-alive packets from the post-processing work
                    796:                 * that the generator does. */
                    797:                if (protocol_version >= 29) {
                    798:                        int iflags, xlen;
                    799:                        uchar fnamecmp_type;
                    800:                        char xname[MAXPATHLEN];
                    801: 
                    802:                        kluge_around_eof = -1;
                    803: 
                    804:                        /* This should only get stopped via a USR2 signal. */
                    805:                        read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
                    806:                                           xname, &xlen);
                    807: 
                    808:                        rprintf(FERROR, "Invalid packet at end of run [%s]\n",
                    809:                                who_am_i());
                    810:                        exit_cleanup(RERR_PROTOCOL);
                    811:                }
                    812: 
                    813:                /* Finally, we go to sleep until our parent kills us with a
                    814:                 * USR2 signal.  We sleep for a short time, as on some OSes
                    815:                 * a signal won't interrupt a sleep! */
                    816:                while (1)
                    817:                        msleep(20);
                    818:        }
                    819: 
                    820:        am_generator = 1;
                    821: 
                    822:        io_end_multiplex_in();
                    823:        if (write_batch && !am_server)
                    824:                stop_write_batch();
                    825: 
                    826:        close(error_pipe[1]);
                    827:        if (f_in != f_out)
                    828:                close(f_in);
                    829: 
                    830:        io_start_buffering_out(f_out);
                    831: 
                    832:        set_msg_fd_in(error_pipe[0]);
                    833:        io_start_buffering_in(error_pipe[0]);
                    834: 
                    835: #ifdef SUPPORT_HARD_LINKS
                    836:        if (preserve_hard_links && inc_recurse) {
                    837:                struct file_list *flist;
                    838:                for (flist = first_flist; flist; flist = flist->next)
                    839:                        match_hard_links(flist);
                    840:        }
                    841: #endif
                    842: 
                    843:        generate_files(f_out, local_name);
                    844: 
                    845:        handle_stats(-1);
                    846:        io_flush(FULL_FLUSH);
                    847:        if (protocol_version >= 24) {
                    848:                /* send a final goodbye message */
                    849:                write_ndx(f_out, NDX_DONE);
                    850:        }
                    851:        io_flush(FULL_FLUSH);
                    852: 
                    853:        set_msg_fd_in(-1);
                    854:        kill(pid, SIGUSR2);
                    855:        wait_process_with_flush(pid, &exit_code);
                    856:        return exit_code;
                    857: }
                    858: 
                    859: static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
                    860: {
                    861:        int exit_code;
                    862:        struct file_list *flist;
                    863:        char *local_name = NULL;
                    864:        int save_verbose = verbose;
                    865: 
                    866:        if (filesfrom_fd >= 0) {
                    867:                /* We can't mix messages with files-from data on the socket,
                    868:                 * so temporarily turn off verbose messages. */
                    869:                verbose = 0;
                    870:        }
                    871: 
                    872:        if (verbose > 2) {
                    873:                rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
                    874:                        argc, (long)getpid());
                    875:        }
                    876: 
                    877:        if (am_daemon && lp_read_only(module_id)) {
                    878:                rprintf(FERROR,"ERROR: module is read only\n");
                    879:                exit_cleanup(RERR_SYNTAX);
                    880:                return;
                    881:        }
                    882: 
                    883:        if (argc > 0) {
                    884:                char *dir = argv[0];
                    885:                argc--;
                    886:                argv++;
                    887:                if (!am_daemon && !change_dir(dir, CD_NORMAL)) {
                    888:                        rsyserr(FERROR, errno, "change_dir#4 %s failed",
                    889:                                full_fname(dir));
                    890:                        exit_cleanup(RERR_FILESELECT);
                    891:                }
                    892:        }
                    893: 
                    894:        if (protocol_version >= 30)
                    895:                io_start_multiplex_in();
                    896:        else
                    897:                io_start_buffering_in(f_in);
                    898:        recv_filter_list(f_in);
                    899: 
                    900:        if (filesfrom_fd >= 0) {
                    901:                /* We need to send the files-from names to the sender at the
                    902:                 * same time that we receive the file-list from them, so we
                    903:                 * need the IO routines to automatically write out the names
                    904:                 * onto our f_out socket as we read the file-list.  This
                    905:                 * avoids both deadlock and extra delays/buffers. */
                    906:                io_set_filesfrom_fds(filesfrom_fd, f_out);
                    907:                filesfrom_fd = -1;
                    908:        }
                    909: 
                    910:        flist = recv_file_list(f_in);
                    911:        if (!flist) {
                    912:                rprintf(FERROR,"server_recv: recv_file_list error\n");
                    913:                exit_cleanup(RERR_FILESELECT);
                    914:        }
                    915:        if (inc_recurse && file_total == 1)
                    916:                recv_additional_file_list(f_in);
                    917:        verbose = save_verbose;
                    918: 
                    919:        if (argc > 0)
                    920:                local_name = get_local_name(flist,argv[0]);
                    921: 
                    922:        /* Now that we know what our destination directory turned out to be,
                    923:         * we can sanitize the --link-/copy-/compare-dest args correctly. */
                    924:        if (sanitize_paths) {
                    925:                char **dir_p;
                    926:                for (dir_p = basis_dir; *dir_p; dir_p++)
                    927:                        *dir_p = sanitize_path(NULL, *dir_p, NULL, curr_dir_depth, SP_DEFAULT);
                    928:                if (partial_dir)
                    929:                        partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth, SP_DEFAULT);
                    930:        }
                    931:        check_alt_basis_dirs();
                    932: 
                    933:        if (daemon_filter_list.head) {
                    934:                char **dir_p;
                    935:                struct filter_list_struct *elp = &daemon_filter_list;
                    936: 
                    937:                for (dir_p = basis_dir; *dir_p; dir_p++) {
                    938:                        char *dir = *dir_p;
                    939:                        if (*dir == '/')
                    940:                                dir += module_dirlen;
                    941:                        if (check_filter(elp, FLOG, dir, 1) < 0)
                    942:                                goto options_rejected;
                    943:                }
                    944:                if (partial_dir && *partial_dir == '/'
                    945:                 && check_filter(elp, FLOG, partial_dir + module_dirlen, 1) < 0) {
                    946:                    options_rejected:
                    947:                        rprintf(FERROR,
                    948:                                "Your options have been rejected by the server.\n");
                    949:                        exit_cleanup(RERR_SYNTAX);
                    950:                }
                    951:        }
                    952: 
                    953:        exit_code = do_recv(f_in, f_out, local_name);
                    954:        exit_cleanup(exit_code);
                    955: }
                    956: 
                    957: 
                    958: int child_main(int argc, char *argv[])
                    959: {
                    960:        start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
                    961:        return 0;
                    962: }
                    963: 
                    964: 
                    965: void start_server(int f_in, int f_out, int argc, char *argv[])
                    966: {
                    967:        set_nonblocking(f_in);
                    968:        set_nonblocking(f_out);
                    969: 
                    970:        io_set_sock_fds(f_in, f_out);
                    971:        setup_protocol(f_out, f_in);
                    972: 
                    973:        if (protocol_version >= 23)
                    974:                io_start_multiplex_out();
                    975: 
                    976:        if (am_sender) {
                    977:                keep_dirlinks = 0; /* Must be disabled on the sender. */
                    978:                if (need_messages_from_generator)
                    979:                        io_start_multiplex_in();
                    980:                recv_filter_list(f_in);
                    981:                do_server_sender(f_in, f_out, argc, argv);
                    982:        } else
                    983:                do_server_recv(f_in, f_out, argc, argv);
                    984:        exit_cleanup(0);
                    985: }
                    986: 
                    987: 
                    988: /*
                    989:  * This is called once the connection has been negotiated.  It is used
                    990:  * for rsyncd, remote-shell, and local connections.
                    991:  */
                    992: int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
                    993: {
                    994:        struct file_list *flist = NULL;
                    995:        int exit_code = 0, exit_code2 = 0;
                    996:        char *local_name = NULL;
                    997: 
                    998:        cleanup_child_pid = pid;
                    999:        if (!read_batch) {
                   1000:                set_nonblocking(f_in);
                   1001:                set_nonblocking(f_out);
                   1002:        }
                   1003: 
                   1004:        io_set_sock_fds(f_in, f_out);
                   1005:        setup_protocol(f_out,f_in);
                   1006: 
                   1007:        /* We set our stderr file handle to blocking because ssh might have
                   1008:         * set it to non-blocking.  This can be particularly troublesome if
                   1009:         * stderr is a clone of stdout, because ssh would have set our stdout
                   1010:         * to non-blocking at the same time (which can easily cause us to lose
                   1011:         * output from our print statements).  This kluge shouldn't cause ssh
                   1012:         * any problems for how we use it.  Note also that we delayed setting
                   1013:         * this until after the above protocol setup so that we know for sure
                   1014:         * that ssh is done twiddling its file descriptors.  */
                   1015:        set_blocking(STDERR_FILENO);
                   1016: 
                   1017:        if (am_sender) {
                   1018:                keep_dirlinks = 0; /* Must be disabled on the sender. */
                   1019:                if (protocol_version >= 30)
                   1020:                        io_start_multiplex_out();
                   1021:                else
                   1022:                        io_start_buffering_out(f_out);
                   1023:                if (!filesfrom_host)
                   1024:                        set_msg_fd_in(f_in);
                   1025:                send_filter_list(f_out);
                   1026:                if (filesfrom_host)
                   1027:                        filesfrom_fd = f_in;
                   1028: 
                   1029:                if (write_batch && !am_server)
                   1030:                        start_write_batch(f_out);
                   1031:                flist = send_file_list(f_out, argc, argv);
                   1032:                if (verbose > 3)
                   1033:                        rprintf(FINFO,"file list sent\n");
                   1034: 
                   1035:                if (protocol_version >= 23)
                   1036:                        io_start_multiplex_in();
                   1037: 
                   1038:                io_flush(NORMAL_FLUSH);
                   1039:                send_files(f_in, f_out);
                   1040:                io_flush(FULL_FLUSH);
                   1041:                handle_stats(-1);
                   1042:                if (protocol_version >= 24)
                   1043:                        read_final_goodbye(f_in);
                   1044:                if (pid != -1) {
                   1045:                        if (verbose > 3)
                   1046:                                rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
                   1047:                        io_flush(FULL_FLUSH);
                   1048:                        wait_process_with_flush(pid, &exit_code);
                   1049:                }
                   1050:                output_summary();
                   1051:                io_flush(FULL_FLUSH);
                   1052:                exit_cleanup(exit_code);
                   1053:        }
                   1054: 
                   1055:        if (!read_batch) {
                   1056:                if (protocol_version >= 23)
                   1057:                        io_start_multiplex_in();
                   1058:                if (need_messages_from_generator)
                   1059:                        io_start_multiplex_out();
                   1060:        }
                   1061: 
                   1062:        send_filter_list(read_batch ? -1 : f_out);
                   1063: 
                   1064:        if (filesfrom_fd >= 0) {
                   1065:                io_set_filesfrom_fds(filesfrom_fd, f_out);
                   1066:                filesfrom_fd = -1;
                   1067:        }
                   1068: 
                   1069:        if (write_batch && !am_server)
                   1070:                start_write_batch(f_in);
                   1071:        flist = recv_file_list(f_in);
                   1072:        if (inc_recurse && file_total == 1)
                   1073:                recv_additional_file_list(f_in);
                   1074: 
                   1075:        if (flist && flist->used > 0) {
                   1076:                local_name = get_local_name(flist, argv[0]);
                   1077: 
                   1078:                check_alt_basis_dirs();
                   1079: 
                   1080:                exit_code2 = do_recv(f_in, f_out, local_name);
                   1081:        } else {
                   1082:                handle_stats(-1);
                   1083:                output_summary();
                   1084:        }
                   1085: 
                   1086:        if (pid != -1) {
                   1087:                if (verbose > 3)
                   1088:                        rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
                   1089:                io_flush(FULL_FLUSH);
                   1090:                wait_process_with_flush(pid, &exit_code);
                   1091:        }
                   1092: 
                   1093:        return MAX(exit_code, exit_code2);
                   1094: }
                   1095: 
                   1096: static int copy_argv(char *argv[])
                   1097: {
                   1098:        int i;
                   1099: 
                   1100:        for (i = 0; argv[i]; i++) {
                   1101:                if (!(argv[i] = strdup(argv[i]))) {
                   1102:                        rprintf (FERROR, "out of memory at %s(%d)\n",
                   1103:                                 __FILE__, __LINE__);
                   1104:                        return RERR_MALLOC;
                   1105:                }
                   1106:        }
                   1107: 
                   1108:        return 0;
                   1109: }
                   1110: 
                   1111: 
                   1112: /**
                   1113:  * Start a client for either type of remote connection.  Work out
                   1114:  * whether the arguments request a remote shell or rsyncd connection,
                   1115:  * and call the appropriate connection function, then run_client.
                   1116:  *
                   1117:  * Calls either start_socket_client (for sockets) or do_cmd and
                   1118:  * client_run (for ssh).
                   1119:  **/
                   1120: static int start_client(int argc, char *argv[])
                   1121: {
                   1122:        char *p, *shell_machine = NULL, *shell_user = NULL;
                   1123:        char **remote_argv;
                   1124:        int remote_argc;
                   1125:        int f_in, f_out;
                   1126:        int ret;
                   1127:        pid_t pid;
                   1128: 
                   1129:        /* Don't clobber argv[] so that ps(1) can still show the right
                   1130:         * command line. */
                   1131:        if ((ret = copy_argv(argv)) != 0)
                   1132:                return ret;
                   1133: 
                   1134:        if (!read_batch) { /* for read_batch, NO source is specified */
                   1135:                char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
                   1136:                if (path) { /* source is remote */
                   1137:                        char *dummy_host;
                   1138:                        int dummy_port = 0;
                   1139:                        *argv = path;
                   1140:                        remote_argv = argv;
                   1141:                        remote_argc = argc;
                   1142:                        argv += argc - 1;
                   1143:                        if (argc == 1 || **argv == ':')
                   1144:                                argc = 0; /* no dest arg */
                   1145:                        else if (check_for_hostspec(*argv, &dummy_host, &dummy_port)) {
                   1146:                                rprintf(FERROR,
                   1147:                                        "The source and destination cannot both be remote.\n");
                   1148:                                exit_cleanup(RERR_SYNTAX);
                   1149:                        } else {
                   1150:                                remote_argc--; /* don't count dest */
                   1151:                                argc = 1;
                   1152:                        }
                   1153:                        if (filesfrom_host && *filesfrom_host
                   1154:                            && strcmp(filesfrom_host, shell_machine) != 0) {
                   1155:                                rprintf(FERROR,
                   1156:                                        "--files-from hostname is not the same as the transfer hostname\n");
                   1157:                                exit_cleanup(RERR_SYNTAX);
                   1158:                        }
                   1159:                        am_sender = 0;
                   1160:                        if (rsync_port)
                   1161:                                daemon_over_rsh = shell_cmd ? 1 : -1;
                   1162:                } else { /* source is local, check dest arg */
                   1163:                        am_sender = 1;
                   1164: 
                   1165:                        if (argc > 1) {
                   1166:                                p = argv[--argc];
                   1167:                                remote_argv = argv + argc;
                   1168:                        } else {
                   1169:                                static char *dotarg[1] = { "." };
                   1170:                                p = dotarg[0];
                   1171:                                remote_argv = dotarg;
                   1172:                        }
                   1173:                        remote_argc = 1;
                   1174: 
                   1175:                        path = check_for_hostspec(p, &shell_machine, &rsync_port);
                   1176:                        if (path && filesfrom_host && *filesfrom_host
                   1177:                            && strcmp(filesfrom_host, shell_machine) != 0) {
                   1178:                                rprintf(FERROR,
                   1179:                                        "--files-from hostname is not the same as the transfer hostname\n");
                   1180:                                exit_cleanup(RERR_SYNTAX);
                   1181:                        }
                   1182:                        if (!path) { /* no hostspec found, so src & dest are local */
                   1183:                                local_server = 1;
                   1184:                                if (filesfrom_host) {
                   1185:                                        rprintf(FERROR,
                   1186:                                                "--files-from cannot be remote when the transfer is local\n");
                   1187:                                        exit_cleanup(RERR_SYNTAX);
                   1188:                                }
                   1189:                                shell_machine = NULL;
                   1190:                        } else { /* hostspec was found, so dest is remote */
                   1191:                                argv[argc] = path;
                   1192:                                if (rsync_port)
                   1193:                                        daemon_over_rsh = shell_cmd ? 1 : -1;
                   1194:                        }
                   1195:                }
                   1196:        } else {  /* read_batch */
                   1197:                local_server = 1;
                   1198:                if (check_for_hostspec(argv[argc-1], &shell_machine, &rsync_port)) {
                   1199:                        rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
                   1200:                        exit_cleanup(RERR_SYNTAX);
                   1201:                }
                   1202:                remote_argv = argv += argc - 1;
                   1203:                remote_argc = argc = 1;
                   1204:        }
                   1205: 
                   1206:        if (am_sender) {
                   1207:                char *dummy_host;
                   1208:                int dummy_port = rsync_port;
                   1209:                int i;
                   1210:                /* For local source, extra source args must not have hostspec. */
                   1211:                for (i = 1; i < argc; i++) {
                   1212:                        if (check_for_hostspec(argv[i], &dummy_host, &dummy_port)) {
                   1213:                                rprintf(FERROR, "Unexpected remote arg: %s\n", argv[i]);
                   1214:                                exit_cleanup(RERR_SYNTAX);
                   1215:                        }
                   1216:                }
                   1217:        } else {
                   1218:                char *dummy_host;
                   1219:                int dummy_port = rsync_port;
                   1220:                int i;
                   1221:                /* For remote source, any extra source args must have either
                   1222:                 * the same hostname or an empty hostname. */
                   1223:                for (i = 1; i < remote_argc; i++) {
                   1224:                        char *arg = check_for_hostspec(remote_argv[i], &dummy_host, &dummy_port);
                   1225:                        if (!arg) {
                   1226:                                rprintf(FERROR, "Unexpected local arg: %s\n", remote_argv[i]);
                   1227:                                rprintf(FERROR, "If arg is a remote file/dir, prefix it with a colon (:).\n");
                   1228:                                exit_cleanup(RERR_SYNTAX);
                   1229:                        }
                   1230:                        if (*dummy_host && strcmp(dummy_host, shell_machine) != 0) {
                   1231:                                rprintf(FERROR, "All source args must come from the same machine.\n");
                   1232:                                exit_cleanup(RERR_SYNTAX);
                   1233:                        }
                   1234:                        if (rsync_port != dummy_port) {
                   1235:                                if (!rsync_port || !dummy_port)
                   1236:                                        rprintf(FERROR, "All source args must use the same hostspec format.\n");
                   1237:                                else
                   1238:                                        rprintf(FERROR, "All source args must use the same port number.\n");
                   1239:                                exit_cleanup(RERR_SYNTAX);
                   1240:                        }
                   1241:                        remote_argv[i] = arg;
                   1242:                }
                   1243:        }
                   1244: 
                   1245:        if (daemon_over_rsh < 0)
                   1246:                return start_socket_client(shell_machine, remote_argc, remote_argv, argc, argv);
                   1247: 
                   1248:        if (password_file && !daemon_over_rsh) {
                   1249:                rprintf(FERROR, "The --password-file option may only be "
                   1250:                                "used when accessing an rsync daemon.\n");
                   1251:                exit_cleanup(RERR_SYNTAX);
                   1252:        }
                   1253: 
                   1254:        if (connect_timeout) {
                   1255:                rprintf(FERROR, "The --contimeout option may only be "
                   1256:                                "used when connecting to an rsync daemon.\n");
                   1257:                exit_cleanup(RERR_SYNTAX);
                   1258:        }
                   1259: 
                   1260:        if (shell_machine) {
                   1261:                p = strrchr(shell_machine,'@');
                   1262:                if (p) {
                   1263:                        *p = 0;
                   1264:                        shell_user = shell_machine;
                   1265:                        shell_machine = p+1;
                   1266:                }
                   1267:        }
                   1268: 
                   1269:        if (verbose > 3) {
                   1270:                rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
                   1271:                        NS(shell_cmd), NS(shell_machine), NS(shell_user),
                   1272:                        remote_argv ? NS(remote_argv[0]) : "");
                   1273:        }
                   1274: 
                   1275:        pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc,
                   1276:                     &f_in, &f_out);
                   1277: 
                   1278:        /* if we're running an rsync server on the remote host over a
                   1279:         * remote shell command, we need to do the RSYNCD protocol first */
                   1280:        if (daemon_over_rsh) {
                   1281:                int tmpret;
                   1282:                tmpret = start_inband_exchange(f_in, f_out, shell_user, remote_argc, remote_argv);
                   1283:                if (tmpret < 0)
                   1284:                        return tmpret;
                   1285:        }
                   1286: 
                   1287:        ret = client_run(f_in, f_out, pid, argc, argv);
                   1288: 
                   1289:        fflush(stdout);
                   1290:        fflush(stderr);
                   1291: 
                   1292:        return ret;
                   1293: }
                   1294: 
                   1295: 
                   1296: static RETSIGTYPE sigusr1_handler(UNUSED(int val))
                   1297: {
                   1298:        exit_cleanup(RERR_SIGNAL1);
                   1299: }
                   1300: 
                   1301: static RETSIGTYPE sigusr2_handler(UNUSED(int val))
                   1302: {
                   1303:        if (!am_server)
                   1304:                output_summary();
                   1305:        close_all();
                   1306:        if (got_xfer_error)
                   1307:                _exit(RERR_PARTIAL);
                   1308:        _exit(0);
                   1309: }
                   1310: 
                   1311: RETSIGTYPE remember_children(UNUSED(int val))
                   1312: {
                   1313: #ifdef WNOHANG
                   1314:        int cnt, status;
                   1315:        pid_t pid;
                   1316:        /* An empty waitpid() loop was put here by Tridge and we could never
                   1317:         * get him to explain why he put it in, so rather than taking it
                   1318:         * out we're instead saving the child exit statuses for later use.
                   1319:         * The waitpid() loop presumably eliminates all possibility of leaving
                   1320:         * zombie children, maybe that's why he did it. */
                   1321:        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
                   1322:                /* save the child's exit status */
                   1323:                for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
                   1324:                        if (pid_stat_table[cnt].pid == 0) {
                   1325:                                pid_stat_table[cnt].pid = pid;
                   1326:                                pid_stat_table[cnt].status = status;
                   1327:                                break;
                   1328:                        }
                   1329:                }
                   1330:        }
                   1331: #endif
                   1332: #ifndef HAVE_SIGACTION
                   1333:        signal(SIGCHLD, remember_children);
                   1334: #endif
                   1335: }
                   1336: 
                   1337: 
                   1338: /**
                   1339:  * This routine catches signals and tries to send them to gdb.
                   1340:  *
                   1341:  * Because it's called from inside a signal handler it ought not to
                   1342:  * use too many library routines.
                   1343:  *
                   1344:  * @todo Perhaps use "screen -X" instead/as well, to help people
                   1345:  * debugging without easy access to X.  Perhaps use an environment
                   1346:  * variable, or just call a script?
                   1347:  *
                   1348:  * @todo The /proc/ magic probably only works on Linux (and
                   1349:  * Solaris?)  Can we be more portable?
                   1350:  **/
                   1351: #ifdef MAINTAINER_MODE
                   1352: const char *get_panic_action(void)
                   1353: {
                   1354:        const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
                   1355: 
                   1356:        if (cmd_fmt)
                   1357:                return cmd_fmt;
                   1358:        else
                   1359:                return "xterm -display :0 -T Panic -n Panic "
                   1360:                        "-e gdb /proc/%d/exe %d";
                   1361: }
                   1362: 
                   1363: 
                   1364: /**
                   1365:  * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
                   1366:  *
                   1367:  * This signal handler is only installed if we were configured with
                   1368:  * --enable-maintainer-mode.  Perhaps it should always be on and we
                   1369:  * should just look at the environment variable, but I'm a bit leery
                   1370:  * of a signal sending us into a busy loop.
                   1371:  **/
                   1372: static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
                   1373: {
                   1374:        char cmd_buf[300];
                   1375:        int ret;
                   1376: 
                   1377:        snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(),
                   1378:                 getpid(), getpid());
                   1379: 
                   1380:        /* Unless we failed to execute gdb, we allow the process to
                   1381:         * continue.  I'm not sure if that's right. */
                   1382:        ret = system(cmd_buf);
                   1383:        if (ret)
                   1384:                _exit(ret);
                   1385: }
                   1386: #endif
                   1387: 
                   1388: 
                   1389: int main(int argc,char *argv[])
                   1390: {
                   1391:        int ret;
                   1392:        int orig_argc = argc;
                   1393:        char **orig_argv = argv;
                   1394: #ifdef HAVE_SIGACTION
                   1395: # ifdef HAVE_SIGPROCMASK
                   1396:        sigset_t sigmask;
                   1397: 
                   1398:        sigemptyset(&sigmask);
                   1399: # endif
                   1400:        sigact.sa_flags = SA_NOCLDSTOP;
                   1401: #endif
                   1402:        SIGACTMASK(SIGUSR1, sigusr1_handler);
                   1403:        SIGACTMASK(SIGUSR2, sigusr2_handler);
                   1404:        SIGACTMASK(SIGCHLD, remember_children);
                   1405: #ifdef MAINTAINER_MODE
                   1406:        SIGACTMASK(SIGSEGV, rsync_panic_handler);
                   1407:        SIGACTMASK(SIGFPE, rsync_panic_handler);
                   1408:        SIGACTMASK(SIGABRT, rsync_panic_handler);
                   1409:        SIGACTMASK(SIGBUS, rsync_panic_handler);
                   1410: #endif
                   1411: 
                   1412:        starttime = time(NULL);
                   1413:        our_uid = MY_UID();
                   1414:        am_root = our_uid == 0;
                   1415: 
                   1416:        memset(&stats, 0, sizeof(stats));
                   1417: 
                   1418:        if (argc < 2) {
                   1419:                usage(FERROR);
                   1420:                exit_cleanup(RERR_SYNTAX);
                   1421:        }
                   1422: 
                   1423:        /* we set a 0 umask so that correct file permissions can be
                   1424:         * carried across */
                   1425:        orig_umask = umask(0);
                   1426: 
                   1427: #if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
                   1428:        setlocale(LC_CTYPE, "");
                   1429: #endif
                   1430: 
                   1431:        if (!parse_arguments(&argc, (const char ***) &argv)) {
                   1432:                /* FIXME: We ought to call the same error-handling
                   1433:                 * code here, rather than relying on getopt. */
                   1434:                option_error();
                   1435:                exit_cleanup(RERR_SYNTAX);
                   1436:        }
                   1437: 
                   1438:        SIGACTMASK(SIGINT, sig_int);
                   1439:        SIGACTMASK(SIGHUP, sig_int);
                   1440:        SIGACTMASK(SIGTERM, sig_int);
                   1441: #if defined HAVE_SIGACTION && HAVE_SIGPROCMASK
                   1442:        sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
                   1443: #endif
                   1444: 
                   1445:        /* Ignore SIGPIPE; we consistently check error codes and will
                   1446:         * see the EPIPE. */
                   1447:        SIGACTION(SIGPIPE, SIG_IGN);
                   1448: #ifdef SIGXFSZ
                   1449:        SIGACTION(SIGXFSZ, SIG_IGN);
                   1450: #endif
                   1451: 
                   1452:        /* Initialize change_dir() here because on some old systems getcwd
                   1453:         * (implemented by forking "pwd" and reading its output) doesn't
                   1454:         * work when there are other child processes.  Also, on all systems
                   1455:         * that implement getcwd that way "pwd" can't be found after chroot. */
                   1456:        change_dir(NULL, CD_NORMAL);
                   1457: 
                   1458:        init_flist();
                   1459: 
                   1460:        if ((write_batch || read_batch) && !am_server) {
                   1461:                if (write_batch)
                   1462:                        write_batch_shell_file(orig_argc, orig_argv, argc);
                   1463: 
                   1464:                if (read_batch && strcmp(batch_name, "-") == 0)
                   1465:                        batch_fd = STDIN_FILENO;
                   1466:                else {
                   1467:                        batch_fd = do_open(batch_name,
                   1468:                                   write_batch ? O_WRONLY | O_CREAT | O_TRUNC
                   1469:                                   : O_RDONLY, S_IRUSR | S_IWUSR);
                   1470:                }
                   1471:                if (batch_fd < 0) {
                   1472:                        rsyserr(FERROR, errno, "Batch file %s open error",
                   1473:                                full_fname(batch_name));
                   1474:                        exit_cleanup(RERR_FILEIO);
                   1475:                }
                   1476:                if (read_batch)
                   1477:                        read_stream_flags(batch_fd);
                   1478:                else
                   1479:                        write_stream_flags(batch_fd);
                   1480:        }
                   1481:        if (write_batch < 0)
                   1482:                dry_run = 1;
                   1483: 
                   1484:        if (am_server) {
                   1485: #ifdef ICONV_CONST
                   1486:                setup_iconv();
                   1487: #endif
                   1488:        } else if (am_daemon)
                   1489:                return daemon_main();
                   1490: 
                   1491:        if (am_server && protect_args) {
                   1492:                char buf[MAXPATHLEN];
                   1493:                protect_args = 2;
                   1494:                read_args(STDIN_FILENO, NULL, buf, sizeof buf, 1, &argv, &argc, NULL);
                   1495:                if (!parse_arguments(&argc, (const char ***) &argv)) {
                   1496:                        option_error();
                   1497:                        exit_cleanup(RERR_SYNTAX);
                   1498:                }
                   1499:        }
                   1500: 
                   1501:        if (argc < 1) {
                   1502:                usage(FERROR);
                   1503:                exit_cleanup(RERR_SYNTAX);
                   1504:        }
                   1505: 
                   1506:        if (am_server) {
                   1507:                set_nonblocking(STDIN_FILENO);
                   1508:                set_nonblocking(STDOUT_FILENO);
                   1509:                if (am_daemon)
                   1510:                        return start_daemon(STDIN_FILENO, STDOUT_FILENO);
                   1511:                start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
                   1512:        }
                   1513: 
                   1514:        ret = start_client(argc, argv);
                   1515:        if (ret == -1)
                   1516:                exit_cleanup(RERR_STARTCLIENT);
                   1517:        else
                   1518:                exit_cleanup(ret);
                   1519: 
                   1520:        return ret;
                   1521: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>