Added some defines for the various exclude-function arg literals.
[rsync/rsync.git] / main.c
diff --git a/main.c b/main.c
index 95e25b3..79929d6 100644 (file)
--- a/main.c
+++ b/main.c
@@ -24,6 +24,9 @@
 time_t starttime = 0;
 
 extern struct stats stats;
+extern char *files_from;
+extern int filesfrom_fd;
+extern char *remote_filesfrom_file;
 extern int am_server;
 extern int am_sender;
 extern int am_daemon;
@@ -82,7 +85,7 @@ static void report(int f)
        extern int remote_version;
        int send_stats;
 
-       if (do_stats) {
+       if (do_stats && verbose > 1) {
                /* These come out from every process */
                show_malloc_stats();
                show_flist_stats();
@@ -139,12 +142,12 @@ static void report(int f)
                rprintf(FINFO,"File list size: %d\n", stats.flist_size);
                rprintf(FINFO,"Total bytes written: %.0f\n",
                        (double)stats.total_written);
-               rprintf(FINFO,"Total bytes read: %.0f\n\n",
+               rprintf(FINFO,"Total bytes read: %.0f\n",
                        (double)stats.total_read);
        }
 
        if (verbose || do_stats) {
-               rprintf(FINFO,"wrote %.0f bytes  read %.0f bytes  %.2f bytes/sec\n",
+               rprintf(FINFO,"\nwrote %.0f bytes  read %.0f bytes  %.2f bytes/sec\n",
                        (double)stats.total_written,
                        (double)stats.total_read,
                        (stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
@@ -282,6 +285,7 @@ oom:
 static char *get_local_name(struct file_list *flist,char *name)
 {
        STRUCT_STAT st;
+       int e;
        extern int orig_umask;
 
        if (verbose > 2)
@@ -307,7 +311,7 @@ static char *get_local_name(struct file_list *flist,char *name)
                return name;
        }
 
-       if (flist->count <= 1)
+       if (flist->count <= 1 && ((e = strlen(name)) <= 1 || name[e-1] != '/'))
                return name;
 
        if (do_mkdir(name,0777 & ~orig_umask) != 0) {
@@ -501,6 +505,15 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
        if (delete_mode && !delete_excluded)
                recv_exclude_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. */
+               io_set_filesfrom_fds(filesfrom_fd, f_out);
+               filesfrom_fd = -1;
+       }
+
        if (read_batch)
                flist = batch_flist;
        else
@@ -593,6 +606,8 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
                        add_cvs_excludes();
                if (delete_mode && !delete_excluded)
                        send_exclude_list(f_out);
+               if (remote_filesfrom_file)
+                       filesfrom_fd = f_in;
                if (!read_batch) /*  dw -- don't write to pipe */
                        flist = send_file_list(f_out,argc,argv);
                if (verbose > 3)
@@ -621,6 +636,11 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
        if (!write_batch)
                send_exclude_list(f_out);
 
+       if (filesfrom_fd >= 0) {
+               io_set_filesfrom_fds(filesfrom_fd, f_out);
+               filesfrom_fd = -1;
+       }
+
        flist = recv_file_list(f_in);
        if (!flist || flist->count == 0) {
                rprintf(FINFO, "client: nothing to do: "
@@ -643,22 +663,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
        return MAX(status, status2);
 }
 
-static char *find_colon(char *s)
-{
-       char *p, *p2;
-
-       p = strchr(s,':');
-       if (!p) return NULL;
-
-       /* now check to see if there is a / in the string before the : - if there is then
-          discard the colon on the assumption that the : is part of a filename */
-       p2 = strchr(s,'/');
-       if (p2 && p2 < p) return NULL;
-
-       return p;
-}
-
-
 static int copy_argv (char *argv[])
 {
        int i;
@@ -727,6 +731,13 @@ static int start_client(int argc, char *argv[])
        if (!read_batch) {
                p = find_colon(argv[0]);
                if (p) {
+                       if (remote_filesfrom_file
+                        && remote_filesfrom_file != files_from + 1
+                        && strncmp(files_from, argv[0], p-argv[0]+1) != 0) {
+                               rprintf(FERROR,
+                                       "--files-from hostname is not transfer hostname\n");
+                               exit_cleanup(RERR_SYNTAX);
+                       }
                        if (p[1] == ':') { /* double colon */
                                *p = 0;
                                if (!shell_cmd) {
@@ -772,8 +783,20 @@ static int start_client(int argc, char *argv[])
                        }
 
                        p = find_colon(argv[argc-1]);
+                       if (p && remote_filesfrom_file
+                        && remote_filesfrom_file != files_from + 1
+                        && strncmp(files_from, argv[argc-1], p-argv[argc-1]+1) != 0) {
+                               rprintf(FERROR,
+                                       "--files-from hostname is not transfer hostname\n");
+                               exit_cleanup(RERR_SYNTAX);
+                       }
                        if (!p) {
                                local_server = 1;
+                               if (remote_filesfrom_file) {
+                                       rprintf(FERROR,
+                                               "--files-from is remote but transfer is local\n");
+                                       exit_cleanup(RERR_SYNTAX);
+                               }
                        } else if (p[1] == ':') { /* double colon */
                                *p = 0;
                                if (!shell_cmd) {