home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
mint
/
mntlib16.lzh
/
MNTLIB16
/
FTW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-03
|
3KB
|
111 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 <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <ftw.h>
#define EQ(a, b) (strcmp((a), (b)) == 0)
int
ftw(directory, funcptr, depth)
char *directory;
int (*funcptr)();
int depth;
{
register DIR *dirp;
struct direct *entp;
struct stat stats;
register char *p;
register int i;
#ifndef __MINT__
long seekpoint;
#endif
char *fullpath;
#ifndef __MINT__
seekpoint = 0; /* avoid spurious warning from gcc -Wall */
#endif
/* If can't stat, tell the user so. */
if (stat(directory, &stats) < 0)
return (*funcptr)(directory, &stats, FTW_NS);
/* If it's not a directory, call the user's function. */
if ((stats.st_mode & S_IFMT) != S_IFDIR)
/* Saying "FTW_F" here is lying; what if this is a symlink? */
return (*funcptr)(directory, &stats, FTW_F);
/* Open directory; if we can't, tell the user so. */
dirp = opendir(directory);
if (dirp == NULL)
return (*funcptr)(directory, &stats, FTW_DNR);
/* See if user wants to go further. */
i = (*funcptr)(directory, &stats, FTW_D);
if (i) {
closedir(dirp);
return i;
}
/* Get ready to hold the full paths. */
i = strlen(directory);
fullpath = malloc(i + 1 + MAXNAMLEN + 1);
if (fullpath == NULL) {
closedir(dirp);
return -1;
}
(void)strcpy(fullpath, directory);
p = &fullpath[i];
if (i && p[-1] != '/')
*p++ = '/';
/* Read all entries in the directory.. */
while (entp = readdir(dirp))
if (!EQ(entp->d_name, ".") && !EQ(entp->d_name, "..")) {
#ifndef __MINT__
if (depth <= 1) {
/* Going too deep; checkpoint and close this directory. */
seekpoint = telldir(dirp);
closedir(dirp);
dirp = NULL;
}
#endif
/* Process the file. */
(void)strcpy(p, entp->d_name);
i = ftw(fullpath, funcptr, depth - 1);
if (i) {
/* User's finished; clean up. */
free(fullpath);
if (dirp)
closedir(dirp);
return i;
}
#ifndef __MINT__
/* Reopen the directory if necessary. */
if (dirp == NULL) {
dirp = opendir(directory);
if (dirp == NULL) {
free(fullpath);
return -1;
}
seekdir(dirp, seekpoint);
}
#endif
}
/* Clean up. */
free(fullpath);
closedir(dirp);
return 0;
}