commit 039b54aa510ddc32b9430bb89b98cb8937ac33c3
Author:     Michael Forney <mfor...@mforney.org>
AuthorDate: Fri Nov 1 20:43:32 2019 -0700
Commit:     Michael Forney <mfor...@mforney.org>
CommitDate: Thu Mar 5 00:45:53 2020 -0800

    Use *at functions with appropriate flags instead of lstat/lchown

diff --git a/chgrp.c b/chgrp.c
index 960ed2c..04b2dd0 100644
--- a/chgrp.c
+++ b/chgrp.c
@@ -2,6 +2,7 @@
 #include <sys/stat.h>
 
 #include <errno.h>
+#include <fcntl.h>
 #include <grp.h>
 #include <unistd.h>
 
@@ -15,19 +16,13 @@ static int   ret = 0;
 static void
 chgrp(const char *path, struct stat *st, void *data, struct recursor *r)
 {
-       char *chownf_name;
-       int (*chownf)(const char *, uid_t, gid_t);
+       int flags = 0;
 
-       if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && 
r->depth) || (hflag && !(r->depth))) {
-               chownf_name = "lchown";
-               chownf = lchown;
-       } else {
-               chownf_name = "chown";
-               chownf = chown;
-       }
+       if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && 
r->depth) || (hflag && !(r->depth)))
+               flags |= AT_SYMLINK_NOFOLLOW;
 
-       if (chownf(path, -1, gid) < 0) {
-               weprintf("%s %s:", chownf_name, path);
+       if (fchownat(AT_FDCWD, path, -1, gid, flags) < 0) {
+               weprintf("chown %s:", path);
                ret = 1;
        } else if (S_ISDIR(st->st_mode)) {
                recurse(path, NULL, r);
diff --git a/chown.c b/chown.c
index c517acf..dcd4914 100644
--- a/chown.c
+++ b/chown.c
@@ -1,5 +1,6 @@
 /* See LICENSE file for copyright and license details. */
 #include <errno.h>
+#include <fcntl.h>
 #include <grp.h>
 #include <limits.h>
 #include <pwd.h>
@@ -18,19 +19,13 @@ static int   ret = 0;
 static void
 chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r)
 {
-       char *chownf_name;
-       int (*chownf)(const char *, uid_t, gid_t);
+       int flags = 0;
 
-       if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && 
r->depth) || (hflag && !(r->depth))) {
-               chownf_name = "lchown";
-               chownf = lchown;
-       } else {
-               chownf_name = "chown";
-               chownf = chown;
-       }
+       if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && 
r->depth) || (hflag && !(r->depth)))
+               flags |= AT_SYMLINK_NOFOLLOW;
 
-       if (chownf(path, uid, gid) < 0) {
-               weprintf("%s %s:", chownf_name, path);
+       if (fchownat(AT_FDCWD, path, uid, gid, flags) < 0) {
+               weprintf("chown %s:", path);
                ret = 1;
        } else if (S_ISDIR(st->st_mode)) {
                recurse(path, NULL, r);
diff --git a/libutil/cp.c b/libutil/cp.c
index bb85c14..23275ac 100644
--- a/libutil/cp.c
+++ b/libutil/cp.c
@@ -26,24 +26,18 @@ int
 cp(const char *s1, const char *s2, int depth)
 {
        DIR *dp;
-       int f1, f2;
+       int f1, f2, flags = 0;
        struct dirent *d;
        struct stat st;
        struct timespec times[2];
        ssize_t r;
-       int (*statf)(const char *, struct stat *);
-       char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX], *statf_name;
+       char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX];
 
-       if (cp_follow == 'P' || (cp_follow == 'H' && depth)) {
-               statf_name = "lstat";
-               statf = lstat;
-       } else {
-               statf_name = "stat";
-               statf = stat;
-       }
+       if (cp_follow == 'P' || (cp_follow == 'H' && depth))
+               flags |= AT_SYMLINK_NOFOLLOW;
 
-       if (statf(s1, &st) < 0) {
-               weprintf("%s %s:", statf_name, s1);
+       if (fstatat(AT_FDCWD, s1, &st, flags) < 0) {
+               weprintf("stat %s:", s1);
                cp_status = 1;
                return 0;
        }
diff --git a/libutil/recurse.c b/libutil/recurse.c
index 487faac..e150fb9 100644
--- a/libutil/recurse.c
+++ b/libutil/recurse.c
@@ -1,6 +1,7 @@
 /* See LICENSE file for copyright and license details. */
 #include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -21,20 +22,15 @@ recurse(const char *path, void *data, struct recursor *r)
        struct history *new, *h;
        struct stat st, dst;
        DIR *dp;
-       int (*statf)(const char *, struct stat *);
-       char subpath[PATH_MAX], *statf_name;
+       char subpath[PATH_MAX];
+       int flags = 0;
 
-       if (r->follow == 'P' || (r->follow == 'H' && r->depth)) {
-               statf_name = "lstat";
-               statf = lstat;
-       } else {
-               statf_name = "stat";
-               statf = stat;
-       }
+       if (r->follow == 'P' || (r->follow == 'H' && r->depth))
+               flags |= AT_SYMLINK_NOFOLLOW;
 
-       if (statf(path, &st) < 0) {
+       if (fstatat(AT_FDCWD, path, &st, flags) < 0) {
                if (!(r->flags & SILENT)) {
-                       weprintf("%s %s:", statf_name, path);
+                       weprintf("stat %s:", path);
                        recurse_status = 1;
                }
                return;
@@ -66,19 +62,17 @@ recurse(const char *path, void *data, struct recursor *r)
                        return;
                }
                while ((d = readdir(dp))) {
-                       if (r->follow == 'H') {
-                               statf_name = "lstat";
-                               statf = lstat;
-                       }
+                       if (r->follow == 'H')
+                               flags |= AT_SYMLINK_NOFOLLOW;
                        if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
                                continue;
                        estrlcpy(subpath, path, sizeof(subpath));
                        if (path[strlen(path) - 1] != '/')
                                estrlcat(subpath, "/", sizeof(subpath));
                        estrlcat(subpath, d->d_name, sizeof(subpath));
-                       if (statf(subpath, &dst) < 0) {
+                       if (fstatat(AT_FDCWD, subpath, &dst, flags) < 0) {
                                if (!(r->flags & SILENT)) {
-                                       weprintf("%s %s:", statf_name, subpath);
+                                       weprintf("stat %s:", subpath);
                                        recurse_status = 1;
                                }
                        } else if ((r->flags & SAMEDEV) && dst.st_dev != 
st.st_dev) {

Reply via email to