Mercurial > hg > toybox
comparison toys/ls.c @ 459:1dbe91079950
Second drop of ls from Andre, adds -l.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 13 Feb 2012 21:27:50 -0600 |
parents | 9786a697d5aa |
children | d10b58563cff |
comparison
equal
deleted
inserted
replaced
458:9786a697d5aa | 459:1dbe91079950 |
---|---|
2 * | 2 * |
3 * ls.c - list files | 3 * ls.c - list files |
4 * | 4 * |
5 * Copyright 2012 Andre Renaud <andre@bluewatersys.com> | 5 * Copyright 2012 Andre Renaud <andre@bluewatersys.com> |
6 * | 6 * |
7 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.htm | 7 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html |
8 | 8 |
9 USE_LS(NEWTOY(ls, "F1a", TOYFLAG_USR|TOYFLAG_BIN)) | 9 USE_LS(NEWTOY(ls, "lF1a", TOYFLAG_BIN)) |
10 | 10 |
11 config LS | 11 config LS |
12 bool "ls" | 12 bool "ls" |
13 default y | 13 default y |
14 help | 14 help |
15 usage: ls [-F] [-a] [-1] [directory...] | 15 usage: ls [-l] [-F] [-a] [-1] [directory...] |
16 list files | 16 list files |
17 | 17 |
18 -F append a character as a file type indicator | 18 -F append a character as a file type indicator |
19 -a list all files | 19 -a list all files |
20 -1 list one file per line | 20 -1 list one file per line |
21 -l show full details for each file | |
21 */ | 22 */ |
22 | 23 |
23 #include "toys.h" | 24 #include "toys.h" |
24 | 25 |
25 #define FLAG_a 1 | 26 #define FLAG_a 1 |
26 #define FLAG_1 2 | 27 #define FLAG_1 2 |
27 #define FLAG_F 4 | 28 #define FLAG_F 4 |
29 #define FLAG_l 8 | |
28 | 30 |
29 static int dir_filter(const struct dirent *d) | 31 static int dir_filter(const struct dirent *d) |
30 { | 32 { |
31 /* Skip over the . & .. entries unless -a is given */ | 33 /* Skip over the . & .. entries unless -a is given */ |
32 if (!(toys.optflags & FLAG_a)) | 34 if (!(toys.optflags & FLAG_a)) |
39 { | 41 { |
40 struct dirent **entries; | 42 struct dirent **entries; |
41 int nentries; | 43 int nentries; |
42 int i; | 44 int i; |
43 int maxwidth = -1; | 45 int maxwidth = -1; |
44 int ncolumns; | 46 int ncolumns = 1; |
45 | 47 |
46 if (strcmp(name, "-") == 0) | 48 if (!name || strcmp(name, "-") == 0) |
47 name = "."; | 49 name = "."; |
48 | 50 |
51 /* Get all the files in this directory */ | |
49 nentries = scandir(name, &entries, dir_filter, alphasort); | 52 nentries = scandir(name, &entries, dir_filter, alphasort); |
50 if (nentries < 0) | 53 if (nentries < 0) |
51 perror_exit("ls: cannot access %s'", name); | 54 perror_exit("ls: cannot access %s'", name); |
52 | 55 |
53 | 56 |
69 if (toys.optflags & FLAG_F) | 72 if (toys.optflags & FLAG_F) |
70 maxwidth++; | 73 maxwidth++; |
71 | 74 |
72 columns_str = getenv("COLUMNS"); | 75 columns_str = getenv("COLUMNS"); |
73 columns = columns_str ? atoi(columns_str) : 80; | 76 columns = columns_str ? atoi(columns_str) : 80; |
74 ncolumns = columns / maxwidth; | 77 ncolumns = maxwidth ? columns / maxwidth : 1; |
75 } | 78 } |
76 | 79 |
77 for (i = 0; i < nentries; i++) { | 80 for (i = 0; i < nentries; i++) { |
78 struct dirent *ent = entries[i]; | 81 struct dirent *ent = entries[i]; |
79 int len = strlen(ent->d_name); | 82 int len = strlen(ent->d_name); |
83 struct stat st; | |
84 int stat_valid = 0; | |
80 | 85 |
81 printf("%s", ent->d_name); | 86 /* Provide the ls -l long output */ |
87 if (toys.optflags & FLAG_l) { | |
88 char type; | |
89 char timestamp[64]; | |
90 struct tm mtime; | |
91 | |
92 if (lstat(ent->d_name, &st)) | |
93 perror_exit("Can't stat %s", ent->d_name); | |
94 stat_valid = 1; | |
95 if (S_ISDIR(st.st_mode)) | |
96 type = 'd'; | |
97 else if (S_ISCHR(st.st_mode)) | |
98 type = 'c'; | |
99 else if (S_ISBLK(st.st_mode)) | |
100 type = 'b'; | |
101 else if (S_ISLNK(st.st_mode)) | |
102 type = 'l'; | |
103 else | |
104 type = '-'; | |
105 | |
106 xprintf("%c%c%c%c%c%c%c%c%c%c ", type, | |
107 (st.st_mode & S_IRUSR) ? 'r' : '-', | |
108 (st.st_mode & S_IWUSR) ? 'w' : '-', | |
109 (st.st_mode & S_IXUSR) ? 'x' : '-', | |
110 (st.st_mode & S_IRGRP) ? 'r' : '-', | |
111 (st.st_mode & S_IWGRP) ? 'w' : '-', | |
112 (st.st_mode & S_IXGRP) ? 'x' : '-', | |
113 (st.st_mode & S_IROTH) ? 'r' : '-', | |
114 (st.st_mode & S_IWOTH) ? 'w' : '-', | |
115 (st.st_mode & S_IXOTH) ? 'x' : '-'); | |
116 | |
117 xprintf("%2d ", st.st_nlink); | |
118 /* FIXME: We're never looking up uid/gid numbers */ | |
119 xprintf("%4d ", st.st_uid); | |
120 xprintf("%4d ", st.st_gid); | |
121 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) | |
122 xprintf("%3d, %3d ", major(st.st_rdev), minor(st.st_rdev)); | |
123 else | |
124 xprintf("%8ld ", st.st_size); | |
125 | |
126 localtime_r(&st.st_mtime, &mtime); | |
127 | |
128 strftime(timestamp, sizeof(timestamp), "%b %e %H:%M", &mtime); | |
129 xprintf("%s ", timestamp); | |
130 } | |
131 | |
132 xprintf("%s", ent->d_name); | |
133 | |
134 /* Append the file-type indicator character */ | |
82 if (toys.optflags & FLAG_F) { | 135 if (toys.optflags & FLAG_F) { |
83 struct stat st; | 136 if (!stat_valid) { |
84 if (stat(ent->d_name, &st)) | 137 if (lstat(ent->d_name, &st)) |
85 perror_exit("Can't stat %s", ent->d_name); | 138 perror_exit("Can't stat %s", ent->d_name); |
139 stat_valid = 1; | |
140 } | |
86 if (S_ISDIR(st.st_mode)) { | 141 if (S_ISDIR(st.st_mode)) { |
87 printf("/"); | 142 xprintf("/"); |
88 len++; | 143 len++; |
89 } | 144 } else if (S_ISREG(st.st_mode) && |
90 if (S_ISREG(st.st_mode) && | |
91 (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) { | 145 (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) { |
92 printf("*"); | 146 xprintf("*"); |
147 len++; | |
148 } else if (S_ISLNK(st.st_mode)) { | |
149 xprintf("@"); | |
93 len++; | 150 len++; |
94 } | 151 } |
95 } | 152 } |
96 if (toys.optflags & FLAG_1) | 153 if (toys.optflags & FLAG_1) { |
97 printf("\n"); | 154 xprintf("\n"); |
98 else { | 155 } else { |
99 if (i % ncolumns == ncolumns - 1) | 156 if (i % ncolumns == ncolumns - 1) |
100 printf("\n"); | 157 xprintf("\n"); |
101 else | 158 else |
102 printf("%*s", maxwidth - len, ""); | 159 xprintf("%*s", maxwidth - len, ""); |
103 } | 160 } |
104 } | 161 } |
105 /* Make sure we put at a trailing new line in */ | 162 /* Make sure we put at a trailing new line in */ |
106 if (!(toys.optflags & FLAG_1) && (i % ncolumns)) | 163 if (!(toys.optflags & FLAG_1) && (i % ncolumns)) |
107 printf("\n"); | 164 xprintf("\n"); |
108 } | 165 } |
109 | 166 |
110 void ls_main(void) | 167 void ls_main(void) |
111 { | 168 { |
169 /* Long output must be one-file per line */ | |
170 if (toys.optflags & FLAG_l) | |
171 toys.optflags |= FLAG_1; | |
112 loopfiles(toys.optargs, do_ls); | 172 loopfiles(toys.optargs, do_ls); |
113 } | 173 } |