示例#1
0
文件: ssh.c 项目: anastasop/oneshot
/*
 * Read entries from dir, one at a time.
 * edir points at the nul at the end of dir.
 * The buffer pointed to by dir is guaranteed to be long enough to hold
 * any matching file name.
 */
void matchdir(char *dir, char *edir, char *pattern){
	DIR *fd;
	struct dirent *dp;
	struct stat st;
	int n;
	char *npattern, *s, *t;
	*edir='\0';
	fd=opendir(*dir?dir:".");
	if(fd==0) return;
	while((dp=readdir(fd))!=0){
		if(npattern=match(dp->d_name, pattern)){
			t=edir;
			if(edir!=dir && edir[-1]!='/') *t++='/';
			for(s=dp->d_name;*s;s++,t++) *t=*s;
			*t='\0';
			if(*npattern=='\0'){
				arg(chargp);
				for(s=dir;*s;s++) argchr(*s);
				argchr('\0');
			}
			else if(stat(dir, &st)==0 && S_ISDIR(st.st_mode))
				matchdir(dir, t, npattern);
		}
	}
	closedir(fd);
}
int globcmp(const void *a, const void *b){
	return strcmp(*(char **)a, *(char **)b);
}
#define	NAMELEN	256 /* file name components can be no longer than this */
void glob(void){
	char *s, *t, *buf, *pattern, **p;
	int mark;
	int nbuf;
	mark=argp-args-1;
	pattern=strdup(argp[-1]);
	nbuf=strlen(pattern+1);
	for(s=pattern;*s;s++) if(*s==GLOB && *++s=='*') nbuf+=NAMELEN;
	buf=malloc(nbuf);
	if(buf==0) nomem();
	if(pattern[0]=='/'){
		buf[0]='/';
		matchdir(buf, buf+1, pattern+1);
	}
	else
		matchdir(buf, buf, pattern);
	if(argp==args+mark+1){	/* no match, just remove GLOB markers */
		for(s=t=args[mark];*t;s++,t++){
			if(*s==GLOB) s++;
			*t=*s;
		}
	}
	else{			/* discard pattern, sort matches */
		for(p=args+mark+1;p!=argp;p++) p[-1]=p[0];
		--argp;
		p=args+mark;
		qsort(p, argp-p, sizeof(char *), globcmp);
	}
	free(pattern);
	free(buf);
}
示例#2
0
文件: ssh.c 项目: anastasop/oneshot
/*
 * Read entries from dir, one at a time.
 * edir points at the nul at the end of dir.
 * The buffer pointed to by dir is guaranteed to be long enough to hold
 * any matching file name.
 */
