aboutsummaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2008-03-18 10:17:02 -0700
committerWayne Davison <wayned@samba.org>2008-03-18 10:57:54 -0700
commite0fd68f5ce8d3ef6add132cc9d42a03fa8888fef (patch)
tree5fa1b4acb0bb544311cbda4fd183ceaf008f7b20 /util.c
parentcc12c488aa71e66f4786fd60494d24e81e425868 (diff)
downloadandroid_external_rsync-e0fd68f5ce8d3ef6add132cc9d42a03fa8888fef.tar.gz
android_external_rsync-e0fd68f5ce8d3ef6add132cc9d42a03fa8888fef.tar.bz2
android_external_rsync-e0fd68f5ce8d3ef6add132cc9d42a03fa8888fef.zip
Improved arg-path checking so that wildcards can't be used to
avoid a daemon-exclude.
Diffstat (limited to 'util.c')
-rw-r--r--util.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/util.c b/util.c
index 9547eef8..b5c15fba 100644
--- a/util.c
+++ b/util.c
@@ -525,6 +525,8 @@ void glob_expand(char *s, char ***argv_ptr, int *argc_ptr, int *maxargs_ptr)
char **argv = *argv_ptr;
int argc = *argc_ptr;
int maxargs = *maxargs_ptr;
+ int count, have_glob_results;
+
#if !defined HAVE_GLOB || !defined HAVE_GLOB_H
if (argc == maxargs) {
maxargs += MAX_ARGS;
@@ -553,25 +555,52 @@ void glob_expand(char *s, char ***argv_ptr, int *argc_ptr, int *maxargs_ptr)
out_of_memory("glob_expand");
memset(&globbuf, 0, sizeof globbuf);
- if (!filter_server_path(s))
- glob(s, 0, NULL, &globbuf);
- if (MAX((int)globbuf.gl_pathc, 1) > maxargs - argc) {
- maxargs += globbuf.gl_pathc + MAX_ARGS;
+ glob(s, 0, NULL, &globbuf);
+ /* Note: we check the first match against the filter list,
+ * just in case the user specified a wildcard in the path. */
+ if ((count = globbuf.gl_pathc) > 0) {
+ if (filter_server_path(globbuf.gl_pathv[0])) {
+ int slashes = 0;
+ char *cp;
+ /* Truncate original arg at glob's truncation point. */
+ for (cp = globbuf.gl_pathv[0]; *cp; cp++) {
+ if (*cp == '/')
+ slashes++;
+ }
+ for (cp = s; *cp; cp++) {
+ if (*cp == '/') {
+ if (--slashes <= 0) {
+ *cp = '\0';
+ break;
+ }
+ }
+ }
+ have_glob_results = 0;
+ count = 1;
+ } else
+ have_glob_results = 1;
+ } else {
+ /* This truncates "s" at a filtered element, if present. */
+ filter_server_path(s);
+ have_glob_results = 0;
+ count = 1;
+ }
+ if (count + argc > maxargs) {
+ maxargs += count + MAX_ARGS;
if (!(argv = realloc_array(argv, char *, maxargs)))
out_of_memory("glob_expand");
*argv_ptr = argv;
*maxargs_ptr = maxargs;
}
- if (globbuf.gl_pathc == 0)
- argv[argc++] = s;
- else {
+ if (have_glob_results) {
int i;
free(s);
- for (i = 0; i < (int)globbuf.gl_pathc; i++) {
+ for (i = 0; i < count; i++) {
if (!(argv[argc++] = strdup(globbuf.gl_pathv[i])))
out_of_memory("glob_expand");
}
- }
+ } else
+ argv[argc++] = s;
globfree(&globbuf);
#endif
*argc_ptr = argc;