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

📄 glob.c

📁 wu-ftpd类unix下的ftp服务器,可用于嵌入式系统
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef WINDOWS32	    if (home_dir == NULL || home_dir[0] == '\0')		home_dir = "c:/users/default";	/* poor default */#else	    if (home_dir == NULL || home_dir[0] == '\0') {		int success;#if defined HAVE_GETLOGIN_R || defined _LIBC		extern int getlogin_r __P((char *, size_t));		size_t buflen = sysconf(_SC_LOGIN_NAME_MAX) + 1;		char *name;		if (buflen == 0)		    /* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try		       a moderate value.  */		    buflen = 16;		name = (char *) __alloca(buflen);		success = getlogin_r(name, buflen) >= 0;#else/*            extern char *getlogin __P (); */		char *name;		success = (name = getlogin()) != NULL;#endif		if (success) {#if defined HAVE_GETPWNAM_R || defined _LIBC		    size_t pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);		    char *pwtmpbuf;		    struct passwd pwbuf, *p;		    pwtmpbuf = (char *) __alloca(pwbuflen);		    success = (__getpwnam_r(name, &pwbuf, pwtmpbuf,					    pwbuflen, &p) >= 0);#else		    struct passwd *p = getpwnam(name);		    success = p != NULL;#endif		    if (success)			home_dir = p->pw_dir;		}	    }	    if (home_dir == NULL || home_dir[0] == '\0')		home_dir = (char *) "~";	/* No luck.  */#endif /* WINDOWS32 */#endif	    /* Now construct the full directory.  */	    if (dirname[1] == '\0')		dirname = home_dir;	    else {		char *newp;		size_t home_len = strlen(home_dir);		newp = (char *) __alloca(home_len + dirlen);#ifdef HAVE_MEMPCPY		mempcpy(mempcpy(newp, home_dir, home_len),			&dirname[1], dirlen);#else		memcpy(newp, home_dir, home_len);		memcpy(&newp[home_len], &dirname[1], dirlen);#endif		dirname = newp;	    }	}#if !defined _AMIGA && !defined WINDOWS32	else {	    char *end_name = strchr(dirname, '/');	    char *user_name;	    char *home_dir;	    if (end_name == NULL)		user_name = dirname + 1;	    else {		user_name = (char *) __alloca(end_name - dirname);#ifdef HAVE_MEMPCPY		*((char *) mempcpy(user_name, dirname + 1, end_name - dirname))		    = '\0';#else		memcpy(user_name, dirname + 1, end_name - dirname);		user_name[end_name - dirname - 1] = '\0';#endif	    }	    /* Look up specific user's home directory.  */	    {#if defined HAVE_GETPWNAM_R || defined _LIBC		size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);		char *pwtmpbuf = (char *) __alloca(buflen);		struct passwd pwbuf, *p;		if (__getpwnam_r(user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0)		    home_dir = p->pw_dir;		else		    home_dir = NULL;#else		struct passwd *p = getpwnam(user_name);		if (p != NULL)		    home_dir = p->pw_dir;		else		    home_dir = NULL;#endif	    }	    /* If we found a home directory use this.  */	    if (home_dir != NULL) {		char *newp;		size_t home_len = strlen(home_dir);		size_t rest_len = end_name == NULL ? 0 : strlen(end_name);		newp = (char *) __alloca(home_len + rest_len + 1);#ifdef HAVE_MEMPCPY		*((char *) mempcpy(mempcpy(newp, home_dir, home_len),				   end_name, rest_len)) = '\0';#else		memcpy(newp, home_dir, home_len);		memcpy(&newp[home_len], end_name, rest_len);		newp[home_len + rest_len] = '\0';#endif		dirname = newp;	    }	}#endif /* Not Amiga && not WINDOWS32.  */    }#endif /* Not VMS.  */    if (__glob_pattern_p(dirname, !(flags & GLOB_NOESCAPE))) {	/* The directory name contains metacharacters, so we	   have to glob for the directory, and then glob for	   the pattern in each directory found.  */	glob_t dirs;	register int i;	status = glob(dirname,		      ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))		       | GLOB_NOSORT | GLOB_ONLYDIR),		      errfunc, &dirs);	if (status != 0)	    return status;	/* We have successfully globbed the preceding directory name.	   For each name we found, call glob_in_dir on it and FILENAME,	   appending the results to PGLOB.  */	for (i = 0; i < dirs.gl_pathc; ++i) {	    int oldcount;	    oldcount = pglob->gl_pathc;	    status = glob_in_dir(filename, dirs.gl_pathv[i],				 ((flags | GLOB_APPEND)				  & ~(GLOB_NOCHECK | GLOB_ERR)),				 errfunc, pglob);	    if (status == GLOB_NOMATCH)		/* No matches in this directory.  Try the next.  */		continue;	    if (status != 0) {		globfree(&dirs);		globfree(pglob);		return status;	    }	    /* Stick the directory on the front of each name.  */	    if (prefix_array(dirs.gl_pathv[i],			     &pglob->gl_pathv[oldcount],			     pglob->gl_pathc - oldcount)) {		globfree(&dirs);		globfree(pglob);		return GLOB_NOSPACE;	    }	}	flags |= GLOB_MAGCHAR;	if (pglob->gl_pathc == oldcount)	    /* No matches.  */	    if (flags & GLOB_NOCHECK) {		size_t len = strlen(pattern) + 1;		char *patcopy = (char *) malloc(len);		if (patcopy == NULL)		    return GLOB_NOSPACE;		memcpy(patcopy, pattern, len);		pglob->gl_pathv		    = (char **) realloc(pglob->gl_pathv,					(pglob->gl_pathc +					 ((flags & GLOB_DOOFFS) ?					  pglob->gl_offs : 0) +					 1 + 1) *					sizeof(char *));		if (pglob->gl_pathv == NULL) {		    free(patcopy);		    return GLOB_NOSPACE;		}		if (flags & GLOB_DOOFFS)		    while (pglob->gl_pathc < pglob->gl_offs)			pglob->gl_pathv[pglob->gl_pathc++] = NULL;		pglob->gl_pathv[pglob->gl_pathc++] = patcopy;		pglob->gl_pathv[pglob->gl_pathc] = NULL;		pglob->gl_flags = flags;	    }	    else		return GLOB_NOMATCH;    }    else {	status = glob_in_dir(filename, dirname, flags, errfunc, pglob);	if (status != 0)	    return status;	if (dirlen > 0) {	    /* Stick the directory on the front of each name.  */	    if (prefix_array(dirname,			     &pglob->gl_pathv[oldcount],			     pglob->gl_pathc - oldcount)) {		globfree(pglob);		return GLOB_NOSPACE;	    }	}    }    if (flags & GLOB_MARK) {	/* Append slashes to directory names.  */	int i;	struct stat st;	for (i = oldcount; i < pglob->gl_pathc; ++i)	    if (((flags & GLOB_ALTDIRFUNC) ?		 (*pglob->gl_stat) (pglob->gl_pathv[i], &st) :		 __stat(pglob->gl_pathv[i], &st)) == 0 &&		S_ISDIR(st.st_mode)) {		size_t len = strlen(pglob->gl_pathv[i]) + 2;		char *new = realloc(pglob->gl_pathv[i], len);		if (new == NULL) {		    globfree(pglob);		    return GLOB_NOSPACE;		}		strcpy(&new[len - 2], "/");		pglob->gl_pathv[i] = new;	    }    }    if (!(flags & GLOB_NOSORT))	/* Sort the vector.  */	qsort((__ptr_t) & pglob->gl_pathv[oldcount],	      pglob->gl_pathc - oldcount,	      sizeof(char *), collated_compare);    return 0;}/* Free storage allocated in PGLOB by a previous `glob' call.  */void globfree(pglob)     register glob_t *pglob;{    if (pglob->gl_pathv != NULL) {	register int i;	for (i = 0; i < pglob->gl_pathc; ++i)	    if (pglob->gl_pathv[i] != NULL)		free((__ptr_t) pglob->gl_pathv[i]);	free((__ptr_t) pglob->gl_pathv);    }}/* Do a collated comparison of A and B.  */static int collated_compare(a, b)     const __ptr_t a;     const __ptr_t b;{    const char *const s1 = *(const char *const *const) a;    const char *const s2 = *(const char *const *const) b;    if (s1 == s2)	return 0;    if (s1 == NULL)	return 1;    if (s2 == NULL)	return -1;    return strcoll(s1, s2);}/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's   elements in place.  Return nonzero if out of memory, zero if successful.   A slash is inserted between DIRNAME and each elt of ARRAY,   unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */static int prefix_array(dirname, array, n)     const char *dirname;     char **array;     size_t n;{    register size_t i;    size_t dirlen = strlen(dirname);    if (dirlen == 1 && dirname[0] == '/')	/* DIRNAME is just "/", so normal prepending would get us "//foo".	   We want "/foo" instead, so don't prepend any chars from DIRNAME.  */	dirlen = 0;    for (i = 0; i < n; ++i) {	size_t eltlen = strlen(array[i]) + 1;	char *new = (char *) malloc(dirlen + 1 + eltlen);	if (new == NULL) {	    while (i > 0)		free((__ptr_t) array[--i]);	    return 1;	}#ifdef HAVE_MEMPCPY	{	    char *endp = (char *) mempcpy(new, dirname, dirlen);	    *endp++ = '/';	    mempcpy(endp, array[i], eltlen);	}#else	memcpy(new, dirname, dirlen);	new[dirlen] = '/';	memcpy(&new[dirlen + 1], array[i], eltlen);#endif	free((__ptr_t) array[i]);	array[i] = new;    }    return 0;}/* Return nonzero if PATTERN contains any metacharacters.   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */int __glob_pattern_p(pattern, quote)     const char *pattern;     int quote;{    register const char *p;    int open = 0;    for (p = pattern; *p != '\0'; ++p)	switch (*p) {	case '?':	case '*':	    return 1;	case '\\':	    if (quote && p[1] != '\0')		++p;	    break;	case '[':	    open = 1;	    break;	case ']':	    if (open)		return 1;	    break;	}    return 0;}#ifdef _LIBCweak_alias(__glob_pattern_p, glob_pattern_p)#endif/* Like `glob', but PATTERN is a final pathname component,   and matches are searched for in DIRECTORY.   The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.   The GLOB_APPEND flag is assumed to be set (always appends).  */     static int         glob_in_dir(pattern, directory, flags, errfunc, pglob)     const char *pattern;     const char *directory;     int flags;     int (*errfunc) __P((const char *, int));     glob_t *pglob;{    __ptr_t stream;    struct globlink {	struct globlink *next;	char *name;    };    struct globlink *names = NULL;    size_t nfound;    int meta;    int save;    stream = ((flags & GLOB_ALTDIRFUNC) ?	      (*pglob->gl_opendir) (directory) :	      (__ptr_t) opendir(directory));    if (stream == NULL) {	if ((errfunc != NULL && (*errfunc) (directory, errno)) ||	    (flags & GLOB_ERR))	    return GLOB_ABORTED;	nfound = 0;	meta = 0;    }    else if (pattern[0] == '\0') {	/* This is a special case for matching directories like in	   "*a/".  */	names = (struct globlink *) __alloca(sizeof(struct globlink));	names->name = (char *) malloc(1);	if (names->name == NULL)	    goto memory_error;	names->name[0] = '\0';	names->next = NULL;	nfound = 1;	meta = 0;    }    else {	nfound = 0;	meta = __glob_pattern_p(pattern, !(flags & GLOB_NOESCAPE));	if (meta)	    flags |= GLOB_MAGCHAR;	while (1) {	    const char *name;	    size_t len;	    struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ?				(*pglob->gl_readdir) (stream) :				readdir((DIR *) stream));	    if (d == NULL)		break;	    if (!REAL_DIR_ENTRY(d))		continue;#ifdef HAVE_D_TYPE	    /* If we shall match only directories use the information	       provided by the dirent call if possible.  */	    if ((flags & GLOB_ONLYDIR)		&& d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)		continue;#endif	    name = d->d_name;	    if ((!meta && strcmp(pattern, name) == 0)		|| wu_fnmatch(pattern, name,			      (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |			      ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)#ifdef _AMIGA			      | FNM_CASEFOLD#endif		) == 0) {		struct globlink *new		= (struct globlink *) __alloca(sizeof(struct globlink));		len = NAMLEN(d);		new->name = (char *) malloc(len + 1);		if (new->name == NULL)		    goto memory_error;#ifdef HAVE_MEMPCPY		*((char *) mempcpy((__ptr_t) new->name, name, len)) = '\0';#else		memcpy((__ptr_t) new->name, name, len);		new->name[len] = '\0';#endif		new->next = names;		names = new;		++nfound;		if (!meta)		    break;	    }	}    }    if (nfound == 0 && (flags & GLOB_NOMAGIC) && !meta)	flags |= GLOB_NOCHECK;    if (nfound == 0 && (flags & GLOB_NOCHECK)) {	size_t len = strlen(pattern);	nfound = 1;	names = (struct globlink *) __alloca(sizeof(struct globlink));	names->next = NULL;	names->name = (char *) malloc(len + 1);	if (names->name == NULL)	    goto memory_error;#ifdef HAVE_MEMPCPY	*((char *) mempcpy(names->name, pattern, len)) = '\0';#else	memcpy(names->name, pattern, len);	names->name[len] = '\0';#endif    }    if (nfound != 0) {	pglob->gl_pathv	    = (char **) realloc(pglob->gl_pathv,				(pglob->gl_pathc +			      ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +				 nfound + 1) *				sizeof(char *));	if (pglob->gl_pathv == NULL)	    goto memory_error;	if (flags & GLOB_DOOFFS)	    while (pglob->gl_pathc < pglob->gl_offs)		pglob->gl_pathv[pglob->gl_pathc++] = NULL;	for (; names != NULL; names = names->next)	    pglob->gl_pathv[pglob->gl_pathc++] = names->name;	pglob->gl_pathv[pglob->gl_pathc] = NULL;	pglob->gl_flags = flags;    }    save = errno;    if (flags & GLOB_ALTDIRFUNC)	(*pglob->gl_closedir) (stream);    else	closedir((DIR *) stream);    __set_errno(save);    return nfound == 0 ? GLOB_NOMATCH : 0;  memory_error:    {	int save = errno;	if (flags & GLOB_ALTDIRFUNC)	    (*pglob->gl_closedir) (stream);	else	    closedir((DIR *) stream);	__set_errno(save);    }    while (names != NULL) {	if (names->name != NULL)	    free((__ptr_t) names->name);	names = names->next;    }    return GLOB_NOSPACE;}#endif /* Not ELIDE_CODE.  */

⌨️ 快捷键说明

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