Make read_args() return the full request.
authorWayne Davison <wayned@samba.org>
Sat, 8 Sep 2012 23:29:45 +0000 (16:29 -0700)
committerWayne Davison <wayned@samba.org>
Sun, 23 Sep 2012 18:15:36 +0000 (11:15 -0700)
When a daemon is sent multiple request args, they are now joined into a
single return value (separated by spaces) so that the RSYNC_REQUEST
environment variable is accurate for any "pre-xfer exec".  The values
in RSYNC_ARG# vars are no longer truncated at the "." arg, so that all
the request values are also listed (separately) in RSYNC_ARG#.

clientserver.c
io.c
rsyncd.conf.yo

index 2294bb005a6039fa75ebd7e26843c603912580c5..6727075a196691c8af9d455cb11e3677f3df0634 100644 (file)
@@ -363,11 +363,8 @@ static char *finish_pre_exec(pid_t pid, int write_fd, int read_fd, char *request
                        write_buf(write_fd, *early_argv, strlen(*early_argv)+1);
                j = 1; /* Skip arg0 name in argv. */
        }
-       for ( ; argv[j]; j++) {
+       for ( ; argv[j]; j++)
                write_buf(write_fd, argv[j], strlen(argv[j])+1);
-               if (argv[j][0] == '.' && argv[j][1] == '\0')
-                       break;
-       }
        write_byte(write_fd, 0);
 
        close(write_fd);
diff --git a/io.c b/io.c
index 88548980802f76548abd0de4f3bb7d2925740e7b..4addda0ae721b466468199f26f51d78b1f2287f2 100644 (file)
--- a/io.c
+++ b/io.c
@@ -1225,8 +1225,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
               char ***argv_p, int *argc_p, char **request_p)
 {
        int maxargs = MAX_ARGS;
-       int dot_pos = 0;
-       int argc = 0;
+       int dot_pos = 0, argc = 0, request_len = 0;
        char **argv, *p;
        int rl_flags = (rl_nulls ? RL_EOL_NULLS : 0);
 
@@ -1239,6 +1238,9 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
        if (mod_name && !protect_args)
                argv[argc++] = "rsyncd";
 
+        if (request_p)
+                *request_p = NULL;
+
        while (1) {
                if (read_line(f_in, buf, bufsiz, rl_flags) == 0)
                        break;
@@ -1250,9 +1252,14 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
                }
 
                if (dot_pos) {
-                       if (request_p) {
-                               *request_p = strdup(buf);
-                               request_p = NULL;
+                       if (request_p && request_len < 1024) {
+                                int len = strlen(buf);
+                                if (request_len)
+                                        request_p[0][request_len++] = ' ';
+                                if (!(*request_p = realloc_array(*request_p, char, request_len + len + 1)))
+                                        out_of_memory("read_args");
+                                memcpy(*request_p + request_len, buf, len + 1);
+                                request_len += len;
                        }
                        if (mod_name)
                                glob_expand_module(mod_name, buf, &argv, &argc, &maxargs);
index 29bb12f5849da999925ee5e24933d62b97eecd2d..011886414e2fe4b0296f8574d052d8cb58c8126c 100644 (file)
@@ -730,11 +730,14 @@ quote(itemization(
   it() bf(RSYNC_USER_NAME): The accessing user's name (empty if no user).
   it() bf(RSYNC_PID): A unique number for this transfer.
   it() bf(RSYNC_REQUEST): (pre-xfer only) The module/path info specified
-  by the user (note that the user can specify multiple source files,
-  so the request can be something like "mod/path1 mod/path2", etc.).
+  by the user.  Note that the user can specify multiple source files,
+  so the request can be something like "mod/path1 mod/path2", etc.
   it() bf(RSYNC_ARG#): (pre-xfer only) The pre-request arguments are set
-  in these numbered values. RSYNC_ARG0 is always "rsyncd", and the last
-  value contains a single period.
+  in these numbered values. RSYNC_ARG0 is always "rsyncd", followed by
+  the options that were used in RSYNC_ARG1, and so on.  There will be a
+  value of "." indicating that the options are done and the path args
+  are beginning -- these contain similar information to RSYNC_REQUEST,
+  but with values separated and the module name stripped off.
   it() bf(RSYNC_EXIT_STATUS): (post-xfer only) the server side's exit value.
   This will be 0 for a successful run, a positive value for an error that the
   server generated, or a -1 if rsync failed to exit properly.  Note that an