[hackers] [PATCH 1/2] Use *at functions with appropriate flags instead of lstat/lchown

From: Michael Forney <mforney_AT_mforney.org>
Date: Sun, 22 Dec 2019 17:03:58 -0800

---
 chgrp.c           | 17 ++++++-----------
 chown.c           | 17 ++++++-----------
 libutil/cp.c      | 18 ++++++------------
 libutil/recurse.c | 28 +++++++++++-----------------
 4 files changed, 29 insertions(+), 51 deletions(-)
diff --git a/chgrp.c b/chgrp.c
index 960ed2c..04b2dd0 100644
--- a/chgrp.c
+++ b/chgrp.c
_AT_@ -2,6 +2,7 @@
 #include <sys/stat.h>
 
 #include <errno.h>
+#include <fcntl.h>
 #include <grp.h>
 #include <unistd.h>
 
_AT_@ -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
_AT_@ -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>
_AT_@ -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 b6f8b23..61c73f4 100644
--- a/libutil/cp.c
+++ b/libutil/cp.c
_AT_@ -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 d2dc3ed..f50347e 100644
--- a/libutil/recurse.c
+++ b/libutil/recurse.c
_AT_@ -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>
_AT_@ -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;
_AT_@ -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) {
-- 
2.24.1
Received on Mon Dec 23 2019 - 02:03:58 CET

This archive was generated by hypermail 2.3.0 : Mon Dec 23 2019 - 02:36:25 CET