X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3f0211b63a6cdc4a2cecfd2a0dffeba172c86a47..e889e0c43bc6b55ff2c20091a66bb1676de5369f:/util.c diff --git a/util.c b/util.c index 74341930..b5c15fba 100644 --- a/util.c +++ b/util.c @@ -4,7 +4,7 @@ * Copyright (C) 1996-2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool - * 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 @@ -147,8 +147,9 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) 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); @@ -465,31 +466,27 @@ void kill_all(int sig) } /** 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 */ @@ -528,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; @@ -556,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; @@ -898,6 +924,9 @@ int push_dir(const char *dir, int set_path_only) 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; } @@ -916,6 +945,9 @@ int pop_dir(const char *dir) 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; }