Update the copyright year.
[rsync/rsync.git] / main.c
diff --git a/main.c b/main.c
index dc3c533..3749605 100644 (file)
--- a/main.c
+++ b/main.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2008 Wayne Davison
+ * Copyright (C) 2003-2009 Wayne Davison
  *
  * 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
@@ -21,7 +21,7 @@
  */
 
 #include "rsync.h"
-#include "ifuncs.h"
+#include "inums.h"
 #include "io.h"
 #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
 #include <locale.h>
@@ -35,7 +35,6 @@ extern int am_sender;
 extern int am_daemon;
 extern int inc_recurse;
 extern int blocking_io;
-extern int human_readable;
 extern int always_checksum;
 extern int remove_source_files;
 extern int output_needs_newline;
@@ -64,11 +63,8 @@ extern int whole_file;
 extern int read_batch;
 extern int write_batch;
 extern int batch_fd;
-extern int flist_eof;
 extern int filesfrom_fd;
-extern int delete_during;
 extern int connect_timeout;
-extern int check_for_io_err;
 extern pid_t cleanup_child_pid;
 extern unsigned int module_dirlen;
 extern struct stats stats;
@@ -175,6 +171,30 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
                *exit_code_ptr = WEXITSTATUS(status);
 }
 
+void write_del_stats(int f)
+{
+       if (!INFO_GTE(STATS, 2) || protocol_version < 31)
+               return;
+       write_varint(f, stats.deleted_files - stats.deleted_dirs
+                     - stats.deleted_symlinks - stats.deleted_devices
+                     - stats.deleted_specials);
+       write_varint(f, stats.deleted_dirs);
+       write_varint(f, stats.deleted_symlinks);
+       write_varint(f, stats.deleted_devices);
+       write_varint(f, stats.deleted_specials);
+}
+
+void read_del_stats(int f)
+{
+       if (!INFO_GTE(STATS, 2) || protocol_version < 31)
+               return;
+       stats.deleted_files = read_varint(f);
+       stats.deleted_files += stats.deleted_dirs = read_varint(f);
+       stats.deleted_files += stats.deleted_symlinks = read_varint(f);
+       stats.deleted_files += stats.deleted_devices = read_varint(f);
+       stats.deleted_files += stats.deleted_specials = read_varint(f);
+}
+
 /* 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
  * all the stats we need.  So, if we're a client sender, we do the report.
@@ -214,6 +234,7 @@ static void handle_stats(int f)
                                write_varlong30(f, stats.flist_buildtime, 3);
                                write_varlong30(f, stats.flist_xfertime, 3);
                        }
+                       write_del_stats(f);
                }
                return;
        }
@@ -232,6 +253,8 @@ static void handle_stats(int f)
                        stats.flist_buildtime = read_varlong30(f, 3);
                        stats.flist_xfertime = read_varlong30(f, 3);
                }
+               if (!read_batch)
+                       read_del_stats(f);
        } else if (write_batch) {
                /* The --read-batch process is going to be a client
                 * receiver, so we need to give it the stats. */
@@ -242,50 +265,77 @@ static void handle_stats(int f)
                        write_varlong30(batch_fd, stats.flist_buildtime, 3);
                        write_varlong30(batch_fd, stats.flist_xfertime, 3);
                }
+               /* We don't write the del stats into the batch file -- they
+                * come from the generator when reading the batch. */
        }
 }
 
