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

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

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