X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=bin%2Fad%2Fad_cp.c;h=5cefe9648a30484cb007d99fd834eabd8bacd4bc;hb=30963c2b3ee34139e0c3307677d181178a15f37f;hp=3593602a3b2a4a5ecdbb3603190bfe590386314f;hpb=4c65d44906949275eb11f4676f8d3be74bc9291c;p=netatalk.git diff --git a/bin/ad/ad_cp.c b/bin/ad/ad_cp.c index 3593602a..5cefe964 100644 --- a/bin/ad/ad_cp.c +++ b/bin/ad/ad_cp.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -66,11 +67,10 @@ #include #include #include -#include #include #include #include - + #include "ad.h" #define STRIP_TRAILING_SLASH(p) { \ @@ -83,7 +83,7 @@ static char emptystring[] = ""; PATH_T to = { to.p_path, emptystring, "" }; enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; -int fflag, iflag, lflag, nflag, pflag, vflag; +int fflag, iflag, nflag, pflag, vflag; mode_t mask; cnid_t ppdid, pdid, did; /* current dir CNID and parent did*/ @@ -91,57 +91,105 @@ cnid_t ppdid, pdid, did; /* current dir CNID and parent did*/ static afpvol_t svolume, dvolume; static enum op type; static int Rflag; -volatile sig_atomic_t sigint; +static volatile sig_atomic_t alarmed; static int badcp, rval; static int ftw_options = FTW_MOUNT | FTW_PHYS | FTW_ACTIONRETVAL; -static char *netatalk_dirs[] = { - ".AppleDouble", - ".AppleDB", - ".AppleDesktop", - NULL -}; - /* Forward declarations */ static int copy(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf); -static void siginfo(int _U_); static int ftw_copy_file(const struct FTW *, const char *, const struct stat *, int); static int ftw_copy_link(const struct FTW *, const char *, const struct stat *, int); static int setfile(const struct stat *, int); -static int preserve_dir_acls(const struct stat *, char *, char *); +// static int preserve_dir_acls(const struct stat *, char *, char *); static int preserve_fd_acls(int, int); +static void upfunc(void) +{ + did = pdid; + pdid = ppdid; +} + /* - Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" - Returns pointer to name or NULL. + SIGNAL handling: + catch SIGINT and SIGTERM which cause clean exit. Ignore anything else. */ -static const char *check_netatalk_dirs(const char *name) -{ - int c; - for (c=0; netatalk_dirs[c]; c++) { - if ((strcmp(name, netatalk_dirs[c])) == 0) - return netatalk_dirs[c]; - } - return NULL; +static void sig_handler(int signo) +{ + alarmed = 1; + return; } -static void upfunc(void) +static void set_signal(void) { - did = pdid; - pdid = ppdid; + struct sigaction sv; + + sv.sa_handler = sig_handler; + sv.sa_flags = SA_RESTART; + sigemptyset(&sv.sa_mask); + if (sigaction(SIGTERM, &sv, NULL) < 0) + ERROR("error in sigaction(SIGTERM): %s", strerror(errno)); + + if (sigaction(SIGINT, &sv, NULL) < 0) + ERROR("error in sigaction(SIGINT): %s", strerror(errno)); + + memset(&sv, 0, sizeof(struct sigaction)); + sv.sa_handler = SIG_IGN; + sigemptyset(&sv.sa_mask); + + if (sigaction(SIGABRT, &sv, NULL) < 0) + ERROR("error in sigaction(SIGABRT): %s", strerror(errno)); + + if (sigaction(SIGHUP, &sv, NULL) < 0) + ERROR("error in sigaction(SIGHUP): %s", strerror(errno)); + + if (sigaction(SIGQUIT, &sv, NULL) < 0) + ERROR("error in sigaction(SIGQUIT): %s", strerror(errno)); } static void usage_cp(void) { printf( - "Usage: ad cp [-R [-P]] [-pvf] \n" - "Usage: ad cp [-R [-P]] [-pvfx] \n" + "Usage: ad cp [-R] [-aipvf] \n" + " ad cp [-R] [-aipvfx] \n\n" + "In the first synopsis form, the cp utility copies the contents of the source_file to the\n" + "target_file. In the second synopsis form, the contents of each named source_file is copied to the\n" + "destination target_directory. The names of the files themselves are not changed. If cp detects an\n" + "attempt to copy a file to itself, the copy will fail.\n\n" + "Netatalk AFP volumes are detected by means of their \".AppleDesktop\" directory\n" + "which is located in their volume root. When a copy targetting an AFP volume\n" + "is detected, its CNID database daemon is connected and all copies will also\n" + "go through the CNID database.\n" + "AppleDouble files are also copied and created as needed when the target is\n" + "an AFP volume.\n\n" + "The following options are available:\n\n" + " -a Archive mode. Same as -Rp.\n\n" + " -f For each existing destination pathname, remove it and create a new\n" + " file, without prompting for confirmation regardless of its permis-\n" + " sions. (The -f option overrides any previous -i or -n options.)\n\n" + " -i Cause cp to write a prompt to the standard error output before\n" + " copying a file that would overwrite an existing file. If the\n" + " response from the standard input begins with the character 'y' or\n" + " 'Y', the file copy is attempted. (The -i option overrides any pre-\n" + " vious -f or -n options.)\n\n" + " -n Do not overwrite an existing file. (The -n option overrides any\n" + " previous -f or -i options.)\n\n" + " -p Cause cp to preserve the following attributes of each source file\n" + " in the copy: modification time, access time, file flags, file mode,\n" + " user ID, and group ID, as allowed by permissions.\n" + " If the user ID and group ID cannot be preserved, no error message\n" + " is displayed and the exit value is not altered.\n\n" + " -R If source_file designates a directory, cp copies the directory and\n" + " the entire subtree connected at that point.If the source_file\n" + " ends in a /, the contents of the directory are copied rather than\n" + " the directory itself.\n\n" + " -v Cause cp to be verbose, showing files as they are copied.\n\n" + " -x File system mount points are not traversed.\n\n" ); exit(EXIT_FAILURE); } -int ad_cp(int argc, char *argv[]) +int ad_cp(int argc, char *argv[], AFPObj *obj) { struct stat to_stat, tmp_stat; int r, ch, have_trailing_slash; @@ -154,11 +202,8 @@ int ad_cp(int argc, char *argv[]) ppdid = pdid = htonl(1); did = htonl(2); - while ((ch = getopt(argc, argv, "Rafilnpvx")) != -1) + while ((ch = getopt(argc, argv, "afinpRvx")) != -1) switch (ch) { - case 'R': - Rflag = 1; - break; case 'a': pflag = 1; Rflag = 1; @@ -171,9 +216,6 @@ int ad_cp(int argc, char *argv[]) iflag = 1; fflag = nflag = 0; break; - case 'l': - lflag = 1; - break; case 'n': nflag = 1; fflag = iflag = 0; @@ -181,6 +223,9 @@ int ad_cp(int argc, char *argv[]) case 'p': pflag = 1; break; + case 'R': + Rflag = 1; + break; case 'v': vflag = 1; break; @@ -197,8 +242,7 @@ int ad_cp(int argc, char *argv[]) if (argc < 2) usage_cp(); - (void)signal(SIGINT, siginfo); - + set_signal(); cnid_init(); /* Save the target base in "to". */ @@ -285,18 +329,21 @@ int ad_cp(int argc, char *argv[]) #endif /* Load .volinfo file for destination*/ - openvol(to.p_path, &dvolume); + openvol(obj, to.p_path, &dvolume); - for (int i = 0; argv[i] != NULL; i++) { + for (int i = 0; argv[i] != NULL; i++) { /* Load .volinfo file for source */ - openvol(argv[i], &svolume); + openvol(obj, argv[i], &svolume); if (nftw(argv[i], copy, upfunc, 20, ftw_options) == -1) { - ERROR("%s: %s", argv[i], strerror(errno)); - exit(EXIT_FAILURE); + if (alarmed) { + SLOG("...break"); + } else { + SLOG("Error: %s: %s", argv[i], strerror(errno)); + } + closevol(&svolume); + closevol(&dvolume); } - - } return rval; } @@ -314,15 +361,20 @@ static int copy(const char *path, const char *p; char *target_mid; + if (alarmed) + return -1; + + /* This currently doesn't work with "." */ + if (strcmp(path, ".") == 0) { + ERROR("\".\" not supported"); + } const char *dir = strrchr(path, '/'); if (dir == NULL) dir = path; else dir++; - if (check_netatalk_dirs(dir) != NULL) { - SLOG("Skipping Netatalk dir %s", path); + if (!dvolume.vol->vfs->vfs_validupath(dvolume.vol, dir)) return FTW_SKIP_SUBTREE; - } /* * If we are in case (2) above, we need to append the @@ -381,24 +433,33 @@ static int copy(const char *path, else { if (to_stat.st_dev == statp->st_dev && to_stat.st_ino == statp->st_ino) { - SLOG("%s and %s are identical (not copied).", - to.p_path, path); + SLOG("%s and %s are identical (not copied).", to.p_path, path); badcp = rval = 1; if (S_ISDIR(statp->st_mode)) /* without using glibc extension FTW_ACTIONRETVAL cant handle this */ - return -1; + return FTW_SKIP_SUBTREE; + return 0; } if (!S_ISDIR(statp->st_mode) && S_ISDIR(to_stat.st_mode)) { SLOG("cannot overwrite directory %s with " - "non-directory %s", - to.p_path, path); - badcp = rval = 1; - return 0; + "non-directory %s", + to.p_path, path); + badcp = rval = 1; + return 0; } dne = 0; } + /* Convert basename to appropiate volume encoding */ + if (dvolume.vol->v_path) { + if ((convert_dots_encoding(&svolume, &dvolume, to.p_path, MAXPATHLEN)) == -1) { + SLOG("Error converting name for %s", to.p_path); + badcp = rval = 1; + return -1; + } + } + switch (statp->st_mode & S_IFMT) { case S_IFLNK: if (ftw_copy_link(ftw, path, statp, !dne)) @@ -427,47 +488,52 @@ static int copy(const char *path, } /* Create ad dir and copy ".Parent" */ - if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) { - /* Create ".AppleDouble" dir */ + if (dvolume.vol->v_path && ADVOL_V2_OR_EA(dvolume.vol->v_adouble)) { mode_t omask = umask(0); - bstring addir = bfromcstr(to.p_path); - bcatcstr(addir, "/.AppleDouble"); - mkdir(cfrombstr(addir), 02777); - - if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) { - /* copy ".Parent" file */ - bcatcstr(addir, "/.Parent"); - bstring sdir = bfromcstr(path); - bcatcstr(sdir, "/.AppleDouble/.Parent"); - if (copy_file(-1, cfrombstr(sdir), cfrombstr(addir), 0666) != 0) { - SLOG("Error copying %s -> %s", cfrombstr(sdir), cfrombstr(addir)); + if (dvolume.vol->v_adouble == AD_VERSION2) { + /* Create ".AppleDouble" dir */ + bstring addir = bfromcstr(to.p_path); + bcatcstr(addir, "/.AppleDouble"); + mkdir(cfrombstr(addir), 02777); + bdestroy(addir); + } + + if (svolume.vol->v_path && ADVOL_V2_OR_EA(svolume.vol->v_adouble)) { + /* copy metadata file */ + if (dvolume.vol->vfs->vfs_copyfile(dvolume.vol, -1, path, to.p_path)) { + SLOG("Error copying adouble for %s -> %s", path, to.p_path); badcp = rval = 1; break; } - bdestroy(sdir); } - bdestroy(addir); /* Get CNID of Parent and add new childir to CNID database */ ppdid = pdid; - pdid = did; - did = cnid_for_path(&dvolume.volinfo, &dvolume.volume, to.p_path); - SLOG("got CNID: %u for path: %s", ntohl(did), to.p_path); + if ((did = cnid_for_path(dvolume.vol->v_cdb, dvolume.vol->v_path, to.p_path, &pdid)) == CNID_INVALID) { + SLOG("Error resolving CNID for %s", to.p_path); + badcp = rval = 1; + return -1; + } struct adouble ad; struct stat st; - if (stat(to.p_path, &st) != 0) { + if (lstat(to.p_path, &st) != 0) { badcp = rval = 1; break; } - ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options); - if (ad_open_metadata(to.p_path, ADFLAGS_DIR, O_RDWR | O_CREAT, &ad) != 0) { + ad_init(&ad, dvolume.vol); + if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) { ERROR("Error opening adouble for: %s", to.p_path); } ad_setid( &ad, st.st_dev, st.st_ino, did, pdid, dvolume.db_stamp); - ad_setname(&ad, utompath(&dvolume.volinfo, path + ftw->base)); + if (dvolume.vol->v_adouble == AD_VERSION2) + ad_setname(&ad, utompath(dvolume.vol, basename(to.p_path))); + ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START); ad_flush(&ad); - ad_close_metadata(&ad); + ad_close(&ad, ADFLAGS_HF); umask(omask); } @@ -496,34 +562,46 @@ static int copy(const char *path, if (ftw_copy_file(ftw, path, statp, dne)) badcp = rval = 1; - if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) { + if (dvolume.vol->v_path && ADVOL_V2_OR_EA(dvolume.vol->v_adouble)) { - SLOG("ad for file: %s", to.p_path); mode_t omask = umask(0); - if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) { + if (svolume.vol->v_path && ADVOL_V2_OR_EA(svolume.vol->v_adouble)) { /* copy ad-file */ - if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) + if (dvolume.vol->vfs->vfs_copyfile(dvolume.vol, -1, path, to.p_path)) { + SLOG("Error copying adouble for %s -> %s", path, to.p_path); badcp = rval = 1; + break; + } } /* Get CNID of Parent and add new childir to CNID database */ - cnid_t cnid = cnid_for_path(&dvolume.volinfo, &dvolume.volume, to.p_path); - SLOG("got CNID: %u for path: %s", ntohl(cnid), to.p_path); + pdid = did; + cnid_t cnid; + if ((cnid = cnid_for_path(dvolume.vol->v_cdb, dvolume.vol->v_path, to.p_path, &did)) == CNID_INVALID) { + SLOG("Error resolving CNID for %s", to.p_path); + badcp = rval = 1; + return -1; + } struct adouble ad; struct stat st; - if (stat(to.p_path, &st) != 0) { + if (lstat(to.p_path, &st) != 0) { badcp = rval = 1; break; } - ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options); - if (ad_open_metadata(to.p_path, 0, O_RDWR | O_CREAT, &ad) != 0) { + ad_init(&ad, dvolume.vol); + if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) { ERROR("Error opening adouble for: %s", to.p_path); } ad_setid( &ad, st.st_dev, st.st_ino, cnid, did, dvolume.db_stamp); - ad_setname(&ad, utompath(&dvolume.volinfo, path + ftw->base)); + if (dvolume.vol->v_adouble == AD_VERSION2) + ad_setname(&ad, utompath(dvolume.vol, basename(to.p_path))); + ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START); ad_flush(&ad); - ad_close_metadata(&ad); + ad_close(&ad, ADFLAGS_HF); umask(omask); } break; @@ -534,11 +612,6 @@ static int copy(const char *path, return 0; } -static void siginfo(int sig _U_) -{ - sigint = 1; -} - /* Memory strategy threshold, in pages: if physmem is larger then this, use a large buffer */ #define PHYSPAGES_THRESHOLD (32*1024) @@ -584,7 +657,7 @@ static int ftw_copy_file(const struct FTW *entp, (void)close(from_fd); return (0); } else if (iflag) { - (void)fprintf(stderr, "overwrite %s? %s", + (void)fprintf(stderr, "overwrite %s? %s", to.p_path, YESNO); checkch = ch = getchar(); while (ch != '\n' && ch != EOF) @@ -595,26 +668,23 @@ static int ftw_copy_file(const struct FTW *entp, return (1); } } - + if (fflag) { - /* remove existing destination file name, + /* remove existing destination file name, * create a new file */ (void)unlink(to.p_path); - (void)dvolume.volume.vfs->vfs_deletefile(&dvolume.volume, -1, to.p_path); - if (!lflag) - to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, - sp->st_mode & ~(S_ISUID | S_ISGID)); + (void)dvolume.vol->vfs->vfs_deletefile(dvolume.vol, -1, to.p_path); + to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, + sp->st_mode & ~(S_ISUID | S_ISGID)); } else { - if (!lflag) - /* overwrite existing destination file name */ - to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0); + /* overwrite existing destination file name */ + to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0); } } else { - if (!lflag) - to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, - sp->st_mode & ~(S_ISUID | S_ISGID)); + to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, + sp->st_mode & ~(S_ISUID | S_ISGID)); } - + if (to_fd == -1) { SLOG("%s: %s", to.p_path, strerror(errno)); (void)close(from_fd); @@ -623,22 +693,58 @@ static int ftw_copy_file(const struct FTW *entp, rval = 0; - if (!lflag) { - /* - * Mmap and write if less than 8M (the limit is so we don't totally - * trash memory on big files. This is really a minor hack, but it - * wins some CPU back. - * Some filesystems, such as smbnetfs, don't support mmap, - * so this is a best-effort attempt. - */ + /* + * Mmap and write if less than 8M (the limit is so we don't totally + * trash memory on big files. This is really a minor hack, but it + * wins some CPU back. + * Some filesystems, such as smbnetfs, don't support mmap, + * so this is a best-effort attempt. + */ - if (S_ISREG(sp->st_mode) && sp->st_size > 0 && - sp->st_size <= 8 * 1024 * 1024 && - (p = mmap(NULL, (size_t)sp->st_size, PROT_READ, - MAP_SHARED, from_fd, (off_t)0)) != MAP_FAILED) { - wtotal = 0; - for (bufp = p, wresid = sp->st_size; ; - bufp += wcount, wresid -= (size_t)wcount) { + if (S_ISREG(sp->st_mode) && sp->st_size > 0 && + sp->st_size <= 8 * 1024 * 1024 && + (p = mmap(NULL, (size_t)sp->st_size, PROT_READ, + MAP_SHARED, from_fd, (off_t)0)) != MAP_FAILED) { + wtotal = 0; + for (bufp = p, wresid = sp->st_size; ; + bufp += wcount, wresid -= (size_t)wcount) { + wcount = write(to_fd, bufp, wresid); + if (wcount <= 0) + break; + wtotal += wcount; + if (wcount >= (ssize_t)wresid) + break; + } + if (wcount != (ssize_t)wresid) { + SLOG("%s: %s", to.p_path, strerror(errno)); + rval = 1; + } + /* Some systems don't unmap on close(2). */ + if (munmap(p, sp->st_size) < 0) { + SLOG("%s: %s", spath, strerror(errno)); + rval = 1; + } + } else { + if (buf == NULL) { + /* + * Note that buf and bufsize are static. If + * malloc() fails, it will fail at the start + * and not copy only some files. + */ + if (sysconf(_SC_PHYS_PAGES) > + PHYSPAGES_THRESHOLD) + bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); + else + bufsize = BUFSIZE_SMALL; + buf = malloc(bufsize); + if (buf == NULL) + ERROR("Not enough memory"); + + } + wtotal = 0; + while ((rcount = read(from_fd, buf, bufsize)) > 0) { + for (bufp = buf, wresid = rcount; ; + bufp += wcount, wresid -= wcount) { wcount = write(to_fd, bufp, wresid); if (wcount <= 0) break; @@ -649,58 +755,15 @@ static int ftw_copy_file(const struct FTW *entp, if (wcount != (ssize_t)wresid) { SLOG("%s: %s", to.p_path, strerror(errno)); rval = 1; - } - /* Some systems don't unmap on close(2). */ - if (munmap(p, sp->st_size) < 0) { - SLOG("%s: %s", spath, strerror(errno)); - rval = 1; - } - } else { - if (buf == NULL) { - /* - * Note that buf and bufsize are static. If - * malloc() fails, it will fail at the start - * and not copy only some files. - */ - if (sysconf(_SC_PHYS_PAGES) > - PHYSPAGES_THRESHOLD) - bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); - else - bufsize = BUFSIZE_SMALL; - buf = malloc(bufsize); - if (buf == NULL) - ERROR("Not enough memory"); - - } - wtotal = 0; - while ((rcount = read(from_fd, buf, bufsize)) > 0) { - for (bufp = buf, wresid = rcount; ; - bufp += wcount, wresid -= wcount) { - wcount = write(to_fd, bufp, wresid); - if (wcount <= 0) - break; - wtotal += wcount; - if (wcount >= (ssize_t)wresid) - break; - } - if (wcount != (ssize_t)wresid) { - SLOG("%s: %s", to.p_path, strerror(errno)); - rval = 1; - break; - } - } - if (rcount < 0) { - SLOG("%s: %s", spath, strerror(errno)); - rval = 1; + break; } } - } else { - if (link(spath, to.p_path)) { - SLOG("%s", to.p_path); + if (rcount < 0) { + SLOG("%s: %s", spath, strerror(errno)); rval = 1; } } - + /* * Don't remove the target even after an error. The target might * not be a regular file, or its attributes might be important, @@ -708,15 +771,13 @@ static int ftw_copy_file(const struct FTW *entp, * to remove it if we created it and its length is 0. */ - if (!lflag) { - if (pflag && setfile(sp, to_fd)) - rval = 1; - if (pflag && preserve_fd_acls(from_fd, to_fd) != 0) - rval = 1; - if (close(to_fd)) { - SLOG("%s: %s", to.p_path, strerror(errno)); - rval = 1; - } + if (pflag && setfile(sp, to_fd)) + rval = 1; + if (pflag && preserve_fd_acls(from_fd, to_fd) != 0) + rval = 1; + if (close(to_fd)) { + SLOG("%s: %s", to.p_path, strerror(errno)); + rval = 1; } (void)close(from_fd); @@ -760,10 +821,16 @@ static int setfile(const struct stat *fs, int fd) islink = !fdval && S_ISLNK(fs->st_mode); mode = fs->st_mode & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO); +#if defined(__FreeBSD__) + TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec); + TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec); +#else TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atim); TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtim); - if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) { - SLOG("%sutimes: %s", islink ? "l" : "", to.p_path); +#endif + + if (utimes(to.p_path, tv)) { + SLOG("utimes: %s", to.p_path); rval = 1; } if (fdval ? fstat(fd, &ts) : @@ -864,9 +931,9 @@ static int preserve_fd_acls(int source_fd, int dest_fd) return (0); } +#if 0 static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest_dir) { -#if 0 acl_t (*aclgetf)(const char *, acl_type_t); int (*aclsetf)(const char *, acl_type_t, acl_t); struct acl *aclp; @@ -948,6 +1015,6 @@ static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest return (1); } acl_free(acl); -#endif return (0); } +#endif