Exemplo n.º 1
0
/*
 * Perform pathname generation and remove control characters.
 * At this point, the only control characters should be CTLESC.
 * The results are stored in the list dstlist.
 */
static void
expandmeta(char *pattern, struct arglist *dstlist)
{
	char *p;
	int firstmatch;
	char c;

	firstmatch = dstlist->count;
	p = pattern;
	for (; (c = *p) != '\0'; p++) {
		/* fast check for meta chars */
		if (c == '*' || c == '?' || c == '[') {
			INTOFF;
			expmeta(expdir, pattern, dstlist);
			INTON;
			break;
		}
	}
	if (dstlist->count == firstmatch) {
		/*
		 * no matches
		 */
		rmescapes(pattern);
		appendarglist(dstlist, pattern);
	} else {
		qsort(&dstlist->args[firstmatch],
		    dstlist->count - firstmatch,
		    sizeof(dstlist->args[0]), expsortcmp);
	}
}
Exemplo n.º 2
0
STATIC void
expandmeta(shinstance *psh, struct strlist *str, int flag)
{
	char *p;
	struct strlist **savelastp;
	struct strlist *sp;
	char c;
	/* TODO - EXP_REDIR */

	while (str) {
		if (fflag(psh))
			goto nometa;
		p = str->text;
		for (;;) {			/* fast check for meta chars */
			if ((c = *p++) == '\0')
				goto nometa;
			if (c == '*' || c == '?' || c == '[' || c == '!')
				break;
		}
		savelastp = psh->exparg.lastp;
		INTOFF;
		if (psh->expdir == NULL) {
			size_t i = strlen(str->text);
			psh->expdir = ckmalloc(psh, i < 2048 ? 2048 : i); /* XXX */
		}

		expmeta(psh, psh->expdir, str->text);
		ckfree(psh, psh->expdir);
		psh->expdir = NULL;
		INTON;
		if (psh->exparg.lastp == savelastp) {
			/*
			 * no matches
			 */
nometa:
			*psh->exparg.lastp = str;
			rmescapes(psh, str->text);
			psh->exparg.lastp = &str->next;
		} else {
			*psh->exparg.lastp = NULL;
			*savelastp = sp = expsort(*savelastp);
			while (sp->next != NULL)
				sp = sp->next;
			psh->exparg.lastp = &sp->next;
		}
		str = str->next;
	}
}
Exemplo n.º 3
0
/*
 * Perform pathname generation and remove control characters.
 * At this point, the only control characters should be CTLESC and CTLQUOTEMARK.
 * The results are stored in the list exparg.
 */
static void
expandmeta(struct strlist* str, int32_t flag __unused)
{
    cstring_t p;
    struct strlist** savelastp;
    struct strlist* sp;
    char c;
    (void)flag;
    /* TODO - EXP_REDIR */
    while (str)
    {
        if (fflag)
            goto nometa;
        p = str->text;
        for (;;)  			/* fast check for meta chars */
        {
            if ((c = *p++) == '\0')
                goto nometa;
            if (c == '*' || c == '?' || c == '[')
                break;
        }
        savelastp = exparg.lastp;
        INTOFF;
        expmeta(expdir, str->text);
        INTON;
        if (exparg.lastp == savelastp)
        {
            /*
             * no matches
             */
nometa:
            *exparg.lastp = str;
            rmescapes(str->text);
            exparg.lastp = &str->next;
        }
        else
        {
            *exparg.lastp = NULL;
            *savelastp = sp = expsort(*savelastp);
            while (sp->next != NULL)
                sp = sp->next;
            exparg.lastp = &sp->next;
        }
        str = str->next;
    }
}
Exemplo n.º 4
0
/*
 * Perform pathname generation and remove control characters.
 * At this point, the only control characters should be CTLESC and CTLQUOTEMARK.
 * The results are stored in the list exparg.
 */
