Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/lib/libsa Support limited filename globbing
details: https://anonhg.NetBSD.org/src/rev/f1b7c11ba62e
branches: trunk
changeset: 542556:f1b7c11ba62e
user: dsl <dsl%NetBSD.org@localhost>
date: Sat Feb 01 14:52:13 2003 +0000
description:
Support limited filename globbing
- agreed by christos
diffstat:
sys/lib/libsa/ufs_ls.c | 165 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 126 insertions(+), 39 deletions(-)
diffs (210 lines):
diff -r d00c4b14ed04 -r f1b7c11ba62e sys/lib/libsa/ufs_ls.c
--- a/sys/lib/libsa/ufs_ls.c Sat Feb 01 14:48:16 2003 +0000
+++ b/sys/lib/libsa/ufs_ls.c Sat Feb 01 14:52:13 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_ls.c,v 1.2 2002/05/09 02:44:39 simonb Exp $ */
+/* $NetBSD: ufs_ls.c,v 1.3 2003/02/01 14:52:13 dsl Exp $ */
/*
* Copyright (c) 1993
@@ -37,13 +37,24 @@
#include <sys/param.h>
+#include <string.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include "stand.h"
#include "ufs.h"
-static char *typestr[] = {
+#define NELEM(x) (sizeof (x) / sizeof(*x))
+
+typedef struct entry_t entry_t;
+struct entry_t {
+ entry_t *e_next;
+ ino_t e_ino;
+ uint8_t e_type;
+ char e_name[1];
+};
+
+static const char *typestr[] = {
"unknown",
"FIFO",
"CHR",
@@ -61,61 +72,137 @@
"WHT"
};
+static int
+fn_match(const char *fname, const char *pattern)
+{
+ char fc, pc;
+
+ do {
+ fc = *fname++;
+ pc = *pattern++;
+ if (!fc && !pc)
+ return 1;
+ if (pc == '?' && fc)
+ pc = fc;
+ } while (fc == pc);
+
+ if (pc != '*')
+ return 0;
+ /* Too hard (and unnecessary really) too check for "*?name" etc....
+ "**" will look for a '*' and "*?" a '?' */
+ pc = *pattern++;
+ if (!pc)
+ return 1;
+ while ((fname = strchr(fname, pc)))
+ if (fn_match(++fname, pattern))
+ return 1;
+ return 0;
+}
+
void
-ufs_ls(path)
- const char *path;
+ufs_ls(const char *path)
{
int fd;
struct stat sb;
size_t size;
char dirbuf[DIRBLKSIZ];
+ const char *fname = 0;
+ char *p;
+ entry_t *names = 0, *n, **np;
- fd = open(path, 0);
- if (fd < 0) {
- printf("ls: %s\n", strerror(errno));
- return;
+ if ((fd = open(path, 0)) < 0
+ || fstat(fd, &sb) < 0
+ || (sb.st_mode & IFMT) != IFDIR) {
+ /* Path supplied isn't a directory, open parent
+ directory and list matching files. */
+ if (fd >= 0)
+ close(fd);
+ fname = strrchr(path, '/');
+ if (fname) {
+ size = fname - path;
+ p = alloc(size + 1);
+ if (!p)
+ goto out;
+ memcpy(p, path, size);
+ p[size] = 0;
+ fd = open(p, 0);
+ free(p, size + 1);
+ } else {
+ fd = open("", 0);
+ fname = path;
+ }
+
+ if (fd < 0) {
+ printf("ls: %s\n", strerror(errno));
+ return;
+ }
+ if (fstat(fd, &sb) < 0) {
+ printf("stat: %s\n", strerror(errno));
+ goto out;
+ }
+ if ((sb.st_mode & IFMT) != IFDIR) {
+ printf("%s: %s\n", path, strerror(ENOTDIR));
+ goto out;
+ }
}
- if (fstat(fd, &sb) < 0) {
- printf("stat: %s\n", strerror(errno));
- goto out;
- }
- if ((sb.st_mode & IFMT) != IFDIR) {
- printf("%s: %s\n", path, strerror(ENOTDIR));
- goto out;
- }
+
while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) {
struct direct *dp, *edp;
dp = (struct direct *) dirbuf;
edp = (struct direct *) (dirbuf + size);
- while (dp < edp) {
- if (dp->d_ino != (ino_t) 0) {
- char *t;
+ for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) {
+ const char *t;
+ if (dp->d_ino == 0)
+ continue;
- if (/* (dp->d_namlen > MAXNAMLEN + 1) || */
- (dp->d_type >
- sizeof(typestr) / sizeof(char *) - 1) ||
- !(t = typestr[dp->d_type])) {
- /*
- * This does not handle "old"
- * filesystems properly. On little
- * endian machines, we get a bogus
- * type name if the namlen matches a
- * valid type identifier. We could
- * check if we read namlen "0" and
- * handle this case specially, if
- * there were a pressing need...
- */
- printf("bad dir entry\n");
- goto out;
- }
- printf("%d: %s (%s)\n", dp->d_ino,
- dp->d_name, t);
+ if (dp->d_type >= NELEM(typestr) ||
+ !(t = typestr[dp->d_type])) {
+ /*
+ * This does not handle "old"
+ * filesystems properly. On little
+ * endian machines, we get a bogus
+ * type name if the namlen matches a
+ * valid type identifier. We could
+ * check if we read namlen "0" and
+ * handle this case specially, if
+ * there were a pressing need...
+ */
+ printf("bad dir entry\n");
+ goto out;
+ }
+ if (fname && !fn_match(dp->d_name, fname))
+ continue;
+ n = alloc(sizeof *n + strlen(dp->d_name));
+ if (!n) {
+ printf("%d: %s (%s)\n",
+ dp->d_ino, dp->d_name, t);
+ continue;
}
- dp = (struct direct *) ((char *) dp + dp->d_reclen);
+ n->e_ino = dp->d_ino;
+ n->e_type = dp->d_type;
+ strcpy(n->e_name, dp->d_name);
+ for (np = &names; *np; np = &(*np)->e_next) {
+ if (strcmp(n->e_name, (*np)->e_name) < 0)
+ break;
+ }
+ n->e_next = *np;
+ *np = n;
}
}
+
+ if (names) {
+ do {
+ n = names;
+ printf("%d: %s (%s)\n",
+ n->e_ino, n->e_name, typestr[n->e_type]);
+ names = n->e_next;
+ free(n, 0);
+ } while (names);
+ } else {
+ printf( "%s not found\n", path );
+ }
out:
close(fd);
}
Home |
Main Index |
Thread Index |
Old Index