遍历目录

#include <dirent.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

typedef int MyFunc(const char *, const struct stat *, int);

static MyFunc myfunc;
static int myftw(char *, MyFunc *);
static int dopath(MyFunc *);

static int nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;


int main(int argc, char *argv[])
{
	int ret;

	if (argc != 2) {
		fprintf(stderr, "usage : ftw <pathname>");
		exit(1);
	}

	ret = myftw(argv[1], myfunc);

	ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;

	if (0 == ntot)
		ntot = 1;

	printf("regular files	= %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);
	printf("directories		= %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot);
	printf("block special	= %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot);
	printf("char special	= %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);
	printf("FIFOs			= %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);
	printf("symbolic links	= %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot);
	printf("sokcets			= %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);

	exit(ret);
}


#define FTW_F	1	/* file other than directory */
#define FTW_D	2	/* directory */
#define FTW_DNR	3	/* directory that can't be read */
#define FTW_NS	4	/* file that we can't stat */

static char *fullpath;

static int myftw(char *pathname, MyFunc *func)
{
	int len;
	fullpath = path_alloc(&len);	/* malloc for PATH_MAX+1 bytes */

	strncpy(fullpath, pathname, len);
	fullpath[len-1] = 0;

	return dopath(func);
}

static int dopath(MyFunc *func)
{
	struct stat	statbuf;
	struct dirent *dirp;
	DIR	*dp;
	int ret;
	char *ptr;

	if (lstat(fullpath, &statbuf) < 0)	/* stat error */
		return func(fullpath, &statbuf, FTW_NS);

	if (S_ISDIR(statbuf.st_mode) == 0)	/* not a directory */
		return func(fullpath, &statbuf, FTW_F);

	if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
		return ret;

	ptr = fullpath + strlen(fullpath);
	*ptr++ = '/';
	*ptr = 0;

	if ((dp = opendir(fullpath)) == NULL)	/* can't read directory */
		return func(fullpath, &statbuf, FTW_DNR);

	while ((dirp = readdir(dp)) != NULL) {
		if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0)
			continue;

		strcpy(ptr, dirp->d_name);

		if ((ret = dopath(func)) != 0)
			break;
	}

	ptr[-1] = 0;

	if (closedir(dp) < 0) {
		fprintf(stderr, "can't close directory %s", fullpath);
		return 0;
	}

	return ret;
}

static int myfunc(const char *pathname, const struct stat *statptr, int type)
{
	switch (type) {
	case FTW_F:
		switch (statptr->st_mode & S_IFMT) {
		case S_IFREG:	nreg++;	break;
		case S_IFBLK:	nblk++;	break;
		case S_IFCHR:	nchr++;	break;
		case S_IFIFO:	nfifo++;	break;
		case S_IFLNK:	nslink++;	break;
		case S_IFSOCK:	nsock++;	break;
		default:	break;
		}
		break;
		
	case FTW_D:
		ndir++;
		break;
		
	case FTW_DNR:
		fprintf(stderr, "can't read directory %s", pathname);
		break;
		
	case FTW_NS:
		fprintf(stderr, "stat error for %s", pathname);
		break;
	
	default:
		break;
	}
	
	return 0;
}

来自《Advanced Programming in the UNIX Environment》 Chapter 4
《The C Programming Language》 Chapter 8 也有类似的程序

你可能感兴趣的:(unix)