From: Wayne Davison Date: Sat, 8 Sep 2012 23:29:45 +0000 (-0700) Subject: Make read_args() return the full request. X-Git-Tag: v3.1.0pre1~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ee51a745c163f3c422a30b22f4beda0e1ead7c20;p=thirdparty%2Frsync.git Make read_args() return the full request. 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#. --- diff --git a/clientserver.c b/clientserver.c index 2294bb00..6727075a 100644 --- a/clientserver.c +++ b/clientserver.c @@ -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 88548980..4addda0a 100644 --- 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); diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo index 29bb12f5..01188641 100644 --- a/rsyncd.conf.yo +++ b/rsyncd.conf.yo @@ -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