static int glob1(char *pattern, glob_t *pglob, size_t *limit) { char pathbuf[MAXPATH]; // A null pathname is invalid -- POSIX 1003.1 sect. 2.4. if (*pattern == EOS) return 0; return glob2(pathbuf, pathbuf, pathbuf + MAXPATH - 1, pattern, pglob, limit); }
int main () { Char pathbuf[MAXPATHLEN+1]; Char *bound = pathbuf + sizeof(pathbuf) - 1; glob2 (pathbuf, bound); return 0; }
static int glob1 ( Char *pattern, glob_t *pglob ) { Char pathbuf[MAXPATHLEN+1]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf, pattern, pglob)); }
static int glob1(Char *pattern, glob_t *pglob, size_t *limit) { Char pathbuf[MaxPathLen+1]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == CHAR_EOS) return(0); return(glob2(pathbuf, pathbuf, pattern, pglob, limit)); }
static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { Char pathbuf[PATH_MAX]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return 0; return glob2(pathbuf, pathbuf + PATH_MAX - 1, pathbuf, pathbuf + PATH_MAX - 1, pattern, pattern_last, pglob, limitp); }
static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, pathbuf, pathbuf+MAXPATHLEN-1, pattern, pattern_last, pglob, limitp)); }
static int glob1(Char *pattern, glob_t *pglob, int no_match) { struct strbuf pathbuf = strbuf_INIT; int err; /* * a null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return (0); err = glob2(&pathbuf, pattern, pglob, no_match); xfree(pathbuf.s); return err; }
static int glob1(Char *pattern, glob_t *pglob, size_t *limit) { Char pathbuf[MAXPATHLEN+1]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); /* * we save one character so that we can use ptr >= limit, * in the general case when we are appending non nul chars only. */ return(glob2(pathbuf, pathbuf, pathbuf + (sizeof(pathbuf) / sizeof(*pathbuf)) - 1, pattern, pglob, limit)); }
static int glob3(char *pathbuf, char *pathend, char *pathend_last, char *pattern, char *restpattern, glob_t *pglob, size_t *limit) { struct dirent *dp; DIR *dirp; int err; if (pathend > pathend_last) return GLOB_ABORTED; *pathend = EOS; errno = 0; if ((dirp = opendir(pathbuf)) == NULL) { if (pglob->gl_errfunc) { if (pglob->gl_errfunc(pathbuf, errno) || pglob->gl_flags & GLOB_ERR) { return GLOB_ABORTED; } } return 0; } err = 0; // Search directory for matching names while ((dp = readdir(dirp))) { // Initial DOT must be matched literally if (dp->d_name[0] == DOT && *pattern != DOT) continue; if (pathend + dp->d_namlen > pathend_last) return GLOB_ABORTED; memcpy(pathend, dp->d_name, dp->d_namlen); pathend[dp->d_namlen] = 0; if (!match(pathend, pattern, restpattern)) { *pathend = EOS; continue; } err = glob2(pathbuf, pathend + dp->d_namlen, pathend_last, restpattern, pglob, limit); if (err) break; } closedir(dirp); return err; }
int main () { Char *buf; Char *pattern; Char *bound; Char A [MAXPATHLEN+1]; Char B [PATTERNLEN]; klee_make_symbolic(A, sizeof(A), "A"); klee_make_symbolic(B, sizeof(B), "B"); buf = A; pattern = B; bound = A + sizeof(A) - 1; glob2 (buf, buf, bound, pattern); return 0; }
int main() { try { init(); SDL_Surface *screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, SDL_DOUBLEBUF); if (screen == NULL) { throw std::string("Unable to set video mode: ")+SDL_GetError(); } Sprite background("images/falsemirror.bmp", 0.0, 0.0, false); Sprite trees("images/ringotrees.bmp", 1.0, 0.0, true); Sprite flowers("images/ringoflowers.bmp", 1.0, 0.0, true); Sprite cells("images/lastring.bmp", 1.0, 0.0, true); Sprite glob1("images/oil.bmp", 430.0, 315.0, true); Sprite glob2("images/oil.bmp", 430.0, 315.0, true); Sprite glob3("images/oil.bmp", 430.0, 315.0, true); Manager manager(START_X, START_Y, INCR_X, X_VELOCITY, Y_VELOCITY, DISC_VELOCITY, DT); manager.animate(screen, background, trees, flowers, cells, glob1, glob2, glob3); SDL_FreeSurface(screen); } catch(const std::string& msg) { std::cout << msg << std::endl; } catch(...) { std::cout << "oops" << std::endl; } }
static int glob2(const char *pattern, char *epathbuf, /* both point *after* the slash */ int lower, int caseless) { const char *pp, *pslash; char *bp; HANDLE hf; WIN32_FIND_DATA wfd; char *my_pattern; int done; if (strcmp(pattern, "...") == 0) { return glob_dirs(pattern+3, epathbuf, 1, lower, caseless); } if (strncmp(pattern, "...", 3) == 0 && (pattern[3] == '\\' || pattern[3] == '/')) { slash = pattern[3]; return glob_dirs(pattern+4, epathbuf, 1, lower, caseless); } *epathbuf = 0; /* copy as many non-wildcard segments as possible */ pp = pattern; bp = epathbuf; pslash = bp-1; while (1) { if (*pp == ':' || *pp == '\\' || *pp == '/') { pslash = bp; if (strcmp(pp+1, "...") == 0 || (strncmp(pp+1, "...", 3) == 0 && (pp[4] == '/' || pp[4] == '\\'))) { if (*pp != ':') slash = *pp; /* printf("glob2: dots at `%s'\n", pp); */ *bp++ = *pp++; break; } } else if (*pp == '*' || *pp == '?' || *pp == '[') { if (pslash > pathbuf) strncpy(epathbuf, pattern, pslash - pathbuf); pp = pattern + (pslash - epathbuf) + 1; bp = epathbuf + (pslash - epathbuf) + 1; break; } else if (*pp == 0) { break; } /* Upper-case or mixed-case patterns force case-sensitive matches in `fnmatch' for LFN filesystems. They also suppress downcasing 8+3 filenames (on all filesystems). */ else if (!preserve_case) { if (*pp >= 'A' && *pp <= 'Z') { if (use_lfn) caseless = 0; lower = 0; } else if (*pp >= 'a' && *pp <= 'z') lower = 1; } *bp++ = *pp++; } *bp = 0; if (*pp == 0) /* end of pattern? */ { if (CLY_FileExists(pathbuf)) { if (flags & GLOB_MARK) { HANDLE _hf; WIN32_FIND_DATA _wfd; _hf = FindFirstFile(pathbuf, &_wfd); //findfirst(pathbuf, &_ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); if (_hf != INVALID_HANDLE_VALUE && _wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { char *_pathbuf = pathbuf + strlen(pathbuf); *_pathbuf++ = '/'; *_pathbuf = 0; } FindClose(_hf); } if (add(pathbuf)) return GLOB_NOSPACE; } return 0; } /* printf("glob2: initial segment is `%s'\n", pathbuf); */ if (wildcard_nesting) { char s = bp[-1]; bp[-1] = 0; if (!CLY_FileExists(pathbuf)) return 0; bp[-1] = s; } for (pslash = pp; *pslash && *pslash != '\\' && *pslash != '/'; pslash++) if (!preserve_case) { if (*pslash >= 'A' && *pslash <= 'Z') { if (use_lfn) caseless = 0; lower = 0; } else if (*pslash >= 'a' && *pslash <= 'z') lower = 1; } if (*pslash) slash = *pslash; my_pattern = (char *)alloca(pslash - pp + 1); if (my_pattern == 0) return GLOB_NOSPACE; strncpy(my_pattern, pp, pslash - pp); my_pattern[pslash-pp] = 0; /* printf("glob2: `%s' `%s'\n", pathbuf, my_pattern); */ if (strcmp(my_pattern, "...") == 0) { if (glob_dirs(*pslash ? pslash+1 : pslash, bp, 1, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; return 0; } strcpy(bp, "*.*"); hf = FindFirstFile(pathbuf, &wfd); done = (hf == INVALID_HANDLE_VALUE); //done = findfirst(pathbuf, &ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); while (!done) { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || (strcmp(wfd.cFileName, ".") && strcmp(wfd.cFileName, ".."))) { if (fnmatch(my_pattern, wfd.cFileName, FNM_NOESCAPE|FNM_PATHNAME|(caseless ? FNM_NOCASE : 0)) == 0) { strcpy(bp, wfd.cFileName); if (*pslash) { char *tp = bp + strlen(bp); *tp++ = *pslash; *tp = 0; /* printf("nest: `%s' `%s'\n", pslash+1, pathbuf); */ wildcard_nesting++; if (glob2(pslash+1, tp, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; wildcard_nesting--; } else { /* printf("ffmatch: `%s' matching `%s', add `%s'\n", wfd.cFileName, my_pattern, pathbuf); */ if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && (flags & GLOB_MARK)) { bp[strlen(bp)+1] = 0; bp[strlen(bp)] = slash; } if (add(pathbuf)) return GLOB_NOSPACE; } } } done = !FindNextFile(hf, &wfd); } return 0; }
static int glob3(struct strbuf *pathbuf, const Char *pattern, const Char *restpattern, const Char *pglobstar, glob_t *pglob, int no_match) { DIR *dirp; struct dirent *dp; struct stat sbuf; int err; Char m_not = (pglob->gl_flags & GLOB_ALTNOT) ? M_ALTNOT : M_NOT; size_t orig_len; int globstar = 0; int chase_symlinks = 0; const Char *termstar = NULL; strbuf_terminate(pathbuf); orig_len = pathbuf->len; errno = err = 0; while (pglobstar < restpattern) { __Char wc; size_t width = One_Char_mbtowc(&wc, pglobstar, MB_LEN_MAX); if ((pglobstar[0] & M_MASK) == M_ALL && (pglobstar[width] & M_MASK) == M_ALL) { globstar = 1; chase_symlinks = (pglobstar[2 * width] & M_MASK) == M_ALL; termstar = pglobstar + (2 + chase_symlinks) * width; break; } pglobstar += width; } if (globstar) { err = pglobstar==pattern && termstar==restpattern ? *restpattern == EOS ? glob2(pathbuf, restpattern - 1, pglob, no_match) : glob2(pathbuf, restpattern + 1, pglob, no_match) : glob3(pathbuf, pattern, restpattern, termstar, pglob, no_match); if (err) return err; pathbuf->len = orig_len; strbuf_terminate(pathbuf); } if (*pathbuf->s && (Lstat(pathbuf->s, &sbuf) || !S_ISDIR(sbuf.st_mode) #ifdef S_IFLINK && ((globstar && !chase_symlinks) || !S_ISLNK(sbuf.st_mode)) #endif )) return 0; if (!(dirp = Opendir(pathbuf->s))) { /* todo: don't call for ENOENT or ENOTDIR? */ if ((pglob->gl_errfunc && (*pglob->gl_errfunc) (pathbuf->s, errno)) || (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABEND); else return (0); } /* search directory for matching names */ while ((dp = readdir(dirp)) != NULL) { /* initial DOT must be matched literally */ if (dp->d_name[0] == DOT && *pattern != DOT) if (!(pglob->gl_flags & GLOB_DOT) || !dp->d_name[1] || (dp->d_name[1] == DOT && !dp->d_name[2])) continue; /*unless globdot and not . or .. */ pathbuf->len = orig_len; strbuf_append(pathbuf, dp->d_name); strbuf_terminate(pathbuf); if (globstar) { #ifdef S_IFLNK if (!chase_symlinks && (Lstat(pathbuf->s, &sbuf) || S_ISLNK(sbuf.st_mode))) continue; #endif if (match(pathbuf->s + orig_len, pattern, termstar, (int)m_not) == no_match) continue; strbuf_append1(pathbuf, SEP); strbuf_terminate(pathbuf); if ((err = glob2(pathbuf, pglobstar, pglob, no_match)) != 0) break; } else { if (match(pathbuf->s + orig_len, pattern, restpattern, (int) m_not) == no_match) continue; if ((err = glob2(pathbuf, restpattern, pglob, no_match)) != 0) break; } } /* todo: check error from readdir? */ closedir(dirp); return (err); }
static bool glob2(const UChar *ename, const UChar *pattern) { int c*k, rok; /* `[...]' - c*k (class), rok (range) */ UChar c, ec, pc; const UChar *e, *n, *p; e = ename; p = pattern; if ((ec = *e++) != EOS) if ((ec &= ASCII) == EOS) ec = (UChar)QUOTE; switch (pc = *p++) { case EOS: return ec == EOS; case ASTERISK: /* * Ignore all but the last `*' in a group of consecutive * `*' characters to avoid unnecessary glob2() recursion. */ while (*p++ == ASTERISK) ; /* nothing */ if (*--p == EOS) return true; e--; while (*e != EOS) if (glob2(e++, p)) return true; break; case QUESTION: if (ec != EOS) return glob2(e, p); break; case LBRACKET: if (*p == EOS) break; for (c = UCHAR(EOS), c*k = rok = 0, n = p + 1; ; ) { pc = *p++; if (pc == RBRACKET && p > n) { if (c*k > 0 || rok > 0) return glob2(e, p); break; } if (*p == EOS) break; if (pc == HYPHEN && c != EOS && *p != RBRACKET) { pc = *p++ & ASCII; if (*p == EOS) break; if (c <= ec && ec <= pc) rok++; else if (c == ec) c*k--; c = UCHAR(EOS); } else { c = pc & ASCII; if (ec == c) c*k++; } } break; default: if ((pc & ASCII) == ec) return glob2(e, p); } return false; }
static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, struct glob_lim *limitp, int recursion) { struct dirent *dp; DIR *dirp; int err; char buf[PATH_MAX]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(void *); if (pathend > pathend_last) { return 1; } *pathend = EOS; errno = 0; if (recursion >= pglob->gl_maxdepth) { return GLOB_NOSPACE; } if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) { return GLOB_ABORTED; } if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) { return GLOB_ABORTED; } } return 0; } err = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) { readdirfunc = pglob->gl_readdir; } else { readdirfunc = (struct dirent *(*)(void *))readdir; } while ((dp = (*readdirfunc)(dirp))) { unsigned char *sc; Char *dc; if (limitp->glim_readdir++ >= pglob->gl_maxfiles) { errno = 0; *pathend++ = SEP; *pathend = EOS; err = GLOB_NOSPACE; break; } /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) { continue; } dc = pathend; sc = (unsigned char *) dp->d_name; while (dc < pathend_last && (*dc++ = *sc++) != EOS) ; if (dc >= pathend_last) { *dc = EOS; err = 1; break; } if (!match(pathend, pattern, restpattern, pglob->gl_maxdepth)) { *pathend = EOS; continue; } err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, restpattern, restpattern_last, pglob, limitp, recursion); if (err) { break; } } if (pglob->gl_flags & GLOB_ALTDIRFUNC) { (*pglob->gl_closedir)(dirp); } else { closedir(dirp); } return err; }
static int glob_dirs(const char *rest, char *epathbuf, int first) /* rest is ptr to null or ptr after slash, bp after slash */ { struct ffblk ff; int done; /* printf("glob_dirs[%d]: rest=`%s' %c epathbuf=`%s' %c pathbuf=`%s'\n", wildcard_nesting, rest, *rest, epathbuf, *epathbuf, pathbuf); */ if (first) { if (*rest) { glob2(rest, epathbuf); } else { char sl = epathbuf[-1]; *epathbuf = 0; /* printf("end, checking `%s'\n", pathbuf); */ if (epathbuf == pathbuf) { epathbuf[0] = '.'; epathbuf[1] = 0; } else epathbuf[-1] = 0; if (__file_exists(pathbuf)) add(pathbuf); epathbuf[-1] = sl; } } strcpy(epathbuf, "*.*"); done = findfirst(pathbuf, &ff, FA_DIREC); while (!done) { if ((ff.ff_name[0] != '.') && (ff.ff_attrib & FA_DIREC)) { int i; char *tp; if (use_lower_case) for (i=0; ff.ff_name[i] && i<13; i++) ff.ff_name[i] = tolower(ff.ff_name[i]); /* printf("found `%s' `%s'\n", pathbuf, ff.ff_name); */ strcpy(epathbuf, ff.ff_name); tp = epathbuf + strlen(epathbuf); *tp++ = slash; *tp = 0; wildcard_nesting++; if (*rest) { glob2(rest, tp); } else { if (!(flags & GLOB_MARK)) tp[-1] = 0; add(pathbuf); tp[-1] = slash; } *tp = 0; glob_dirs(rest, tp, 0); wildcard_nesting--; } done = findnext(&ff); } return 0; }
static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, struct glob_lim *limitp) { struct dirent *dp; DIR *dirp; int err; char buf[PATH_MAX]; if (pathend > pathend_last) return 1; *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return GLOB_ABORTED; if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return GLOB_ABORTED; } return 0; } err = 0; /* Search directory for matching names. */ while ((dp = readdir(dirp))) { unsigned char *sc; Char *dc; if ((pglob->gl_flags & GLOB_LIMIT) && limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) { errno = 0; *pathend++ = SEP; *pathend = EOS; err = GLOB_NOSPACE; break; } /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; dc = pathend; sc = (unsigned char *) dp->d_name; while (dc < pathend_last && (*dc++ = *sc++) != EOS) continue; if (dc >= pathend_last) { *dc = EOS; err = 1; break; } if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) { *pathend = EOS; continue; } err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, restpattern, restpattern_last, pglob, limitp); if (err) break; } closedir(dirp); return err; }
static int glob3(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, glob_t *pglob, size_t *limit) { struct dirent *dp; DIR *dirp; int err; char buf[MAXPATHLEN]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(); if (pathend > pathend_last) return (GLOB_ABORTED); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return (GLOB_ABORTED); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return (GLOB_ABORTED); } return(0); } err = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else readdirfunc = readdir; while ((dp = (*readdirfunc)(dirp))) { char *sc; Char *dc; wchar_t wc; size_t clen; mbstate_t mbs; /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; memset(&mbs, 0, sizeof(mbs)); dc = pathend; sc = dp->d_name; while (dc < pathend_last) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { wc = *sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) break; sc += clen; } if (!match(pathend, pattern, restpattern)) { *pathend = EOS; continue; } err = glob2(pathbuf, --dc, pathend_last, restpattern, pglob, limit); if (err) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); return(err); }
static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, size_t *limitp) { struct dirent *dp; DIR *dirp; int err; char buf[MAXPATHLEN]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(void *); if (pathend > pathend_last) return (1); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return(GLOB_ABORTED); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return(GLOB_ABORTED); } return(0); } err = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else readdirfunc = (struct dirent *(*)(void *))readdir; while ((dp = (*readdirfunc)(dirp))) { u_char *sc; Char *dc; /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; dc = pathend; sc = (u_char *) dp->d_name; while (dc < pathend_last && (*dc++ = *sc++) != EOS) ; if (dc >= pathend_last) { *dc = EOS; err = 1; break; } if (!match(pathend, pattern, restpattern)) { *pathend = EOS; continue; } err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, restpattern, restpattern_last, pglob, limitp); if (err) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); return(err); }
/* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h; const Char *p; Char *b, *eb; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; /* Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, h = (char *) patbuf; h < (char *)eb && *p && *p != SLASH; *h++ = *p++) ; *h = EOS; #if 0 if (h == (char *)eb) return what; #endif if (((char *) patbuf)[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME * first and then trying the password file */ #if 0 if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { #endif if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { if ((pwd = getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; } } else { /* * Expand a ~user */ if ((pwd = getpwnam((char*) patbuf)) == NULL) return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ for (b = patbuf; b < eb && *h; *b++ = *h++) ; /* Append the rest of the pattern */ while (b < eb && (*b++ = *p++) != EOS) ; *b = EOS; return patbuf; } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0(const Char *pattern, glob_t *pglob) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[MAXPATHLEN]; size_t limit = 0; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return(globextend(pattern, pglob, &limit)); else return(GLOB_NOMATCH); } if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); } static int compare(const void *p, const void *q) { return(strcmp(*(char **)p, *(char **)q)); } static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, pathbuf, pathbuf+MAXPATHLEN-1, pattern, pattern_last, pglob, limitp)); }
static int glob3(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern, Char *restpattern, glob_t *pglob, size_t *limit) { struct dirent *dp; DIR *dirp; int error; char buf[MAXPATHLEN]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(void *); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return (GLOB_ABORTED); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return (GLOB_ABORTED); } /* * Posix/XOpen: glob should return when it encounters a * directory that it cannot open or read * XXX: Should we ignore ENOTDIR and ENOENT though? * I think that Posix had in mind EPERM... */ if (pglob->gl_flags & GLOB_ERR) return (GLOB_ABORTED); return(0); } error = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else readdirfunc = (struct dirent *(*)(void *)) readdir; while ((dp = (*readdirfunc)(dirp)) != NULL) { unsigned char *sc; Char *dc; /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; /* * The resulting string contains EOS, so we can * use the pathlim character, if it is the nul */ for (sc = (unsigned char *) dp->d_name, dc = pathend; dc <= pathlim && (*dc++ = *sc++) != EOS;) continue; /* * Have we filled the buffer without seeing EOS? */ if (dc > pathlim && *pathlim != EOS) { /* * Abort when requested by caller, otherwise * reset pathend back to last SEP and continue * with next dir entry. */ if (pglob->gl_flags & GLOB_ERR) { error = GLOB_ABORTED; break; } else { *pathend = EOS; continue; } } if (!match(pathend, pattern, restpattern)) { *pathend = EOS; continue; } error = glob2(pathbuf, --dc, pathlim, restpattern, pglob, limit); if (error) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); /* * Again Posix X/Open issue with regards to error handling. */ if ((error || errno) && (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABORTED); return(error); }
static int glob3 ( Char *pathbuf, Char *pathend, Char *pattern, Char *restpattern, glob_t *pglob ) { register struct dirent *dp; DIR *dirp; int err; char buf[MAXPATHLEN]; int nocase = 0; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { g_Ctoc(pathbuf, buf); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return (GLOB_ABEND); } return(0); } err = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else readdirfunc = readdir; if (pglob->gl_flags & GLOB_INSENSITIVE) nocase = 1; while ((dp = (*readdirfunc)(dirp))) { register u_char *sc; register Char *dc; #if defined(__EMX__) || defined(WINNT) if(dp->d_name && *(dp->d_name)) strlwr(dp->d_name); #endif /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; for (sc = (u_char *) dp->d_name, dc = pathend; (*dc++ = *sc++) != EOS;) continue; if (!match(pathend, pattern, restpattern, nocase)) { *pathend = EOS; continue; } err = glob2(pathbuf, --dc, restpattern, pglob); if (err) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); return(err); }
int glob(const char *_pattern, int _flags, int (*_errfunc)(const char *_epath, int _eerrno), glob_t *_pglob) { char path_buffer[2000]; int l_ofs, l_ptr; pathbuf = path_buffer+1; flags = _flags; errfunc = _errfunc; wildcard_nesting = 0; save_count = 0; save_list = 0; preserve_case = (char)_preserve_fncase(); slash = '/'; if (!(_flags & GLOB_APPEND)) { _pglob->gl_pathc = 0; _pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) _pglob->gl_offs = 0; } if (glob2(_pattern, pathbuf, preserve_case ? 0 : 1, /*preserve_case ? 0 :*/1) == GLOB_NOSPACE) { return GLOB_NOSPACE; } if (save_count == 0) { if (flags & GLOB_NOCHECK) { if (add(_pattern)) return GLOB_NOSPACE; } else return GLOB_NOMATCH; } if (flags & GLOB_DOOFFS) l_ofs = _pglob->gl_offs; else l_ofs = 0; if (flags & GLOB_APPEND) { _pglob->gl_pathv = (char **)realloc(_pglob->gl_pathv, (l_ofs + _pglob->gl_pathc + save_count + 1) * sizeof(char *)); if (_pglob->gl_pathv == 0) return GLOB_NOSPACE; l_ptr = l_ofs + _pglob->gl_pathc; } else { _pglob->gl_pathv = (char* *)malloc((l_ofs + save_count + 1) * sizeof(char *)); if (_pglob->gl_pathv == 0) return GLOB_NOSPACE; l_ptr = l_ofs; if (l_ofs) memset(_pglob->gl_pathv, 0, l_ofs * sizeof(char *)); } l_ptr += save_count; _pglob->gl_pathv[l_ptr] = 0; while (save_list) { Save *s = save_list; l_ptr --; _pglob->gl_pathv[l_ptr] = save_list->entry; save_list = save_list->prev; free(s); } if (!(flags & GLOB_NOSORT)) qsort(_pglob->gl_pathv + l_ptr, save_count, sizeof(char *), str_compare); _pglob->gl_pathc = l_ptr + save_count; return 0; }
static int glob2(const char *pattern, char *epathbuf) /* both point *after* the slash */ { const char *pp, *pslash; char *bp; struct ffblk ff; char *my_pattern; int done; if (strcmp(pattern, "...") == 0) { return glob_dirs(pattern+3, epathbuf, 1); } if (strncmp(pattern, "...", 3) == 0 && (pattern[3] == '\\' || pattern[3] == '/')) { slash = pattern[3]; return glob_dirs(pattern+4, epathbuf, 1); } *epathbuf = 0; /* copy as many non-wildcard segments as possible */ pp = pattern; bp = epathbuf; pslash = bp-1; while (1) { if (*pp == ':' || *pp == '\\' || *pp == '/') { pslash = bp; if (strcmp(pp+1, "...") == 0 || (strncmp(pp+1, "...", 3) == 0 && (pp[4] == '/' || pp[4] == '\\'))) { if (*pp != ':') slash = *pp; /* printf("glob2: dots at `%s'\n", pp); */ *bp++ = *pp++; break; } } else if (*pp == '*' || *pp == '?' || *pp == '[') { if (pslash > pathbuf) strncpy(epathbuf, pattern, pslash - pathbuf); pp = pattern + (pslash - epathbuf) + 1; bp = epathbuf + (pslash - epathbuf) + 1; break; } else if (*pp == 0) { break; } else if (islower(*pp)) use_lower_case = 1; else if (isupper(*pp)) use_lower_case = 0; *bp++ = *pp++; } *bp = 0; if (*pp == 0) /* end of pattern? */ { if (wildcard_nesting==0 || __file_exists(pathbuf)) add(pathbuf); return 0; } /* printf("glob2: initial segment is `%s'\n", pathbuf); */ if (wildcard_nesting) { char s = bp[-1]; bp[-1] = 0; if (!__file_exists(pathbuf)) return 0; bp[-1] = s; } for (pslash = pp; *pslash && *pslash != '\\' && *pslash != '/'; pslash++) { if (islower(*pslash)) use_lower_case = 1; else if (isupper(*pslash)) use_lower_case = 0; } if (*pslash) slash = *pslash; my_pattern = (char *)alloca(pslash - pp + 1); if (my_pattern == 0) return 0; strncpy(my_pattern, pp, pslash - pp); my_pattern[pslash-pp] = 0; /* printf("glob2: `%s' `%s'\n", pathbuf, my_pattern); */ if (strcmp(my_pattern, "...") == 0) { glob_dirs(*pslash ? pslash+1 : pslash, bp, 1); return 0; } strcpy(bp, "*.*"); done = findfirst(pathbuf, &ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); while (!done) { int i; if (ff.ff_name[0] != '.') { if (use_lower_case) for (i=0; ff.ff_name[i] && i<13; i++) ff.ff_name[i] = tolower(ff.ff_name[i]); if (fnmatch(my_pattern, ff.ff_name, FNM_NOESCAPE|FNM_PATHNAME|FNM_NOCASE) == 0) { strcpy(bp, ff.ff_name); if (*pslash) { char *tp = bp + strlen(bp); *tp++ = *pslash; *tp = 0; /* printf("nest: `%s' `%s'\n", pslash+1, pathbuf); */ wildcard_nesting++; glob2(pslash+1, tp); wildcard_nesting--; } else { /* printf("ffmatch: `%s' matching `%s', add `%s'\n", ff.ff_name, my_pattern, pathbuf); */ if (ff.ff_attrib & FA_DIREC & (flags & GLOB_MARK)) { bp[strlen(bp)] = slash; bp[strlen(bp)+1] = 0; } add(pathbuf); } } } done = findnext(&ff); } return 0; }
static int glob_dirs(const char *rest, char *epathbuf, int first, /* rest is ptr to null or ptr after slash, bp after slash */ int lower, int caseless) { // struct ffblk ff; HANDLE hf; WIN32_FIND_DATA wfd; BOOL done; /* printf("glob_dirs[%d]: rest=`%s' %c epathbuf=`%s' %c pathbuf=`%s'\n", wildcard_nesting, rest, *rest, epathbuf, *epathbuf, pathbuf); */ if (first) { if (*rest) { if (glob2(rest, epathbuf, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; } else { char sl = epathbuf[-1]; *epathbuf = 0; /* printf("end, checking `%s'\n", pathbuf); */ if (epathbuf == pathbuf) { epathbuf[0] = '.'; epathbuf[1] = 0; } else epathbuf[-1] = 0; if (CLY_FileExists(pathbuf)) if (add(pathbuf)) return GLOB_NOSPACE; epathbuf[-1] = sl; } } strcpy(epathbuf, "*.*"); hf = FindFirstFile(pathbuf, &wfd); done = (hf == INVALID_HANDLE_VALUE); while (!done) { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(wfd.cFileName, ".") && strcmp(wfd.cFileName, ".."))) { char *tp; strcpy(epathbuf, wfd.cFileName); tp = epathbuf + strlen(epathbuf); *tp++ = slash; *tp = 0; wildcard_nesting++; if (*rest) { if (glob2(rest, tp, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; } else { if (!(flags & GLOB_MARK)) tp[-1] = 0; if (add(pathbuf)) return GLOB_NOSPACE; tp[-1] = slash; } *tp = 0; if (glob_dirs(rest, tp, 0, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; wildcard_nesting--; } done = !FindNextFile(hf, &wfd); } FindClose(hf); return 0; }
static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *pattern_last, Char *restpattern, Char *restpattern_last, glob_t *pglob, size_t *limitp) { register Direntry_t *dp; DIR *dirp; int err; int nocase; char buf[MAXPATHLEN]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ Direntry_t *(*readdirfunc)(DIR*); if (pathend > pathend_last) return (1); *pathend = BG_EOS; errno = 0; #ifdef VMS { Char *q = pathend; if (q - pathbuf > 5) { q -= 5; if (q[0] == '.' && tolower(q[1]) == 'd' && tolower(q[2]) == 'i' && tolower(q[3]) == 'r' && q[4] == '/') { q[0] = '/'; q[1] = BG_EOS; pathend = q+1; } } } #endif if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return (GLOB_ABEND); if (pglob->gl_errfunc(buf, errno) || (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABEND); } return(0); } err = 0; nocase = ((pglob->gl_flags & GLOB_NOCASE) != 0); /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = (Direntry_t *(*)(DIR *))pglob->gl_readdir; else readdirfunc = (Direntry_t *(*)(DIR *))my_readdir; while ((dp = (*readdirfunc)(dirp))) { register U8 *sc; register Char *dc; /* Initial BG_DOT must be matched literally. */ if (dp->d_name[0] == BG_DOT && *pattern != BG_DOT) continue; dc = pathend; sc = (U8 *) dp->d_name; while (dc < pathend_last && (*dc++ = *sc++) != BG_EOS) ; if (dc >= pathend_last) { *dc = BG_EOS; err = 1; break; } if (!match(pathend, pattern, restpattern, nocase)) { *pathend = BG_EOS; continue; } err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, restpattern, restpattern_last, pglob, limitp); if (err) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else PerlDir_close(dirp); return(err); }