#include "rc.h" char *globname; Word *globv; int matchfn(char *s, char *p); int globsize(char *p); /* * delete all the GLOB marks from s, in place */ void deglob(char *s) { char *t=s; do{ if(*t==GLOB) t++; *s++=*t; }while(*t++); } int globcmp(void *a, void *b) { return strcmp(*(char**)a, *(char**)b); } void globsort(Word *left, Word *right) { char **list; Word *a; int n=0; for(a=left;a!=right;a=a->next) n++; list=(char **)malloc(n*sizeof(char *)); for(a=left,n=0;a!=right;a=a->next,n++) list[n]=a->word; qsort((char *)list, n, sizeof(char *), globcmp); for(a=left,n=0;a!=right;a=a->next,n++) a->word=list[n]; free(list); } /* * Push names prefixed by globname and suffixed by a match of p onto the astack. * namep points to the end of the prefix in globname. */ void globdir(char *p, char *namep) { char *t, *newp; int fd, n, i; Dir *dir; /* scan the pattern looking for a component with a metacharacter in it */ if(*p=='\0'){ globv=newword(globname, globv); return; } 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(globname, 0)==0) globv=newword(globname, globv); return; } /* read the directory and recur for any entry that matches */ *namep='\0'; fd = open(globname[0]?globname:".", OREAD); if(fd < 0) { fprint(2, "could not open %s: %r\n", globname[0]?globname:"."); return; } if((dir=dirfstat(fd)) == nil || !(dir->mode&DMDIR)) { free(dir); close(fd); return; } free(dir); while(*newp!='/' && *newp!='\0') newp++; for(;;) { n = dirread(fd, &dir); if(n <= 0) break; for(i=0; inext); glob(gl->word); } } void globlist(void) { Word *a; globv=0; globlist1(runq->argv->words); poplist(); pushlist(); if(globv){ for(a=globv;a->next;a=a->next); a->next=runq->argv->words; runq->argv->words=globv; } } #define NAMELEN 256 /* should be a better way */ int globsize(char *p) { ulong isglob=0, globlen=NAMELEN+1; for(;*p;p++){ if(*p==GLOB){ p++; if(*p!=GLOB) isglob++; globlen+=*p=='*'?NAMELEN:1; } else globlen++; } return isglob?globlen:0; }