* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2007 Wayne Davison
+ * Copyright (C) 2003-2008 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
extern unsigned int module_dirlen;
extern mode_t orig_umask;
extern char *partial_dir;
-extern struct filter_list_struct server_filter_list;
+extern struct filter_list_struct daemon_filter_list;
int sanitize_paths = 0;
t[1].tv_usec = 0;
# ifdef HAVE_LUTIMES
if (S_ISLNK(mode)) {
- if (lutimes(fname, t) < 0 && errno != ENOSYS)
- return -1;
+ if (lutimes(fname, t) < 0)
+ return errno == ENOSYS ? 1 : -1;
return 0;
}
# endif
return fcntl(fd,F_SETLK,&lock) == 0;
}
-static int filter_server_path(char *arg)
+static int filter_daemon_path(char *arg)
{
- char *s;
-
- if (server_filter_list.head) {
+ if (daemon_filter_list.head) {
+ char *s;
for (s = arg; (s = strchr(s, '/')) != NULL; ) {
*s = '\0';
- if (check_filter(&server_filter_list, arg, 1) < 0) {
+ if (check_filter(&daemon_filter_list, arg, 1) < 0) {
/* We must leave arg truncated! */
return 1;
}
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;
if (!*s)
s = ".";
s = argv[argc++] = strdup(s);
- filter_server_path(s);
+ filter_daemon_path(s);
#else
glob_t globbuf;
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_daemon_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_daemon_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;
}
start = sanp = dest + rlen;
+ /* This loop iterates once per filename component in p, pointing at
+ * the start of the name (past any prior slash) for each iteration. */
while (*p) {
/* discard leading or extra slashes */
if (*p == '/') {
p++;
continue;
}
- /* this loop iterates once per filename component in p.
- * both p (and sanp if the original had a slash) should
- * always be left pointing after a slash
- */
if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
if (leave_one_dotdir && p[1])
leave_one_dotdir = 0;
curr_dir_depth = count_dir_elements(curr_dir + module_dirlen);
}
- if (verbose >= 5)
- rprintf(FINFO, "[%s] dir is now %s\n", who_am_i(), curr_dir);
+ if (verbose >= 5 && !set_path_only)
+ rprintf(FINFO, "[%s] push_dir(%s)\n", who_am_i(), curr_dir);
return 1;
}
if (sanitize_paths)
curr_dir_depth = count_dir_elements(curr_dir + module_dirlen);
+ if (verbose >= 5)
+ rprintf(FINFO, "[%s] pop_dir(%s)\n", who_am_i(), curr_dir);
+
return 1;
}
fn = fname;
if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
return NULL;
- if (server_filter_list.head) {
+ if (daemon_filter_list.head) {
t = strrchr(partial_fname, '/');
*t = '\0';
- if (check_filter(&server_filter_list, partial_fname, 1) < 0)
+ if (check_filter(&daemon_filter_list, partial_fname, 1) < 0)
return NULL;
*t = '/';
- if (check_filter(&server_filter_list, partial_fname, 0) < 0)
+ if (check_filter(&daemon_filter_list, partial_fname, 0) < 0)
return NULL;
}