X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3696674bc62b0c1250027dbeedafdd7ebafdcf8b..1b502f3ec234bf1045c6bb146f64734d09e81956:/util.c diff --git a/util.c b/util.c index bad2faed..6019fccb 100644 --- a/util.c +++ b/util.c @@ -34,7 +34,7 @@ extern char *module_dir; extern unsigned int module_dirlen; extern mode_t orig_umask; extern char *partial_dir; -extern struct filter_list_struct daemon_filter_list; +extern filter_rule_list daemon_filter_list; int sanitize_paths = 0; @@ -123,9 +123,9 @@ NORETURN void overflow_exit(const char *str) exit_cleanup(RERR_MALLOC); } -int set_modtime(const char *fname, time_t modtime, mode_t mode) +int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) { -#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES +#ifndef CAN_SET_SYMLINK_TIMES if (S_ISLNK(mode)) return 1; #endif @@ -140,20 +140,28 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) return 0; { -#ifdef HAVE_UTIMES +#ifdef HAVE_UTIMENSAT + struct timespec t[2]; + t[0].tv_sec = 0; + t[0].tv_nsec = UTIME_NOW; + t[1].tv_sec = modtime; + t[1].tv_nsec = mod_nsec; + if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) < 0) + return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1; + return 0; +#elif defined HAVE_UTIMES || defined HAVE_LUTIMES struct timeval t[2]; t[0].tv_sec = time(NULL); t[0].tv_usec = 0; t[1].tv_sec = modtime; - t[1].tv_usec = 0; + t[1].tv_usec = mod_nsec / 1000; # ifdef HAVE_LUTIMES - if (S_ISLNK(mode)) { - if (lutimes(fname, t) < 0) - return errno == ENOSYS ? 1 : -1; - return 0; - } -# endif + if (lutimes(fname, t) < 0) + return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1; + return 0; +# else return utimes(fname, t); +# endif #elif defined HAVE_STRUCT_UTIMBUF struct utimbuf tbuf; tbuf.actime = time(NULL); @@ -534,24 +542,32 @@ void kill_all(int sig) } } -/** Turn a user name into a uid */ -int name_to_uid(const char *name, uid_t *uid_p) +/* Parse a user name or (optionally) a number into a uid */ +int user_to_uid(const char *name, uid_t *uid_p, BOOL num_ok) { struct passwd *pass; if (!name || !*name) return 0; + if (num_ok && name[strspn(name, "0123456789")] == '\0') { + *uid_p = atol(name); + return 1; + } 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_p) +/* Parse a group name or (optionally) a number into a gid */ +int group_to_gid(const char *name, gid_t *gid_p, BOOL num_ok) { struct group *grp; if (!name || !*name) return 0; + if (num_ok && name[strspn(name, "0123456789")] == '\0') { + *gid_p = atol(name); + return 1; + } if (!(grp = getgrnam(name))) return 0; *gid_p = grp->gr_gid;