* 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)) {
- lutimes(fname, t);
- return 0; /* ignore errors */
+ if (lutimes(fname, t) < 0)
+ return errno == ENOSYS ? 1 : -1;
+ return 0;
}
# endif
return utimes(fname, t);
int len; /* Number of bytes read into `buf'. */
if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
- rsyserr(FERROR, errno, "open %s", full_fname(source));
+ rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
return -1;
}
if (ofd < 0) {
if (robust_unlink(dest) && errno != ENOENT) {
- rsyserr(FERROR, errno, "unlink %s", full_fname(dest));
+ rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
return -1;
}
if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0
&& (!create_bak_dir || errno != ENOENT || make_bak_dir(dest) < 0
|| (ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)) {
- rsyserr(FERROR, errno, "open %s", full_fname(dest));
+ rsyserr(FERROR_XFER, errno, "open %s", full_fname(dest));
close(ifd);
return -1;
}
while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
if (full_write(ofd, buf, len) < 0) {
- rsyserr(FERROR, errno, "write %s", full_fname(dest));
+ rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
close(ifd);
close(ofd);
return -1;
}
if (len < 0) {
- rsyserr(FERROR, errno, "read %s", full_fname(source));
+ rsyserr(FERROR_XFER, errno, "read %s", full_fname(source));
close(ifd);
close(ofd);
return -1;
}
if (close(ifd) < 0) {
- rsyserr(FINFO, errno, "close failed on %s",
+ rsyserr(FWARNING, errno, "close failed on %s",
full_fname(source));
}
if (close(ofd) < 0) {
- rsyserr(FERROR, errno, "close failed on %s",
+ rsyserr(FERROR_XFER, errno, "close failed on %s",
full_fname(dest));
return -1;
}
} while ((rc = access(path, 0)) == 0 && counter != start);
if (verbose > 0) {
- rprintf(FINFO,"renaming %s to %s because of text busy\n",
+ rprintf(FWARNING, "renaming %s to %s because of text busy\n",
fname, path);
}
}
/** Turn a user name into a uid */
-int name_to_uid(const char *name, uid_t *uid)
+int name_to_uid(const char *name, uid_t *uid_p)
{
struct passwd *pass;
if (!name || !*name)
return 0;
- pass = getpwnam(name);
- if (pass) {
- *uid = pass->pw_uid;
- return 1;
- }
- return 0;
+ if (!(pass = getpwnam(name)))
+ return 0;
+ *uid_p = pass->pw_uid;
+ return 1;
}
/** Turn a group name into a gid */
-int name_to_gid(const char *name, gid_t *gid)
+int name_to_gid(const char *name, gid_t *gid_p)
{
struct group *grp;
if (!name || !*name)
return 0;
- grp = getgrnam(name);
- if (grp) {
- *gid = grp->gr_gid;
- return 1;
- }
- return 0;
+ if (!(grp = getgrnam(name)))
+ return 0;
+ *gid_p = grp->gr_gid;
+ return 1;
}
/** Lock a byte range in a open file */
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 && !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;
}