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

This commit is contained in:
Michael Forney 2019-11-01 20:43:32 -07:00
parent 3e160b616a
commit 039b54aa51
4 changed files with 29 additions and 51 deletions

17
chgrp.c
View File

@ -2,6 +2,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <grp.h> #include <grp.h>
#include <unistd.h> #include <unistd.h>
@ -15,19 +16,13 @@ static int ret = 0;
static void static void
chgrp(const char *path, struct stat *st, void *data, struct recursor *r) chgrp(const char *path, struct stat *st, void *data, struct recursor *r)
{ {
char *chownf_name; int flags = 0;
int (*chownf)(const char *, uid_t, gid_t);
if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) { if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth)))
chownf_name = "lchown"; flags |= AT_SYMLINK_NOFOLLOW;
chownf = lchown;
} else {
chownf_name = "chown";
chownf = chown;
}
if (chownf(path, -1, gid) < 0) { if (fchownat(AT_FDCWD, path, -1, gid, flags) < 0) {
weprintf("%s %s:", chownf_name, path); weprintf("chown %s:", path);
ret = 1; ret = 1;
} else if (S_ISDIR(st->st_mode)) { } else if (S_ISDIR(st->st_mode)) {
recurse(path, NULL, r); recurse(path, NULL, r);

17
chown.c
View File

@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <grp.h> #include <grp.h>
#include <limits.h> #include <limits.h>
#include <pwd.h> #include <pwd.h>
@ -18,19 +19,13 @@ static int ret = 0;
static void static void
chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r) chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r)
{ {
char *chownf_name; int flags = 0;
int (*chownf)(const char *, uid_t, gid_t);
if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth))) { if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' && r->depth) || (hflag && !(r->depth)))
chownf_name = "lchown"; flags |= AT_SYMLINK_NOFOLLOW;
chownf = lchown;
} else {
chownf_name = "chown";
chownf = chown;
}
if (chownf(path, uid, gid) < 0) { if (fchownat(AT_FDCWD, path, uid, gid, flags) < 0) {
weprintf("%s %s:", chownf_name, path); weprintf("chown %s:", path);
ret = 1; ret = 1;
} else if (S_ISDIR(st->st_mode)) { } else if (S_ISDIR(st->st_mode)) {
recurse(path, NULL, r); recurse(path, NULL, r);

View File

@ -26,24 +26,18 @@ int
cp(const char *s1, const char *s2, int depth) cp(const char *s1, const char *s2, int depth)
{ {
DIR *dp; DIR *dp;
int f1, f2; int f1, f2, flags = 0;
struct dirent *d; struct dirent *d;
struct stat st; struct stat st;
struct timespec times[2]; struct timespec times[2];
ssize_t r; ssize_t r;
int (*statf)(const char *, struct stat *); char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX];
char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX], *statf_name;
if (cp_follow == 'P' || (cp_follow == 'H' && depth)) { if (cp_follow == 'P' || (cp_follow == 'H' && depth))
statf_name = "lstat"; flags |= AT_SYMLINK_NOFOLLOW;
statf = lstat;
} else {
statf_name = "stat";
statf = stat;
}
if (statf(s1, &st) < 0) { if (fstatat(AT_FDCWD, s1, &st, flags) < 0) {
weprintf("%s %s:", statf_name, s1); weprintf("stat %s:", s1);
cp_status = 1; cp_status = 1;
return 0; return 0;
} }

View File

@ -1,6 +1,7 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -21,20 +22,15 @@ recurse(const char *path, void *data, struct recursor *r)
struct history *new, *h; struct history *new, *h;
struct stat st, dst; struct stat st, dst;
DIR *dp; DIR *dp;
int (*statf)(const char *, struct stat *); char subpath[PATH_MAX];
char subpath[PATH_MAX], *statf_name; int flags = 0;
if (r->follow == 'P' || (r->follow == 'H' && r->depth)) { if (r->follow == 'P' || (r->follow == 'H' && r->depth))
statf_name = "lstat"; flags |= AT_SYMLINK_NOFOLLOW;
statf = lstat;
} else {
statf_name = "stat";
statf = stat;
}
if (statf(path, &st) < 0) { if (fstatat(AT_FDCWD, path, &st, flags) < 0) {
if (!(r->flags & SILENT)) { if (!(r->flags & SILENT)) {
weprintf("%s %s:", statf_name, path); weprintf("stat %s:", path);
recurse_status = 1; recurse_status = 1;
} }
return; return;
@ -66,19 +62,17 @@ recurse(const char *path, void *data, struct recursor *r)
return; return;
} }
while ((d = readdir(dp))) { while ((d = readdir(dp))) {
if (r->follow == 'H') { if (r->follow == 'H')
statf_name = "lstat"; flags |= AT_SYMLINK_NOFOLLOW;
statf = lstat;
}
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue; continue;
estrlcpy(subpath, path, sizeof(subpath)); estrlcpy(subpath, path, sizeof(subpath));
if (path[strlen(path) - 1] != '/') if (path[strlen(path) - 1] != '/')
estrlcat(subpath, "/", sizeof(subpath)); estrlcat(subpath, "/", sizeof(subpath));
estrlcat(subpath, d->d_name, 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)) { if (!(r->flags & SILENT)) {
weprintf("%s %s:", statf_name, subpath); weprintf("stat %s:", subpath);
recurse_status = 1; recurse_status = 1;
} }
} else if ((r->flags & SAMEDEV) && dst.st_dev != st.st_dev) { } else if ((r->flags & SAMEDEV) && dst.st_dev != st.st_dev) {