FreeBSD/Linux Kernel Cross Reference
sys/lib/libsa/ufs_ls.c
1 /* $NetBSD: ufs_ls.c,v 1.8 2004/03/24 16:21:06 drochner Exp $ */
2
3 /*
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1996
34 * Matthias Drochner. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 */
56
57
58 #include <sys/param.h>
59 #include <lib/libkern/libkern.h>
60 #include <ufs/ufs/dinode.h>
61 #include <ufs/ufs/dir.h>
62
63 #include "stand.h"
64 #include "ufs.h"
65
66 #define NELEM(x) (sizeof (x) / sizeof(*x))
67
68 typedef struct entry_t entry_t;
69 struct entry_t {
70 entry_t *e_next;
71 ino_t e_ino;
72 uint8_t e_type;
73 char e_name[1];
74 };
75
76 static const char *const typestr[] = {
77 "unknown",
78 "FIFO",
79 "CHR",
80 0,
81 "DIR",
82 0,
83 "BLK",
84 0,
85 "REG",
86 0,
87 "LNK",
88 0,
89 "SOCK",
90 0,
91 "WHT"
92 };
93
94 static int
95 fn_match(const char *fname, const char *pattern)
96 {
97 char fc, pc;
98
99 do {
100 fc = *fname++;
101 pc = *pattern++;
102 if (!fc && !pc)
103 return 1;
104 if (pc == '?' && fc)
105 pc = fc;
106 } while (fc == pc);
107
108 if (pc != '*')
109 return 0;
110 /* Too hard (and unnecessary really) too check for "*?name" etc....
111 "**" will look for a '*' and "*?" a '?' */
112 pc = *pattern++;
113 if (!pc)
114 return 1;
115 while ((fname = strchr(fname, pc)))
116 if (fn_match(++fname, pattern))
117 return 1;
118 return 0;
119 }
120
121 void
122 ufs_ls(const char *path)
123 {
124 int fd;
125 struct stat sb;
126 size_t size;
127 char dirbuf[DIRBLKSIZ];
128 const char *fname = 0;
129 char *p;
130 entry_t *names = 0, *n, **np;
131
132 if ((fd = open(path, 0)) < 0
133 || fstat(fd, &sb) < 0
134 || (sb.st_mode & IFMT) != IFDIR) {
135 /* Path supplied isn't a directory, open parent
136 directory and list matching files. */
137 if (fd >= 0)
138 close(fd);
139 fname = strrchr(path, '/');
140 if (fname) {
141 size = fname - path;
142 p = alloc(size + 1);
143 if (!p)
144 goto out;
145 memcpy(p, path, size);
146 p[size] = 0;
147 fd = open(p, 0);
148 free(p, size + 1);
149 } else {
150 fd = open("", 0);
151 fname = path;
152 }
153
154 if (fd < 0) {
155 printf("ls: %s\n", strerror(errno));
156 return;
157 }
158 if (fstat(fd, &sb) < 0) {
159 printf("stat: %s\n", strerror(errno));
160 goto out;
161 }
162 if ((sb.st_mode & IFMT) != IFDIR) {
163 printf("%s: %s\n", path, strerror(ENOTDIR));
164 goto out;
165 }
166 }
167
168 while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) {
169 struct direct *dp, *edp;
170
171 dp = (struct direct *) dirbuf;
172 edp = (struct direct *) (dirbuf + size);
173
174 for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) {
175 const char *t;
176 if (dp->d_ino == 0)
177 continue;
178
179 if (dp->d_type >= NELEM(typestr) ||
180 !(t = typestr[dp->d_type])) {
181 /*
182 * This does not handle "old"
183 * filesystems properly. On little
184 * endian machines, we get a bogus
185 * type name if the namlen matches a
186 * valid type identifier. We could
187 * check if we read namlen "" and
188 * handle this case specially, if
189 * there were a pressing need...
190 */
191 printf("bad dir entry\n");
192 goto out;
193 }
194 if (fname && !fn_match(dp->d_name, fname))
195 continue;
196 n = alloc(sizeof *n + strlen(dp->d_name));
197 if (!n) {
198 printf("%d: %s (%s)\n",
199 dp->d_ino, dp->d_name, t);
200 continue;
201 }
202 n->e_ino = dp->d_ino;
203 n->e_type = dp->d_type;
204 strcpy(n->e_name, dp->d_name);
205 for (np = &names; *np; np = &(*np)->e_next) {
206 if (strcmp(n->e_name, (*np)->e_name) < 0)
207 break;
208 }
209 n->e_next = *np;
210 *np = n;
211 }
212 }
213
214 if (names) {
215 do {
216 n = names;
217 printf("%d: %s (%s)\n",
218 n->e_ino, n->e_name, typestr[n->e_type]);
219 names = n->e_next;
220 free(n, 0);
221 } while (names);
222 } else {
223 printf( "%s not found\n", path );
224 }
225 out:
226 close(fd);
227 }
Cache object: 2ada53b9002f484f8e693a73f0b94b2f
|