1/* $NetBSD: efifs_ls.c,v 1.1 2006/04/07 14:21:32 cherry 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/* Based on libsa/ufs_ls.c */ 58 59#include <dirent.h> 60#include <sys/param.h> 61#include <sys/stat.h> 62 63#include <lib/libkern/libkern.h> 64 65#include "stand.h" 66 67#include <efi.h> 68#include <efilib.h> 69 70#include "efifs.h" 71 72#define NELEM(x) (sizeof (x) / sizeof(*x)) 73 74typedef struct entry_t entry_t; 75struct entry_t { 76 entry_t *e_next; 77 ino_t e_ino; 78 uint8_t e_type; 79 char e_name[1]; 80}; 81 82static const char *const typestr[] = { 83 "unknown", 84 "FIFO", 85 "CHR", 86 0, 87 "DIR", 88 0, 89 "BLK", 90 0, 91 "REG", 92 0, 93 "LNK", 94 0, 95 "SOCK", 96 0, 97 "WHT" 98}; 99 100static int 101fn_match(const char *fname, const char *pattern) 102{ 103 char fc, pc; 104 105 do { 106 fc = *fname++; 107 pc = *pattern++; 108 if (!fc && !pc) 109 return 1; 110 if (pc == '?' && fc) 111 pc = fc; 112 } while (fc == pc); 113 114 if (pc != '*') 115 return 0; 116 /* Too hard (and unnecessary really) too check for "*?name" etc.... 117 "**" will look for a '*' and "*?" a '?' */ 118 pc = *pattern++; 119 if (!pc) 120 return 1; 121 while ((fname = strchr(fname, pc))) 122 if (fn_match(++fname, pattern)) 123 return 1; 124 return 0; 125} 126 127void 128efifs_ls(const char *path) 129{ 130 int fd; 131 struct stat sb; 132 size_t size; 133 char dirbuf[DIRBLKSIZ]; 134 const char *fname = 0; 135 char *p; 136 entry_t *names = 0, *n, **np; 137 138 if ((fd = open(path, 0)) < 0 139 || fstat(fd, &sb) < 0 140 || (sb.st_mode & S_IFMT) != S_IFDIR) { 141 /* Path supplied isn't a directory, open parent 142 directory and list matching files. */ 143 if (fd >= 0) 144 close(fd); 145 fname = strrchr(path, '/'); 146 if (fname) { 147 size = fname - path; 148 p = alloc(size + 1); 149 if (!p) 150 goto out; 151 memcpy(p, path, size); 152 p[size] = 0; 153 fd = open(p, 0); 154 free(p, size + 1); 155 } else { 156 fd = open("", 0); 157 fname = path; 158 } 159 160 if (fd < 0) { 161 printf("ls: %s\n", strerror(errno)); 162 return; 163 } 164 if (fstat(fd, &sb) < 0) { 165 printf("stat: %s\n", strerror(errno)); 166 goto out; 167 } 168 if ((sb.st_mode & S_IFMT) != S_IFDIR) { 169 printf("%s: %s\n", path, strerror(ENOTDIR)); 170 goto out; 171 } 172 } 173 174 while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) { 175 struct dirent *dp, *edp; 176 177 dp = (struct dirent *) dirbuf; 178 edp = (struct dirent *) (dirbuf + size); 179 180 for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) { 181 const char *t; 182 if (dp->d_ino == 0) 183 continue; 184 185 if (dp->d_type >= NELEM(typestr) || 186 !(t = typestr[dp->d_type])) { 187 /* 188 * This does not handle "old" 189 * filesystems properly. On little 190 * endian machines, we get a bogus 191 * type name if the namlen matches a 192 * valid type identifier. We could 193 * check if we read namlen "0" and 194 * handle this case specially, if 195 * there were a pressing need... 196 */ 197 printf("bad dir entry\n"); 198 goto out; 199 } 200 if (fname && !fn_match(dp->d_name, fname)) 201 continue; 202 n = alloc(sizeof *n + strlen(dp->d_name)); 203 if (!n) { 204 printf("%d: %s (%s)\n", 205 dp->d_ino, dp->d_name, t); 206 continue; 207 } 208 n->e_ino = dp->d_ino; 209 n->e_type = dp->d_type; 210 strcpy(n->e_name, dp->d_name); 211 for (np = &names; *np; np = &(*np)->e_next) { 212 if (strcmp(n->e_name, (*np)->e_name) < 0) 213 break; 214 } 215 n->e_next = *np; 216 *np = n; 217 } 218 } 219 220 if (names) { 221 do { 222 n = names; 223 printf("%d: %s (%s)\n", 224 n->e_ino, n->e_name, typestr[n->e_type]); 225 names = n->e_next; 226 free(n, 0); 227 } while (names); 228 } else { 229 printf( "%s not found\n", path ); 230 } 231out: 232 close(fd); 233} 234