X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/41cfde6be388364f9bf7dfa9a532625b1f660df7..7842418b7b87c4c78ad8ad06fec44150c8aa0956:/main.c diff --git a/main.c b/main.c index 20c93c25..b45a9806 100644 --- a/main.c +++ b/main.c @@ -33,8 +33,9 @@ extern int verbose; extern int blocking_io; extern int cvs_exclude; extern int delete_mode; -extern int delete_excluded; +extern int delete_before; extern int delete_after; +extern int delete_excluded; extern int daemon_over_rsh; extern int do_stats; extern int dry_run; @@ -59,7 +60,8 @@ extern int filesfrom_fd; extern pid_t cleanup_child_pid; extern char *files_from; extern char *remote_filesfrom_file; -extern char *compare_dest; +extern char *partial_dir; +extern char *basis_dir[]; extern char *rsync_path; extern char *shell_cmd; extern char *batch_name; @@ -432,7 +434,7 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[]) argv[i] += l+1; } - if (argc == 0 && recurse) { + if (argc == 0 && (recurse || list_only)) { argc = 1; argv--; argv[0] = "."; @@ -463,7 +465,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) int pid; int status = 0; int error_pipe[2], name_pipe[2]; - BOOL need_name_pipe = compare_dest && !dry_run; + BOOL need_name_pipe = (basis_dir[0] || partial_dir) && !dry_run; /* The receiving side mustn't obey this, or an existing symlink that * points to an identical file won't be replaced by the referent. */ @@ -472,21 +474,26 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) if (preserve_hard_links) init_hard_links(flist); - if (!delete_after) { + if (delete_before) { /* I moved this here from recv_files() to prevent a race condition */ - if (recurse && delete_mode && !local_name && flist->count > 0) + if (recurse && !local_name && flist->count > 0) delete_files(flist); } if (fd_pair(error_pipe) < 0 || (need_name_pipe && fd_pair(name_pipe) < 0)) { rsyserr(FERROR, errno, "pipe failed in do_recv"); - exit_cleanup(RERR_SOCKETIO); + exit_cleanup(RERR_IPC); } io_flush(NORMAL_FLUSH); - if ((pid = do_fork()) == 0) { + if ((pid = do_fork()) == -1) { + rsyserr(FERROR, errno, "fork failed in do_recv"); + exit_cleanup(RERR_IPC); + } + + if (pid == 0) { close(error_pipe[0]); if (need_name_pipe) { close(name_pipe[1]); @@ -535,7 +542,6 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) generate_files(f_out, flist, local_name, name_pipe[1]); - get_redo_num(); /* Read final MSG_DONE and any prior messages. */ report(-1); io_flush(FULL_FLUSH); if (protocol_version >= 24) { @@ -557,6 +563,13 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[]) struct file_list *flist; char *local_name = NULL; char *dir = NULL; + int save_verbose = verbose; + + if (filesfrom_fd >= 0) { + /* We can't mix messages with files-from data on the socket, + * so temporarily turn off verbose messages. */ + verbose = 0; + } if (verbose > 2) { rprintf(FINFO, "server_recv(%d) starting pid=%ld\n", @@ -583,18 +596,20 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[]) io_start_buffering_in(); if (delete_mode && !delete_excluded) - recv_exclude_list(f_in); + recv_filter_list(f_in); if (filesfrom_fd >= 0) { - /* We're receiving the file info from the sender, so we need - * the IO routines to automatically write out the names onto - * our f_out socket as we read the list info from the sender. - * This avoids both deadlock and extra delays/buffers. */ + /* We need to send the files-from names to the sender at the + * same time that we receive the file-list from them, so we + * need the IO routines to automatically write out the names + * onto our f_out socket as we read the file-list. This + * avoids both deadlock and extra delays/buffers. */ io_set_filesfrom_fds(filesfrom_fd, f_out); filesfrom_fd = -1; } flist = recv_file_list(f_in); + verbose = save_verbose; if (!flist) { rprintf(FERROR,"server_recv: recv_file_list error\n"); exit_cleanup(RERR_FILESELECT); @@ -635,7 +650,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ - recv_exclude_list(f_in); + recv_filter_list(f_in); if (cvs_exclude) add_cvs_excludes(); do_server_sender(f_in, f_out, argc, argv); @@ -657,9 +672,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) char *local_name = NULL; cleanup_child_pid = pid; - if (read_batch) { - assert(am_sender == 0); - } else { + if (!read_batch) { set_nonblocking(f_in); set_nonblocking(f_out); } @@ -683,10 +696,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ io_start_buffering_out(); + if (!remote_filesfrom_file) + set_msg_fd_in(f_in); if (cvs_exclude) add_cvs_excludes(); if (delete_mode && !delete_excluded) - send_exclude_list(f_out); + send_filter_list(f_out); if (remote_filesfrom_file) filesfrom_fd = f_in; @@ -694,6 +709,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) start_write_batch(f_out); if (!read_batch) /* don't write to pipe */ flist = send_file_list(f_out,argc,argv); + set_msg_fd_in(-1); if (verbose > 3) rprintf(FINFO,"file list sent\n"); @@ -716,10 +732,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) } if (argc == 0) - list_only = 1; + list_only |= 1; if (!read_batch) - send_exclude_list(f_out); + send_filter_list(f_out); + if (cvs_exclude) + add_cvs_excludes(); if (filesfrom_fd >= 0) { io_set_filesfrom_fds(filesfrom_fd, f_out); @@ -947,9 +965,8 @@ static int start_client(int argc, char *argv[]) } /* ... or no dest at all */ - if (!am_sender && argc == 0) { - list_only = 1; - } + if (!am_sender && argc == 0) + list_only |= 1; pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path, &f_in,&f_out);