void matchdir(char *dir, char *edir, char *pattern){
	DIR *fd;
	struct dirent *dp;
	struct stat st;
	int n;
	char *npattern, *s, *t;
	*edir='\0';
	fd=opendir(*dir?dir:".");
	if(fd==0) return;
	while((dp=readdir(fd))!=0){
		if(npattern=match(dp->d_name, pattern)){
			t=edir;
			if(edir!=dir && edir[-1]!='/') *t++='/';
			for(s=dp->d_name;*s;s++,t++) *t=*s;
			*t='\0';
			if(*npattern=='\0'){
				arg(chargp);
				for(s=dir;*s;s++) argchr(*s);
				argchr('\0');
			}
			else if(stat(dir, &st)==0 && S_ISDIR(st.st_mode))
				matchdir(dir, t, npattern);
		}
	}
	closedir(fd);
}
示例#3
0
static 
void
expand(const char *as)
{
	const char *cs;
	const char *oldcs;
	char *sgpathp;
	struct stat stb;

	sgpathp = gpathp;
	cs = as;
	if (*cs == '~' && gpathp == gpath) {
		addpath('~');
		for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
			addpath(*cs++);
		if (!*cs || *cs == '/') {
			if (gpathp != gpath + 1) {
				*gpathp = 0;
				if (gethdir(gpath + 1))
					globerr = "Unknown user name after ~";
				/*
				 * Was: strcpy(gpath, gpath + 1);
				 * but that's WRONG
				 */
				memmove(gpath, gpath+1, strlen(gpath+1)+1);
			} 
			else {
				(void) strcpy(gpath, home);
			}
			gpathp = strend(gpath);
		}
	}
	while (!any(*cs, globchars)) {
		if (*cs == 0) {
			if (!globbed)
				Gcat(gpath, "");
			else if (stat(gpath, &stb) >= 0) {
				Gcat(gpath, "");
				globcnt++;
			}
			goto endit;
		}
		addpath(*cs++);
	}
	oldcs = cs;
	while (cs > as && *cs != '/')
		cs--, gpathp--;
	if (*cs == '/')
		cs++, gpathp++;
	*gpathp = 0;
	if (*oldcs == '{') {
		(void) execbrc(cs, ((char *)0));
		return;
	}
	matchdir(cs);
endit:
	gpathp = sgpathp;
	*gpathp = 0;
}
示例#4
0
文件: glob.c 项目: joshuaeckroth/cadr
static void
expand(char *as)
{
	char *cs;
	char *sgpathp, *oldcs;
	struct stat stb;

	sgpathp = gpathp;
	cs = as;
	if (*cs == '~' && gpathp == gpath) {
		addpath('~');
		for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
			addpath(*cs++);
		if (!*cs || *cs == '/') {
			if (gpathp != gpath + 1) {
				*gpathp = 0;
				if (gethdir(gpath + 1)) {
					(void)sprintf(errstring = errbuf,
					"Unknown user name: %s after '~'",
					gpath+1);
					globerr = IPS;
				}
				strcpy(gpath, gpath + 1);
			} else
				strcpy(gpath, home);
			gpathp = strend(gpath);
		}
	}
	while (!any(*cs, globchars) && globerr == 0) {
		if (*cs == 0) {
			if (!globbed)
				Gcat(gpath, "");
			else if (stat(gpath, &stb) >= 0) {
				Gcat(gpath, "");
				globcnt++;
			}
			goto endit;
		}
		addpath(*cs++);
	}
	oldcs = cs;
	while (cs > as && *cs != '/')
		cs--, gpathp--;
	if (*cs == '/')
		cs++, gpathp++;
	*gpathp = 0;
	if (*oldcs == '{') {
		(void)execbrc(cs, ((char *)0));
		return;
	}
	matchdir(cs);
endit:
	gpathp = sgpathp;
	*gpathp = 0;
}
static int
doglob(struct dirbuf *np, const char *pattern)
{
	struct dirbuf	name = *np;
	struct stat	stb;
	const char	*s;


	/* Loop over all pattern components */
	while (*pattern) {
		/* Skip slashes, but make sure the named file
		 * exists and is a directory.
		 * This takes care of "foobar/" patterns
		 */
		if (*pattern == '/' || !strncmp(pattern, "./", 2)) {
			if (stat(dirbuf_as_path(&name), &stb) < 0
			 || !S_ISDIR(stb.st_mode))
				return 0;
			pattern++;
			continue;
		}

		/* Try to match a component of the path name */
		for (s = pattern; *s && *s != '/'; s++) {
			/* Remainder has globbing chars */
			if (strchr(GLOBCHARS, *s))
				return matchdir(&name, pattern);
		}

		/* This path component didn't contain a special
		 * character, so no matching required.
		 * Make sure though that the file exists. */
		if (!dirbuf_addslash(&name)
		 || !dirbuf_appends(&name, pattern, s - pattern)
		 || access(dirbuf_as_path(&name), F_OK) < 0)
			return 0;
		pattern = s;
	}

	remember(dirbuf_as_path(&name));
	return 1;
}
示例#6
0
		/* NOTREACHED */
	    }

	    if ( p == '\0' )
		return FAIL;

	    if ( p == '[' ) {
		char s = *string++;
		char reverse = '\0';
		char first, last;
		char gotcha = '\0';

		NEXTP;
		if ( p == '^' ) {
		    reverse = '\1';
		    NEXTP;
		}
		if ( p == ']' ) { /* special case */
		    gotcha = (s==p);
		    NEXTP;
		}

		while (  p != ']' && !gotcha ) {
		    first = p;
		    NEXTP;
		    if ( p == '-' && pattern[1] != ']' ) {
			NEXTP;
			last = p;
			NEXTP;
		    } else
			last = first;
		    if ( first > last )
			return ERROR;
		    gotcha = (first <= s && s <= last );
		}
		while ( p != ']' )
		    NEXTP;

		if ( reverse ? gotcha : !gotcha )
		    return FAIL;
	    } else if ( p != *string )
		return FAIL;
	    else
		string++;
	}
    }
    if ( seenstar )
	return SUCCES;

    if ( *string )
	return FAIL;
    return SUCCES;
}

static char *main_path;		/* ptr to scratchpad */
static int offset;		/* no of leading char in main_path to ignore */
static char **namelist;		/* name list buildup */
static int nnames;		/* no of names found */
static int left;		/* no of slots allocated but not used yet */

#define GLOBMAXSEG	50	/* max segments in pattern */
#define GLOBCHUNK	20	/* no of slots to allocate at a time */

#ifndef MAXNAMLEN
#define MAXNAMLEN 256
#endif

int
#ifndef ANSI_PROTOTYPES
glob_path( pattern, names )
    char *pattern;
    char ***names;
