sbase

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

commit 74b5aa151cf1fbf439b1aec60c0da4e1904ad1ef
parent 1905b83cc9c56b850f691d290f6f51e1f3a0d697
Author: Quentin Rameau <quinq@quinq.eu.org>
Date:   Fri, 12 Jun 2015 19:38:07 +0200

ls: correctly handle recursivity

the path is now carried through ls() and lsdir(), directory entries are
listed before recursing.

Diffstat:
Mls.c | 106++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 65 insertions(+), 41 deletions(-)

diff --git a/ls.c b/ls.c @@ -45,9 +45,8 @@ static int tflag = 0; static int Uflag = 0; static int uflag = 0; static int first = 1; -static int many; -static void ls(const struct entry *ent, int recurse); +static void ls(const char *, const struct entry *, int); static void mkent(struct entry *ent, char *path, int dostat, int follow) @@ -213,64 +212,87 @@ entcmp(const void *va, const void *vb) } static void -lsdir(const char *path) +lsdir(const char *path, const struct entry *dir) { DIR *dp; - struct entry ent, *ents = NULL; + struct entry *ent, *ents = NULL; struct dirent *d; size_t i, n = 0; - char cwd[PATH_MAX], *name; + char prefix[PATH_MAX]; - if (!getcwd(cwd, sizeof(cwd))) - eprintf("getcwd:"); - if (!(dp = opendir(path))) - eprintf("opendir %s:", path); - if (chdir(path) < 0) - eprintf("chdir %s:", path); - - if (many || Rflag) { - if (!first) - putchar('\n'); - printf("%s:\n", path); - } - first = 0; + if (!(dp = opendir(dir->name))) + eprintf("opendir %s:", dir->name); + if (chdir(dir->name) < 0) + eprintf("chdir %s:", dir->name); while ((d = readdir(dp))) { if (d->d_name[0] == '.' && !aflag && !Aflag) continue; else if (Aflag) - if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) + if (strcmp(d->d_name, ".") == 0 || + strcmp(d->d_name, "..") == 0) continue; - if (Uflag){ - mkent(&ent, d->d_name, Fflag || lflag || pflag || iflag || Rflag, Lflag); - ls(&ent, Rflag); - } else { - ents = ereallocarray(ents, ++n, sizeof(*ents)); - name = estrdup(d->d_name); - mkent(&ents[n - 1], name, tflag || Sflag || Fflag || iflag || lflag || pflag || Rflag, Lflag); - } + + ents = ereallocarray(ents, ++n, sizeof(*ents)); + mkent(&ents[n - 1], estrdup(d->d_name), Fflag || iflag || + lflag || pflag || Rflag || Sflag, Lflag); } + closedir(dp); - if (!Uflag){ + + if (!Uflag) qsort(ents, n, sizeof(*ents), entcmp); + + if (path[0] || dir->name[0] != '.') + printf("%s:\n", dir->name); + for (i = 0; i < n; i++) + output(&ents[rflag ? (n - 1 - i) : i]); + + if (Rflag) { + if (snprintf(prefix, PATH_MAX, "%s%s/", path, dir->name) >= + PATH_MAX) + eprintf("path too long: %s%s\n", path, dir->name); + for (i = 0; i < n; i++) { - ls(&ents[rflag ? (n - i - 1) : i], Rflag); - free(ents[rflag ? (n - i - 1) : i].name); + ent = &ents[rflag ? (n - 1 - i) : i]; + if (strcmp(ent->name, ".") == 0 || + strcmp(ent->name, "..") == 0) + continue; + if (S_ISLNK(ent->mode) && S_ISDIR(ent->tmode) && !Lflag) + continue; + + ls(prefix, ent, Rflag); } } - if (chdir(cwd) < 0) - eprintf("chdir %s:", cwd); + + for (i = 0; i < n; ++i) + free(ents[i].name); free(ents); } static void -ls(const struct entry *ent, int recurse) +ls(const char *path, const struct entry *ent, int listdir) { - if (recurse && (S_ISDIR(ent->mode) || (S_ISLNK(ent->mode) && - S_ISDIR(ent->tmode) && !Fflag && !lflag)) && !dflag) - lsdir(ent->name); - else + char cwd[PATH_MAX]; + + if (!listdir) { output(ent); + } else if (S_ISDIR(ent->mode) || + (S_ISLNK(ent->mode) && S_ISDIR(ent->tmode))) { + if (!getcwd(cwd, PATH_MAX)) + eprintf("getcwd:"); + + if (first) + first = !first; + else + putchar('\n'); + + printf("%s", path); + lsdir(path, ent); + + if (chdir(cwd) < 0) + eprintf("chdir %s:", cwd); + } } static void @@ -367,10 +389,12 @@ main(int argc, char *argv[]) case 1: ent = emalloc(sizeof(*ent)); mkent(ent, argv[0], 1, Hflag || Lflag); - ls(ent, 1); + ls("", ent, (!dflag && S_ISDIR(ent->mode)) || + ((S_ISLNK(ent->mode) && S_ISDIR(ent->tmode)) && + ((Hflag || Lflag) || !(dflag || Fflag || lflag)))); + break; default: - many = 1; for (i = ds = fs = 0, fents = dents = NULL; i < argc; ++i) { ent = emalloc(sizeof(*ent)); mkent(ent, argv[i], 1, Hflag || Lflag); @@ -390,11 +414,11 @@ main(int argc, char *argv[]) qsort(dents, ds, sizeof(ent), entcmp); for (i = 0; i < fs; ++i) - ls(fents[rflag ? (fs - i - 1) : i], 0); + ls("", fents[rflag ? (fs - i - 1) : i], 0); if (fs && ds) putchar('\n'); for (i = 0; i < ds; ++i) - ls(dents[rflag ? (ds - i - 1) : i], 1); + ls("", dents[rflag ? (ds - i - 1) : i], 1); } return fshut(stdout, "<stdout>");