Some code I whipped up in about an hour to do a depth-first traversal of given directory. Was wondering if anyone can critique this code and maybe suggest some things to do differently, etc. Am I correct in assuming that depth-first traversal has possible bugs due to running out of memory, etc ? Also, this program is just a template for the do_dir() function itself that would traverse directories, and does nothing useful at the moment save print the directories that it currently opens. In the future I could use it for any number of utilities that would have a directory traversal need.
Thanks
Code:
/* show.c */
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define VALIDDIR 1
#define SUBTRACT 0
#define ADD 1
char fullpath[PATH_MAX];
char *curpath = &fullpath[0];
int do_stat(const char *dname);
void do_dir(const char *dirname);
void update_fpath(const char *dname, int method);
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage: show directory\n");
exit(1);
}
do_dir(argv[1]);
return 0;
}
void do_dir(const char *dirname)
{
DIR *p;
struct dirent *t;
char lastdir[PATH_MAX];
getcwd(lastdir, PATH_MAX);
update_fpath(dirname, ADD);
if ((p = opendir(dirname)) == NULL) {
fprintf(stderr, "Couldn't open %s: %s\n",
fullpath, strerror(errno));
} else {
printf("opening %s\n", fullpath);
chdir(dirname);
while (t = readdir(p))
if ((do_stat(t->d_name)) == VALIDDIR)
do_dir(t->d_name);
chdir(lastdir);
closedir(p);
}
update_fpath(dirname, SUBTRACT);
}
int do_stat(const char *dname)
{
struct stat t;
lstat(dname, &t);
switch(t.st_mode & S_IFMT) {
case S_IFDIR:
if (strcmp(dname, ".") != 0 &&
strcmp(dname, "..") != 0)
return VALIDDIR;
break;
default:
break;
}
return 0;
}
void update_fpath(const char *dname, int method)
{
switch (method) {
case ADD:
strcpy(curpath, dname);
curpath += strlen(dname);
strcpy(curpath, "/");
curpath += strlen("/");
break;
case SUBTRACT:
curpath -= (strlen(dname) + 1);
*curpath = '\0';
break;
default:
break;
}
}