X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a0f1ed55cd5ae7393b904b2e2bd31c2ee0b59d40..73b9b90a0b548d1177d2bf004c800ae6d9926a1f:/main.c diff --git a/main.c b/main.c index 00da2db9..de5bc489 100644 --- a/main.c +++ b/main.c @@ -70,9 +70,12 @@ extern int sock_f_out; extern int filesfrom_fd; extern int connect_timeout; extern int send_msgs_to_gen; +extern dev_t filesystem_dev; extern pid_t cleanup_child_pid; extern size_t bwlimit_writemax; extern unsigned int module_dirlen; +extern BOOL flist_receiving_enabled; +extern BOOL shutting_down; extern struct stats stats; extern char *stdout_format; extern char *logfile_format; @@ -92,7 +95,8 @@ extern filter_rule_list daemon_filter_list; uid_t our_uid; gid_t our_gid; -int am_generator = 0; +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 local_server = 0; int daemon_over_rsh = 0; mode_t orig_umask = 0; @@ -127,7 +131,7 @@ static void show_malloc_stats(void); pid_t wait_process(pid_t pid, int *status_ptr, int flags) { pid_t waited_pid; - + do { waited_pid = waitpid(pid, status_ptr, flags); } while (waited_pid == -1 && errno == EINTR); @@ -393,7 +397,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in int *f_in_p, int *f_out_p) { int i, argc = 0; - char *args[MAX_ARGS]; + char *args[MAX_ARGS], *need_to_free = NULL; pid_t pid; int dash_l_set = 0; @@ -404,7 +408,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in cmd = rsh_env; if (!cmd) cmd = RSYNC_RSH; - cmd = strdup(cmd); /* MEMORY LEAK */ + cmd = need_to_free = strdup(cmd); if (!cmd) goto oom; @@ -490,7 +494,11 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n"); exit_cleanup(RERR_SYNTAX); } - args[argc++] = *remote_argv++; + if (**remote_argv == '-') { + if (asprintf(args + argc++, "./%s", *remote_argv++) < 0) + out_of_memory("do_cmd"); + } else + args[argc++] = *remote_argv++; remote_argc--; } } @@ -536,6 +544,9 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in send_protected_args(*f_out_p, args); } + if (need_to_free) + free(need_to_free); + return pid; oom: @@ -570,6 +581,10 @@ static char *get_local_name(struct file_list *flist, char *dest_path) if (!dest_path || list_only) return NULL; + /* Treat an empty string as a copy into the current directory. */ + if (!*dest_path) + dest_path = "."; + if (daemon_filter_list.head) { char *slash = strrchr(dest_path, '/'); if (slash && (slash[1] == '\0' || (slash[1] == '.' && slash[2] == '\0'))) @@ -596,6 +611,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path) full_fname(dest_path)); exit_cleanup(RERR_FILESELECT); } + filesystem_dev = st.st_dev; /* ensures --force works right w/-x */ return NULL; } if (file_total > 1) { @@ -633,7 +649,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path) exit_cleanup(RERR_SYNTAX); } - if (mkdir_defmode(dest_path) != 0) { + if (do_mkdir(dest_path, ACCESSPERMS) != 0) { rsyserr(FERROR, errno, "mkdir %s failed", full_fname(dest_path)); exit_cleanup(RERR_FILEIO); @@ -726,6 +742,8 @@ static void read_final_goodbye(int f_in, int f_out) uchar fnamecmp_type; char xname[MAXPATHLEN]; + shutting_down = True; + if (protocol_version < 29) i = read_int(f_in); else { @@ -844,6 +862,7 @@ static int do_recv(int f_in, int f_out, char *local_name) } if (pid == 0) { + am_receiver = 1; send_msgs_to_gen = am_server; close(error_pipe[0]); @@ -895,6 +914,7 @@ static int do_recv(int f_in, int f_out, char *local_name) } am_generator = 1; + flist_receiving_enabled = True; io_end_multiplex_in(MPLX_SWITCHING); if (write_batch && !am_server) @@ -921,6 +941,7 @@ static int do_recv(int f_in, int f_out, char *local_name) handle_stats(-1); io_flush(FULL_FLUSH); + shutting_down = True; if (protocol_version >= 24) { /* send a final goodbye message */ write_ndx(f_out, NDX_DONE); @@ -1358,7 +1379,7 @@ static int start_client(int argc, char *argv[]) if (DEBUG_GTE(CMD, 2)) { rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n", NS(shell_cmd), NS(shell_machine), NS(shell_user), - remote_argv ? NS(remote_argv[0]) : ""); + NS(remote_argv[0])); } pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc, @@ -1510,9 +1531,10 @@ int main(int argc,char *argv[]) exit_cleanup(RERR_SYNTAX); } - /* we set a 0 umask so that correct file permissions can be - * carried across */ - orig_umask = umask(0); + /* Get the umask for use in permission calculations. We no longer set + * it to zero; that is ugly and pointless now that all the callers that + * relied on it have been reeducated to work with default ACLs. */ + umask(orig_umask = umask(0)); #if defined CONFIG_LOCALE && defined HAVE_SETLOCALE setlocale(LC_CTYPE, "");