[hackers] [sbase] Refactor enmasse() and recurse() to reflect depth || FRIGN

From: <git_AT_suckless.org>
Date: Tue, 3 Mar 2015 14:32:27 +0100 (CET)

commit 3b619cbc4b85aaa060acb0de3d7d6dc5b2c34f49
Author: FRIGN <dev_AT_frign.de>
Date: Mon Mar 2 21:43:56 2015 +0100

    Refactor enmasse() and recurse() to reflect depth
    
    The HLP-changes to sbase have been a great addition of functionality,
    but they kind of "polluted" the enmasse() and recurse() prototypes.
    As this will come in handy in the future, knowing at which "depth"
    you are inside a recursing function is an important functionality.
    
    Instead of having a special HLP-flag passed to enmasse, each sub-
    function needs to provide it on its own and can calculate results
    based on the current depth (for instance, 'H' implies 'P' at
    depth > 0).
    A special case is recurse(), because it actually depends on the
    follow-type. A new flag "recurse_follow" brings consistency into
    what used to be spread across different naming conventions (fflag,
    HLP_flag, ...).
    
    This also fixes numerous bugs with the behaviour of HLP in the
    tools using it.

diff --git a/chgrp.c b/chgrp.c
index 0d55ce8..0ca2466 100644
--- a/chgrp.c
+++ b/chgrp.c
_AT_@ -10,20 +10,19 @@
 static int gid;
 static int status;
 static int Rflag;
-static int fflag = 'P';
 static struct stat st;
-static char *chown_f_name = "chown";
-static int (*chown_f)(const char *, uid_t, gid_t) = chown;
+static char *chownf_name = "chown";
+static int (*chownf)(const char *, uid_t, gid_t) = chown;
 
 static void
-chgrp(const char *path, int fflag)
+chgrp(const char *path, int depth)
 {
- if (chown_f(path, st.st_uid, gid) < 0) {
- weprintf("%s %s:", chown_f_name, path);
+ if (chownf(path, st.st_uid, gid) < 0) {
+ weprintf("%s %s:", chownf_name, path);
                 status = 1;
         }
         if (Rflag)
- recurse(path, chgrp, fflag);
+ recurse(path, chgrp, depth);
 }
 
 static void
_AT_@ -39,8 +38,8 @@ main(int argc, char *argv[])
 
         ARGBEGIN {
         case 'h':
- chown_f_name = "lchown";
- chown_f = lchown;
+ chownf_name = "lchown";
+ chownf = lchown;
                 break;
         case 'R':
                 Rflag = 1;
_AT_@ -48,14 +47,18 @@ main(int argc, char *argv[])
         case 'H':
         case 'L':
         case 'P':
- fflag = ARGC();
+ recurse_follow = ARGC();
                 break;
         default:
                 usage();
         } ARGEND;
 
- if (argc < 2 || (chown_f == lchown && Rflag))
+ if (argc < 2)
                 usage();
+ if (recurse_follow == 'P') {
+ chownf_name = "lchown";
+ chownf = lchown;
+ }
 
         errno = 0;
         gr = getgrnam(argv[0]);
_AT_@ -73,7 +76,7 @@ main(int argc, char *argv[])
                         status = 1;
                         continue;
                 }
- chgrp(*argv, fflag);
+ chgrp(*argv, 0);
         }
         return status;
 }
diff --git a/chmod.c b/chmod.c
index ac94a53..a29b04a 100644
--- a/chmod.c
+++ b/chmod.c
_AT_@ -4,13 +4,12 @@
 #include "util.h"
 
 static int Rflag = 0;
-static int fflag = 'P';
 static char *modestr = "";
 static mode_t mask = 0;
 static int ret = 0;
 
 void
-chmodr(const char *path, int fflag)
+chmodr(const char *path, int depth)
 {
         struct stat st;
         mode_t m;
_AT_@ -27,7 +26,7 @@ chmodr(const char *path, int fflag)
                 ret = 1;
         }
         if (Rflag)
- recurse(path, chmodr, fflag);
+ recurse(path, chmodr, depth);
 }
 
 static void
_AT_@ -50,7 +49,7 @@ main(int argc, char *argv[])
                 case 'H':
                 case 'L':
                 case 'P':
