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