1 /* $NetBSD: ls.c,v 1.5 2014/03/20 03:13:18 christos Exp $ */
2
3 /*-
4 * Copyright (c) 2011
5 * The NetBSD Foundation, Inc. All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Martin Husemann.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1993
34 * The Regents of the University of California. 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 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61 /*
62 * Copyright (c) 1996
63 * Matthias Drochner. All rights reserved.
64 *
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
67 * are met:
68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution.
73 *
74 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
75 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
76 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
77 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
78 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
79 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
80 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
81 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
83 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84 */
85
86
87 #include "stand.h"
88 #include "ls.h"
89 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
90 #include <sys/param.h>
91 #endif /* defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
92 #include <sys/stat.h>
93 #include <lib/libkern/libkern.h>
94
95 void
ls(const char * path)96 ls(const char *path)
97 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
98 {
99 load_mods(path, NULL);
100 }
101
102 void
load_mods(const char * path,void (* funcp)(char * arg))103 load_mods(const char *path, void (*funcp)(char* arg))
104 {
105 #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
106 int fd;
107 struct stat sb;
108 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
109 size_t size = -1;
110 #else
111 size_t size;
112 #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
113
114 const char *fname = 0;
115 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
116 char *p = NULL;
117 #else
118 char *p;
119 #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
120 struct open_file *f;
121
122 if ((fd = open(path, 0)) < 0
123 || fstat(fd, &sb) < 0
124 || (sb.st_mode & S_IFMT) != S_IFDIR) {
125 /* Path supplied isn't a directory, open parent
126 directory and list matching files. */
127 if (fd >= 0)
128 close(fd);
129 fname = strrchr(path, '/');
130 if (fname) {
131 size = fname - path;
132 fname++;
133 p = alloc(size + 1);
134 if (!p)
135 goto out;
136 memcpy(p, path, size);
137 p[size] = 0;
138 fd = open(p, 0);
139 #if defined(__minix) && !defined(LIBSA_ENABLE_LOAD_MODS_OP)
140 dealloc(p, size + 1);
141 #endif /* !defined(__minix) && !defined(LIBSA_ENABLE_LOAD_MODS_OP) */
142 } else {
143 fd = open("", 0);
144 fname = path;
145 }
146
147 if (fd < 0) {
148 printf("ls: %s\n", strerror(errno));
149 return;
150 }
151 if (fstat(fd, &sb) < 0) {
152 printf("stat: %s\n", strerror(errno));
153 goto out;
154 }
155 if ((sb.st_mode & S_IFMT) != S_IFDIR) {
156 printf("%s: %s\n", path, strerror(ENOTDIR));
157 goto out;
158 }
159 }
160
161 f = &files[fd];
162
163 #if !defined(LIBSA_NO_FD_CHECKING)
164 if ((unsigned int)fd >= SOPEN_MAX || f->f_flags == 0) {
165 errno = EBADF;
166 goto out;
167 }
168 #endif
169
170 #if !defined(LIBSA_NO_RAW_ACCESS)
171 /* operation not defined on raw devices */
172 if (f->f_flags & F_RAW) {
173 errno = EOPNOTSUPP;
174 goto out;
175 }
176 #endif
177
178 if (FS_LS(f->f_ops) != NULL)
179 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
180 FS_LOAD_MODS(f->f_ops)(f, fname, funcp, p);
181 #else
182 FS_LS(f->f_ops)(f, fname);
183 #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
184 else
185 printf("no ls support for this file system\n");
186
187 out:
188 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
189 /* LSC: MINIX Modification for correct glob support, beware! */
190 if (p != NULL)
191 dealloc(p, size + 1);
192 #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
193 close(fd);
194 }
195
196 struct lsentry {
197 struct lsentry *e_next;
198 uint32_t e_ino;
199 const char *e_type;
200 char e_name[1];
201 };
202
203 __compactcall void
lsadd(lsentry_t ** names,const char * pattern,const char * name,size_t namelen,uint32_t ino,const char * type)204 lsadd(lsentry_t **names, const char *pattern, const char *name, size_t namelen,
205 uint32_t ino, const char *type)
206 {
207 lsentry_t *n, **np;
208
209 if (pattern && !fnmatch(name, pattern))
210 return;
211
212 n = alloc(sizeof *n + namelen);
213 if (!n) {
214 printf("%d: %.*s (%s)\n", ino, (int)namelen, name, type);
215 return;
216 }
217
218 n->e_ino = ino;
219 n->e_type = type;
220 memcpy(n->e_name, name, namelen);
221 n->e_name[namelen] = '\0';
222
223 for (np = names; *np; np = &(*np)->e_next) {
224 if (strcmp(n->e_name, (*np)->e_name) < 0)
225 break;
226 }
227 n->e_next = *np;
228 *np = n;
229 }
230
231 #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
232 __compactcall void
lsapply(lsentry_t * names,const char * pattern,void (* funcp)(char * arg),char * path)233 lsapply(lsentry_t * names, const char * pattern, void (* funcp)(char * arg),
234 char * path)
235 {
236 if (!names) {
237 printf("not found\n");
238 return;
239 }
240 if (NULL == funcp) {
241 printf("no callback provided\n");
242 return;
243 }
244 do {
245 lsentry_t *n = names;
246 char namebuf[MAXPATHLEN+1];
247 namebuf[0] = '\0';
248
249 if (path != pattern) {
250 strcpy(namebuf, path);
251 namebuf[strlen(path)] = '/';
252 namebuf[strlen(path) + 1] = '\0';
253 }
254 strcat(namebuf, n->e_name);
255
256 funcp(namebuf);
257
258 names = n->e_next;
259 } while (names);
260 }
261 #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
262 #if defined(__minix)
263 __compactcall void
load_modsunsup(const char * name)264 load_modsunsup(const char *name) {
265 printf("The load_mods command is not currently supported for %s\n", name);
266 }
267 #endif /* defined(__minix) */
268
269 __compactcall void
lsprint(lsentry_t * names)270 lsprint(lsentry_t *names) {
271 if (!names) {
272 printf("not found\n");
273 return;
274 }
275 do {
276 lsentry_t *n = names;
277 printf("%d: %s (%s)\n", n->e_ino, n->e_name, n->e_type);
278 names = n->e_next;
279 } while (names);
280 }
281
282 __compactcall void
lsfree(lsentry_t * names)283 lsfree(lsentry_t *names) {
284 if (!names)
285 return;
286 do {
287 lsentry_t *n = names;
288 names = n->e_next;
289 dealloc(n, 0);
290 } while (names);
291 }
292
293 __compactcall void
lsunsup(const char * name)294 lsunsup(const char *name) {
295 printf("The ls command is not currently supported for %s\n", name);
296 }
297