Support the new --files-from option.
authorWayne Davison <wayned@samba.org>
Sun, 30 Mar 2003 23:00:33 +0000 (23:00 +0000)
committerWayne Davison <wayned@samba.org>
Sun, 30 Mar 2003 23:00:33 +0000 (23:00 +0000)
clientserver.c
main.c
pipe.c

index d158a2f..8a26ed5 100644 (file)
@@ -33,6 +33,7 @@ extern int verbose;
 extern int rsync_port;
 char *auth_user;
 extern int sanitize_paths;
+extern int filesfrom_fd;
 
 /**
  * Run a client connected to an rsyncd.  The alternative to this
@@ -424,6 +425,9 @@ static int rsync_module(int f_in, int f_out, int i)
         argp = argv;
        ret = parse_arguments(&argc, (const char ***) &argp, 0);
 
+       if (filesfrom_fd == 0)
+               filesfrom_fd = f_in;
+
        if (request) {
                if (*auth_user) {
                        rprintf(FINFO,"rsync %s %s from %s@%s (%s)\n",
diff --git a/main.c b/main.c
index 95e25b3..c6bd2c2 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;
@@ -501,6 +504,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 +605,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 +635,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 +662,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 +730,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 +782,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) {
diff --git a/pipe.c b/pipe.c
index 4752958..59a0d76 100644 (file)
--- a/pipe.c
+++ b/pipe.c
@@ -99,7 +99,10 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
        pid_t pid;
        int to_child_pipe[2];
        int from_child_pipe[2];
-       extern int read_batch;  /* dw */
+       extern int read_batch;
+       extern int am_sender;
+       extern int am_server;
+       extern int filesfrom_fd;
 
        if (fd_pair(to_child_pipe) < 0 ||
            fd_pair(from_child_pipe) < 0) {
@@ -115,12 +118,12 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
        }
 
        if (pid == 0) {
-               extern int am_sender;
-               extern int am_server;
-
                am_sender = read_batch ? 0 : !am_sender;
                am_server = 1;          
 
+               if (!am_sender)
+                       filesfrom_fd = -1;
+
                if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
                    close(to_child_pipe[1]) < 0 ||
                    close(from_child_pipe[0]) < 0 ||
@@ -133,6 +136,9 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
                child_main(argc, argv);
        }
 
+       if (!am_sender)
+               filesfrom_fd = -1;
+
        if (close(from_child_pipe[1]) < 0 ||
            close(to_child_pipe[0]) < 0) {
                rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
@@ -144,5 +150,3 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
   
        return pid;
 }
-
-