When rsync encountered an empty file list, it behaved differently
[rsync/rsync.git] / main.c
diff --git a/main.c b/main.c
index 81be989..4cc1d3c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -20,8 +20,9 @@
 */
 
 #include "rsync.h"
-
-time_t starttime = 0;
+#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
+#include <locale.h>
+#endif
 
 extern int verbose;
 extern int dry_run;
@@ -77,6 +78,9 @@ struct pid_status {
        int   status;
 } pid_stat_table[MAXCHILDPROCS];
 
+static time_t starttime, endtime;
+static int64 total_read, total_written;
+
 static void show_malloc_stats(void);
 
 /****************************************************************************
@@ -121,12 +125,13 @@ void wait_process(pid_t pid, int *status)
  * the report.  All processes might also generate a set of debug stats, if
  * the verbose level is high enough (this is the only thing that the
  * generator process and the server receiver ever do here). */
-static void report(int f)
+static void handle_stats(int f)
 {
+       endtime = time(NULL);
+
        /* Cache two stats because the read/write code can change it. */
-       int64 total_read = stats.total_read;
-       int64 total_written = stats.total_written;
-       time_t t = time(NULL);
+       total_read = stats.total_read;
+       total_written = stats.total_written;
 
        if (do_stats && verbose > 1) {
                /* These come out from every process */
@@ -158,7 +163,9 @@ static void report(int f)
 
        /* this is the client */
 
-       if (!am_sender) {
+       if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */
+               ; 
+       else if (!am_sender) {
                /* Read the first two in opposite order because the meaning of
                 * read/write swaps when switching from sender to receiver. */
                total_written = read_longint(f);
@@ -168,7 +175,7 @@ static void report(int f)
                        stats.flist_buildtime = read_longint(f);
                        stats.flist_xfertime = read_longint(f);
                }
-       } else if (write_batch) {
+       } else if (write_batch && !am_server) {
                /* The --read-batch process is going to be a client
                 * receiver, so we need to give it the stats. */
                write_longint(batch_fd, total_read);
@@ -207,11 +214,17 @@ static void report(int f)
                        (double)total_read);
        }
 
+       fflush(stdout);
+       fflush(stderr);
+}
+
+static void output_summary(void)
+{
        if (verbose || do_stats) {
                rprintf(FINFO,
                        "\nsent %.0f bytes  received %.0f bytes  %.2f bytes/sec\n",
                        (double)total_written, (double)total_read,
-                       (total_written + total_read)/(0.5 + (t - starttime)));
+                       (total_written + total_read)/(0.5 + (endtime - starttime)));
                rprintf(FINFO, "total size is %.0f  speedup is %.2f\n",
                        (double)stats.total_size,
                        (double)stats.total_size / (total_written+total_read));
@@ -509,7 +522,7 @@ 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);
+       handle_stats(f_out);
        if (protocol_version >= 24)
                read_final_goodbye(f_in, f_out);
        io_flush(FULL_FLUSH);
@@ -555,7 +568,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
 
                recv_files(f_in, flist, local_name);
                io_flush(FULL_FLUSH);
-               report(f_in);
+               handle_stats(f_in);
 
                send_msg(MSG_DONE, "", 0);
                io_flush(FULL_FLUSH);
@@ -583,7 +596,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
 
        am_generator = 1;
        close_multiplexing_in();
-       if (write_batch)
+       if (write_batch && !am_server)
                stop_write_batch();
 
        close(error_pipe[1]);
@@ -596,7 +609,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
 
        generate_files(f_out, flist, local_name);
 
-       report(-1);
+       handle_stats(-1);
        io_flush(FULL_FLUSH);
        if (protocol_version >= 24) {
                /* send a final goodbye message */
@@ -756,7 +769,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
                if (filesfrom_host)
                        filesfrom_fd = f_in;
 
-               if (write_batch)
+               if (write_batch && !am_server)
                        start_write_batch(f_out);
                flist = send_file_list(f_out, argc, argv);
                set_msg_fd_in(-1);
@@ -767,6 +780,7 @@ 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);
+               handle_stats(-1);
                if (protocol_version >= 24)
                        read_final_goodbye(f_in, f_out);
                if (pid != -1) {
@@ -775,7 +789,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
                        io_flush(FULL_FLUSH);
                        wait_process(pid, &status);
                }
-               report(-1);
+               output_summary();
                io_flush(FULL_FLUSH);
                exit_cleanup(status);
        }
@@ -793,20 +807,19 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
                filesfrom_fd = -1;
        }
 
-       if (write_batch)
+       if (write_batch && !am_server)
                start_write_batch(f_in);
        flist = recv_file_list(f_in);
-       if (!flist || flist->count == 0) {
-               rprintf(FINFO, "client: nothing to do: "
-                       "perhaps you need to specify some filenames or "
-                       "the --recursive option?\n");
-               exit_cleanup(0);
-       }
        the_file_list = flist;
 
-       local_name = get_local_name(flist,argv[0]);
+       if (flist && flist->count > 0) {
+               local_name = get_local_name(flist, argv[0]);
 
-       status2 = do_recv(f_in,f_out,flist,local_name);
+               status2 = do_recv(f_in, f_out, flist, local_name);
+       } else {
+               handle_stats(-1);
+               output_summary();
+       }
 
        if (pid != -1) {
                if (verbose > 3)
@@ -977,8 +990,11 @@ static RETSIGTYPE sigusr1_handler(UNUSED(int val))
 
 static RETSIGTYPE sigusr2_handler(UNUSED(int val))
 {
+       if (!am_server)
+               output_summary();
        close_all();
-       if (log_got_error) _exit(RERR_PARTIAL);
+       if (log_got_error)
+               _exit(RERR_PARTIAL);
        _exit(0);
 }
 
@@ -1103,6 +1119,10 @@ int main(int argc,char *argv[])
         * see the EPIPE. */
        signal(SIGPIPE, SIG_IGN);
 
+#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
+       setlocale(LC_CTYPE, "");
+#endif
+
        /* Initialize push_dir here because on some old systems getcwd
         * (implemented by forking "pwd" and reading its output) doesn't
         * work when there are other child processes.  Also, on all systems
@@ -1111,7 +1131,7 @@ int main(int argc,char *argv[])
 
        init_flist();
 
-       if (write_batch || read_batch) {
+       if ((write_batch || read_batch) && !am_server) {
                if (write_batch)
                        write_batch_shell_file(orig_argc, orig_argv, argc);
 
@@ -1130,6 +1150,8 @@ int main(int argc,char *argv[])
                if (read_batch)
                        read_stream_flags(batch_fd);
        }
+       if (write_batch < 0)
+               dry_run = 1;
 
        if (am_daemon && !am_server)
                return daemon_main();