home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume1
/
8712
/
15
/
ftw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-13
|
2KB
|
104 lines
/*
** FTW
** Walk a directory hierarchy from a given point, calling a user-supplied
** function at each thing we find. If we go below a specified depth,
** recycle file descriptors.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <ftw.h>
#ifdef RCSID
static char RCS[] = "$Header: ftw.c,v 1.1 87/12/29 21:38:52 rsalz Exp $";
#endif /* RCSID */
/* Handy shorthand. */
#define EQ(a, b) (strcmp((a), (b)) == 0)
/* Linked in later. */
extern char *malloc();
extern char *strcpy();
int
ftw(directory, funcptr, depth)
char *directory;
int (*funcptr)();
int depth;
{
register DIR *Dp;
register char *p;
register int i;
struct direct *E;
struct stat Sb;
long seekpoint;
char *fullpath;
/* If can't stat, tell the user so. */
if (stat(directory, &Sb) < 0)
return((*funcptr)(directory, &Sb, FTW_NS));
/* If it's not a directory, call the user's function. */
if ((Sb.st_mode & S_IFMT) != S_IFDIR)
/* Saying "FTW_F" here is lying, what if this is a symlink? */
return((*funcptr)(directory, &Sb, FTW_F));
/* Open directory; and if we can't tell the user so. */
if ((Dp = opendir(directory)) == NULL)
return((*funcptr)(directory, &Sb, FTW_DNR));
/* See if user wants to go further. */
if (i = (*funcptr)(directory, &Sb, FTW_D)) {
closedir(Dp);
return(i);
}
/* Get ready to hold the full paths. */
i = strlen(directory);
if ((fullpath = malloc(i + 1 + MAXNAMLEN + 1)) == NULL) {
closedir(Dp);
return(-1);
}
(void)strcpy(fullpath, directory);
p = &fullpath[i];
if (i && p[-1] != '/')
*p++ = '/';
/* Read all entries in the directory.. */
while (E = readdir(Dp))
if (!EQ(E->d_name, ".") && !EQ(E->d_name, "..")) {
if (depth <= 1) {
/* Going too deep; checkpoint and close this directory. */
seekpoint = telldir(Dp);
closedir(Dp);
Dp = NULL;
}
/* Process the file. */
(void)strcpy(p, E->d_name);
if (i = ftw(fullpath, funcptr, depth - 1)) {
/* User's finished; clean up. */
free(fullpath);
if (Dp)
closedir(Dp);
return(i);
}
/* Reopen the directory if necessary. */
if (Dp == NULL) {
if ((Dp = opendir(directory)) == NULL) {
/* WTF? */
free(fullpath);
return(-1);
}
seekdir(Dp, seekpoint);
}
}
/* Clean up. */
free(fullpath);
closedir(Dp);
return(0);
}