Ejemplo n.º 1
0
    str * next() {
        switch(__last_yield) {
            case 0: goto __after_yield_0;
            case 1: goto __after_yield_1;
            case 2: goto __after_yield_2;
            case 3: goto __after_yield_3;
            default: break;
        }
        if ((!has_magic(pathname))) {
            if (__os__::__path__::lexists(pathname)) {
                __last_yield = 0;
                return pathname;
                __after_yield_0:;
            }
            throw new StopIteration();
        }
        __0 = __os__::__path__::split(pathname);
        dirname = __0->__getfirst__();
        basename = __0->__getsecond__();
        if ((!___bool(dirname))) {

            FOR_IN_SEQ(name,glob1(__os__::curdir, basename),1,3)
                __last_yield = 1;
                return name;
                __after_yield_1:;
            END_FOR

            throw new StopIteration();
        }
        if (has_magic(dirname)) {
            dirs = iglob(dirname);
        }
        else {
            dirs = (new list<str *>(1, dirname));
        }
        if (has_magic(basename)) {

            FOR_IN(dirname,dirs,5)

                FOR_IN_SEQ(name,glob1(dirname, basename),7,9)
                    __last_yield = 2;
                    return __os__::__path__::join(2, dirname, name);
                    __after_yield_2:;
                END_FOR

            END_FOR

        }
        else {
Ejemplo n.º 2
0
/*
 * 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(GDir *dir, const gchar *pattern, wapi_glob_t *pglob, gboolean ignorecase,
	gboolean unique)
{
	const gchar *qpatnext;
	int c, err, oldpathc;
	gchar *bufnext, patbuf[PATH_MAX];
	size_t limit = 0;

	qpatnext = pattern;
	oldpathc = pglob->gl_pathc;
	bufnext = patbuf;

	/* We don't need to check for buffer overflow any more. */
	while ((c = *qpatnext++) != EOS) {
		switch (c) {
		case QUESTION:
			pglob->gl_flags |= WAPI_GLOB_MAGCHAR;
			*bufnext++ = M_ONE;
			break;
		case STAR:
			pglob->gl_flags |= WAPI_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_ENABLED
	qprintf("glob0:", patbuf);
#endif

	if ((err = glob1(dir, patbuf, patbuf+PATH_MAX-1, pglob, &limit,
			 ignorecase, unique)) != 0)
		return(err);

	if (pglob->gl_pathc == oldpathc) {
		return(WAPI_GLOB_NOMATCH);
	}

	return(0);
}
Ejemplo n.º 3
0
/* glob0 -- glob a list, (destructively) passing through entries we don't care about */
static List *glob0(List *list, StrList *quote) {
	List *result, **prevp, *expand1;
	
	for (result = NULL, prevp = &result; list != NULL; list = list->next, quote = quote->next) {
		char *str;
		if (
			quote->str == QUOTED
			|| !haswild(str = getstr(list->term), quote->str)
			|| (expand1 = glob1(str, quote->str)) == NULL
		) {
			*prevp = list;
			prevp = &list->next;
		} else {
			*prevp = sortlist(expand1);
			while (*prevp != NULL)
				prevp = &(*prevp)->next;
		}
	}
	return result;
}
Ejemplo n.º 4
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;  }
}
Ejemplo n.º 5
0
/*
 * 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.
 */
int
glob(const char *pattern, int flags, int (*errfunc) (const char *, int),
     glob_t *pglob)
{
    int     err, oldpathc;
    Char *bufnext, m_not;
    const unsigned char *patnext;
    int     c, not;
    Char *qpatnext, *patbuf;
    int     no_match;

    patnext = (const unsigned char *) pattern;
    if (!(flags & GLOB_APPEND)) {
	pglob->gl_pathc = 0;
	pglob->gl_pathv = NULL;
	if (!(flags & GLOB_DOOFFS))
	    pglob->gl_offs = 0;
    }
    pglob->gl_flags = flags & ~GLOB_MAGCHAR;
    pglob->gl_errfunc = errfunc;
    oldpathc = pglob->gl_pathc;
    pglob->gl_matchc = 0;

    if (pglob->gl_flags & GLOB_ALTNOT) {
	not = ALTNOT;
	m_not = M_ALTNOT;
    }
    else {
	not = NOT;
	m_not = M_NOT;
    }

    patbuf = xmalloc((strlen(pattern) + 1) * sizeof(*patbuf));
    bufnext = patbuf;

    no_match = *patnext == not;
    if (no_match)
	patnext++;

    if (flags & GLOB_QUOTE) {
	/* Protect the quoted characters */
	while ((c = *patnext++) != EOS) {
#ifdef WIDE_STRINGS
	    int len;
	    
	    len = mblen((const char *)(patnext - 1), MB_LEN_MAX);
	    if (len == -1)
		TCSH_IGNORE(mblen(NULL, 0));
	    else if (len > 1) {
		*bufnext++ = (Char) c;
		while (--len != 0)
		    *bufnext++ = (Char) (*patnext++ | M_PROTECT);
	    } else
#endif /* WIDE_STRINGS */
	    if (c == QUOTE) {
		if ((c = *patnext++) == EOS) {
		    c = QUOTE;
		    --patnext;
		}
		*bufnext++ = (Char) (c | M_PROTECT);
	    }
	    else
		*bufnext++ = (Char) c;
	}
    }
    else
	while ((c = *patnext++) != EOS)
	    *bufnext++ = (Char) c;
    *bufnext = EOS;

    bufnext = patbuf;
    qpatnext = patbuf;
    while ((c = *qpatnext++) != EOS) {
	switch (c) {
	case LBRACKET:
	    c = *qpatnext;
	    if (c == not)
		++qpatnext;
	    if (*qpatnext == EOS ||
		Strchr(qpatnext + 1, RBRACKET) == NULL) {
		*bufnext++ = LBRACKET;
		if (c == not)
		    --qpatnext;
		break;
	    }
	    pglob->gl_flags |= GLOB_MAGCHAR;
	    *bufnext++ = M_SET;
	    if (c == not)
		*bufnext++ = m_not;
	    c = *qpatnext++;
	    do {
		*bufnext++ = LCHAR(c);
		if (*qpatnext == RANGE &&
		    (c = qpatnext[1]) != RBRACKET) {
		    *bufnext++ = M_RNG;
		    *bufnext++ = LCHAR(c);
		    qpatnext += 2;
		}
	    } while ((c = *qpatnext++) != RBRACKET);
	    *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 [or three if globstar],
	     * to avoid exponential behavior
	     */
	    if (bufnext == patbuf || bufnext[-1] != M_ALL ||
	       ((flags & GLOB_STAR) != 0 && 
		 (bufnext - 1 == patbuf || bufnext[-2] != M_ALL ||
		 bufnext - 2 == patbuf || bufnext[-3] != M_ALL)))
		*bufnext++ = M_ALL;
	    break;
	default:
	    *bufnext++ = LCHAR(c);
	    break;
	}
    }
    *bufnext = EOS;
#ifdef DEBUG
    qprintf(patbuf);
#endif

    if ((err = glob1(patbuf, pglob, no_match)) != 0) {
	xfree(patbuf);
	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 && 
	((flags & GLOB_NOCHECK) || 
	 ((flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) {
	if (!(flags & GLOB_QUOTE))
	    globextend(pattern, pglob);
	else {
	    char *copy, *dest;
	    const char *src;

	    /* copy pattern, interpreting quotes */
	    copy = xmalloc(strlen(pattern) + 1);
	    dest = copy;
	    src = pattern;
	    while (*src != EOS) {
		/* Don't interpret quotes. The spec does not say we should do */
		if (*src == QUOTE) {
		    if (*++src == EOS)
			--src;
		}
		*dest++ = *src++;
	    }
	    *dest = EOS;
	    globextend(copy, pglob);
	    xfree(copy);
	}
	xfree(patbuf);
	return 0;
    }
    else if (!(flags & GLOB_NOSORT) && (pglob->gl_pathc != oldpathc))
	qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
	      pglob->gl_pathc - oldpathc, sizeof(char *), compare);
    xfree(patbuf);
    return (0);
}
Ejemplo n.º 6
0
/*
 * 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, struct glob_lim *limitp)
{
    const Char *qpatnext;
    int c, err, oldpathc;
    Char *bufnext, patbuf[PATH_MAX];

    qpatnext = pattern;
    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(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;

    if ((err = glob1(patbuf, patbuf+PATH_MAX - 1, pglob, limitp, 1)) != 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, limitp, NULL);
        } else {
            return GLOB_NOMATCH;
        }
    }
    if (!(pglob->gl_flags & GLOB_NOSORT)) {
        if ((pglob->gl_flags & GLOB_KEEPSTAT)) {
            /* Keep the paths and stat info synced during sort */
            struct glob_path_stat *path_stat;
            int i;
            int n = pglob->gl_pathc - oldpathc;
            int o = pglob->gl_offs + oldpathc;

            if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) {
                return GLOB_NOSPACE;
            }
            for (i = 0; i < n; i++) {
                path_stat[i].gps_path = pglob->gl_pathv[o + i];
                path_stat[i].gps_stat = pglob->gl_statv[o + i];
            }
            qsort(path_stat, n, sizeof(*path_stat), compare_gps);
            for (i = 0; i < n; i++) {
                pglob->gl_pathv[o + i] = path_stat[i].gps_path;
                pglob->gl_statv[o + i] = path_stat[i].gps_stat;
            }
            free(path_stat);
        } else {
            qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
                  pglob->gl_pathc - oldpathc, sizeof(char *),
                  compare);
        }
    }
    return 0;
}
Ejemplo n.º 7
0
/*
 * 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.
 */
