static void
globsort(word *left, word *right)
{
char **list;
word *a;
int n = 0;
for(a = left;a!=right;a = a->next) n++;
list = (char **)emalloc(n*sizeof(char *));
for(a = left,n = 0;a!=right;a = a->next,n++) list[n] = a->word;
qsort((void *)list, n, sizeof(void *), globcmp);
for(a = left,n = 0;a!=right;a = a->next,n++) a->word = list[n];
free(list);
}
/*
* Does the string s match the pattern p
* . and .. are only matched by patterns starting with .
* * matches any sequence of characters
* ? matches any single character
* [...] matches the enclosed list of characters
*/
static word*
globdir(word *list, char *p, char *name, char *namep)
{
char *t, *newp;
int f;
/* scan the pattern looking for a component with a metacharacter in it */
if(*p=='\0')
return newword(name, list);
t = namep;
newp = p;
while(*newp){
if(*newp==GLOB)
break;
*t=*newp++;
if(*t++=='/'){
namep = t;
p = newp;
}
}
/* If we ran out of pattern, append the name if accessible */
if(*newp=='\0'){
*t='\0';
if(access(name, 0)==0)
list = newword(name, list);
return list;
}
/* read the directory and recur for any entry that matches */
*namep='\0';
if((f = Opendir(name[0]?name:".")) >= 0){
while(*newp!='/' && *newp!='\0') newp++;
while(Readdir(f, namep, *newp=='/')){
if(matchfn(namep, p)){
for(t = namep;*t;t++);
list = globdir(list, newp, name, t);
}
}
Closedir(f);
}
return list;
}
/*
* Subsitute a word with its glob in place.
*/
static void
globword(word *w)
{
word *left, *right;
char *name;