+static void output_itemized_counts(const char *prefix, int *counts)
+{
+       static char *labels[] = { "reg", "dir", "link", "dev", "special" };
+       char buf[1024], *pre = " (";
+       int j, len = 0;
+       int total = counts[0];
+       if (total) {
+               counts[0] -= counts[1] + counts[2] + counts[3] + counts[4];
+               for (j = 0; j < 5; j++) {
+                       if (counts[j]) {
+                               len += snprintf(buf+len, sizeof buf - len - 2,
+                                       "%s%s: %s",
+                                       pre, labels[j], comma_num(counts[j]));
+                               pre = ", ";
+                       }
+               }
+               buf[len++] = ')';
+       }
+       buf[len] = '\0';
+       rprintf(FINFO, "%s: %s%s\n", prefix, comma_num(total), buf);
+}
+
 static void output_summary(void)
 {
        if (INFO_GTE(STATS, 2)) {
                rprintf(FCLIENT, "\n");
-               rprintf(FINFO,"Number of files: %d\n", stats.num_files);
-               rprintf(FINFO,"Number of files transferred: %d\n",
-                       stats.num_transferred_files);
+               output_itemized_counts("Number of files", &stats.num_files);
+               if (protocol_version >= 29)
+                       output_itemized_counts("Number of created files", &stats.created_files);
+               if (protocol_version >= 31)
+                       output_itemized_counts("Number of deleted files", &stats.deleted_files);
+               rprintf(FINFO,"Number of regular files transferred: %s\n",
+                       comma_num(stats.xferred_files));
                rprintf(FINFO,"Total file size: %s bytes\n",
-                       big_num(stats.total_size, human_readable));
+                       human_num(stats.total_size));
                rprintf(FINFO,"Total transferred file size: %s bytes\n",
-                       big_num(stats.total_transferred_size, human_readable));
+                       human_num(stats.total_transferred_size));
                rprintf(FINFO,"Literal data: %s bytes\n",
-                       big_num(stats.literal_data, human_readable));
+                       human_num(stats.literal_data));
                rprintf(FINFO,"Matched data: %s bytes\n",
-                       big_num(stats.matched_data, human_readable));
+                       human_num(stats.matched_data));
                rprintf(FINFO,"File list size: %s\n",
-                       big_num(stats.flist_size, human_readable));
+                       human_num(stats.flist_size));
                if (stats.flist_buildtime) {
                        rprintf(FINFO,
-                               "File list generation time: %.3f seconds\n",
-                               (double)stats.flist_buildtime / 1000);
+                               "File list generation time: %s seconds\n",
+                               comma_dnum((double)stats.flist_buildtime / 1000, 3));
                        rprintf(FINFO,
-                               "File list transfer time: %.3f seconds\n",
-                               (double)stats.flist_xfertime / 1000);
+                               "File list transfer time: %s seconds\n",
+                               comma_dnum((double)stats.flist_xfertime / 1000, 3));
                }
                rprintf(FINFO,"Total bytes sent: %s\n",
-                       big_num(total_written, human_readable));
+                       human_num(total_written));
                rprintf(FINFO,"Total bytes received: %s\n",
-                       big_num(total_read, human_readable));
+                       human_num(total_read));
        }
 
        if (INFO_GTE(STATS, 1)) {
                rprintf(FCLIENT, "\n");
                rprintf(FINFO,
                        "sent %s bytes  received %s bytes  %s bytes/sec\n",
-                       big_num(total_written, human_readable),
-                       big_num(total_read, human_readable),
+                       human_num(total_written), human_num(total_read),
                        human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
-               rprintf(FINFO, "total size is %s  speedup is %.2f%s\n",
-                       big_num(stats.total_size, human_readable),
-                       (double)stats.total_size / (total_written+total_read),
+               rprintf(FINFO, "total size is %s  speedup is %s%s\n",
+                       human_num(stats.total_size),
+                       comma_dnum((double)stats.total_size / (total_written+total_read), 2),
                        write_batch < 0 ? " (BATCH ONLY)" : dry_run ? " (DRY RUN)" : "");
        }
 
@@ -478,7 +528,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
 #ifdef ICONV_CONST
                setup_iconv();
 #endif
-               if (protect_args)
+               if (protect_args && !daemon_over_rsh)
                        send_protected_args(*f_out_p, args);
        }
 
@@ -768,8 +818,6 @@ static int do_recv(int f_in, int f_out, char *local_name)
                exit_cleanup(RERR_IPC);
        }
 
-       check_for_io_err = inc_recurse && delete_during && !flist_eof;
-
        if (pid == 0) {
                close(error_pipe[0]);
                if (f_in != f_out)
@@ -1213,8 +1261,8 @@ static int start_client(int argc, char *argv[])
                        rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
                        exit_cleanup(RERR_SYNTAX);
                }
-               remote_argv = argv + argc - 1;
-               remote_argc = 1;
+               remote_argv = argv += argc - 1;
+               remote_argc = argc = 1;
        }
 
        if (am_sender) {