#else /* ANSI_PROTOTYPES */
glob_path(char *pattern, char ***names)
#endif /* ANSI_PROTOTYPES */
{
    char mpath[ MAXPATHLEN + MAXNAMLEN + 1 ];
    char *gpat[GLOBMAXSEG];
    char *pat;

    if (pattern == 0)
	return -1;

    if ((pat = strdup(pattern)) == NULL)
	return -1;

    if (split_pat(pat, gpat) < 0)
    {
	(void)free(pat);
	return -1;
    }
    
    main_path = mpath;		/* initalisation of static storage */
    namelist = 0;
    nnames = left = 0;

    if ( *gpat && **gpat == '/' )
    {
	main_path[0] = '/';
	main_path[1] = '\0';
	offset = 0;
	do_glob(main_path, gpat + 1);
    }
    else
    {
	main_path[0] = '.';
	main_path[1] = '\0';
	offset = 2;
	do_glob(main_path + 1, gpat);
    }

    (void)free(pat);

    if (namelist == 0)
	*names = (char **)malloc(sizeof(char *));
    else
	*names = (char **)realloc(namelist, (nnames+1) * sizeof(char *));

    if (*names == 0)
	return -1;
    (*names)[nnames] = 0;
    return nnames;
}

static int
#ifndef ANSI_PROTOTYPES
split_pat(pattern, table)
    char *pattern;
    char **table;
#else /* ANSI_PROTOTYPES */
split_pat(char *pattern, char **table)
#endif /* ANSI_PROTOTYPES */
{
    char *pp = pattern;
    int size = GLOBMAXSEG;

    if (*pattern == '/')
    {
	*table++ = "/";
	--size;
    }

    do
    {
	while (*pp == '/')
	    *pp++ = '\0';
	if (*pp == '\0')
	    break;
	if (--size < 0)
	    return -1;
	*table++ = pp;
	while (*pp && *pp != '/')
	    pp++;
    }
    while (*pp);

    *table = 0;
    return 0;
}


#define ISGLOB(x) ((x)=='*' || (x)=='?' || (x)=='[')

static int
#ifndef ANSI_PROTOTYPES
no_glob(pat)
    char *pat;
#else /* ANSI_PROTOTYPES */
no_glob(char *pat)
#endif /* ANSI_PROTOTYPES */
{
    while (*pat && !ISGLOB(*pat))
	pat++;

    return (*pat == '\0');
}
	
static void
#ifndef ANSI_PROTOTYPES
do_glob(path_end, gpat)
    char *path_end;		/* ptr to the end of main_path */
    char **gpat;		/* the rest of the pattern segments */
#else /* ANSI_PROTOTYPES */
do_glob(char *path_end, char **gpat)
                   		/* ptr to the end of main_path */
                		/* the rest of the pattern segments */
#endif /* ANSI_PROTOTYPES */
{
    char *saved_end = path_end;	/* saved to be resored */
    char *pat;			/* current pattern segment */
    struct stat st;		/* to check if file exists */

#ifdef GLOBDEBUG
    ffprintf(STDDBG,"do_glob: path = '%s', pat = '%s'\n", main_path, *gpat );
#endif

    for ( ; (pat = *gpat) != 0 && no_glob(pat); gpat++ )
    {
#ifdef GLOBDEBUG
	ffprintf(STDDBG,"no_glob: path = '%s', pat = '%s'\n", main_path, pat );
#endif
	*path_end = '/';
	(void)strcpy(path_end+1, pat);
	path_end += strlen(pat) + 1;

	if (GLOBSTAT(main_path, &st) != 0 )
	{
	    *saved_end = '\0';
	    return;
	}
    }
    if (pat)
	matchdir(path_end, gpat);
    else
	add_name();

    *saved_end = '\0';
    return;
}
示例#7
0
/*
 * If there are any Shell meta characters in the name,
 * expand into a list, after searching directory
 */
static void
expsh(char *s)
{
	char *cp;
	char *spathp, *oldcp;
	struct stat stb;

	spathp = pathp;
	cp = s;
	while (!any(*cp, shchars)) {
		if (*cp == '\0') {
			if (!expany || stat(path, &stb) >= 0) {
				if (which & E_TILDE)
					Cat(path, "");
				else
					Cat(tilde, tpathp);
			}
			goto endit;
		}
		addpath(*cp++);
	}
	oldcp = cp;
	while (cp > s && *cp != '/')
		cp--, pathp--;
	if (*cp == '/')
		cp++, pathp++;
	*pathp = '\0';
	if (*oldcp == '{') {
		execbrc(cp, NULL);
		return;
	}
	matchdir(cp);
endit:
	pathp = spathp;
	*pathp = '\0';
}