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; }
static int fn_match(char *pattern, char *string, char **pend) { char c; char test; *pend = NULL; for (;;) { switch (c = *pattern++) { case '\0': /* * Ok we found an exact match */ if (*string == '\0') return(0); /* * Check if it is a prefix match */ if ((dflag == 1) || (*string != '/')) return(-1); /* * It is a prefix match, remember where the trailing * / is located */ *pend = string; return(0); case '?': if ((test = *string++) == '\0') return (-1); break; case '*': c = *pattern; /* * Collapse multiple *'s. */ while (c == '*') c = *++pattern; /* * Optimized hack for pattern with a * at the end */ if (c == '\0') return (0); /* * General case, use recursion. */ while ((test = *string) != '\0') { if (!fn_match(pattern, string, pend)) return (0); ++string; } return (-1); case '[': /* * range match */ if (((test = *string++) == '\0') || ((pattern = range_match(pattern, test)) == NULL)) return (-1); break; case '\\': default: if (c != *string++) return (-1); break; } } /* NOTREACHED */ }
int pat_match(ARCHD *arcn) { PATTERN *pt; arcn->pat = NULL; /* * if there are no more patterns and we have -n (and not -c) we are * done. otherwise with no patterns to match, matches all */ if (pathead == NULL) { if (nflag && !cflag) return(-1); return(0); } /* * have to search down the list one at a time looking for a match. */ pt = pathead; while (pt != NULL) { /* * check for a file name match unless we have DIR_MTCH set in * this pattern then we want a prefix match */ if (pt->flgs & DIR_MTCH) { /* * this pattern was matched before to a directory * as we must have -n set for this (but not -d). We can * only match CHILDREN of that directory so we must use * an exact prefix match (no wildcards). */ if ((arcn->name[pt->plen] == '/') && (strncmp(pt->pstr, arcn->name, pt->plen) == 0)) break; } else if (fn_match(pt->pstr, arcn->name, &pt->pend) == 0) break; pt = pt->fow; } /* * return the result, remember that cflag (-c) inverts the sense of a * match */ if (pt == NULL) return(cflag ? 0 : 1); /* * We had a match, now when we invert the sense (-c) we reject this * member. However we have to tag the pattern a being successful, (in a * match, not in selecting an archive member) so we call pat_sel() here. */ arcn->pat = pt; if (!cflag) return(0); if (pat_sel(arcn) < 0) return(-1); arcn->pat = NULL; return(1); }
__compactcall void ufs_ls(struct open_file *f, const char *pattern, void (*funcp)(char* arg), char* path) { struct file *fp = (struct file *)f->f_fsdata; char *buf; size_t buf_size; entry_t *names = 0, *n, **np; fp->f_seekp = 0; while (fp->f_seekp < (off_t)fp->f_di.di_size) { struct direct *dp, *edp; int rc = buf_read_file(f, &buf, &buf_size); if (rc) goto out; /* some firmware might use block size larger than DEV_BSIZE */ if (buf_size < DIRBLKSIZ) goto out; dp = (struct direct *)buf; edp = (struct direct *)(buf + buf_size); for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) { const char *t; if (dp->d_ino == 0) continue; 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 (pattern && !fn_match(dp->d_name, pattern)) continue; n = alloc(sizeof *n + strlen(dp->d_name)); if (!n) { printf("%d: %s (%s)\n", dp->d_ino, dp->d_name, t); continue; } 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; } fp->f_seekp += buf_size; } if (names) { entry_t *p_names = names; do { n = p_names; printf("%d: %s (%s)\n", n->e_ino, n->e_name, typestr[n->e_type]); p_names = n->e_next; } while (p_names); } else { printf("not found\n"); } out: if (names) { do { n = names; names = n->e_next; dealloc(n, 0); } while (names); } }
void efifs_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; if ((fd = open(path, 0)) < 0 || fstat(fd, &sb) < 0 || (sb.st_mode & S_IFMT) != S_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 & S_IFMT) != S_IFDIR) { printf("%s: %s\n", path, strerror(ENOTDIR)); goto out; } } while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) { struct dirent *dp, *edp; dp = (struct dirent *) dirbuf; edp = (struct dirent *) (dirbuf + size); for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) { const char *t; if (dp->d_ino == 0) continue; 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; } 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); }