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

📄 ftw.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#define HAVE_DIRENT 1#define HAVE_SYMLINK 1#ifdef HAVE_DIRENT#if defined(__APPLE__)/* Add: Mac OS X Support */#include <stdint.h>#endif#include <dirent.h>#else#include <sys/dir.h>#endif#include <errno.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/stat.h>#include "ftw.h"#if !HAS_FTW#if defined(LIBC_SCCS) && !defined(lint)static char sccsid[] = "@(#)ftw.c	5.3 (Berkeley) 8/5/88";#endif /* LIBC_SCCS and not lint *//* #include "../src/config.h" */#define	NODESC	-1#ifdef HAVE_SYMLINK# define	ISLINK(sb)	((sb.st_mode&S_IFMT) == S_IFLNK)#else# define lstat stat#endif#define	ISDIR(sb)	((sb.st_mode&S_IFMT) == S_IFDIR)#define	ISDOT(dp) \	(dp->d_name[0] == '.' && (!dp->d_name[1] || \	    (dp->d_name[1] == '.' && !dp->d_name[2])))extern int errno;static int g_fds,  (*g_fn) (),  g_opts;static char *bp;#ifdef __STDC__int treewalk(const char *path, int (*fn) (const char *file, const struct stat *sb, int flag), int maxfds, int opts);#elseint treewalk();#endif/* * cycle through the directories at the top of the tree, otherwise, once * you run out of descriptors you have to keep reusing the same one and * it gets *real* slow. */typedef struct d_fd {	struct d_fd *next;	DIR *dirp;	off_t off;} FD;static FD *freep, *node;static intwalk(register char *name){#ifdef HAVE_DIRENT	register struct dirent *dp;#else	register struct direct *dp;#endif	register int rval;	struct stat sb;	FD cur;	char *save,#ifdef __STDC__	 *strcpy(char *, const char *);#else	 *strcpy();#endif	if (!freep)		freep = &cur;	else		node->next = &cur;	node = &cur;	cur.off = 0;  getfd:if (!g_fds) {		freep->off = telldir(freep->dirp);		closedir(freep->dirp);		freep = freep->next;		++g_fds;	}	if ( !(cur.dirp = opendir(bp)) ) {		if (errno == EMFILE) {			g_fds = 0;			goto getfd;		}		return (errno == EACCES ? (*g_fn) (bp, &sb, FTW_DNR) : -1);	} else		--g_fds;	for (; *name; ++name) ;	*name++ = '/';	for (rval = 0, dp = readdir(cur.dirp); dp; dp = readdir(cur.dirp)) {		if (ISDOT(dp))			continue;		(void) strcpy(name, dp->d_name);		if (lstat(bp, &sb)) {			rval = errno == EACCES ?				(*g_fn) (bp, &sb, FTW_NS) : -1;			if (rval)				break;		}#ifdef HAVE_SYMLINK		if (ISLINK(sb) && g_opts & FTW_SYMLINK)			if (stat(bp, &sb))				continue;#endif		if (!ISDIR(sb)) {			rval = (*g_fn) (bp, &sb, FTW_F);			if (rval)				break;			continue;		}		if (g_opts & FTW_DIRLAST)#ifdef HAVE_D_NAMLEN			save = name + dp->d_namlen;#else			save = name + strlen(dp->d_name);#endif		rval = (*g_fn) (bp, &sb, FTW_D);		if ( (rval && rval != NODESC) || (rval = walk(name)))			break;		if (g_opts & FTW_DIRLAST) {			*save = '\0';			rval = (*g_fn) (dp->d_name, &sb, FTW_D2);			if (rval)				if (rval == NODESC)					rval = 0;				else					break;		}		if (cur.off) {			*name = '\0';			if ( (cur.dirp = opendir(bp)) ) {				seekdir(cur.dirp, cur.off);				/* tricky; if we have to reset the directory pointer we know				 * it's the next one to reuse */				freep = &cur;				--g_fds;			}			/* directory moved from under us!!! */			else {				rval = -1;				break;			}		}	}	closedir(cur.dirp);	++g_fds;	return (rval);}static intchwalk(register const char *name){#ifdef HAVE_DIRENT	register struct dirent *dp;#else	register struct direct *dp;#endif	register int rval;	struct stat sb;	FD cur;	char *pwd,	 *getwd(char *),#ifndef NO_MALLOC_PROTO	 *malloc(size_t),#endif	 *strcpy(char *, const char *);	if (!freep)		freep = &cur;	else		node->next = &cur;	node = &cur;	cur.off = 0;	if (chdir(name))		return (errno == EACCES ? (*g_fn) (name, &sb, FTW_DNR) : -1);  getfd:if (!g_fds) {		freep->off = telldir(freep->dirp);		closedir(freep->dirp);		freep = freep->next;		++g_fds;	}	if ( !(cur.dirp = opendir(".")) )  {		if (errno == EMFILE) {			g_fds = 0;			goto getfd;		}		return (errno == EACCES ? (*g_fn) (".", &sb, FTW_DNR) : -1);	} else		--g_fds;	for (rval = 0, dp = readdir(cur.dirp); dp; dp = readdir(cur.dirp)) {		if (ISDOT(dp))			continue;		if (lstat(dp->d_name, &sb)) {			rval = errno == EACCES ?				(*g_fn) (dp->d_name, &sb, FTW_NS) : -1;			if (rval)				break;		}		pwd = NULL;#ifdef HAVE_SYMLINK		if (ISLINK(sb) && g_opts & FTW_SYMLINK) {			if (stat(dp->d_name, &sb))				continue;			if (ISDIR(sb)) {				/* NOSTRICT */				if (!(pwd = malloc((u_int) MAXPATHLEN))) {					rval = -1;					break;				}				if (!getwd(pwd)) {					rval = -1;					break;				}			}		}#endif		if (!ISDIR(sb)) {			rval = (*g_fn) (dp->d_name, &sb, FTW_F);			if (rval)				break;			continue;		}		rval = (*g_fn) (dp->d_name, &sb, FTW_D);		if ((rval && rval != NODESC) || (rval = chwalk(dp->d_name)))			break;		if (g_opts & FTW_DIRLAST) {			rval = (*g_fn) (dp->d_name, &sb, FTW_D2);			if (rval)				if (rval == NODESC)					rval = 0;				else					break;		}		if (pwd && chdir(pwd)) {			rval = -1;			break;		}		if (cur.off) {			if ( (cur.dirp = opendir(".")) ) {				seekdir(cur.dirp, cur.off);				/* tricky; if we have to reset the directory pointer we know				 * it's the next one to reuse */				freep = &cur;				--g_fds;			}			/* directory moved from under us!!! */			else {				rval = -1;				break;			}		}	}	closedir(cur.dirp);	++g_fds;	if (chdir(".."))		return (-1);	return (rval);}/* S5 compatible ftw(BA_LIB) */intftw(const char *path, int (*fn) (const char *file, const struct stat *sb, int flag), int maxfds){	return (treewalk(path, fn, maxfds, 0));}inttreewalk(const char *path, int (*fn) (const char *file, const struct stat *sb, int flag), int maxfds, int opts){	struct stat sb;	int rval;	char *pwd,	 *getwd(char *),#ifndef NO_MALLOC_PROTO	 *malloc(size_t),#endif	 *strcpy(char *, const char *);	if (lstat(path, &sb))		return (errno == EACCES ? (*fn) (path, &sb, FTW_NS) : -1);	pwd = NULL;#ifdef HAVE_SYMLINK	if (ISLINK(sb) && opts & FTW_SYMLINK) {		if (stat(path, &sb))			return (0);		if (ISDIR(sb)) {			/* NOSTRICT */			if (!(pwd = malloc((u_int) MAXPATHLEN)))				return (-1);			if (!getwd(pwd))				return (-1);		}	}#endif	if (!ISDIR(sb))		return ((*fn) (path, &sb, FTW_F));	if (!maxfds)		return (-1);	g_fds = maxfds == -1 ? getdtablesize(): maxfds;	g_fn = fn;	g_opts = opts;	if (!(opts & FTW_CHDIR) && !(bp = malloc((u_int) MAXPATHLEN))) {		errno = ENOMEM;		return (-1);	}	rval = (*fn) (path, &sb, FTW_D);	if (rval == NODESC)		rval = 0;	else if (!rval) {		if (opts & FTW_CHDIR)			rval = chwalk(path);		else			rval = walk(strcpy(bp, path));		if (!rval && opts & FTW_DIRLAST) {			rval = (*fn) (path, &sb, FTW_D2);			if (rval == NODESC)				rval = 0;		}	}	if (pwd && chdir(pwd))		return (-1);	return (rval);}#endif

⌨️ 快捷键说明

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