sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

commit 82bc92da5175c181ecf5dfb9f93eb9e9aca068bc
parent 5a13865385cf32e072c8dd69c5d6bf4adb6e4957
Author: Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
Date:   Mon Feb  9 19:53:24 +0000

recurse: add symlink derefencing flags -H and -L

Diffstat:
chgrp.c | 12+++++++++---
chmod.c | 6+++---
chown.c | 12+++++++++---
libutil/recurse.c | 10++++++----
libutil/rm.c | 2+-
tar.c | 12++++++++----
util.h | 2+-
7 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/chgrp.c b/chgrp.c @@ -10,19 +10,20 @@ static int gid; static int status; static int rflag; +static char fflag = 'P'; static struct stat st; static char *chown_f_name = "chown"; static int (*chown_f)(const char *, uid_t, gid_t) = chown; static void -chgrp(const char *path) +chgrp(const char *path, char fflag) { if (chown_f(path, st.st_uid, gid) < 0) { weprintf("%s %s:", chown_f_name, path); status = 1; } if (rflag) - recurse(path, chgrp); + recurse(path, chgrp, fflag); } static void @@ -44,6 +45,11 @@ main(int argc, char *argv[]) case 'R': rflag = 1; break; + case 'H': + case 'L': + case 'P': + fflag = ARGC(); + break; default: usage(); } ARGEND; @@ -67,7 +73,7 @@ main(int argc, char *argv[]) status = 1; continue; } - chgrp(*argv); + chgrp(*argv, fflag); } return status; } diff --git a/chmod.c b/chmod.c @@ -9,7 +9,7 @@ static mode_t mask = 0; static int ret = 0; void -chmodr(const char *path) +chmodr(const char *path, char fflag) { struct stat st; mode_t m; @@ -26,7 +26,7 @@ chmodr(const char *path) ret = 1; } if (rflag) - recurse(path, chmodr); + recurse(path, chmodr, fflag); } static void @@ -65,7 +65,7 @@ done: usage(); for (++i; i < argc; i++) - chmodr(argv[i]); + chmodr(argv[i], 'P'); return ret; } diff --git a/chown.c b/chown.c @@ -9,6 +9,7 @@ #include "util.h" static int rflag = 0; +static int fflag = 'P'; static uid_t uid = -1; static gid_t gid = -1; static int ret = 0; @@ -16,14 +17,14 @@ static char *chown_f_name = "chown"; static int (*chown_f)(const char *, uid_t, gid_t) = chown; static void -chownpwgr(const char *path) +chownpwgr(const char *path, int fflag) { if (chown_f(path, uid, gid) < 0) { weprintf("%s %s:", chown_f_name, path); ret = 1; } if (rflag) - recurse(path, chownpwgr); + recurse(path, chownpwgr, fflag); } static void @@ -48,6 +49,11 @@ main(int argc, char *argv[]) case 'r': rflag = 1; break; + case 'H': + case 'L': + case 'P': + fflag = ARGC(); + break; default: usage(); } ARGEND; @@ -88,7 +94,7 @@ main(int argc, char *argv[]) } } for (; argc > 0; argc--, argv++) - chownpwgr(argv[0]); + chownpwgr(argv[0], fflag); return ret; } diff --git a/libutil/recurse.c b/libutil/recurse.c @@ -11,14 +11,16 @@ #include "../util.h" void -recurse(const char *path, void (*fn)(const char *)) +recurse(const char *path, void (*fn)(const char *, char), char follow) { char buf[PATH_MAX]; struct dirent *d; - struct stat st; + struct stat lst, st; DIR *dp; - if (lstat(path, &st) < 0 || !S_ISDIR(st.st_mode)) + if (lstat(path, &lst) < 0 || stat(path, &st) < 0 || + !(S_ISDIR(lst.st_mode) || + (follow != 'P' && S_ISLNK(lst.st_mode) && S_ISDIR(st.st_mode)))) return; if (!(dp = opendir(path))) @@ -35,7 +37,7 @@ recurse(const char *path, void (*fn)(const char *)) eprintf("path too long\n"); if (strlcat(buf, d->d_name, sizeof(buf)) >= sizeof(buf)) eprintf("path too long\n"); - fn(buf); + fn(buf, follow == 'H' ? 'P' : follow); } closedir(dp); diff --git a/libutil/rm.c b/libutil/rm.c @@ -12,7 +12,7 @@ void rm(const char *path) { if (rm_rflag) - recurse(path, rm); + recurse(path, rm, 'P'); if (remove(path) < 0) { if (!rm_fflag) weprintf("remove %s:", path); diff --git a/tar.c b/tar.c @@ -44,7 +44,7 @@ static void putoctal(char *, unsigned, int); static int archive(const char *); static int unarchive(char *, int, char[Blksiz]); static int print(char *, int , char[Blksiz]); -static void c(const char *); +static void c(const char *, char); static void xt(int (*)(char*, int, char[Blksiz])); static FILE *tarfile; @@ -52,6 +52,7 @@ static ino_t tarinode; static dev_t tardev; static int mflag; +static char fflag = 'P'; static char filtermode; static FILE * @@ -245,10 +246,10 @@ print(char * fname, int l, char b[Blksiz]) } static void -c(const char * path) +c(const char * path, char fflag) { archive(path); - recurse(path, c); + recurse(path, c, fflag); } static void @@ -304,6 +305,9 @@ main(int argc, char *argv[]) usage(); filtermode = ARGC(); break; + case 'h': + fflag = 'L'; + break; default: usage(); } ARGEND; @@ -325,7 +329,7 @@ main(int argc, char *argv[]) tarfile = stdout; } chdir(dir); - c(argv[0]); + c(argv[0], fflag); break; case 't': case 'x': diff --git a/util.h b/util.h @@ -60,7 +60,7 @@ mode_t getumask(void); char *humansize(double); mode_t parsemode(const char *, mode_t, mode_t); void putword(const char *); -void recurse(const char *, void (*)(const char *)); +void recurse(const char *, void (*)(const char *, char), char); #undef strtonum long long strtonum(const char *, long long, long long, const char **); long long enstrtonum(int, const char *, long long, long long);