ls: add support for -R flag

This commit is contained in:
Tai Chi Minh Ralph Eastwood 2015-02-21 10:45:15 +00:00 committed by sin
parent 9c30fbf018
commit dacd523ec1
2 changed files with 18 additions and 10 deletions

2
ls.1
View File

@ -42,6 +42,8 @@ links, owner, group, size, and last file status/modification time.
Append a file type indicator to directories. Append a file type indicator to directories.
.It Fl q .It Fl q
Replace non-printable characters in filenames with '?'. Replace non-printable characters in filenames with '?'.
.It Fl R
List directory content recursively.
.It Fl r .It Fl r
Reverse the sort order. Reverse the sort order.
.It Fl t .It Fl t

26
ls.c
View File

@ -36,6 +36,7 @@ static int Lflag = 0;
static int lflag = 0; static int lflag = 0;
static int pflag = 0; static int pflag = 0;
static int qflag = 0; static int qflag = 0;
static int Rflag = 0;
static int rflag = 0; static int rflag = 0;
static int tflag = 0; static int tflag = 0;
static int Uflag = 0; static int Uflag = 0;
@ -43,6 +44,8 @@ static int uflag = 0;
static int first = 1; static int first = 1;
static int many; static int many;
static void ls(const struct entry *ent, int recurse);
static void static void
mkent(struct entry *ent, char *path, int dostat, int follow) mkent(struct entry *ent, char *path, int dostat, int follow)
{ {
@ -197,12 +200,12 @@ lsdir(const char *path)
if (chdir(path) < 0) if (chdir(path) < 0)
eprintf("chdir %s:", path); eprintf("chdir %s:", path);
if (many) { if (many || Rflag) {
if (!first) if (!first)
putchar('\n'); putchar('\n');
printf("%s:\n", path); printf("%s:\n", path);
first = 0;
} }
first = 0;
while ((d = readdir(dp))) { while ((d = readdir(dp))) {
if (d->d_name[0] == '.' && !aflag && !Aflag) if (d->d_name[0] == '.' && !aflag && !Aflag)
@ -211,8 +214,8 @@ lsdir(const char *path)
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){ if (Uflag){
mkent(&ent, d->d_name, Fflag || lflag || pflag || iflag, Lflag); mkent(&ent, d->d_name, Fflag || lflag || pflag || iflag || Rflag, Lflag);
output(&ent); ls(&ent, Rflag);
} else { } else {
ents = erealloc(ents, ++n * sizeof(*ents)); ents = erealloc(ents, ++n * sizeof(*ents));
name = p = estrdup(d->d_name); name = p = estrdup(d->d_name);
@ -230,14 +233,14 @@ lsdir(const char *path)
} }
*p = '\0'; *p = '\0';
} }
mkent(&ents[n - 1], name, tflag || Fflag || iflag || lflag || pflag, Lflag); mkent(&ents[n - 1], name, tflag || 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);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
output(&ents[rflag ? (n - i - 1) : i]); ls(&ents[rflag ? (n - i - 1) : i], Rflag);
free(ents[rflag ? (n - i - 1) : i].name); free(ents[rflag ? (n - i - 1) : i].name);
} }
} }
@ -248,9 +251,9 @@ lsdir(const char *path)
} }
static void static void
ls(const struct entry *ent) ls(const struct entry *ent, int recurse)
{ {
if ((S_ISDIR(ent->mode) || (S_ISLNK(ent->mode) && if (recurse && (S_ISDIR(ent->mode) || (S_ISLNK(ent->mode) &&
S_ISDIR(ent->tmode) && !Fflag && !lflag)) && !dflag) S_ISDIR(ent->tmode) && !Fflag && !lflag)) && !dflag)
lsdir(ent->name); lsdir(ent->name);
else else
@ -260,7 +263,7 @@ ls(const struct entry *ent)
static void static void
usage(void) usage(void)
{ {
eprintf("usage: %s [-1AacdFHhiLlqrtUu] [file ...]\n", argv0); eprintf("usage: %s [-1AacdFHhiLlqRrtUu] [file ...]\n", argv0);
} }
int int
@ -310,6 +313,9 @@ main(int argc, char *argv[])
case 'q': case 'q':
qflag = 1; qflag = 1;
break; break;
case 'R':
Rflag = 1;
break;
case 'r': case 'r':
rflag = 1; rflag = 1;
break; break;
@ -337,7 +343,7 @@ main(int argc, char *argv[])
mkent(&ents[i], argv[i], 1, Hflag || Lflag); mkent(&ents[i], argv[i], 1, Hflag || Lflag);
qsort(ents, argc, sizeof(*ents), entcmp); qsort(ents, argc, sizeof(*ents), entcmp);
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
ls(&ents[rflag ? argc-i-1 : i]); ls(&ents[rflag ? argc-i-1 : i], 1);
return 0; return 0;
} }