aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clientserver.c4
-rw-r--r--main.c54
-rw-r--r--pipe.c16
3 files changed, 52 insertions, 22 deletions
diff --git a/clientserver.c b/clientserver.c
index d158a2ff..8a26ed5a 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -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 95e25b30..c6bd2c29 100644
--- 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 47529588..59a0d762 100644
--- 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;
}
-
-