static void
expandmeta(struct strlist *str)
{
	char *p;
	struct strlist **savelastp;
	struct strlist *sp;
	char c;

	while (str) {
		savelastp = exparg.lastp;
		if (!fflag) {
			p = str->text;
			for (; (c = *p) != '\0'; p++) {
				/* fast check for meta chars */
				if (c == '*' || c == '?' || c == '[') {
		INTOFF;
		expmeta(expdir, str->text);
		INTON;
					break;
				}
			}
		}
		if (exparg.lastp == savelastp) {
			/*
			 * no matches
			 */
			*exparg.lastp = str;
			rmescapes(str->text);
			exparg.lastp = &str->next;
		} else {
			*exparg.lastp = NULL;
			*savelastp = sp = expsort(*savelastp);
			while (sp->next != NULL)
				sp = sp->next;
			exparg.lastp = &sp->next;
		}
		str = str->next;
	}
}
Exemplo n.º 5
0
static void
expmeta(char *enddir, char *name)
{
	const char *p;
	const char *q;
	const char *start;
	char *endname;
	int metaflag;
	struct stat statb;
	DIR *dirp;
	struct dirent *dp;
	int atend;
	int matchdot;
	int esc;
	int namlen;

	metaflag = 0;
	start = name;
	for (p = name; esc = 0, *p; p += esc + 1) {
		if (*p == '*' || *p == '?')
			metaflag = 1;
		else if (*p == '[') {
			q = p + 1;
			if (*q == '!' || *q == '^')
				q++;
			for (;;) {
				while (*q == CTLQUOTEMARK)
					q++;
				if (*q == CTLESC)
					q++;
				if (*q == '/' || *q == '\0')
					break;
				if (*++q == ']') {
					metaflag = 1;
					break;
				}
			}
		} else if (*p == '\0')
			break;
		else if (*p == CTLQUOTEMARK)
			continue;
		else {
			if (*p == CTLESC)
				esc++;
			if (p[esc] == '/') {
				if (metaflag)
					break;
				start = p + esc + 1;
			}
		}
	}
	if (metaflag == 0) {	/* we've reached the end of the file name */
		if (enddir != expdir)
			metaflag++;
		for (p = name ; ; p++) {
			if (*p == CTLQUOTEMARK)
				continue;
			if (*p == CTLESC)
				p++;
			*enddir++ = *p;
			if (*p == '\0')
				break;
			if (enddir == expdir_end)
				return;
		}
		if (metaflag == 0 || lstat(expdir, &statb) >= 0)
			addfname(expdir);
		return;
	}
	endname = name + (p - name);
	if (start != name) {
		p = name;
		while (p < start) {
			while (*p == CTLQUOTEMARK)
				p++;
			if (*p == CTLESC)
				p++;
			*enddir++ = *p++;
			if (enddir == expdir_end)
				return;
		}
	}
	if (enddir == expdir) {
		p = ".";
	} else if (enddir == expdir + 1 && *expdir == '/') {
		p = "/";
	} else {
		p = expdir;
		enddir[-1] = '\0';
	}
	if ((dirp = opendir(p)) == NULL)
		return;
	if (enddir != expdir)
		enddir[-1] = '/';
	if (*endname == 0) {
		atend = 1;
	} else {
		atend = 0;
		*endname = '\0';
		endname += esc + 1;
	}
	matchdot = 0;
	p = start;
	while (*p == CTLQUOTEMARK)
		p++;
	if (*p == CTLESC)
		p++;
	if (*p == '.')
		matchdot++;
	while (! int_pending() && (dp = readdir(dirp)) != NULL) {
		if (dp->d_name[0] == '.' && ! matchdot)
			continue;
		if (patmatch(start, dp->d_name, 0)) {
			namlen = dp->d_namlen;
			if (enddir + namlen + 1 > expdir_end)
				continue;
			memcpy(enddir, dp->d_name, namlen + 1);
			if (atend)
				addfname(expdir);
			else {
				if (dp->d_type != DT_UNKNOWN &&
				    dp->d_type != DT_DIR &&
				    dp->d_type != DT_LNK)
					continue;
				if (enddir + namlen + 2 > expdir_end)
					continue;
				enddir[namlen] = '/';
				enddir[namlen + 1] = '\0';
				expmeta(enddir + namlen + 1, endname);
			}
		}
	}
	closedir(dirp);
	if (! atend)
		endname[-esc - 1] = esc ? CTLESC : '/';
}
Exemplo n.º 6
0
STATIC void
expmeta(shinstance *psh, char *enddir, char *name)
{
	char *p;
	const char *cp;
	char *q;
	char *start;
	char *endname;
	int metaflag;
	struct stat statb;
	shdir *dirp;
	shdirent *dp;
	int atend;
	int matchdot;

	metaflag = 0;
	start = name;
	for (p = name ; ; p++) {
		if (*p == '*' || *p == '?')
			metaflag = 1;
		else if (*p == '[') {
			q = p + 1;
			if (*q == '!')
				q++;
			for (;;) {
				while (*q == CTLQUOTEMARK)
					q++;
				if (*q == CTLESC)
					q++;
				if (*q == '/' || *q == '\0')
					break;
				if (*++q == ']') {
					metaflag = 1;
					break;
				}
			}
		} else if (*p == '!' && p[1] == '!'	&& (p == name || p[-1] == '/')) {
			metaflag = 1;
		} else if (*p == '\0')
			break;
		else if (*p == CTLQUOTEMARK)
			continue;
		else if (*p == CTLESC)
			p++;
		if (*p == '/') {
			if (metaflag)
				break;
			start = p + 1;
		}
	}
	if (metaflag == 0) {	/* we've reached the end of the file name */
		if (enddir != psh->expdir)
			metaflag++;
		for (p = name ; ; p++) {
			if (*p == CTLQUOTEMARK)
				continue;
			if (*p == CTLESC)
				p++;
			*enddir++ = *p;
			if (*p == '\0')
				break;
		}
		if (metaflag == 0 || shfile_lstat(&psh->fdtab, psh->expdir, &statb) >= 0)
			addfname(psh, psh->expdir);
		TRACE2((psh, "expandarg: return #1 (metaflag=%d)\n", metaflag));
		return;
	}
	endname = p;
	if (start != name) {
		p = name;
		while (p < start) {
			while (*p == CTLQUOTEMARK)
				p++;
			if (*p == CTLESC)
				p++;
			*enddir++ = *p++;
		}
	}
	if (enddir == psh->expdir) {
		cp = ".";
	} else if (enddir == psh->expdir + 1 && *psh->expdir == '/') {
		cp = "/";
	} else {
		cp = psh->expdir;
		enddir[-1] = '\0';
	}
	if ((dirp = shfile_opendir(&psh->fdtab, cp)) == NULL) {
		TRACE2((psh, "expandarg: return #2 (shfile_opendir(,%s) failed)\n", cp));
		return;
	}
	if (enddir != psh->expdir)
		enddir[-1] = '/';
	if (*endname == 0) {
		atend = 1;
	} else {
		atend = 0;
		*endname++ = '\0';
	}
	matchdot = 0;
	p = start;
	while (*p == CTLQUOTEMARK)
		p++;
	if (*p == CTLESC)
		p++;
	if (*p == '.')
		matchdot++;
	while (! int_pending() && (dp = shfile_readdir(dirp)) != NULL) {
		if (dp->name[0] == '.' && ! matchdot)
			continue;
		if (patmatch(psh, start, dp->name, 0)) {
			if (atend) {
				scopy(dp->name, enddir);
				addfname(psh, psh->expdir);
			} else {
				for (p = enddir, cp = dp->name;
				     (*p++ = *cp++) != '\0';)
					continue;
				p[-1] = '/';
				expmeta(psh, p, endname);
			}
		}
	}
	shfile_closedir(dirp);
	if (! atend)
		endname[-1] = '/';
}
Exemplo n.º 7
0
STATIC void
expmeta(char *enddir, char *name)
{
	char *p;
	const char *cp;
	char *q;
	char *start;
	char *endname;
	int metaflag;
	struct stat statb;
	DIR *dirp;
	struct dirent *dp;
	int atend;
	int matchdot;

	metaflag = 0;
	start = name;
	for (p = name ; ; p++) {
		if (*p == '*' || *p == '?')
			metaflag = 1;
		else if (*p == '[') {
			q = p + 1;
			if (*q == '!')
				q++;
			for (;;) {
				while (*q == CTLQUOTEMARK)
					q++;
				if (*q == CTLESC)
					q++;
				if (*q == '/' || *q == '\0')
					break;
				if (*++q == ']') {
					metaflag = 1;
					break;
				}
			}
		} else if (*p == '!' && p[1] == '!'	&& (p == name || p[-1] == '/')) {
			metaflag = 1;
		} else if (*p == '\0')
			break;
		else if (*p == CTLQUOTEMARK)
			continue;
		else if (*p == CTLESC)
			p++;
		if (*p == '/') {
			if (metaflag)
				break;
			start = p + 1;
		}
	}
	if (metaflag == 0) {	/* we've reached the end of the file name */
		if (enddir != expdir)
			metaflag++;
		for (p = name ; ; p++) {
			if (*p == CTLQUOTEMARK)
				continue;
			if (*p == CTLESC)
				p++;
			*enddir++ = *p;
			if (*p == '\0')
				break;
		}
		if (metaflag == 0 || lstat(expdir, &statb) >= 0)
			addfname(expdir);
		return;
	}
	endname = p;
	if (start != name) {
		p = name;
		while (p < start) {
			while (*p == CTLQUOTEMARK)
				p++;
			if (*p == CTLESC)
				p++;
			*enddir++ = *p++;
		}
	}
	if (enddir == expdir) {
		cp = ".";
	} else if (enddir == expdir + 1 && *expdir == '/') {
		cp = "/";
	} else {
		cp = expdir;
		enddir[-1] = '\0';
	}
	if ((dirp = opendir(cp)) == NULL)
		return;
	if (enddir != expdir)
		enddir[-1] = '/';
	if (*endname == 0) {
		atend = 1;
	} else {
		atend = 0;
		*endname++ = '\0';
	}
	matchdot = 0;
	p = start;
	while (*p == CTLQUOTEMARK)
		p++;
	if (*p == CTLESC)
		p++;
	if (*p == '.')
		matchdot++;
	while (! int_pending() && (dp = readdir(dirp)) != NULL) {
		if (dp->d_name[0] == '.' && ! matchdot)
			continue;
		if (patmatch(start, dp->d_name, 0)) {
			if (atend) {
				scopy(dp->d_name, enddir);
				addfname(expdir);
			} else {
				for (p = enddir, cp = dp->d_name;
				     (*p++ = *cp++) != '\0';)
					continue;
				p[-1] = '/';
				expmeta(p, endname);
			}
		}
	}
	closedir(dirp);
	if (! atend)
		endname[-1] = '/';
}