X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/38e3910b6f37eab2156496d1c4837c306235e9c7..8ebdc9724efd6a4f3aeaf6287f5dc7c4762969b8:/main.c diff --git a/main.c b/main.c index 5ff99249..3a0a3550 100644 --- a/main.c +++ b/main.c @@ -32,10 +32,10 @@ extern int am_sender; extern int am_generator; extern int am_daemon; extern int blocking_io; -extern int delete_before; extern int remove_sent_files; extern int daemon_over_rsh; extern int need_messages_from_generator; +extern int kluge_around_eof; extern int do_stats; extern int log_got_error; extern int module_id; @@ -429,6 +429,29 @@ static char *get_local_name(struct file_list *flist,char *name) } +/* This is only called by the sender. */ +static void read_final_goodbye(int f_in, int f_out, int flist_count) +{ + int i; + + if (protocol_version < 29) + i = read_int(f_in); + else { + while ((i = read_int(f_in)) == flist_count + && read_shortint(f_in) == ITEM_IS_NEW) { + /* Forward the keep-alive (no-op) to the receiver. */ + write_int(f_out, flist_count); + write_shortint(f_out, ITEM_IS_NEW); + } + } + + if (i != -1) { + rprintf(FERROR, "Invalid packet from generator at end of run.\n"); + exit_cleanup(RERR_PROTOCOL); + } +} + + static void do_server_sender(int f_in, int f_out, int argc,char *argv[]) { int i; @@ -485,10 +508,8 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[]) send_files(flist,f_out,f_in); io_flush(FULL_FLUSH); report(f_out); - if (protocol_version >= 24) { - /* final goodbye message */ - read_int(f_in); - } + if (protocol_version >= 24) + read_final_goodbye(f_in, f_out, flist->count); io_flush(FULL_FLUSH); exit_cleanup(0); } @@ -509,11 +530,6 @@ 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_before && !local_name && flist->count > 0) { - /* Moved here from recv_files() to prevent a race condition */ - 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"); @@ -549,9 +565,23 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) send_msg(MSG_DONE, "", 0); io_flush(FULL_FLUSH); - /* finally we go to sleep until our parent kills us - * with a USR2 signal. We sleep for a short time as on - * some OSes a signal won't interrupt a sleep! */ + + /* Handle any keep-alive packets from the post-processing work + * that the generator does. */ + if (protocol_version >= 29) { + kluge_around_eof = -1; + + /* This should only get stopped via a USR2 signal. */ + while (read_int(f_in) == flist->count + && read_shortint(f_in) == ITEM_IS_NEW) {} + + rprintf(FERROR, "Invalid packet from server at end of run.\n"); + exit_cleanup(RERR_PROTOCOL); + } + + /* Finally, we go to sleep until our parent kills us with a + * USR2 signal. We sleep for a short time, as on some OSes + * a signal won't interrupt a sleep! */ while (1) msleep(20); } @@ -746,10 +776,8 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_flush(NORMAL_FLUSH); send_files(flist,f_out,f_in); io_flush(FULL_FLUSH); - if (protocol_version >= 24) { - /* final goodbye message */ - read_int(f_in); - } + if (protocol_version >= 24) + read_final_goodbye(f_in, f_out, flist->count); if (pid != -1) { if (verbose > 3) rprintf(FINFO,"client_run waiting on %d\n", (int) pid); @@ -1027,6 +1055,7 @@ static RETSIGTYPE sigusr1_handler(UNUSED(int val)) static RETSIGTYPE sigusr2_handler(UNUSED(int val)) { + close_all(); if (log_got_error) _exit(RERR_PARTIAL); _exit(0); }