Exemple #1
0
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);
}
Exemple #2
0
int main ()
{
  Char pathbuf[MAXPATHLEN+1];

  Char *bound = pathbuf + sizeof(pathbuf) - 1;

  glob2 (pathbuf, bound);

  return 0;
}
Exemple #3
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));
}
Exemple #4
0
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));
}
Exemple #5
0
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);
}
Exemple #6
0
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));
}
Exemple #7
0
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;
}
Exemple #8
0
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));
}
Exemple #9
0
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;
}
Exemple #11
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;  }
}
Exemple #12
0
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;
}
Exemple #13
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);
}
Exemple #14
0
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;
}
Exemple #15
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, 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;
}
Exemple #16
0
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;
}
Exemple #17
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;
}
Exemple #18
0
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);
}
Exemple #19
0
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);
}
Exemple #20
0
/*
 * 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));
}
Exemple #21
0
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);
}
Exemple #22
0
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);
}
Exemple #23
0
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;
}
Exemple #24
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;
}
Exemple #25
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;
}
Exemple #26
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);
}