- fflag = argv[i][1];
+ recurse_follow = argv[i][1];
                         break;
                 case 'r': case 'w': case 'x': case 's': case 't':
                         /*
_AT_@ -71,7 +70,7 @@ done:
                 usage();
 
         for (++i; i < argc; i++)
- chmodr(argv[i], fflag);
+ chmodr(argv[i], 0);
 
         return ret;
 }
diff --git a/chown.c b/chown.c
index 332cb62..cd76f9c 100644
--- a/chown.c
+++ b/chown.c
_AT_@ -9,22 +9,21 @@
 #include "util.h"
 
 static int rflag = 0;
-static int HLPflag = 'P';
 static uid_t uid = -1;
 static gid_t gid = -1;
 static int ret = 0;
-static char *chown_f_name = "chown";
-static int (*chown_f)(const char *, uid_t, gid_t) = chown;
+static char *chownf_name = "chown";
+static int (*chownf)(const char *, uid_t, gid_t) = chown;
 
 static void
-chownpwgr(const char *path, int HLPflag)
+chownpwgr(const char *path, int depth)
 {
- if (chown_f(path, uid, gid) < 0) {
- weprintf("%s %s:", chown_f_name, path);
+ if (chownf(path, uid, gid) < 0) {
+ weprintf("%s %s:", chownf_name, path);
                 ret = 1;
         }
         if (rflag)
- recurse(path, chownpwgr, HLPflag);
+ recurse(path, chownpwgr, depth);
 }
 
 static void
_AT_@ -42,8 +41,8 @@ main(int argc, char *argv[])
 
         ARGBEGIN {
         case 'h':
- chown_f_name = "lchown";
- chown_f = lchown;
+ chownf_name = "lchown";
+ chownf = lchown;
                 break;
         case 'r':
         case 'R':
_AT_@ -52,7 +51,7 @@ main(int argc, char *argv[])
         case 'H':
         case 'L':
         case 'P':
- HLPflag = ARGC();
+ recurse_follow = ARGC();
                 break;
         default:
                 usage();
_AT_@ -60,6 +59,10 @@ main(int argc, char *argv[])
 
         if (argc == 0)
                 usage();
+ if (recurse_follow == 'P') {
+ chownf_name = "lchown";
+ chownf = lchown;
+ }
 
         owner = argv[0];
         argv++;
_AT_@ -94,7 +97,7 @@ main(int argc, char *argv[])
                 }
         }
         for (; argc > 0; argc--, argv++)
- chownpwgr(argv[0], HLPflag);
+ chownpwgr(argv[0], 0);
 
         return ret;
 }
diff --git a/cp.c b/cp.c
index cc976d1..4bba1b5 100644
--- a/cp.c
+++ b/cp.c
_AT_@ -51,7 +51,7 @@ main(int argc, char *argv[])
                 if (!S_ISDIR(st.st_mode))
                         eprintf("%s: not a directory\n", argv[argc - 1]);
         }
- enmasse(argc, argv, cp, cp_HLPflag);
+ enmasse(argc, argv, cp);
 
         return cp_status;
 }
diff --git a/fs.h b/fs.h
index 7c59515..53cc39a 100644
--- a/fs.h
+++ b/fs.h
_AT_@ -11,5 +11,5 @@ extern int rm_fflag;
 extern int rm_rflag;
 extern int rm_status;
 
-int cp(const char *, const char *, char);
+int cp(const char *, const char *, int);
 void rm(const char *, int);
diff --git a/libutil/cp.c b/libutil/cp.c
index 9145590..e58716e 100644
--- a/libutil/cp.c
+++ b/libutil/cp.c
_AT_@ -24,7 +24,7 @@ int cp_status = 0;
 int cp_HLPflag = 'L';
 
 int
-cp(const char *s1, const char *s2, char ff)
+cp(const char *s1, const char *s2, int depth)
 {
         FILE *f1, *f2;
         char *ns1, *ns2;
_AT_@ -39,9 +39,11 @@ cp(const char *s1, const char *s2, char ff)
         if (cp_vflag)
                 printf("'%s' -> '%s'\n", s1, s2);
 
- r = ff == 'P' ? lstat(s1, &st) : stat(s1, &st);
+ r = (cp_HLPflag == 'P' || (cp_HLPflag == 'H' && depth > 0)) ?
+ lstat(s1, &st) : stat(s1, &st);
         if (r < 0) {
- weprintf("%s %s:", ff == 'P' ? "lstat" : "stat", s1);
+ weprintf("%s %s:", (cp_HLPflag == 'P' ||
+ (cp_HLPflag == 'H' && depth > 0)) ? "lstat" : "stat", s1);
                 cp_status = 1;
                 return 0;
         }
_AT_@ -83,7 +85,7 @@ cp(const char *s1, const char *s2, char ff)
                                         eprintf("%s/%s: filename too long\n",
                                                 s2, d->d_name);
                                 }
- fnck(ns1, ns2, cp, ff == 'H' ? 'P' : ff);
+ fnck(ns1, ns2, cp, depth + 1);
                         }
                 }
                 closedir(dp);
diff --git a/libutil/enmasse.c b/libutil/enmasse.c
index 6281b79..24af279 100644
--- a/libutil/enmasse.c
+++ b/libutil/enmasse.c
_AT_@ -9,7 +9,7 @@
 #include "../util.h"
 
 void
-enmasse(int argc, char *argv[], int (*fn)(const char *, const char *, char), char ff)
+enmasse(int argc, char *argv[], int (*fn)(const char *, const char *, int))
 {
         char *buf, *dir;
         int i, len;
_AT_@ -18,7 +18,7 @@ enmasse(int argc, char *argv[], int (*fn)(const char *, const char *, char), cha
         size_t dlen;
 
         if (argc == 2 && !(stat(argv[1], &st) == 0 && S_ISDIR(st.st_mode))) {
- fnck(argv[0], argv[1], fn, ff);
+ fnck(argv[0], argv[1], fn, 0);
                 return;
         } else {
                 dir = (argc == 1) ? "." : argv[--argc];
_AT_@ -35,7 +35,7 @@ enmasse(int argc, char *argv[], int (*fn)(const char *, const char *, char), cha
                         eprintf("%s/%s: filename too long\n", dir,
                                 basename(argv[i]));
                 }
- fnck(argv[i], buf, fn, ff);
+ fnck(argv[i], buf, fn, 0);
         }
         free(buf);
 }
diff --git a/libutil/fnck.c b/libutil/fnck.c
index 8afc4b1..92da1f4 100644
--- a/libutil/fnck.c
+++ b/libutil/fnck.c
_AT_@ -5,7 +5,7 @@
 
 void
 fnck(const char *a, const char *b,
- int (*fn)(const char *, const char *, char), char ff)
+ int (*fn)(const char *, const char *, int), int depth)
 {
         struct stat sta, stb;
 
_AT_@ -16,6 +16,6 @@ fnck(const char *a, const char *b,
                 eprintf("%s -> %s: same file\n", a, b);
         }
 
- if (fn(a, b, ff) < 0)
+ if (fn(a, b, depth) < 0)
                 eprintf("%s -> %s:", a, b);
 }
diff --git a/libutil/recurse.c b/libutil/recurse.c
index e4ab2e0..f30f160 100644
--- a/libutil/recurse.c
+++ b/libutil/recurse.c
_AT_@ -10,25 +10,29 @@
 
 #include "../util.h"
 
+int recurse_follow = 'P';
+
 void
-recurse(const char *path, void (*fn)(const char *, int), int follow)
+recurse(const char *path, void (*fn)(const char *, int), int depth)
 {
         char buf[PATH_MAX];
         struct dirent *d;
         struct stat lst, st;
         DIR *dp;
 
- 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))))
+ if (lstat(path, &lst) < 0)
+ eprintf("lstat %s:", path);
+ if (stat(path, &st) < 0)
+ eprintf("stat %s:", path);
+ if (!S_ISDIR(lst.st_mode) && !(S_ISLNK(lst.st_mode) && S_ISDIR(st.st_mode) &&
+ !(recurse_follow == 'P' || (recurse_follow == 'H' && depth > 0))))
                 return;
 
         if (!(dp = opendir(path)))
                 eprintf("opendir %s:", path);
 
         while ((d = readdir(dp))) {
- if (strcmp(d->d_name, ".") == 0 ||
- strcmp(d->d_name, "..") == 0)
+ if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
                         continue;
                 if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf))
                         eprintf("path too long\n");
_AT_@ -37,7 +41,7 @@ recurse(const char *path, void (*fn)(const char *, int), int follow)
                                 eprintf("path too long\n");
                 if (strlcat(buf, d->d_name, sizeof(buf)) >= sizeof(buf))
                         eprintf("path too long\n");
- fn(buf, follow == 'H' ? 'P' : follow);
+ fn(buf, depth + 1);
         }
 
         closedir(dp);
diff --git a/libutil/rm.c b/libutil/rm.c
index 45e972c..60c97c1 100644
--- a/libutil/rm.c
+++ b/libutil/rm.c
_AT_@ -10,10 +10,10 @@ int rm_rflag = 0;
 int rm_status = 0;
 
 void
-rm(const char *path, int flag)
+rm(const char *path, int depth)
 {
         if (rm_rflag)
- recurse(path, rm, 'P');
+ recurse(path, rm, depth);
         if (remove(path) < 0) {
                 if (!rm_fflag)
                         weprintf("remove %s:", path);
diff --git a/mv.c b/mv.c
index 7481597..b46981c 100644
--- a/mv.c
+++ b/mv.c
_AT_@ -10,14 +10,15 @@
 static int mv_status = 0;
 
 static int
-mv(const char *s1, const char *s2, char ff)
+mv(const char *s1, const char *s2, int depth)
 {
         if (rename(s1, s2) == 0)
                 return (mv_status = 0);
         if (errno == EXDEV) {
                 cp_aflag = cp_rflag = cp_pflag = 1;
+ cp_HLPflag = 'P';
                 rm_rflag = 1;
- cp(s1, s2, ff);
+ cp(s1, s2, depth);
                 rm(s1, 0);
                 return (mv_status = cp_status || rm_status);
         }
_AT_@ -48,7 +49,7 @@ main(int argc, char *argv[])
 
         if (argc > 3 && !(stat(argv[argc-1], &st) == 0 && S_ISDIR(st.st_mode)))
                 eprintf("%s: not a directory\n", argv[argc-1]);
- enmasse(argc, &argv[0], mv, 'P');
+ enmasse(argc, argv, mv);
 
         return mv_status;
 }
diff --git a/tar.c b/tar.c
index 2057005..bdf34b8 100644
--- a/tar.c
+++ b/tar.c
_AT_@ -42,7 +42,6 @@ static ino_t tarinode;
 static dev_t tardev;
 
 static int mflag;
-static int fflag = 'P';
 static char filtermode;
 
 static FILE *
_AT_@ -234,14 +233,14 @@ print(char * fname, int l, char b[BLKSIZ])
 }
 
 static void
-c(const char * path, int fflag)
+c(const char *path, int depth)
 {
         archive(path);
- recurse(path, c, fflag);
+ recurse(path, c, depth);
 }
 
 static void
-xt(int (*fn)(char*, int, char[BLKSIZ]))
+xt(int (*fn)(char *, int, char[BLKSIZ]))
 {
         char b[BLKSIZ], fname[257], *s;
         struct header *h = (void*)b;
_AT_@ -293,7 +292,7 @@ main(int argc, char *argv[])
                 filtermode = ARGC();
                 break;
         case 'h':
- fflag = 'L';
+ recurse_follow = 'L';
                 break;
         default:
                 usage();
_AT_@ -316,7 +315,7 @@ main(int argc, char *argv[])
                         tarfile = stdout;
                 }
                 chdir(dir);
- c(argv[0], fflag);
+ c(argv[0], 0);
                 break;
         case 't':
         case 'x':
diff --git a/util.h b/util.h
index a107a07..2fec2d9 100644
--- a/util.h
+++ b/util.h
_AT_@ -56,12 +56,13 @@ int enregcomp(int, regex_t *, const char *, int);
 int eregcomp(regex_t *, const char *, int);
 
 /* misc */
-void enmasse(int, char **, int (*)(const char *, const char *, char), char);
-void fnck(const char *, const char *, int (*)(const char *, const char *, char), char);
+void enmasse(int, char **, int (*)(const char *, const char *, int));
+void fnck(const char *, const char *, int (*)(const char *, const char *, int), int);
 mode_t getumask(void);
 char *humansize(double);
 mode_t parsemode(const char *, mode_t, mode_t);
 void putword(const char *);
+extern int recurse_follow;
 void recurse(const char *, void (*)(const char *, int), int);
 #undef strtonum
 long long strtonum(const char *, long long, long long, const char **);
Received on Tue Mar 03 2015 - 14:32:27 CET

This archive was generated by hypermail 2.3.0 : Tue Mar 03 2015 - 14:36:33 CET