sbase

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

commit 7b2465c101a5d02c0d669f6a3e855564879235cb
parent e14d9412f8397f5d27914386210f50a320e86fac
Author: FRIGN <dev@frign.de>
Date:   Sat Apr 18 22:04:49 +0200

Add maxdepth to recurse()

This also makes more sense.

Diffstat:
chgrp.c | 7++++---
chmod.c | 7++++---
chown.c | 7++++---
du.c | 3++-
fs.h | 18+++++++++---------
libutil/recurse.c | 44+++++++++++++++++++++++---------------------
libutil/rm.c | 2+-
mv.c | 3++-
rm.c | 5+++--
tar.c | 3++-
10 files changed, 54 insertions(+), 45 deletions(-)
diff --git a/chgrp.c b/chgrp.c @@ -29,7 +29,7 @@ chgrp(const char *path, struct stat *st, void *data, struct recursor *r) if (st && chownf(path, st->st_uid, gid) < 0) { weprintf("%s %s:", chownf_name, path); ret = 1; - } else if (!(r->flags & NODIRS) && st && S_ISDIR(st->st_mode)) { + } else if (st && S_ISDIR(st->st_mode)) { recurse(path, NULL, r); } } @@ -44,14 +44,15 @@ int main(int argc, char *argv[]) { struct group *gr; - struct recursor r = { .fn = chgrp, .hist = NULL, .depth = 0, .follow = 'P', .flags = NODIRS }; + struct recursor r = { .fn = chgrp, .hist = NULL, .depth = 0, .maxdepth = 1, + .follow = 'P', .flags = 0 }; ARGBEGIN { case 'h': hflag = 1; break; case 'R': - r.flags &= ~NODIRS; + r.maxdepth = 0; break; case 'H': case 'L': diff --git a/chmod.c b/chmod.c @@ -17,7 +17,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r) if (chmod(path, m) < 0) { weprintf("chmod %s:", path); ret = 1; - } else if (!(r->flags & NODIRS) && st && S_ISDIR(st->st_mode)) { + } else if (st && S_ISDIR(st->st_mode)) { recurse(path, NULL, r); } } @@ -31,7 +31,8 @@ usage(void) int main(int argc, char *argv[]) { - struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .follow = 'P', .flags = NODIRS}; + struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .maxdepth = 1, + .follow = 'P', .flags = 0 }; size_t i; argv0 = argv[0], argc--, argv++; @@ -42,7 +43,7 @@ main(int argc, char *argv[]) for (i = 1; (*argv)[i]; i++) { switch ((*argv)[i]) { case 'R': - r.flags &= ~NODIRS; + r.maxdepth = 0; break; case 'H': case 'L': diff --git a/chown.c b/chown.c @@ -32,7 +32,7 @@ chownpwgr(const char *path, struct stat *st, void *data, struct recursor *r) if (chownf(path, uid, gid) < 0) { weprintf("%s %s:", chownf_name, path); ret = 1; - } else if (!(r->flags & NODIRS) && st && S_ISDIR(st->st_mode)) { + } else if (st && S_ISDIR(st->st_mode)) { recurse(path, NULL, r); } } @@ -48,7 +48,8 @@ main(int argc, char *argv[]) { struct group *gr; struct passwd *pw; - struct recursor r = { .fn = chownpwgr, .hist = NULL, .depth = 0, .follow = 'P', .flags = NODIRS}; + struct recursor r = { .fn = chownpwgr, .hist = NULL, .depth = 0, .maxdepth = 1, + .follow = 'P', .flags = 0 }; char *owner, *group; ARGBEGIN { @@ -57,7 +58,7 @@ main(int argc, char *argv[]) break; case 'r': case 'R': - r.flags &= ~NODIRS; + r.maxdepth = 0; break; case 'H': case 'L': diff --git a/du.c b/du.c @@ -55,7 +55,8 @@ usage(void) int main(int argc, char *argv[]) { - struct recursor r = { .fn = du, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0}; + struct recursor r = { .fn = du, .hist = NULL, .depth = 0, .maxdepth = 0, + .follow = 'P', .flags = 0 }; size_t n = 0; int kflag = 0, dflag = 0; char *bsize; diff --git a/fs.h b/fs.h @@ -3,23 +3,23 @@ #include <sys/types.h> struct history { - struct history *prev; - dev_t dev; - ino_t ino; + struct history *prev; + dev_t dev; + ino_t ino; }; struct recursor { - void (*fn)(const char *, struct stat *st, void *, struct recursor *); - struct history *hist; - int depth; - int follow; - int flags; + void (*fn)(const char *, struct stat *st, void *, struct recursor *); + struct history *hist; + int depth; + int maxdepth; + int follow; + int flags; }; enum { SAMEDEV = 1 << 0, DIRFIRST = 1 << 1, - NODIRS = 1 << 2, }; extern int cp_aflag; diff --git a/libutil/recurse.c b/libutil/recurse.c @@ -37,7 +37,7 @@ recurse(const char *path, void *data, struct recursor *r) recurse_status = 1; return; } - if (!S_ISDIR(st.st_mode) || (S_ISDIR(st.st_mode) && (r->flags & NODIRS))) { + if (!S_ISDIR(st.st_mode)) { (r->fn)(path, &st, data, r); return; } @@ -61,26 +61,28 @@ recurse(const char *path, void *data, struct recursor *r) if (!r->depth && (r->flags & DIRFIRST)) (r->fn)(path, &st, data, r); - while ((d = readdir(dp))) { - if (r->follow == 'H') { - statf_name = "lstat"; - statf = lstat; - } - 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) { - weprintf("%s %s:", statf_name, subpath); - recurse_status = 1; - } else if ((r->flags & SAMEDEV) && dst.st_dev != st.st_dev) { - continue; - } else { - r->depth++; - (r->fn)(subpath, &dst, data, r); - r->depth--; + if (!r->maxdepth || r->depth + 1 < r->maxdepth) { + while ((d = readdir(dp))) { + if (r->follow == 'H') { + statf_name = "lstat"; + statf = lstat; + } + 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) { + weprintf("%s %s:", statf_name, subpath); + recurse_status = 1; + } else if ((r->flags & SAMEDEV) && dst.st_dev != st.st_dev) { + continue; + } else { + r->depth++; + (r->fn)(subpath, &dst, data, r); + r->depth--; + } } } diff --git a/libutil/rm.c b/libutil/rm.c @@ -14,7 +14,7 @@ int rm_status = 0; void rm(const char *path, struct stat *st, void *data, struct recursor *r) { - if (!(r->flags & NODIRS) && st && S_ISDIR(st->st_mode)) { + if (!r->maxdepth && st && S_ISDIR(st->st_mode)) { recurse(path, NULL, r); if (rmdir(path) < 0) { diff --git a/mv.c b/mv.c @@ -12,7 +12,8 @@ static int mv_status = 0; static int mv(const char *s1, const char *s2, int depth) { - struct recursor r = { .fn = rm, .hist = NULL, .depth = 0, .follow = 'P', .flags = 0}; + struct recursor r = { .fn = rm, .hist = NULL, .depth = 0, .maxdepth = 0, + .follow = 'P', .flags = 0 }; if (!rename(s1, s2)) return (mv_status = 0); diff --git a/rm.c b/rm.c @@ -11,7 +11,8 @@ usage(void) int main(int argc, char *argv[]) { - struct recursor r = { .fn = rm, .hist = NULL, .depth = 0, .follow = 'P', .flags = NODIRS }; + struct recursor r = { .fn = rm, .hist = NULL, .depth = 0, .maxdepth = 1, + .follow = 'P', .flags = 0 }; ARGBEGIN { case 'f': @@ -19,7 +20,7 @@ main(int argc, char *argv[]) break; case 'R': case 'r': - r.flags &= ~NODIRS; + r.maxdepth = 0; break; default: usage(); diff --git a/tar.c b/tar.c @@ -315,7 +315,8 @@ int main(int argc, char *argv[]) { FILE *fp; - struct recursor r = { .fn = c, .hist = NULL, .depth = 0, .follow = 'P', .flags = DIRFIRST}; + struct recursor r = { .fn = c, .hist = NULL, .depth = 0, .maxdepth = 0, + .follow = 'P', .flags = DIRFIRST }; struct stat st; char *file = NULL, *dir = ".", mode = '\0';