Diff for /embedaddon/rsync/main.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2016/11/01 09:54:32 version 1.1.1.4, 2021/03/17 00:32:36
Line 4 Line 4
  * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>   * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 1996 Paul Mackerras   * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>   * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
 * Copyright (C) 2003-2015 Wayne Davison * Copyright (C) 2003-2020 Wayne Davison
  *   *
  * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
Line 22 Line 22
   
 #include "rsync.h"  #include "rsync.h"
 #include "inums.h"  #include "inums.h"
   #include "ifuncs.h"
 #include "io.h"  #include "io.h"
 #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H  #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
 #include <locale.h>  #include <locale.h>
 #endif  #endif
   #include <popt.h>
   #ifdef __TANDEM
   #include <floss.h(floss_execlp)>
   #endif
   #ifdef SUPPORT_FORCE_CHANGE
   #include <sys/sysctl.h>
   #endif
   #ifdef SUPPORT_HFS_COMPRESSION
   #include <sys/attr.h> /* For getattrlist() */
   #include <sys/mount.h> /* For statfs() */
   #endif
   
 extern int force_change;  extern int force_change;
 extern int dry_run;  extern int dry_run;
Line 35  extern int am_root; Line 47  extern int am_root;
 extern int am_server;  extern int am_server;
 extern int am_sender;  extern int am_sender;
 extern int am_daemon;  extern int am_daemon;
   extern int am_dbadmin;
 extern int inc_recurse;  extern int inc_recurse;
 extern int blocking_io;  extern int blocking_io;
 extern int always_checksum;  extern int always_checksum;
 extern int remove_source_files;  extern int remove_source_files;
 extern int output_needs_newline;  extern int output_needs_newline;
   extern int called_from_signal_handler;
 extern int need_messages_from_generator;  extern int need_messages_from_generator;
 extern int kluge_around_eof;  extern int kluge_around_eof;
 extern int got_xfer_error;  extern int got_xfer_error;
   extern int force_change;
 extern int msgs2stderr;  extern int msgs2stderr;
 extern int module_id;  extern int module_id;
 extern int read_only;  extern int read_only;
Line 51  extern int copy_dirlinks; Line 66  extern int copy_dirlinks;
 extern int copy_unsafe_links;  extern int copy_unsafe_links;
 extern int keep_dirlinks;  extern int keep_dirlinks;
 extern int preserve_hard_links;  extern int preserve_hard_links;
   extern int preserve_hfs_compression;
 extern int protocol_version;  extern int protocol_version;
   extern int always_checksum;
   extern int mkpath_dest_arg;
 extern int file_total;  extern int file_total;
 extern int recurse;  extern int recurse;
 extern int xfer_dirs;  extern int xfer_dirs;
Line 76  extern pid_t cleanup_child_pid; Line 94  extern pid_t cleanup_child_pid;
 extern size_t bwlimit_writemax;  extern size_t bwlimit_writemax;
 extern unsigned int module_dirlen;  extern unsigned int module_dirlen;
 extern BOOL flist_receiving_enabled;  extern BOOL flist_receiving_enabled;
 extern BOOL shutting_down;  
 extern BOOL want_progress_now;  extern BOOL want_progress_now;
   extern BOOL shutting_down;
 extern int backup_dir_len;  extern int backup_dir_len;
 extern int basis_dir_cnt;  extern int basis_dir_cnt;
   extern int default_af_hint;
 extern struct stats stats;  extern struct stats stats;
 extern char *stdout_format;  extern char *stdout_format;
 extern char *logfile_format;  extern char *logfile_format;
 extern char *filesfrom_host;  extern char *filesfrom_host;
 extern char *partial_dir;  extern char *partial_dir;
 extern char *dest_option;  
 extern char *rsync_path;  extern char *rsync_path;
   extern char *db_config;
 extern char *shell_cmd;  extern char *shell_cmd;
 extern char *batch_name;  
 extern char *password_file;  extern char *password_file;
 extern char *backup_dir;  extern char *backup_dir;
   extern char *copy_as;
   extern char *tmpdir;
 extern char curr_dir[MAXPATHLEN];  extern char curr_dir[MAXPATHLEN];
 extern char backup_dir_buf[MAXPATHLEN];  extern char backup_dir_buf[MAXPATHLEN];
 extern char *basis_dir[MAX_BASIS_DIRS+1];  extern char *basis_dir[MAX_BASIS_DIRS+1];
Line 102  gid_t our_gid; Line 122  gid_t our_gid;
 int am_receiver = 0;  /* Only set to 1 after the receiver/generator fork. */  int am_receiver = 0;  /* Only set to 1 after the receiver/generator fork. */
 int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */  int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */
 int local_server = 0;  int local_server = 0;
int daemon_over_rsh = 0;int daemon_connection = 0; /* 0 = no daemon, 1 = daemon via remote shell, -1 = daemon via socket */
 mode_t orig_umask = 0;  mode_t orig_umask = 0;
 int batch_gen_fd = -1;  int batch_gen_fd = -1;
 int sender_keeps_checksum = 0;  int sender_keeps_checksum = 0;
   int fs_supports_hfs_compression = 0;
   int raw_argc, cooked_argc;
   char **raw_argv, **cooked_argv;
   
 /* There's probably never more than at most 2 outstanding child processes,  /* There's probably never more than at most 2 outstanding child processes,
  * but set it higher, just in case. */   * but set it higher, just in case. */
Line 156  pid_t wait_process(pid_t pid, int *status_ptr, int fla Line 179  pid_t wait_process(pid_t pid, int *status_ptr, int fla
         return waited_pid;          return waited_pid;
 }  }
   
   int shell_exec(const char *cmd)
   {
           char *shell = getenv("RSYNC_SHELL");
           int status;
           pid_t pid;
   
           if (!shell)
                   return system(cmd);
   
           if ((pid = fork()) < 0)
                   return -1;
   
           if (pid == 0) {
                   execlp(shell, shell, "-c", cmd, NULL);
                   _exit(1);
           }
   
           int ret = wait_process(pid, &status, 0);
           return ret < 0 ? -1 : status;
   }
   
 /* Wait for a process to exit, calling io_flush while waiting. */  /* Wait for a process to exit, calling io_flush while waiting. */
static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
 {  {
         pid_t waited_pid;          pid_t waited_pid;
         int status;          int status;
Line 184  static void wait_process_with_flush(pid_t pid, int *ex Line 228  static void wait_process_with_flush(pid_t pid, int *ex
                         *exit_code_ptr = RERR_TERMINATED;                          *exit_code_ptr = RERR_TERMINATED;
                 else                  else
                         *exit_code_ptr = RERR_WAITCHILD;                          *exit_code_ptr = RERR_WAITCHILD;
        } else        } else {
                 *exit_code_ptr = WEXITSTATUS(status);                  *exit_code_ptr = WEXITSTATUS(status);
                   if (*exit_code_ptr == RERR_WECRASHED)
                           *exit_code_ptr = RERR_CRASHED;
           }
 }  }
   
 void write_del_stats(int f)  void write_del_stats(int f)