static int
glob0(const Char *pattern, glob_t *pglob, size_t *limit)
{
	const Char *qpatnext;
	int err;
	size_t oldpathc;
	Char *bufnext, c, patbuf[MAXPATHLEN];

	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(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, 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);
}
Ejemplo n.º 8
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));
}
Ejemplo n.º 9
0
/*
 * 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 *qpat, *qpatnext;
	int c, err, oldflags, oldpathc;
	Char *bufnext, patbuf[MAXPATHLEN];
	size_t limit = 0;

	qpat = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
	qpatnext = qpat;
	oldflags = pglob->gl_flags;
	oldpathc = pglob->gl_pathc;
	bufnext = patbuf;

	/* We don't need to check for buffer overflow any more. */
	while ((c = *qpatnext++) != BG_EOS) {
		switch (c) {
		case BG_LBRACKET:
			c = *qpatnext;
			if (c == BG_NOT)
				++qpatnext;
			if (*qpatnext == BG_EOS ||
			    g_strchr((Char *) qpatnext+1, BG_RBRACKET) == NULL) {
				*bufnext++ = BG_LBRACKET;
				if (c == BG_NOT)
					--qpatnext;
				break;
			}
			*bufnext++ = M_SET;
			if (c == BG_NOT)
				*bufnext++ = M_NOT;
			c = *qpatnext++;
			do {
				*bufnext++ = CHAR(c);
				if (*qpatnext == BG_RANGE &&
				    (c = qpatnext[1]) != BG_RBRACKET) {
					*bufnext++ = M_RNG;
					*bufnext++ = CHAR(c);
					qpatnext += 2;
				}
			} while ((c = *qpatnext++) != BG_RBRACKET);
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_END;
			break;
		case BG_QUESTION:
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_ONE;
			break;
		case BG_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 = BG_EOS;
#ifdef GLOB_DEBUG
	qprintf("glob0:", patbuf);
#endif /* GLOB_DEBUG */

	if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) {
		pglob->gl_flags = oldflags;
		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 &&
	    ((pglob->gl_flags & GLOB_NOCHECK) ||
	      ((pglob->gl_flags & GLOB_NOMAGIC) &&
	       !(pglob->gl_flags & GLOB_MAGCHAR))))
	{
#ifdef GLOB_DEBUG
		printf("calling globextend from glob0\n");
#endif /* GLOB_DEBUG */
		pglob->gl_flags = oldflags;
		return(globextend(qpat, pglob, &limit));
        }
	else if (!(pglob->gl_flags & GLOB_NOSORT))
		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
		    pglob->gl_pathc - oldpathc, sizeof(char *),
		    (pglob->gl_flags & (GLOB_ALPHASORT|GLOB_NOCASE))
			? ci_compare : compare);
	pglob->gl_flags = oldflags;
	return(0);
}
Ejemplo n.º 10
0
/*
 * 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, struct glob_lim *limitp)
{
	const Char *qpatnext;
	int c, err, oldpathc;
	Char *bufnext, patbuf[PATH_MAX];

	qpatnext = globtilde(pattern, patbuf, PATH_MAX, 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(qpatnext+1, RBRACKET) == NULL) {
				*bufnext++ = LBRACKET;
				if (c == NOT)
					--qpatnext;
				break;
			}
			*bufnext++ = M_SET;
			if (c == NOT)
				*bufnext++ = M_NOT;
			c = *qpatnext++;
			do {
				if (c == LBRACKET && *qpatnext == ':') {
					do {
						err = g_charclass(&qpatnext,
						    &bufnext);
						if (err)
							break;
						c = *qpatnext++;
					} while (c == LBRACKET && *qpatnext == ':');
					if (err == -1 &&
					    !(pglob->gl_flags & GLOB_NOCHECK))
						return GLOB_NOMATCH;
					if (c == RBRACKET)
						break;
				}
				*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 + PATH_MAX - 1, pglob, limitp)) != 0)
		return err;

	/*
	 * If there was no match we are going to append the pattern
	 * if GLOB_NOCHECK was specified.
	 */
	if (pglob->gl_pathc == oldpathc) {
		if ((pglob->gl_flags & GLOB_NOCHECK))
			return globextend(pattern, pglob, limitp, NULL);
		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;
}
Ejemplo n.º 11
0
/*
 * NAME
 *	glob - global command (file name generation)
 *
 * SYNOPSIS
 *	glob command [arg ...]
 *
 * DESCRIPTION
 *	See glob(1) the manual page for full details.
 */
