ls: correctly handle recursivity
the path is now carried through ls() and lsdir(), directory entries are listed before recursing.
This commit is contained in:
parent
1905b83cc9
commit
74b5aa151c
106
ls.c
106
ls.c
|
@ -45,9 +45,8 @@ static int tflag = 0;
|
||||||
static int Uflag = 0;
|
static int Uflag = 0;
|
||||||
static int uflag = 0;
|
static int uflag = 0;
|
||||||
static int first = 1;
|
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
|
static void
|
||||||
mkent(struct entry *ent, char *path, int dostat, int follow)
|
mkent(struct entry *ent, char *path, int dostat, int follow)
|
||||||
|
@ -213,64 +212,87 @@ entcmp(const void *va, const void *vb)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lsdir(const char *path)
|
lsdir(const char *path, const struct entry *dir)
|
||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
struct entry ent, *ents = NULL;
|
struct entry *ent, *ents = NULL;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
size_t i, n = 0;
|
size_t i, n = 0;
|
||||||
char cwd[PATH_MAX], *name;
|
char prefix[PATH_MAX];
|
||||||
|
|
||||||
if (!getcwd(cwd, sizeof(cwd)))
|
if (!(dp = opendir(dir->name)))
|
||||||
eprintf("getcwd:");
|
eprintf("opendir %s:", dir->name);
|
||||||
if (!(dp = opendir(path)))
|
if (chdir(dir->name) < 0)
|
||||||
eprintf("opendir %s:", path);
|
eprintf("chdir %s:", dir->name);
|
||||||
if (chdir(path) < 0)
|
|
||||||
eprintf("chdir %s:", path);
|
|
||||||
|
|
||||||
if (many || Rflag) {
|
|
||||||
if (!first)
|
|
||||||
putchar('\n');
|
|
||||||
printf("%s:\n", path);
|
|
||||||
}
|
|
||||||
first = 0;
|
|
||||||
|
|
||||||
while ((d = readdir(dp))) {
|
while ((d = readdir(dp))) {
|
||||||
if (d->d_name[0] == '.' && !aflag && !Aflag)
|
if (d->d_name[0] == '.' && !aflag && !Aflag)
|
||||||
continue;
|
continue;
|
||||||
else if (Aflag)
|
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;
|
continue;
|
||||||
if (Uflag){
|
|
||||||
mkent(&ent, d->d_name, Fflag || lflag || pflag || iflag || Rflag, Lflag);
|
ents = ereallocarray(ents, ++n, sizeof(*ents));
|
||||||
ls(&ent, Rflag);
|
mkent(&ents[n - 1], estrdup(d->d_name), Fflag || iflag ||
|
||||||
} else {
|
lflag || pflag || Rflag || Sflag, Lflag);
|
||||||
ents = ereallocarray(ents, ++n, sizeof(*ents));
|
|
||||||
name = estrdup(d->d_name);
|
|
||||||
mkent(&ents[n - 1], name, tflag || Sflag || Fflag || iflag || lflag || pflag || Rflag, Lflag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dp);
|
closedir(dp);
|
||||||
if (!Uflag){
|
|
||||||
|
if (!Uflag)
|
||||||
qsort(ents, n, sizeof(*ents), entcmp);
|
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++) {
|
for (i = 0; i < n; i++) {
|
||||||
ls(&ents[rflag ? (n - i - 1) : i], Rflag);
|
ent = &ents[rflag ? (n - 1 - i) : i];
|
||||||
free(ents[rflag ? (n - i - 1) : i].name);
|
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);
|
free(ents);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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) &&
|
char cwd[PATH_MAX];
|
||||||
S_ISDIR(ent->tmode) && !Fflag && !lflag)) && !dflag)
|
|
||||||
lsdir(ent->name);
|
if (!listdir) {
|
||||||
else
|
|
||||||
output(ent);
|
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
|
static void
|
||||||
|
@ -367,10 +389,12 @@ main(int argc, char *argv[])
|
||||||
case 1:
|
case 1:
|
||||||
ent = emalloc(sizeof(*ent));
|
ent = emalloc(sizeof(*ent));
|
||||||
mkent(ent, argv[0], 1, Hflag || Lflag);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
many = 1;
|
|
||||||
for (i = ds = fs = 0, fents = dents = NULL; i < argc; ++i) {
|
for (i = ds = fs = 0, fents = dents = NULL; i < argc; ++i) {
|
||||||
ent = emalloc(sizeof(*ent));
|
ent = emalloc(sizeof(*ent));
|
||||||
mkent(ent, argv[i], 1, Hflag || Lflag);
|
mkent(ent, argv[i], 1, Hflag || Lflag);
|
||||||
|
@ -390,11 +414,11 @@ main(int argc, char *argv[])
|
||||||
qsort(dents, ds, sizeof(ent), entcmp);
|
qsort(dents, ds, sizeof(ent), entcmp);
|
||||||
|
|
||||||
for (i = 0; i < fs; ++i)
|
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)
|
if (fs && ds)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
for (i = 0; i < ds; ++i)
|
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>");
|
return fshut(stdout, "<stdout>");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user