Magellan Linux

Contents of /trunk/mkinitrd-magellan/klibc/usr/utils/ls.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1122 - (show annotations) (download)
Wed Aug 18 21:11:40 2010 UTC (13 years, 9 months ago) by niro
File MIME type: text/plain
File size: 4425 byte(s)
-updated to klibc-1.5.19
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <dirent.h>
4 #include <unistd.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <sys/sysmacros.h>
8
9 #define STAT_ISSET(mode, mask) (((mode) & mask) == mask)
10
11 static size_t max_linksiz = 128;
12 static int max_nlinks = 1;
13 static int max_size = 1;
14 static int max_uid = 1;
15 static int max_gid = 1;
16 static int max_min = 1;
17 static int max_maj = 1;
18
19 static void do_preformat(const struct stat *st)
20 {
21 int bytes;
22
23 if ((bytes = snprintf(NULL, 0, "%ju", (uintmax_t) st->st_nlink)) > max_nlinks)
24 max_nlinks = bytes;
25
26 if ((bytes = snprintf(NULL, 0, "%ju", (uintmax_t) st->st_uid)) > max_uid)
27 max_uid = bytes;
28
29 if ((bytes = snprintf(NULL, 0, "%ju", (uintmax_t) st->st_gid)) > max_gid)
30 max_gid = bytes;
31
32 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
33 if ((bytes = snprintf(NULL, 0, "%u", major(st->st_rdev))) > max_maj)
34 max_maj = bytes;
35
36 if ((bytes = snprintf(NULL, 0, "%u", minor(st->st_rdev))) > max_min)
37 max_min = bytes;
38
39 max_size = max_maj + max_min + 1;
40 }
41 else {
42 if ((bytes = snprintf(NULL, 0, "%ju", (uintmax_t) st->st_size)) > max_size)
43 max_size = bytes;
44 }
45 return;
46 }
47
48 static void do_stat(const struct stat *st, const char *path)
49 {
50 char *fmt, *link_name;
51 int rc;
52
53 switch (st->st_mode & S_IFMT) {
54 case S_IFBLK: putchar('b'); break;
55 case S_IFCHR: putchar('c'); break;
56 case S_IFDIR: putchar('d'); break;
57 case S_IFIFO: putchar('p'); break;
58 case S_IFLNK: putchar('l'); break;
59 case S_IFSOCK: putchar('s'); break;
60 case S_IFREG: putchar('-'); break;
61 default: putchar('?'); break;
62 }
63 putchar(STAT_ISSET(st->st_mode, S_IRUSR) ? 'r' : '-');
64 putchar(STAT_ISSET(st->st_mode, S_IWUSR) ? 'w' : '-');
65
66 !STAT_ISSET(st->st_mode, S_ISUID) ?
67 putchar(STAT_ISSET(st->st_mode, S_IXUSR) ? 'x' : '-') :
68 putchar('S');
69
70 putchar(STAT_ISSET(st->st_mode, S_IRGRP) ? 'r' : '-');
71 putchar(STAT_ISSET(st->st_mode, S_IWGRP) ? 'w' : '-');
72
73 !STAT_ISSET(st->st_mode, S_ISGID) ?
74 putchar(STAT_ISSET(st->st_mode, S_IXGRP) ? 'x' : '-') :
75 putchar('S');
76
77 putchar(STAT_ISSET(st->st_mode, S_IROTH) ? 'r' : '-');
78 putchar(STAT_ISSET(st->st_mode, S_IWOTH) ? 'w' : '-');
79
80 !STAT_ISSET(st->st_mode, S_ISVTX) ?
81 putchar(STAT_ISSET(st->st_mode, S_IXOTH) ? 'x' : '-') :
82 putchar(S_ISDIR(st->st_mode) ? 't' : 'T');
83
84 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
85 rc = asprintf(&fmt," %%%dju %%%dju %%%dju %%%du,%%%du %%s",
86 max_nlinks, max_uid, max_gid, max_maj, max_min);
87 if (rc == -1) {
88 perror("asprintf");
89 exit(1);
90 }
91 fprintf(stdout, fmt,
92 (uintmax_t) st->st_nlink,
93 (uintmax_t) st->st_uid,
94 (uintmax_t) st->st_gid,
95 major(st->st_rdev),
96 minor(st->st_rdev),
97 path);
98 }
99 else {
100 rc = asprintf(&fmt," %%%dju %%%dju %%%dju %%%dju %%s",
101 max_nlinks, max_uid, max_gid, max_size);
102 if (rc == -1) {
103 perror("asprintf");
104 exit(1);
105 }
106 fprintf(stdout, fmt,
107 (uintmax_t) st->st_nlink,
108 (uintmax_t) st->st_uid,
109 (uintmax_t) st->st_gid,
110 (uintmax_t) st->st_size,
111 path);
112 }
113 free(fmt);
114
115 if (S_ISLNK(st->st_mode)) {
116 if ((link_name = malloc(max_linksiz)) == NULL) {
117 perror("malloc");
118 exit(1);
119 }
120 if ((rc = readlink(path, link_name, max_linksiz)) == -1) {
121 free(link_name);
122 perror("readlink");
123 exit(1);
124 }
125 link_name[rc] = '\0';
126 fprintf(stdout, " -> %s", link_name);
127 free(link_name);
128 }
129
130 putchar('\n');
131 return;
132 }
133
134 static void do_dir(const char *path, int preformat)
135 {
136 DIR *dir;
137 struct dirent *dent;
138 struct stat st;
139
140 if (chdir(path) == -1) {
141 perror(path);
142 exit(1);
143 }
144
145 if ((dir = opendir(path)) == NULL) {
146 perror(path);
147 exit(1);
148 }
149
150 while ((dent = readdir(dir)) != NULL) {
151 if (lstat(dent->d_name, &st)) {
152 perror(dent->d_name);
153 exit(1);
154 }
155 (preformat) ?
156 do_preformat(&st) :
157 do_stat(&st, dent->d_name);
158 }
159
160 closedir(dir);
161 }
162
163 int main(int argc, char *argv[])
164 {
165 int i;
166 struct stat st;
167
168 if (argc == 1) {
169 do_dir(".", 1);
170 do_dir(".", 0);
171 return 0;
172 }
173
174 for (i = 1; i < argc; i++) {
175 if (argv[i][0] == '-' && argv[i][1] == 'h') {
176 fprintf(stdout, "Usage: ls [-h] [FILE ...]\n");
177 return 0;
178 }
179
180 if (lstat(argv[i], &st)) {
181 perror(argv[i]);
182 exit(1);
183 }
184
185 S_ISDIR(st.st_mode) ?
186 do_dir(argv[i], 1) :
187 do_preformat(&st);
188 }
189
190 for (i = 1; i < argc; i++) {
191 if (lstat(argv[i], &st)) {
192 perror(argv[i]);
193 exit(1);
194 }
195
196 S_ISDIR(st.st_mode) ?
197 do_dir(argv[i], 0) :
198 do_stat(&st, argv[i]);
199 }
200
201 return 0;
202 }