Line 212  void read_del_stats(int f) Line 259  void read_del_stats(int f)
         stats.deleted_files += stats.deleted_specials = read_varint(f);          stats.deleted_files += stats.deleted_specials = read_varint(f);
 }  }
   
   static void become_copy_as_user()
   {
           char *gname;
           uid_t uid;
           gid_t gid;
   
           if (!copy_as)
                   return;
   
           if (DEBUG_GTE(CMD, 2))
                   rprintf(FINFO, "[%s] copy_as=%s\n", who_am_i(), copy_as);
   
           if ((gname = strchr(copy_as, ':')) != NULL)
                   *gname++ = '\0';
   
           if (!user_to_uid(copy_as, &uid, True)) {
                   rprintf(FERROR, "Invalid copy-as user: %s\n", copy_as);
                   exit_cleanup(RERR_SYNTAX);
           }
   
           if (gname) {
                   if (!group_to_gid(gname, &gid, True)) {
                           rprintf(FERROR, "Invalid copy-as group: %s\n", gname);
                           exit_cleanup(RERR_SYNTAX);
                   }
           } else {
                   struct passwd *pw;
                   if ((pw = getpwuid(uid)) == NULL) {
                           rsyserr(FERROR, errno, "getpwuid failed");
                           exit_cleanup(RERR_SYNTAX);
                   }
                   gid = pw->pw_gid;
           }
   
           if (setgid(gid) < 0) {
                   rsyserr(FERROR, errno, "setgid failed");
                   exit_cleanup(RERR_SYNTAX);
           }
   #ifdef HAVE_SETGROUPS
           if (setgroups(1, &gid)) {
                   rsyserr(FERROR, errno, "setgroups failed");
                   exit_cleanup(RERR_SYNTAX);
           }
   #endif
   #ifdef HAVE_INITGROUPS
           if (!gname && initgroups(copy_as, gid) < 0) {
                   rsyserr(FERROR, errno, "initgroups failed");
                   exit_cleanup(RERR_SYNTAX);
           }
   #endif
   
           if (setuid(uid) < 0
   #ifdef HAVE_SETEUID
            || seteuid(uid) < 0
   #endif
           ) {
                   rsyserr(FERROR, errno, "setuid failed");
                   exit_cleanup(RERR_SYNTAX);
           }
   
           our_uid = MY_UID();
           our_gid = MY_GID();
           am_root = (our_uid == ROOT_UID);
   
           if (gname)
                   gname[-1] = ':';
   }
   
 /* This function gets called from all 3 processes.  We want the client side  /* This function gets called from all 3 processes.  We want the client side
  * to actually output the text, but the sender is the only process that has   * to actually output the text, but the sender is the only process that has
  * all the stats we need.  So, if we're a client sender, we do the report.   * all the stats we need.  So, if we're a client sender, we do the report.
Line 304  static void output_itemized_counts(const char *prefix, Line 419  static void output_itemized_counts(const char *prefix,
         rprintf(FINFO, "%s: %s%s\n", prefix, comma_num(total), buf);          rprintf(FINFO, "%s: %s%s\n", prefix, comma_num(total), buf);
 }  }
   
   static const char *bytes_per_sec_human_dnum(void)
   {
           if (starttime == (time_t)-1 || endtime == (time_t)-1)
                   return "UNKNOWN";
           return human_dnum((total_written + total_read) / (0.5 + (endtime - starttime)), 2);
   }
   
 static void output_summary(void)  static void output_summary(void)
 {  {
         if (INFO_GTE(STATS, 2)) {          if (INFO_GTE(STATS, 2)) {
Line 344  static void output_summary(void) Line 466  static void output_summary(void)
                 rprintf(FINFO,                  rprintf(FINFO,
                         "sent %s bytes  received %s bytes  %s bytes/sec\n",                          "sent %s bytes  received %s bytes  %s bytes/sec\n",
                         human_num(total_written), human_num(total_read),                          human_num(total_written), human_num(total_read),
                        human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));                        bytes_per_sec_human_dnum());
                 rprintf(FINFO, "total size is %s  speedup is %s%s\n",                  rprintf(FINFO, "total size is %s  speedup is %s%s\n",
                         human_num(stats.total_size),                          human_num(stats.total_size),
                         comma_dnum((double)stats.total_size / (total_written+total_read), 2),                          comma_dnum((double)stats.total_size / (total_written+total_read), 2),
Line 413  static pid_t do_cmd(char *cmd, char *machine, char *us Line 535  static pid_t do_cmd(char *cmd, char *machine, char *us
                 if (!cmd)                  if (!cmd)
                         cmd = RSYNC_RSH;                          cmd = RSYNC_RSH;
                 cmd = need_to_free = strdup(cmd);                  cmd = need_to_free = strdup(cmd);
                 if (!cmd)  
                         goto oom;  
   
                 for (t = f = cmd; *f; f++) {                  for (t = f = cmd; *f; f++) {
                         if (*f == ' ')                          if (*f == ' ')
Line 427  static pid_t do_cmd(char *cmd, char *machine, char *us Line 547  static pid_t do_cmd(char *cmd, char *machine, char *us
                                 if (!*f) {                                  if (!*f) {
                                         if (in_quote) {                                          if (in_quote) {
                                                 rprintf(FERROR,                                                  rprintf(FERROR,
                                                    "Missing trailing-%c in remote-shell command.\n",                                                        "Missing trailing-%c in remote-shell command.\n",
                                                    in_quote);                                                        in_quote);
                                                 exit_cleanup(RERR_SYNTAX);                                                  exit_cleanup(RERR_SYNTAX);
                                         }                                          }
                                         f--;                                          f--;
Line 449  static pid_t do_cmd(char *cmd, char *machine, char *us Line 569  static pid_t do_cmd(char *cmd, char *machine, char *us
                         *t++ = '\0';                          *t++ = '\0';
                 }                  }
   
                /* check to see if we've already been given '-l user' in                /* NOTE: must preserve t == start of command name until the end of the args handling! */
                 * the remote-shell command */                if ((t = strrchr(cmd, '/')) != NULL)
                         t++;
                 else
                         t = cmd;
 
                 /* Check to see if we've already been given '-l user' in the remote-shell command. */
                 for (i = 0; i < argc-1; i++) {                  for (i = 0; i < argc-1; i++) {
                         if (!strcmp(args[i], "-l") && args[i+1][0] != '-')                          if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
                                 dash_l_set = 1;                                  dash_l_set = 1;
Line 459  static pid_t do_cmd(char *cmd, char *machine, char *us Line 584  static pid_t do_cmd(char *cmd, char *machine, char *us
 #ifdef HAVE_REMSH  #ifdef HAVE_REMSH
                 /* remsh (on HPUX) takes the arguments the other way around */                  /* remsh (on HPUX) takes the arguments the other way around */
                 args[argc++] = machine;                  args[argc++] = machine;
                if (user && !(daemon_over_rsh && dash_l_set)) {                if (user && !(daemon_connection && dash_l_set)) {
                         args[argc++] = "-l";                          args[argc++] = "-l";
                         args[argc++] = user;                          args[argc++] = user;
                 }                  }
 #else  #else
                if (user && !(daemon_over_rsh && dash_l_set)) {                if (user && !(daemon_connection && dash_l_set)) {
                         args[argc++] = "-l";                          args[argc++] = "-l";
                         args[argc++] = user;                          args[argc++] = user;
                 }                  }
   #ifdef AF_INET
                   if (default_af_hint == AF_INET && strcmp(t, "ssh") == 0)
                           args[argc++] = "-4"; /* we're using ssh so we can add a -4 option */
   #endif
   #ifdef AF_INET6
                   if (default_af_hint == AF_INET6 && strcmp(t, "ssh") == 0)
                           args[argc++] = "-6"; /* we're using ssh so we can add a -6 option */
   #endif
                 args[argc++] = machine;                  args[argc++] = machine;
 #endif  #endif
   
                 args[argc++] = rsync_path;                  args[argc++] = rsync_path;
   
                if (blocking_io < 0) {                if (blocking_io < 0 && (strcmp(t, "rsh") == 0 || strcmp(t, "remsh") == 0))
                        char *cp;                        blocking_io = 1;
                        if ((cp = strrchr(cmd, '/')) != NULL) 
                                cp++; 
                        else 
                                cp = cmd; 
                        if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0) 
                                blocking_io = 1; 
                } 
   
                server_options(args,&argc);                if (daemon_connection > 0) {
                         args[argc++] = "--server";
                         args[argc++] = "--daemon";
                 } else
                         server_options(args, &argc);
   
                 if (argc >= MAX_ARGS - 2)                  if (argc >= MAX_ARGS - 2)
                         goto arg_overflow;                          goto arg_overflow;
Line 491  static pid_t do_cmd(char *cmd, char *machine, char *us Line 621  static pid_t do_cmd(char *cmd, char *machine, char *us
   
         args[argc++] = ".";          args[argc++] = ".";
   
        if (!daemon_over_rsh) {        if (!daemon_connection) {
                 while (remote_argc > 0) {                  while (remote_argc > 0) {
                         if (argc >= MAX_ARGS - 1) {                          if (argc >= MAX_ARGS - 1) {
                           arg_overflow:                            arg_overflow:
Line 544  static pid_t do_cmd(char *cmd, char *machine, char *us Line 674  static pid_t do_cmd(char *cmd, char *machine, char *us
 #ifdef ICONV_CONST  #ifdef ICONV_CONST
                 setup_iconv();                  setup_iconv();
 #endif  #endif
                if (protect_args && !daemon_over_rsh)                if (protect_args && !daemon_connection)
                         send_protected_args(*f_out_p, args);                          send_protected_args(*f_out_p, args);
         }          }
   
Line 552  static pid_t do_cmd(char *cmd, char *machine, char *us Line 682  static pid_t do_cmd(char *cmd, char *machine, char *us
                 free(need_to_free);                  free(need_to_free);
   
         return pid;          return pid;
   }
   
  oom:#ifdef SUPPORT_HFS_COMPRESSION
        out_of_memory("do_cmd");static void hfs_receiver_check(void)
        return 0; /* not reached */{
         struct statfs fsb;
         struct attrlist attrs;
         struct {
                 int32_t len;
                 vol_capabilities_set_t caps;
         } attrData;
 
         if (preserve_hfs_compression != 1)
                 return; /* Nothing to check if --hfs-compression option isn't enabled. */
 
         if (statfs(".", &fsb) < 0) {
                 rsyserr(FERROR, errno, "statfs %s failed", curr_dir);
                 exit_cleanup(RERR_FILESELECT);
         }
 
         bzero(&attrs, sizeof attrs);
         attrs.bitmapcount = ATTR_BIT_MAP_COUNT;
         attrs.volattr = ATTR_VOL_CAPABILITIES;
 
         bzero(&attrData, sizeof attrData);
         attrData.len = sizeof attrData;
 
         if (getattrlist(fsb.f_mntonname, &attrs, &attrData, sizeof attrData, 0) < 0) {
                 rsyserr(FERROR, errno, "getattrlist %s failed", curr_dir);
                 exit_cleanup(RERR_FILESELECT);
         }
 
         if (!(attrData.caps[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_DECMPFS_COMPRESSION)) {
                 rprintf(FERROR, "The destination filesystem does not support HFS+ compression.\n");
                 exit_cleanup(RERR_UNSUPPORTED);
         }
 }  }
   #endif
   
 /* The receiving side operates in one of two modes:  /* The receiving side operates in one of two modes:
  *   *
Line 574  static pid_t do_cmd(char *cmd, char *machine, char *us Line 737  static pid_t do_cmd(char *cmd, char *machine, char *us
 static char *get_local_name(struct file_list *flist, char *dest_path)  static char *get_local_name(struct file_list *flist, char *dest_path)
 {  {
         STRUCT_STAT st;          STRUCT_STAT st;
        int statret;        int statret, trailing_slash;
         char *cp;          char *cp;
   
         if (DEBUG_GTE(RECV, 1)) {          if (DEBUG_GTE(RECV, 1)) {
Line 587  static char *get_local_name(struct file_list *flist, c Line 750  static char *get_local_name(struct file_list *flist, c
   
         /* Treat an empty string as a copy into the current directory. */          /* Treat an empty string as a copy into the current directory. */
         if (!*dest_path)          if (!*dest_path)
            dest_path = ".";                dest_path = ".";
   
         if (daemon_filter_list.head) {          if (daemon_filter_list.head) {
                 char *slash = strrchr(dest_path, '/');                  char *slash = strrchr(dest_path, '/');
Line 607  static char *get_local_name(struct file_list *flist, c Line 770  static char *get_local_name(struct file_list *flist, c
         }          }
   
         /* See what currently exists at the destination. */          /* See what currently exists at the destination. */
        if ((statret = do_stat(dest_path, &st)) == 0) {        statret = do_stat(dest_path, &st);
         cp = strrchr(dest_path, '/');
         trailing_slash = cp && !cp[1];
 
         if (mkpath_dest_arg && statret < 0 && (cp || file_total > 1)) {
                 int ret = make_path(dest_path, ACCESSPERMS, file_total > 1 && !trailing_slash ? 0 : MKP_DROP_NAME);
                 if (ret < 0)
                         goto mkdir_error;
                 if (INFO_GTE(NAME, 1)) {
                         if (file_total == 1 || trailing_slash)
                                 *cp = '\0';
                         rprintf(FINFO, "created %d director%s for %s\n", ret, ret == 1 ? "y" : "ies", dest_path);
                         if (file_total == 1 || trailing_slash)
                                 *cp = '/';
                 }
                 if (file_total > 1 || trailing_slash)
                         statret = do_stat(dest_path, &st);
         }
 
         if (statret == 0) {
                 /* If the destination is a dir, enter it and use mode 1. */                  /* If the destination is a dir, enter it and use mode 1. */
                 if (S_ISDIR(st.st_mode)) {                  if (S_ISDIR(st.st_mode)) {
                         if (!change_dir(dest_path, CD_NORMAL)) {                          if (!change_dir(dest_path, CD_NORMAL)) {
Line 616  static char *get_local_name(struct file_list *flist, c Line 798  static char *get_local_name(struct file_list *flist, c
                                 exit_cleanup(RERR_FILESELECT);                                  exit_cleanup(RERR_FILESELECT);
                         }                          }
                         filesystem_dev = st.st_dev; /* ensures --force works right w/-x */                          filesystem_dev = st.st_dev; /* ensures --force works right w/-x */
   #ifdef SUPPORT_HFS_COMPRESSION
                           hfs_receiver_check();
   #endif
                         return NULL;                          return NULL;
                 }                  }
                 if (file_total > 1) {                  if (file_total > 1) {
Line 637  static char *get_local_name(struct file_list *flist, c Line 822  static char *get_local_name(struct file_list *flist, c
                 exit_cleanup(RERR_FILESELECT);                  exit_cleanup(RERR_FILESELECT);
         }          }
   
         cp = strrchr(dest_path, '/');  
   
         /* If we need a destination directory because the transfer is not          /* If we need a destination directory because the transfer is not
          * of a single non-directory or the user has requested one via a           * of a single non-directory or the user has requested one via a
          * destination path ending in a slash, create one and use mode 1. */           * destination path ending in a slash, create one and use mode 1. */
        if (file_total > 1 || (cp && !cp[1])) {        if (file_total > 1 || trailing_slash) {
                /* Lop off the final slash (if any). */                if (trailing_slash)
                if (cp && !cp[1])                        *cp = '\0'; /* Lop off the final slash (if any). */
                        *cp = '\0'; 
   
                 if (statret == 0) {                  if (statret == 0) {
                        rprintf(FERROR,                        rprintf(FERROR, "ERROR: destination path is not a directory\n");
                            "ERROR: destination path is not a directory\n"); 
                         exit_cleanup(RERR_SYNTAX);                          exit_cleanup(RERR_SYNTAX);
                 }                  }
   
                 if (do_mkdir(dest_path, ACCESSPERMS) != 0) {                  if (do_mkdir(dest_path, ACCESSPERMS) != 0) {
                       mkdir_error:
                         rsyserr(FERROR, errno, "mkdir %s failed",                          rsyserr(FERROR, errno, "mkdir %s failed",
                                 full_fname(dest_path));                                  full_fname(dest_path));
                         exit_cleanup(RERR_FILEIO);                          exit_cleanup(RERR_FILEIO);
Line 676  static char *get_local_name(struct file_list *flist, c Line 858  static char *get_local_name(struct file_list *flist, c
                                 full_fname(dest_path));                                  full_fname(dest_path));
                         exit_cleanup(RERR_FILESELECT);                          exit_cleanup(RERR_FILESELECT);
                 }                  }
#ifdef SUPPORT_HFS_COMPRESSION
                 hfs_receiver_check();
 #endif
                 return NULL;                  return NULL;
         }          }
   
Line 696  static char *get_local_name(struct file_list *flist, c Line 880  static char *get_local_name(struct file_list *flist, c
                         full_fname(dest_path));                          full_fname(dest_path));
                 exit_cleanup(RERR_FILESELECT);                  exit_cleanup(RERR_FILESELECT);
         }          }
   #ifdef SUPPORT_HFS_COMPRESSION
           hfs_receiver_check();
   #endif
         *cp = '/';          *cp = '/';
   
         return cp + 1;          return cp + 1;
Line 720  static void check_alt_basis_dirs(void) Line 907  static void check_alt_basis_dirs(void)
                 if (dry_run > 1 && *bdir != '/') {                  if (dry_run > 1 && *bdir != '/') {
                         int len = curr_dir_len + 1 + bd_len + 1;                          int len = curr_dir_len + 1 + bd_len + 1;
                         char *new = new_array(char, len);                          char *new = new_array(char, len);
                         if (!new)  
                                 out_of_memory("check_alt_basis_dirs");  
                         if (slash && strncmp(bdir, "../", 3) == 0) {                          if (slash && strncmp(bdir, "../", 3) == 0) {
                            /* We want to remove only one leading "../" prefix for                                /* We want to remove only one leading "../" prefix for
                             * the directory we couldn't create in dry-run mode:                                 * the directory we couldn't create in dry-run mode:
                             * this ensures that any other ".." references get                                 * this ensures that any other ".." references get
                             * evaluated the same as they would for a live copy. */                                 * evaluated the same as they would for a live copy. */
                            *slash = '\0';                                *slash = '\0';
                            pathjoin(new, len, curr_dir, bdir + 3);                                pathjoin(new, len, curr_dir, bdir + 3);
                            *slash = '/';                                *slash = '/';
                         } else                          } else
                            pathjoin(new, len, curr_dir, bdir);                                pathjoin(new, len, curr_dir, bdir);
                         basis_dir[j] = bdir = new;                          basis_dir[j] = bdir = new;
                 }                  }
                 if (do_stat(bdir, &st) < 0)                  if (do_stat(bdir, &st) < 0)
                        rprintf(FWARNING, "%s arg does not exist: %s\n", dest_option, bdir);                        rprintf(FWARNING, "%s arg does not exist: %s\n", alt_dest_opt(0), bdir);
                 else if (!S_ISDIR(st.st_mode))                  else if (!S_ISDIR(st.st_mode))
                        rprintf(FWARNING, "%s arg is not a dir: %s\n", dest_option, bdir);                        rprintf(FWARNING, "%s arg is not a dir: %s\n", alt_dest_opt(0), bdir);
         }          }
 }  }
   
Line 778  static void read_final_goodbye(int f_in, int f_out) Line 963  static void read_final_goodbye(int f_in, int f_out)
 static void do_server_sender(int f_in, int f_out, int argc, char *argv[])  static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
 {  {
         struct file_list *flist;          struct file_list *flist;
        char *dir = argv[0];        char *dir;
   
         if (DEBUG_GTE(SEND, 1))          if (DEBUG_GTE(SEND, 1))
                 rprintf(FINFO, "server_sender starting pid=%d\n", (int)getpid());                  rprintf(FINFO, "server_sender starting pid=%d\n", (int)getpid());
Line 786  static void do_server_sender(int f_in, int f_out, int  Line 971  static void do_server_sender(int f_in, int f_out, int 
         if (am_daemon && lp_write_only(module_id)) {          if (am_daemon && lp_write_only(module_id)) {
                 rprintf(FERROR, "ERROR: module is write only\n");                  rprintf(FERROR, "ERROR: module is write only\n");
                 exit_cleanup(RERR_SYNTAX);                  exit_cleanup(RERR_SYNTAX);
                 return;  
         }          }
         if (am_daemon && read_only && remove_source_files) {          if (am_daemon && read_only && remove_source_files) {
                 rprintf(FERROR,                  rprintf(FERROR,
                    "ERROR: --remove-%s-files cannot be used with a read-only module\n",                        "ERROR: --remove-%s-files cannot be used with a read-only module\n",
                    remove_source_files == 1 ? "source" : "sent");                        remove_source_files == 1 ? "source" : "sent");
                 exit_cleanup(RERR_SYNTAX);                  exit_cleanup(RERR_SYNTAX);
                 return;  
         }          }
           if (argc < 1) {
                   rprintf(FERROR, "ERROR: do_server_sender called without args\n");
                   exit_cleanup(RERR_SYNTAX);
           }
   
           become_copy_as_user();
   
           dir = argv[0];
         if (!relative_paths) {          if (!relative_paths) {
                 if (!change_dir(dir, CD_NORMAL)) {                  if (!change_dir(dir, CD_NORMAL)) {
                         rsyserr(FERROR, errno, "change_dir#3 %s failed",                          rsyserr(FERROR, errno, "change_dir#3 %s failed",
Line 842  static int do_recv(int f_in, int f_out, char *local_na Line 1032  static int do_recv(int f_in, int f_out, char *local_na
          * points to an identical file won't be replaced by the referent. */           * points to an identical file won't be replaced by the referent. */
         copy_links = copy_dirlinks = copy_unsafe_links = 0;          copy_links = copy_dirlinks = copy_unsafe_links = 0;
   
   #ifdef SUPPORT_FORCE_CHANGE
           if (force_change & SYS_IMMUTABLE) {
                   /* Determine whether we'll be able to unlock a system immutable item. */
                   int mib[2];
                   int securityLevel = 0;
                   size_t len = sizeof securityLevel;
   
                   mib[0] = CTL_KERN;
                   mib[1] = KERN_SECURELVL;
                   if (sysctl(mib, 2, &securityLevel, &len, NULL, 0) == 0 && securityLevel > 0) {
                           rprintf(FERROR, "System security level is too high to force mutability on system immutable files and directories.\n");
                           exit_cleanup(RERR_UNSUPPORTED);
                   }
           }
   #endif
   
 #ifdef SUPPORT_HARD_LINKS  #ifdef SUPPORT_HARD_LINKS
         if (preserve_hard_links && !inc_recurse)          if (preserve_hard_links && !inc_recurse)
                 match_hard_links(first_flist);                  match_hard_links(first_flist);
Line 867  static int do_recv(int f_in, int f_out, char *local_na Line 1073  static int do_recv(int f_in, int f_out, char *local_na
                                 rprintf(FERROR, "Failed to stat %s: %s\n", backup_dir_buf, strerror(errno));                                  rprintf(FERROR, "Failed to stat %s: %s\n", backup_dir_buf, strerror(errno));
                                 exit_cleanup(RERR_FILEIO);                                  exit_cleanup(RERR_FILEIO);
                         }                          }
                        rprintf(FINFO, "(new) backup_dir is %s\n", backup_dir_buf);                        if (INFO_GTE(BACKUP, 1))
                                 rprintf(FINFO, "(new) backup_dir is %s\n", backup_dir_buf);
                 } else if (INFO_GTE(BACKUP, 1))                  } else if (INFO_GTE(BACKUP, 1))
                         rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);                          rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
                 if (backup_dir_len > 1)                  if (backup_dir_len > 1)
                         backup_dir_buf[backup_dir_len-1] = '/';                          backup_dir_buf[backup_dir_len-1] = '/';
         }          }
   
           if (tmpdir) {
                   STRUCT_STAT st;
                   int ret = do_stat(tmpdir, &st);
                   if (ret < 0 || !S_ISDIR(st.st_mode)) {
                           if (ret == 0) {
                                   rprintf(FERROR, "The temp-dir is not a directory: %s\n", tmpdir);
                                   exit_cleanup(RERR_SYNTAX);
                           }
                           if (errno == ENOENT) {
                                   rprintf(FERROR, "The temp-dir does not exist: %s\n", tmpdir);
                                   exit_cleanup(RERR_SYNTAX);
                           }
                           rprintf(FERROR, "Failed to stat temp-dir %s: %s\n", tmpdir, strerror(errno));
                           exit_cleanup(RERR_FILEIO);
                   }
           }
   
         io_flush(FULL_FLUSH);          io_flush(FULL_FLUSH);
   
         if ((pid = do_fork()) == -1) {          if ((pid = do_fork()) == -1) {
Line 980  static void do_server_recv(int f_in, int f_out, int ar Line 1204  static void do_server_recv(int f_in, int f_out, int ar
         char *local_name = NULL;          char *local_name = NULL;
         int negated_levels;          int negated_levels;
   
        if (filesfrom_fd >= 0 && !msgs2stderr && protocol_version < 31) {        if (filesfrom_fd >= 0 && msgs2stderr != 1 && protocol_version < 31) {
                 /* We can't mix messages with files-from data on the socket,                  /* We can't mix messages with files-from data on the socket,
                  * so temporarily turn off info/debug messages. */                   * so temporarily turn off info/debug messages. */
                 negate_output_levels();                  negate_output_levels();
Line 997  static void do_server_recv(int f_in, int f_out, int ar Line 1221  static void do_server_recv(int f_in, int f_out, int ar
                 return;                  return;
         }          }
   
           become_copy_as_user();
   
         if (argc > 0) {          if (argc > 0) {
                 char *dir = argv[0];                  char *dir = argv[0];
                 argc--;                  argc--;
Line 1029  static void do_server_recv(int f_in, int f_out, int ar Line 1255  static void do_server_recv(int f_in, int f_out, int ar
                 rprintf(FERROR,"server_recv: recv_file_list error\n");                  rprintf(FERROR,"server_recv: recv_file_list error\n");
                 exit_cleanup(RERR_FILESELECT);                  exit_cleanup(RERR_FILESELECT);
         }          }
   
         if (inc_recurse && file_total == 1)          if (inc_recurse && file_total == 1)
                 recv_additional_file_list(f_in);                  recv_additional_file_list(f_in);
   
Line 1064  static void do_server_recv(int f_in, int f_out, int ar Line 1289  static void do_server_recv(int f_in, int f_out, int ar
                 if (partial_dir && *partial_dir == '/'                  if (partial_dir && *partial_dir == '/'
                  && check_filter(elp, FLOG, partial_dir + module_dirlen, 1) < 0) {                   && check_filter(elp, FLOG, partial_dir + module_dirlen, 1) < 0) {
                     options_rejected:                      options_rejected:
                        rprintf(FERROR,                        rprintf(FERROR, "Your options have been rejected by the server.\n");
                                "Your options have been rejected by the server.\n"); 
                         exit_cleanup(RERR_SYNTAX);                          exit_cleanup(RERR_SYNTAX);
                 }                  }
         }          }
Line 1095  void start_server(int f_in, int f_out, int argc, char  Line 1319  void start_server(int f_in, int f_out, int argc, char 
         if (am_daemon && io_timeout && protocol_version >= 31)          if (am_daemon && io_timeout && protocol_version >= 31)
                 send_msg_int(MSG_IO_TIMEOUT, io_timeout);                  send_msg_int(MSG_IO_TIMEOUT, io_timeout);
   
           if (db_config)
                   db_read_config(FERROR, db_config);
   
         if (am_sender) {          if (am_sender) {
                 keep_dirlinks = 0; /* Must be disabled on the sender. */                  keep_dirlinks = 0; /* Must be disabled on the sender. */
                 if (need_messages_from_generator)                  if (need_messages_from_generator)
Line 1157  int client_run(int f_in, int f_out, pid_t pid, int arg Line 1384  int client_run(int f_in, int f_out, pid_t pid, int arg
   
                 if (write_batch && !am_server)                  if (write_batch && !am_server)
                         start_write_batch(f_out);                          start_write_batch(f_out);
   
                   become_copy_as_user();
   
                 flist = send_file_list(f_out, argc, argv);                  flist = send_file_list(f_out, argc, argv);
                 if (DEBUG_GTE(FLIST, 3))                  if (DEBUG_GTE(FLIST, 3))
                         rprintf(FINFO,"file list sent\n");                          rprintf(FINFO,"file list sent\n");
Line 1190  int client_run(int f_in, int f_out, pid_t pid, int arg Line 1420  int client_run(int f_in, int f_out, pid_t pid, int arg
                         io_start_buffering_out(f_out);                          io_start_buffering_out(f_out);
         }          }
   
           become_copy_as_user();
   
         send_filter_list(read_batch ? -1 : f_out);          send_filter_list(read_batch ? -1 : f_out);
   
         if (filesfrom_fd >= 0) {          if (filesfrom_fd >= 0) {
Line 1224  int client_run(int f_in, int f_out, pid_t pid, int arg Line 1456  int client_run(int f_in, int f_out, pid_t pid, int arg
         return MAX(exit_code, exit_code2);          return MAX(exit_code, exit_code2);
 }  }
   
static int copy_argv(char *argv[])static void dup_argv(char *argv[])
 {  {
         int i;          int i;
   
        for (i = 0; argv[i]; i++) {        for (i = 0; argv[i]; i++)
                if (!(argv[i] = strdup(argv[i]))) {                argv[i] = strdup(argv[i]);
                        rprintf (FERROR, "out of memory at %s(%d)\n", 
                                 __FILE__, __LINE__); 
                        return RERR_MALLOC; 
                } 
        } 
 
        return 0; 
 }  }
   
   
Line 1250  static int start_client(int argc, char *argv[]) Line 1475  static int start_client(int argc, char *argv[])
 {  {
         char *p, *shell_machine = NULL, *shell_user = NULL;          char *p, *shell_machine = NULL, *shell_user = NULL;
         char **remote_argv;          char **remote_argv;
        int remote_argc;        int remote_argc, env_port = rsync_port;
         int f_in, f_out;          int f_in, f_out;
         int ret;          int ret;
         pid_t pid;          pid_t pid;
   
         /* Don't clobber argv[] so that ps(1) can still show the right          /* Don't clobber argv[] so that ps(1) can still show the right
          * command line. */           * command line. */
        if ((ret = copy_argv(argv)) != 0)        dup_argv(argv);
                return ret; 
   
         if (!read_batch) { /* for read_batch, NO source is specified */          if (!read_batch) { /* for read_batch, NO source is specified */
                 char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);                  char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
   
                   if (shell_machine && !shell_machine[0]) {
   #ifdef HAVE_LIBSLP
                           /* User entered just rsync:// URI */
                           if (lp_use_slp()) {
                                   print_service_list();
                                   exit_cleanup(0);
                           }
                           rprintf(FINFO, "SLP is disabled, cannot browse\n");
                           exit_cleanup(RERR_SYNTAX);
   #else /* No SLP, die here */
                           rprintf(FINFO, "No SLP support, cannot browse\n");
                           exit_cleanup(RERR_SYNTAX);
   #endif
                   }
   
                 if (path) { /* source is remote */                  if (path) { /* source is remote */
                         char *dummy_host;                          char *dummy_host;
                         int dummy_port = 0;                          int dummy_port = 0;
Line 1279  static int start_client(int argc, char *argv[]) Line 1519  static int start_client(int argc, char *argv[])
                                 remote_argc--; /* don't count dest */                                  remote_argc--; /* don't count dest */
                                 argc = 1;                                  argc = 1;
                         }                          }
                        if (filesfrom_host && *filesfrom_host                        if (filesfrom_host && *filesfrom_host && strcmp(filesfrom_host, shell_machine) != 0) {
                            && strcmp(filesfrom_host, shell_machine) != 0) { 
                                 rprintf(FERROR,                                  rprintf(FERROR,
                                         "--files-from hostname is not the same as the transfer hostname\n");                                          "--files-from hostname is not the same as the transfer hostname\n");
                                 exit_cleanup(RERR_SYNTAX);                                  exit_cleanup(RERR_SYNTAX);
                         }                          }
                         am_sender = 0;                          am_sender = 0;
                         if (rsync_port)                          if (rsync_port)
                                daemon_over_rsh = shell_cmd ? 1 : -1;                                daemon_connection = shell_cmd ? 1 : -1;
                 } else { /* source is local, check dest arg */                  } else { /* source is local, check dest arg */
                         am_sender = 1;                          am_sender = 1;
   
Line 1302  static int start_client(int argc, char *argv[]) Line 1541  static int start_client(int argc, char *argv[])
                         remote_argc = 1;                          remote_argc = 1;
   
                         path = check_for_hostspec(p, &shell_machine, &rsync_port);                          path = check_for_hostspec(p, &shell_machine, &rsync_port);
                        if (path && filesfrom_host && *filesfrom_host                        if (path && filesfrom_host && *filesfrom_host && strcmp(filesfrom_host, shell_machine) != 0) {
                            && strcmp(filesfrom_host, shell_machine) != 0) { 
                                 rprintf(FERROR,                                  rprintf(FERROR,
                                         "--files-from hostname is not the same as the transfer hostname\n");                                          "--files-from hostname is not the same as the transfer hostname\n");
                                 exit_cleanup(RERR_SYNTAX);                                  exit_cleanup(RERR_SYNTAX);
Line 1316  static int start_client(int argc, char *argv[]) Line 1554  static int start_client(int argc, char *argv[])
                                         exit_cleanup(RERR_SYNTAX);                                          exit_cleanup(RERR_SYNTAX);
                                 }                                  }
                                 shell_machine = NULL;                                  shell_machine = NULL;
                                   rsync_port = 0;
                         } else { /* hostspec was found, so dest is remote */                          } else { /* hostspec was found, so dest is remote */
                                 argv[argc] = path;                                  argv[argc] = path;
                                 if (rsync_port)                                  if (rsync_port)
                                        daemon_over_rsh = shell_cmd ? 1 : -1;                                        daemon_connection = shell_cmd ? 1 : -1;
                         }                          }
                 }                  }
         } else {  /* read_batch */          } else {  /* read_batch */
Line 1330  static int start_client(int argc, char *argv[]) Line 1569  static int start_client(int argc, char *argv[])
                 }                  }
                 remote_argv = argv += argc - 1;                  remote_argv = argv += argc - 1;
                 remote_argc = argc = 1;                  remote_argc = argc = 1;
                   rsync_port = 0;
         }          }
   
         if (!rsync_port && remote_argc && !**remote_argv) /* Turn an empty arg into a dot dir. */          if (!rsync_port && remote_argc && !**remote_argv) /* Turn an empty arg into a dot dir. */
Line 1339  static int start_client(int argc, char *argv[]) Line 1579  static int start_client(int argc, char *argv[])
                 char *dummy_host;                  char *dummy_host;
                 int dummy_port = rsync_port;                  int dummy_port = rsync_port;
                 int i;                  int i;
                   if (!argv[0][0])
                           goto invalid_empty;
                 /* For local source, extra source args must not have hostspec. */                  /* For local source, extra source args must not have hostspec. */
                 for (i = 1; i < argc; i++) {                  for (i = 1; i < argc; i++) {
                           if (!argv[i][0]) {
                               invalid_empty:
                                   rprintf(FERROR, "Empty source arg specified.\n");
                                   exit_cleanup(RERR_SYNTAX);
                           }
                         if (check_for_hostspec(argv[i], &dummy_host, &dummy_port)) {                          if (check_for_hostspec(argv[i], &dummy_host, &dummy_port)) {
                                 rprintf(FERROR, "Unexpected remote arg: %s\n", argv[i]);                                  rprintf(FERROR, "Unexpected remote arg: %s\n", argv[i]);
                                 exit_cleanup(RERR_SYNTAX);                                  exit_cleanup(RERR_SYNTAX);
Line 1376  static int start_client(int argc, char *argv[]) Line 1623  static int start_client(int argc, char *argv[])
                 }                  }
         }          }
   
        if (daemon_over_rsh < 0)        if (rsync_port < 0)
                 rsync_port = RSYNC_PORT;
         else
                 env_port = rsync_port;
 
         if (db_config)
                 db_read_config(FERROR, db_config);
 
         if (daemon_connection < 0)
                 return start_socket_client(shell_machine, remote_argc, remote_argv, argc, argv);                  return start_socket_client(shell_machine, remote_argc, remote_argv, argc, argv);
   
        if (password_file && !daemon_over_rsh) {        if (password_file && !daemon_connection) {
                 rprintf(FERROR, "The --password-file option may only be "                  rprintf(FERROR, "The --password-file option may only be "
                                 "used when accessing an rsync daemon.\n");                                  "used when accessing an rsync daemon.\n");
                 exit_cleanup(RERR_SYNTAX);                  exit_cleanup(RERR_SYNTAX);
Line 1406  static int start_client(int argc, char *argv[]) Line 1661  static int start_client(int argc, char *argv[])
                         NS(remote_argv[0]));                          NS(remote_argv[0]));
         }          }
   
        pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc,#ifdef HAVE_PUTENV
                     &f_in, &f_out);        if (daemon_connection)
                 set_env_num("RSYNC_PORT", env_port);
 #endif
   
           pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc, &f_in, &f_out);
   
         /* if we're running an rsync server on the remote host over a          /* if we're running an rsync server on the remote host over a
          * remote shell command, we need to do the RSYNCD protocol first */           * remote shell command, we need to do the RSYNCD protocol first */
        if (daemon_over_rsh) {        if (daemon_connection) {
                 int tmpret;                  int tmpret;
                tmpret = start_inband_exchange(f_in, f_out, shell_user, remote_argc, remote_argv);                tmpret = start_inband_exchange(f_in, f_out, shell_user, shell_machine, remote_argc, remote_argv);
                 if (tmpret < 0)                  if (tmpret < 0)
                         return tmpret;                          return tmpret;
         }          }
Line 1429  static int start_client(int argc, char *argv[]) Line 1688  static int start_client(int argc, char *argv[])
   
 static void sigusr1_handler(UNUSED(int val))  static void sigusr1_handler(UNUSED(int val))
 {  {
           called_from_signal_handler = 1;
         exit_cleanup(RERR_SIGNAL1);          exit_cleanup(RERR_SIGNAL1);
 }  }
   
Line 1442  static void sigusr2_handler(UNUSED(int val)) Line 1702  static void sigusr2_handler(UNUSED(int val))
         _exit(0);          _exit(0);
 }  }
   
#ifdef SIGINFO#if defined SIGINFO || defined SIGVTALRM
 static void siginfo_handler(UNUSED(int val))  static void siginfo_handler(UNUSED(int val))
 {  {
        if (!am_server && !INFO_GTE(PROGRESS, 1))
        if (!am_server) 
                 want_progress_now = True;                  want_progress_now = True;
 }  }
 #endif  #endif
Line 1470  void remember_children(UNUSED(int val)) Line 1729  void remember_children(UNUSED(int val))
                                 break;                                  break;
                         }                          }
                 }                  }
                   if (WIFSIGNALED(status)) {
                           rprintf(FLOG,
                                   "rsync error: (1) Child proccess has unexpectedly died with signal %d\n",
                                   WTERMSIG(status));
                   } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) {
                           rprintf(FLOG,
                                   "rsync error: (1) Child proccess has CRASHED.\n");
                   }
         }          }
 #endif  #endif
 #ifndef HAVE_SIGACTION  #ifndef HAVE_SIGACTION
Line 1498  const char *get_panic_action(void) Line 1765  const char *get_panic_action(void)
   
         if (cmd_fmt)          if (cmd_fmt)
                 return cmd_fmt;                  return cmd_fmt;
        else        return "xterm -display :0 -T Panic -n Panic -e gdb /proc/%d/exe %d";
                return "xterm -display :0 -T Panic -n Panic " 
                        "-e gdb /proc/%d/exe %d"; 
 }  }
   
   
Line 1521  static void rsync_panic_handler(UNUSED(int whatsig)) Line 1786  static void rsync_panic_handler(UNUSED(int whatsig))
   
         /* Unless we failed to execute gdb, we allow the process to          /* Unless we failed to execute gdb, we allow the process to
          * continue.  I'm not sure if that's right. */           * continue.  I'm not sure if that's right. */
        ret = system(cmd_buf);        ret = shell_exec(cmd_buf);
         if (ret)          if (ret)
                 _exit(ret);                  _exit(ret);
 }  }
 #endif  #endif
   
   static void rsync_crash_handler(UNUSED(int whatsig))
   {
           log_exit(RERR_WECRASHED, __FILE__, __LINE__);
           logfile_close();
           _exit(RERR_WECRASHED);
   }
   
 int main(int argc,char *argv[])  int main(int argc,char *argv[])
 {  {
         int ret;          int ret;
        int orig_argc = argc;
        char **orig_argv = argv;        raw_argc = argc;
         raw_argv = argv;
 
 #ifdef HAVE_SIGACTION  #ifdef HAVE_SIGACTION
 # ifdef HAVE_SIGPROCMASK  # ifdef HAVE_SIGPROCMASK
         sigset_t sigmask;          sigset_t sigmask;
Line 1549  int main(int argc,char *argv[]) Line 1822  int main(int argc,char *argv[])
         SIGACTMASK(SIGFPE, rsync_panic_handler);          SIGACTMASK(SIGFPE, rsync_panic_handler);
         SIGACTMASK(SIGABRT, rsync_panic_handler);          SIGACTMASK(SIGABRT, rsync_panic_handler);
         SIGACTMASK(SIGBUS, rsync_panic_handler);          SIGACTMASK(SIGBUS, rsync_panic_handler);
   #else
           SIGACTMASK(SIGSEGV, rsync_crash_handler);
           SIGACTMASK(SIGFPE, rsync_crash_handler);
           SIGACTMASK(SIGABRT, rsync_crash_handler);
           SIGACTMASK(SIGBUS, rsync_crash_handler);
 #endif  #endif
 #ifdef SIGINFO  #ifdef SIGINFO
         SIGACTMASK(SIGINFO, siginfo_handler);          SIGACTMASK(SIGINFO, siginfo_handler);
 #endif  #endif
   #ifdef SIGVTALRM
           SIGACTMASK(SIGVTALRM, siginfo_handler);
   #endif
   
         starttime = time(NULL);          starttime = time(NULL);
         our_uid = MY_UID();          our_uid = MY_UID();
         our_gid = MY_GID();          our_gid = MY_GID();
        am_root = our_uid == 0;        am_root = our_uid == ROOT_UID;
   
         memset(&stats, 0, sizeof(stats));          memset(&stats, 0, sizeof(stats));
   
           /* Even a non-daemon runs needs the default config values to be set, e.g.
            * lp_dont_compress() is queried when no --skip-compress option is set. */
           reset_daemon_vars();
   
         if (argc < 2) {          if (argc < 2) {
                 usage(FERROR);                  usage(FERROR);
                 exit_cleanup(RERR_SYNTAX);                  exit_cleanup(RERR_SYNTAX);
Line 1576  int main(int argc,char *argv[]) Line 1861  int main(int argc,char *argv[])
 #endif  #endif
   
         if (!parse_arguments(&argc, (const char ***) &argv)) {          if (!parse_arguments(&argc, (const char ***) &argv)) {
                 /* FIXME: We ought to call the same error-handling  
                  * code here, rather than relying on getopt. */  
                 option_error();                  option_error();
                 exit_cleanup(RERR_SYNTAX);                  exit_cleanup(RERR_SYNTAX);
         }          }
           if (write_batch
            && poptDupArgv(argc, (const char **)argv, &cooked_argc, (const char ***)&cooked_argv) != 0)
                   out_of_memory("main");
   
         SIGACTMASK(SIGINT, sig_int);          SIGACTMASK(SIGINT, sig_int);
         SIGACTMASK(SIGHUP, sig_int);          SIGACTMASK(SIGHUP, sig_int);
Line 1602  int main(int argc,char *argv[]) Line 1888  int main(int argc,char *argv[])
          * that implement getcwd that way "pwd" can't be found after chroot. */           * that implement getcwd that way "pwd" can't be found after chroot. */
         change_dir(NULL, CD_NORMAL);          change_dir(NULL, CD_NORMAL);
   
         init_flist();  
   
         if ((write_batch || read_batch) && !am_server) {          if ((write_batch || read_batch) && !am_server) {
                if (write_batch)                open_batch_files(); /* sets batch_fd */
                        write_batch_shell_file(orig_argc, orig_argv, argc); 
 
                if (read_batch && strcmp(batch_name, "-") == 0) 
                        batch_fd = STDIN_FILENO; 
                else { 
                        batch_fd = do_open(batch_name, 
                                   write_batch ? O_WRONLY | O_CREAT | O_TRUNC 
                                   : O_RDONLY, S_IRUSR | S_IWUSR); 
                } 
                if (batch_fd < 0) { 
                        rsyserr(FERROR, errno, "Batch file %s open error", 
                                full_fname(batch_name)); 
                        exit_cleanup(RERR_FILEIO); 
                } 
                 if (read_batch)                  if (read_batch)
                         read_stream_flags(batch_fd);                          read_stream_flags(batch_fd);
                 else                  else

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


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