Annotation of prex/usr/bin/ls/ls.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 2005-2006, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: #include <sys/stat.h>
31:
32: #include <unistd.h>
33: #include <err.h>
34: #include <string.h>
35: #include <stdlib.h>
36: #include <dirent.h>
37: #include <limits.h>
38: #include <stdio.h>
39: #include <errno.h>
40:
41: #ifdef CMDBOX
42: #define main(argc, argv) ls_main(argc, argv)
43: #endif
44:
45: static void print_entry(char *name, struct stat *sp);
46: static int do_ls(char *path);
47:
48: /* Flags */
49: #define LSF_DOT 0x01 /* List files begining with . */
50: #define LSF_LONG 0x02 /* Long format */
51: #define LSF_SINGLE 0x04 /* Single column */
52: #define LSF_TYPE 0x08 /* Add /(dir) and @(symlink) with file name */
53: #define LSF_ALL 0x10 /* List hidden files */
54:
55: #define LSF_RECURSIVE 0x20 /* List Subdirectory */
56: #define LSF_TIMESORT 0x40 /* Sort by time */
57:
58: static unsigned int ls_flags;
59:
60: int
61: main(int argc, char *argv[])
62: {
63: int ch, rc;
64:
65: ls_flags = 0;
66:
67: while ((ch = getopt(argc, argv, "1ClFaA")) != -1) {
68: switch(ch) {
69: case '1':
70: ls_flags |= LSF_SINGLE;
71: ls_flags &= ~LSF_LONG;
72: break;
73: case 'C':
74: ls_flags &= ~LSF_SINGLE;
75: ls_flags &= ~LSF_LONG;
76: break;
77: case 'l':
78: ls_flags |= LSF_LONG;
79: ls_flags &= ~LSF_SINGLE;
80: break;
81: case 'F':
82: ls_flags |= LSF_TYPE;
83: break;
84: case 'a':
85: ls_flags |= LSF_DOT;
86: /* FALLTHROUGH */
87: case 'A':
88: ls_flags |= LSF_ALL;
89: break;
90: default:
91: case '?':
92: fprintf(stderr, "usage: ls [-1CFAal] [file ...]\n");
93: exit(1);
94: }
95: }
96: argc -= optind;
97: argv += optind;
98:
99: if (argc == 0)
100: rc = do_ls(".");
101: else {
102: do {
103: rc = do_ls(*argv);
104: ++argv;
105: } while (*argv);
106: }
107: if (rc)
108: err(1, NULL);
109: return 0;
110: }
111:
112: static void
113: print_entry(char *name, struct stat *sp)
114: {
115: int color;
116: int dot = 0;
117:
118: if (name[0] == '.') {
119: if ((ls_flags & LSF_DOT) == 0)
120: return;
121: dot = 1;
122: }
123:
124: /* set color */
125: color = 0;
126: if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
127: color = 35; /* magenta */
128: else if (S_ISDIR(sp->st_mode))
129: color = 36; /* cyan */
130: else if (S_ISFIFO(sp->st_mode))
131: color = 34;
132: else if (S_ISLNK(sp->st_mode))
133: color = 33; /* yellow */
134:
135: if (ls_flags & LSF_LONG) {
136: /* print mode */
137: if (S_ISDIR(sp->st_mode))
138: putchar('d');
139: else if (S_ISLNK(sp->st_mode))
140: putchar('@');
141: else if (S_ISFIFO(sp->st_mode))
142: putchar('|');
143: else
144: putchar('-');
145:
146: printf("rw");
147: if (sp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
148: putchar('x');
149: else
150: putchar('-');
151: printf("------");
152:
153: /* print link */
154: printf(" 1 ");
155:
156: /* print owner */
157: printf("prex ");
158:
159: /* print date/time */
160: printf("%s 12:00 ", __DATE__);
161:
162: /* print size */
163: printf("%7d ", (int)sp->st_size);
164: }
165:
166: /* print name */
167: printf("\033[%dm", color);
168: printf("%s", name);
169:
170: /* print type */
171: if (!dot && (ls_flags & LSF_TYPE)) {
172: switch (sp->st_mode & S_IFMT) {
173: case S_IFDIR:
174: putchar('/');
175: break;
176: case S_IFIFO:
177: putchar('|');
178: break;
179: case S_IFLNK:
180: putchar('@');
181: break;
182: case S_IFSOCK:
183: putchar('=');
184: break;
185: case S_IFWHT:
186: putchar('%');
187: break;
188: }
189: if (sp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
190: putchar('*');
191: }
192: printf("\033[0m");
193: if (ls_flags & LSF_LONG || ls_flags & LSF_SINGLE) {
194: putchar('\n');
195: } else {
196: putchar(' ');
197: }
198: }
199:
200: static int
201: do_ls(char *path)
202: {
203: struct stat st;
204: int nr_file = 0;
205: char buf[PATH_MAX];
206: DIR *dir;
207: struct dirent *entry;
208:
209: if (stat(path, &st) == -1)
210: return ENOTDIR;
211:
212: if (S_ISDIR(st.st_mode)) {
213:
214: dir = opendir(path);
215: if (dir == NULL)
216: return ENOTDIR;
217:
218: for (;;) {
219: entry = readdir(dir);
220: if (entry == NULL)
221: break;
222: buf[0] = 0;
223: strlcpy(buf, path, sizeof(buf));
224: buf[sizeof(buf) - 1] = '\0';
225: if (!strcmp(entry->d_name, "."))
226: ; /* Do nothing */
227: else if (!strcmp(entry->d_name, ".."))
228: ; /* Do nothing */
229: else {
230: strlcat(buf, "/", sizeof(buf));
231: strlcat(buf, entry->d_name, sizeof(buf));
232: }
233: if (stat(buf, &st) == -1)
234: break;
235: print_entry(entry->d_name, &st);
236: nr_file++;
237: }
238: closedir(dir);
239: if (ls_flags & LSF_LONG)
240: printf("total %d\n", nr_file);
241: else
242: putchar('\n');
243: } else {
244: print_entry(path, &st);
245: putchar('\n');
246: }
247: return 0;
248: }
CVSweb