/* * Perform pathname generation and remove control characters. * At this point, the only control characters should be CTLESC. * The results are stored in the list dstlist. */ static void expandmeta(char *pattern, struct arglist *dstlist) { char *p; int firstmatch; char c; firstmatch = dstlist->count; p = pattern; for (; (c = *p) != '\0'; p++) { /* fast check for meta chars */ if (c == '*' || c == '?' || c == '[') { INTOFF; expmeta(expdir, pattern, dstlist); INTON; break; } } if (dstlist->count == firstmatch) { /* * no matches */ rmescapes(pattern); appendarglist(dstlist, pattern); } else { qsort(&dstlist->args[firstmatch], dstlist->count - firstmatch, sizeof(dstlist->args[0]), expsortcmp); } }
STATIC void expandmeta(shinstance *psh, struct strlist *str, int flag) { char *p; struct strlist **savelastp; struct strlist *sp; char c; /* TODO - EXP_REDIR */ while (str) { if (fflag(psh)) goto nometa; p = str->text; for (;;) { /* fast check for meta chars */ if ((c = *p++) == '\0') goto nometa; if (c == '*' || c == '?' || c == '[' || c == '!') break; } savelastp = psh->exparg.lastp; INTOFF; if (psh->expdir == NULL) { size_t i = strlen(str->text); psh->expdir = ckmalloc(psh, i < 2048 ? 2048 : i); /* XXX */ } expmeta(psh, psh->expdir, str->text); ckfree(psh, psh->expdir); psh->expdir = NULL; INTON; if (psh->exparg.lastp == savelastp) { /* * no matches */ nometa: *psh->exparg.lastp = str; rmescapes(psh, str->text); psh->exparg.lastp = &str->next; } else { *psh->exparg.lastp = NULL; *savelastp = sp = expsort(*savelastp); while (sp->next != NULL) sp = sp->next; psh->exparg.lastp = &sp->next; } str = str->next; } }
/* * Perform pathname generation and remove control characters. * At this point, the only control characters should be CTLESC and CTLQUOTEMARK. * The results are stored in the list exparg. */ static void expandmeta(struct strlist* str, int32_t flag __unused) { cstring_t p; struct strlist** savelastp; struct strlist* sp; char c; (void)flag; /* TODO - EXP_REDIR */ while (str) { if (fflag) goto nometa; p = str->text; for (;;) /* fast check for meta chars */ { if ((c = *p++) == '\0') goto nometa; if (c == '*' || c == '?' || c == '[') break; } savelastp = exparg.lastp; INTOFF; expmeta(expdir, str->text); INTON; if (exparg.lastp == savelastp) { /* * no matches */ nometa: *exparg.lastp = str; rmescapes(str->text); exparg.lastp = &str->next; } else { *exparg.lastp = NULL; *savelastp = sp = expsort(*savelastp); while (sp->next != NULL) sp = sp->next; exparg.lastp = &sp->next; } str = str->next; } }
/* * Perform pathname generation and remove control characters. * At this point, the only control characters should be CTLESC and CTLQUOTEMARK. * The results are stored in the list exparg. */ static void expandmeta(struct strlist *str) { char *p; struct strlist **savelastp; struct strlist *sp; char c; while (str) { savelastp = exparg.lastp; if (!fflag) { p = str->text; for (; (c = *p) != '\0'; p++) { /* fast check for meta chars */ if (c == '*' || c == '?' || c == '[') { INTOFF; expmeta(expdir, str->text); INTON; break; } } } if (exparg.lastp == savelastp) { /* * no matches */ *exparg.lastp = str; rmescapes(str->text); exparg.lastp = &str->next; } else { *exparg.lastp = NULL; *savelastp = sp = expsort(*savelastp); while (sp->next != NULL) sp = sp->next; exparg.lastp = &sp->next; } str = str->next; } }
static void expmeta(char *enddir, char *name) { const char *p; const char *q; const char *start; char *endname; int metaflag; struct stat statb; DIR *dirp; struct dirent *dp; int atend; int matchdot; int esc; int namlen; metaflag = 0; start = name; for (p = name; esc = 0, *p; p += esc + 1) { if (*p == '*' || *p == '?') metaflag = 1; else if (*p == '[') { q = p + 1; if (*q == '!' || *q == '^') q++; for (;;) { while (*q == CTLQUOTEMARK) q++; if (*q == CTLESC) q++; if (*q == '/' || *q == '\0') break; if (*++q == ']') { metaflag = 1; break; } } } else if (*p == '\0') break; else if (*p == CTLQUOTEMARK) continue; else { if (*p == CTLESC) esc++; if (p[esc] == '/') { if (metaflag) break; start = p + esc + 1; } } } if (metaflag == 0) { /* we've reached the end of the file name */ if (enddir != expdir) metaflag++; for (p = name ; ; p++) { if (*p == CTLQUOTEMARK) continue; if (*p == CTLESC) p++; *enddir++ = *p; if (*p == '\0') break; if (enddir == expdir_end) return; } if (metaflag == 0 || lstat(expdir, &statb) >= 0) addfname(expdir); return; } endname = name + (p - name); if (start != name) { p = name; while (p < start) { while (*p == CTLQUOTEMARK) p++; if (*p == CTLESC) p++; *enddir++ = *p++; if (enddir == expdir_end) return; } } if (enddir == expdir) { p = "."; } else if (enddir == expdir + 1 && *expdir == '/') { p = "/"; } else { p = expdir; enddir[-1] = '\0'; } if ((dirp = opendir(p)) == NULL) return; if (enddir != expdir) enddir[-1] = '/'; if (*endname == 0) { atend = 1; } else { atend = 0; *endname = '\0'; endname += esc + 1; } matchdot = 0; p = start; while (*p == CTLQUOTEMARK) p++; if (*p == CTLESC) p++; if (*p == '.') matchdot++; while (! int_pending() && (dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.' && ! matchdot) continue; if (patmatch(start, dp->d_name, 0)) { namlen = dp->d_namlen; if (enddir + namlen + 1 > expdir_end) continue; memcpy(enddir, dp->d_name, namlen + 1); if (atend) addfname(expdir); else { if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_DIR && dp->d_type != DT_LNK) continue; if (enddir + namlen + 2 > expdir_end) continue; enddir[namlen] = '/'; enddir[namlen + 1] = '\0'; expmeta(enddir + namlen + 1, endname); } } } closedir(dirp); if (! atend) endname[-esc - 1] = esc ? CTLESC : '/'; }
STATIC void expmeta(shinstance *psh, char *enddir, char *name) { char *p; const char *cp; char *q; char *start; char *endname; int metaflag; struct stat statb; shdir *dirp; shdirent *dp; int atend; int matchdot; metaflag = 0; start = name; for (p = name ; ; p++) { if (*p == '*' || *p == '?') metaflag = 1; else if (*p == '[') { q = p + 1; if (*q == '!') q++; for (;;) { while (*q == CTLQUOTEMARK) q++; if (*q == CTLESC) q++; if (*q == '/' || *q == '\0') break; if (*++q == ']') { metaflag = 1; break; } } } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { metaflag = 1; } else if (*p == '\0') break; else if (*p == CTLQUOTEMARK) continue; else if (*p == CTLESC) p++; if (*p == '/') { if (metaflag) break; start = p + 1; } } if (metaflag == 0) { /* we've reached the end of the file name */ if (enddir != psh->expdir) metaflag++; for (p = name ; ; p++) { if (*p == CTLQUOTEMARK) continue; if (*p == CTLESC) p++; *enddir++ = *p; if (*p == '\0') break; } if (metaflag == 0 || shfile_lstat(&psh->fdtab, psh->expdir, &statb) >= 0) addfname(psh, psh->expdir); TRACE2((psh, "expandarg: return #1 (metaflag=%d)\n", metaflag)); return; } endname = p; if (start != name) { p = name; while (p < start) { while (*p == CTLQUOTEMARK) p++; if (*p == CTLESC) p++; *enddir++ = *p++; } } if (enddir == psh->expdir) { cp = "."; } else if (enddir == psh->expdir + 1 && *psh->expdir == '/') { cp = "/"; } else { cp = psh->expdir; enddir[-1] = '\0'; } if ((dirp = shfile_opendir(&psh->fdtab, cp)) == NULL) { TRACE2((psh, "expandarg: return #2 (shfile_opendir(,%s) failed)\n", cp)); return; } if (enddir != psh->expdir) enddir[-1] = '/'; if (*endname == 0) { atend = 1; } else { atend = 0; *endname++ = '\0'; } matchdot = 0; p = start; while (*p == CTLQUOTEMARK) p++; if (*p == CTLESC) p++; if (*p == '.') matchdot++; while (! int_pending() && (dp = shfile_readdir(dirp)) != NULL) { if (dp->name[0] == '.' && ! matchdot) continue; if (patmatch(psh, start, dp->name, 0)) { if (atend) { scopy(dp->name, enddir); addfname(psh, psh->expdir); } else { for (p = enddir, cp = dp->name; (*p++ = *cp++) != '\0';) continue; p[-1] = '/'; expmeta(psh, p, endname); } } } shfile_closedir(dirp); if (! atend) endname[-1] = '/'; }
STATIC void expmeta(char *enddir, char *name) { char *p; const char *cp; char *q; char *start; char *endname; int metaflag; struct stat statb; DIR *dirp; struct dirent *dp; int atend; int matchdot; metaflag = 0; start = name; for (p = name ; ; p++) { if (*p == '*' || *p == '?') metaflag = 1; else if (*p == '[') { q = p + 1; if (*q == '!') q++; for (;;) { while (*q == CTLQUOTEMARK) q++; if (*q == CTLESC) q++; if (*q == '/' || *q == '\0') break; if (*++q == ']') { metaflag = 1; break; } } } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { metaflag = 1; } else if (*p == '\0') break; else if (*p == CTLQUOTEMARK) continue; else if (*p == CTLESC) p++; if (*p == '/') { if (metaflag) break; start = p + 1; } } if (metaflag == 0) { /* we've reached the end of the file name */ if (enddir != expdir) metaflag++; for (p = name ; ; p++) { if (*p == CTLQUOTEMARK) continue; if (*p == CTLESC) p++; *enddir++ = *p; if (*p == '\0') break; } if (metaflag == 0 || lstat(expdir, &statb) >= 0) addfname(expdir); return; } endname = p; if (start != name) { p = name; while (p < start) { while (*p == CTLQUOTEMARK) p++; if (*p == CTLESC) p++; *enddir++ = *p++; } } if (enddir == expdir) { cp = "."; } else if (enddir == expdir + 1 && *expdir == '/') { cp = "/"; } else { cp = expdir; enddir[-1] = '\0'; } if ((dirp = opendir(cp)) == NULL) return; if (enddir != expdir) enddir[-1] = '/'; if (*endname == 0) { atend = 1; } else { atend = 0; *endname++ = '\0'; } matchdot = 0; p = start; while (*p == CTLQUOTEMARK) p++; if (*p == CTLESC) p++; if (*p == '.') matchdot++; while (! int_pending() && (dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.' && ! matchdot) continue; if (patmatch(start, dp->d_name, 0)) { if (atend) { scopy(dp->d_name, enddir); addfname(expdir); } else { for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';) continue; p[-1] = '/'; expmeta(p, endname); } } } closedir(dirp); if (! atend) endname[-1] = '/'; }