-/*
- * globals (file name generation)
- *
- * "*" in params matches r.e ".*"
- * "?" in params matches r.e. "."
- * "[...]" in params matches character class
- * "[...a-z...]" in params matches a through z.
- */
-expandarg(arg, ap)
- char *arg;
- register struct arglist *ap;
-{
- static struct afile single;
- struct entry *ep;
- int size;
-
- ap->head = ap->last = (struct afile *)0;
- size = expand(arg, 0, ap);
- if (size == 0) {
- ep = lookupname(arg);
- single.fnum = ep ? ep->e_ino : 0;
- single.fname = savename(arg);
- ap->head = &single;
- ap->last = ap->head + 1;
- return;
- }
- qsort((char *)ap->head, ap->last - ap->head, sizeof *ap->head, fcmp);
-}
-
-/*
- * Expand a file name
- */
-expand(as, rflg, ap)
- char *as;
- int rflg;
- register struct arglist *ap;
-{
- int count, size;
- char dir = 0;
- char *rescan = 0;
- DIR *dirp;
- register char *s, *cs;
- int sindex, rindex, lindex;
- struct direct *dp;
- register char slash;
- register char *rs;
- register char c;
-
- /*
- * check for meta chars
- */
- s = cs = as;
- slash = 0;
- while (*cs != '*' && *cs != '?' && *cs != '[') {
- if (*cs++ == 0) {
- if (rflg && slash)
- break;
- else
- return (0) ;
- } else if (*cs == '/') {
- slash++;
- }
- }
- for (;;) {
- if (cs == s) {
- s = "";
- break;
- } else if (*--cs == '/') {
- *cs = 0;
- if (s == cs)
- s = "/";
- break;
- }
- }
- if ((dirp = rst_opendir(s)) != NULL)
- dir++;
- count = 0;
- if (*cs == 0)
- *cs++ = 0200;
- if (dir) {
- /*
- * check for rescan
- */
- rs = cs;
- do {
- if (*rs == '/') {
- rescan = rs;
- *rs = 0;
- }
- } while (*rs++);
- sindex = ap->last - ap->head;
- while ((dp = rst_readdir(dirp)) != NULL && dp->d_ino != 0) {
- if (!dflag && BIT(dp->d_ino, dumpmap) == 0)
- continue;
- if ((*dp->d_name == '.' && *cs != '.'))
- continue;
- if (gmatch(dp->d_name, cs)) {
- if (addg(dp, s, rescan, ap) < 0)
- return (-1);
- count++;
- }
- }
- if (rescan) {
- rindex = sindex;
- lindex = ap->last - ap->head;
- if (count) {
- count = 0;
- while (rindex < lindex) {
- size = expand(ap->head[rindex].fname,
- 1, ap);
- if (size < 0)
- return (size);
- count += size;
- rindex++;
- }
- }
- bcopy((char *)&ap->head[lindex],
- (char *)&ap->head[sindex],
- (ap->last - &ap->head[rindex]) * sizeof *ap->head);
- ap->last -= lindex - sindex;
- *rescan = '/';
- }
- }
- s = as;
- while (c = *s)
- *s++ = (c&0177 ? c : '/');
- return (count);
-}
-
-/*
- * Check for a name match
- */
-gmatch(s, p)
- register char *s, *p;
-{
- register int scc;
- char c;
- char ok;
- int lc;
-
- if (scc = *s++)
- if ((scc &= 0177) == 0)
- scc = 0200;
- switch (c = *p++) {
-
- case '[':
- ok = 0;
- lc = 077777;
- while (c = *p++) {
- if (c == ']') {
- return (ok ? gmatch(s, p) : 0);
- } else if (c == '-') {
- if (lc <= scc && scc <= (*p++))
- ok++ ;
- } else {
- if (scc == (lc = (c&0177)))
- ok++ ;
- }
- }
- return (0);
-
- default:
- if ((c&0177) != scc)
- return (0) ;
- /* falls through */
-
- case '?':
- return (scc ? gmatch(s, p) : 0);
-
- case '*':
- if (*p == 0)
- return (1) ;
- s--;
- while (*s) {
- if (gmatch(s++, p))
- return (1);
- }
- return (0);
-
- case 0:
- return (scc == 0);
- }
-}
-
-/*
- * Construct a matched name.
- */
-addg(dp, as1, as3, ap)
- struct direct *dp;
- char *as1, *as3;
- struct arglist *ap;
-{
- register char *s1, *s2;
- register int c;
- char buf[BUFSIZ];
-
- s2 = buf;
- s1 = as1;
- while (c = *s1++) {
- if ((c &= 0177) == 0) {
- *s2++ = '/';
- break;
- }
- *s2++ = c;
- }
- s1 = dp->d_name;
- while (*s2 = *s1++)
- s2++;
- if (s1 = as3) {
- *s2++ = '/';
- while (*s2++ = *++s1)
- /* void */;
- }
- if (mkentry(buf, dp->d_ino, ap) == FAIL)
- return (-1);
-}
-