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