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