int
main(int argc, char **argv)
{
	const char **gav;	/* points to generated argument vector */
	int pmc = 0;		/* pattern-match count                 */
	int i;
	const char **tav;
	const char *cmd;

	setmyerrexit(&ut_errexit);
	setmyname(argv[0]);
	setmypid(getpid());

	/*
	 * Set-ID execution is not supported.
	 */
	if (geteuid() != getuid() || getegid() != getgid())
		err(SH_ERR, FMT1S, ERR_SETID);

	if (argc < 2)
		err(SH_ERR, FMT1S, ERR_GARGCOUNT);

	if ((gav = malloc(GAVNEW * sizeof(char *))) == NULL) {
		err(SH_ERR, FMT1S, ERR_NOMEM);
		/*NOTREACHED*/
	}

	*gav = NULL;
	gavp = gav;
	gave = &gav[GAVNEW - 1];
	while (*++argv != NULL)
		gav = glob1(gav, *argv, &pmc);
	gavp = NULL;

	if (pmc == 0) {
		err(SH_ERR, FMT1S, ERR_NOMATCH);
		/*NOTREACHED*/
	}

	cmd = gav[0];
	if (IS_LIBEXEC(EQUAL)) {
		for (i = 0; gav[i] != NULL; i++)
			;	/* nothing */
		if ((tav = malloc((i + 1) * sizeof(char *))) == NULL) {
			err(SH_ERR, FMT1S, ERR_NOMEM);
			/*NOTREACHED*/
		}
		if (EQUAL(cmd, "fd2"))
			tav[0] = FD2_PATH;
		else if (EQUAL(cmd, "goto"))
			tav[0] = GOTO_PATH;
		else
			tav[0] = IF_PATH;
		cmd = tav[0];
		(void)memcpy(&tav[1], &gav[1], i * sizeof(char *));
		(void)err_pexec(cmd, (char *const *)tav);
	} else
		(void)err_pexec(cmd, (char *const *)gav);

	/*NOTREACHED*/
	return SH_ERR;
}