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