⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glob.c

📁 sock5代理服务器源代码
💻 C
字号:
/* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * C-shell glob for random programs. */#include "ftp_var.h"#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif#ifdef HAVE_DIRENT_H# include <dirent.h># define NLENGTH(direct) (strlen((direct)->d_name))#else /* not HAVE_DIRENT_H */# define dirent direct# define NLENGTH(direct) ((direct)->d_namlen)# ifdef HAVE_SYS_NDIR_H#  include <sys/ndir.h># endif /* HAVE_SYS_NDIR_H */# ifdef HAVE_SYS_DIR_H#  include <sys/dir.h># endif /* HAVE_SYS_DIR_H */# ifdef HAVE_NDIR_H#  include <ndir.h># endif /* HAVE_NDIR_H */#endif /* HAVE_DIRENT_H */#include <pwd.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define	QUOTE 0200#define	TRIM 0177#define	eq(a,b)		(strcmp(a, b)==0)#ifndef NCARGS#define NCARGS 256#endif#define	GAVSIZ		(NCARGS/6)#define	isdir(d)	((d.st_mode & S_IFMT) == S_IFDIR)static	char **gargv;		/* Pointer to the (stack) arglist */static	int gargc;		/* Number args in gargv */static	int gnleft;static	short gflag;static	char *gpath, *gpathp, *lastgpathp;static	int globbed, globcnt;static	char **sortbas;static	char *entp;char	*globchars = "`{[*?";char	*globerr;char	*home;extern	int errno;static int match P((char *, char *));static int execbrc P((char *, char *));int any(register int c, register char *s) {    while (*s) if (*s++ == c) return(1);    return(0);}static int tglob(register char c) {    if (any(c, globchars)) gflag |= c == '{' ? 2 : 1;    return (c);}int letter(register char c) {    return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');}int digit(register char c) {    return (c >= '0' && c <= '9');}int blklen(register char **av) {    register int i = 0;        while (*av++) i++;    return (i);}char ** blkcpy(char **oav, register char **bv) {    register char **av = oav;        while ((*av++ = *bv++));    return (oav);}void blkfree(char **av0) {    register char **av = av0;        /* if gflag is 0, we did not malloc() the space! */    if (!av || !gflag) return;    while (*av)	free(*av++);}static void ginit(char **agargv) {    agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;    gnleft = NCARGS - 4;}static void sort() {    register char **p1, **p2, *c;    char **Gvp = &gargv[gargc];        p1 = sortbas;    while (p1 < Gvp-1) {	p2 = p1;	while (++p2 < Gvp)	    if (strcmp(*p1, *p2) > 0)		c = *p1, *p1 = *p2, *p2 = c;	p1++;    }    sortbas = Gvp;}static void addpath(char c) {    if (gpathp >= lastgpathp)	globerr = "Pathname too long";    else {	*gpathp++ = c;	*gpathp = 0;    }}static char *strspl(register char *cp, register char *dp) {    register char *ep = (char *)malloc((unsigned)(strlen(cp) + strlen(dp) + 1));    if (ep == NULL) fatal("Out of memory");    strcpy(ep, cp);    strcat(ep, dp);    return (ep);}static char *strend(register char *cp) {    while (*cp) cp++;    return (cp);}static void Gcat(register char *s1, register char *s2) {    register int len = strlen(s1) + strlen(s2) + 1;        if (len >= gnleft || gargc >= GAVSIZ - 1)	globerr = "Arguments too long";    else {	gargc++;	gnleft -= len;	gargv[gargc] = 0;	gargv[gargc - 1] = strspl(s1, s2);    }}/* * Extract a home directory from the password file * The argument points to a buffer where the name of the * user whose home directory is sought is currently. * We write the home directory of the user back there. */int gethdir(char *home) {    register struct passwd *pp = getpwnam(home);        if (!pp || home + strlen(pp->pw_dir) >= lastgpathp) return (1);    strcpy(home, pp->pw_dir);    return (0);}static void matchdir(char *pattern) {    register struct dirent *dp;    DIR *dirp;        /*      * opendir() does not accept a null directory string     * to mean the current directory.  Must use ".". But leave     *  the gpath prefix alone     */      if (*gpath == 0)	dirp = opendir(".");    else	dirp = opendir(gpath);    if (dirp == NULL) {	if (globbed) return;	goto patherr2;    }#ifndef linux    {	struct stat stb;	if (fstat(dirp->dd_fd, &stb) < 0)	    goto patherr1;	if (!isdir(stb)) {	    errno = ENOTDIR;	    goto patherr1;	}    }#endif /* linux */    while ((dp = readdir(dirp)) != NULL) {	if (dp->d_ino == 0)	    continue;	if (match(dp->d_name, pattern)) {	    Gcat(gpath, dp->d_name);	    globcnt++;	}    }    closedir(dirp);    return;#ifndef linux  patherr1:#endif    closedir(dirp);  patherr2:    globerr = "Bad directory components";}static void expand(char *as) {    register char *cs;    register 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))		    globerr = "Unknown user name after ~";		strcpy(gpath, gpath + 1);	    } else		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 == '{') {	execbrc(cs, ((char *)0));	return;    }    matchdir(cs);  endit:    gpathp = sgpathp;    *gpathp = 0;}static int amatch(register char *s, register char *p) {	register int scc;	int ok, lc;	char *sgpathp;	struct stat stb;	int c, cc;	globbed = 1;	for (;;) {		scc = *s++ & TRIM;		switch (c = *p++) {		    case '{':			return (execbrc(p - 1, s - 1));					    case '[':			ok = 0;			lc = 077777;			while ((cc = *p++)) {			    if (cc == ']') {				if (ok) break;				return (0);			    }			    if (cc == '-') {				if (lc <= scc && scc <= *p++) ok++;			    } else 			    if (scc == (lc = cc)) ok++;			}						if (cc == 0) {			    if (!ok) { return 0; }			    else { p--; }			}			continue;		    case '*':			if (!*p) return (1);						if (*p == '/') {			    p++;			    goto slash;			}						s--;						do {			    if (amatch(s, p)) return (1);			} while (*s++);			return (0);					    case 0:			return (scc == 0);					    default:			if (c != scc) return (0);			continue;					    case '?':			if (scc == 0) return (0);			continue;					    case '/':			if (scc) return (0);		  slash:			s = entp;			sgpathp = gpathp;			while (*s) addpath(*s++);			addpath('/');			if (stat(gpath, &stb) == 0 && isdir(stb)) {			    if (*p == 0) {				Gcat(gpath, "");				globcnt++;			    } 			    else { expand(p); }			}			gpathp = sgpathp;			*gpathp = 0;			return (0);		}	}}static int match(char *s, char *p) {	register int c;	register char *sentp;	char sglobbed = globbed;	if (*s == '.' && *p != '.')		return (0);	sentp = entp;	entp = s;	c = amatch(s, p);	entp = sentp;	globbed = sglobbed;	return (c);}static int execbrc(char *p, char *s) {    char restbuf[BUFSIZ + 2];    register char *pe, *pm, *pl;    int brclev = 0;    char *lm, savec, *sgpathp;        for (lm = restbuf; *p != '{'; *lm++ = *p++);     for (pe = ++p; *pe; pe++)	switch (*pe) {	    case '{':		brclev++;		continue;	    case '}':		if (brclev == 0) goto pend;		brclev--;		continue;	    case '[':		for (pe++; *pe && *pe != ']'; pe++);		continue;	}pend:    brclev = 0;    for (pl = pm = p; pm <= pe; pm++)	switch (*pm & (QUOTE|TRIM)) {	    case '{':		brclev++;		continue;	    case '}':		if (brclev) {		    brclev--;		    continue;		}		goto doit;	    case ','|QUOTE:	    case ',':		if (brclev) continue;doit:		savec = *pm;		*pm = 0;		strcpy(lm, pl);		strcat(restbuf, pe + 1);		*pm = savec;		if (s == 0) {		    sgpathp = gpathp;		    expand(restbuf);		    gpathp = sgpathp;		    *gpathp = 0;		} else if (amatch(s, restbuf)) {		    return (1);		}		sort();		pl = pm + 1;		if (brclev) return (0);		continue;	    case '[':		for (pm++; *pm && *pm != ']'; pm++);		if (!*pm) pm--;		continue;	}    if (brclev) goto doit;    return (0);}static void acollect(register char *as) {    register int ogargc = gargc;        gpathp = gpath; *gpathp = 0; globbed = 0;    expand(as);    if (gargc != ogargc) sort();}static void collect(register char *as) {    if (eq(as, "{") || eq(as, "{}")) {	Gcat(as, "");	sort();    } else	acollect(as);}static int Gmatch(register char *s, register char *p) {    register int scc;    int ok, lc;    int c, cc;        for (;;) {	scc = *s++ & TRIM;	switch (c = *p++) {	    case '[':		ok = 0;		lc = 077777;		while ((cc = *p++)) {		    if (cc == ']') {			if (ok) break;			return (0);		    }		    if (cc == '-') {			if (lc <= scc && scc <= *p++) ok++;		    } else			if (scc == (lc = cc)) ok++;		}		if (cc == 0) {		    if (!ok) { return 0; }		    else { p--; }		}		continue;	    case '*':		if (!*p) return (1);		for (s--; *s; s++)		    if (Gmatch(s, p))			return (1);		return (0);	    case 0:		return (scc == 0);			    default:		if ((c & TRIM) != scc) return (0);		continue;	    case '?':		if (scc == 0) return (0);		continue;	}    }}static void rscan(register char **t, int (*f)P((char))) {    register char *p, c;        while ((p = *t++)) {	if (f == tglob) {	    if (*p == '~') { gflag |= 2; }	    else { if (eq(p, "{") || eq(p, "{}"))		continue;	    }	}	while ((c = *p++)) (*f)(c);    }}char **copyblk(register char **v) {    register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) * sizeof(char **)));    if (nv == (char **)0) fatal("Out of memory");    return (blkcpy(nv, v));}char **ftpglob(register char *v) {	char agpath[BUFSIZ];	char *agargv[GAVSIZ];	char *vv[2];	vv[0] = v;	vv[1] = 0;	gflag = 0;	rscan(vv, tglob);	if (gflag == 0)		return (copyblk(vv));	globerr = 0;	gpath = agpath; gpathp = gpath; *gpathp = 0;	lastgpathp = &gpath[sizeof agpath - 2];	ginit(agargv); globcnt = 0;	collect(v);	if (globcnt == 0 && (gflag&1)) {	    blkfree(gargv), gargv = 0;	    return (0);	} else {	    return (gargv = copyblk(gargv));	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -