Re: directory traversal



Jeff Abrahamson wrote:
I want to recursively traverse a directory. It seems dumb to write
this from scratch (and easy to goof on corner cases), but I haven't
found anything in glib / gtk / etc. that seems to address it. (Yeah,
this is more of a glib question than a gtk question, I guess.)


The following proglet exercises a function called read_directory(),
which traverses a directory. I often use it as a template for other
programs requiring this functionality. The section on file utility
functions in the Glib documentation may be worth a read as well.

/* gcc -g -Wall -Werror -o walker walker.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>

static void read_directory(char *);
static void usage(void);

int main(int argc, char *argv[]) {
    char path[MAXPATHLEN] = "";

    if(argc != 1 && argc != 3) {
        usage();
        return 1;
    }

    if(argc == 3) {
        if(strcmp(argv[1], "-p")) {
            usage();
            return 1;
        } else if(strlen(argv[2]) >= MAXPATHLEN) {
            fprintf(stderr, "Startpath is too long\n");
            return 1;
        } else {
            strcpy(path, argv[argc - 1]);
        }
    } else if(!getcwd(path, MAXPATHLEN)) {
        perror("getcwd");
        return 1;
    }

    read_directory(path);

    return 0;
}

void read_directory(char *path) {
    unsigned pathlen;
    char *pathptr;
    DIR *dir;
    struct dirent *d;
    struct stat s;

    pathlen = strlen(path);
    pathptr = path + pathlen;

    if(!(dir = opendir(path)))
        return;

    printf("DIR  %s\n", path);

    while((d = readdir(dir))) {
        if(!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
            continue;

        if(pathlen + strlen(d->d_name) + 2 > MAXPATHLEN) {
            fprintf(stderr, "Fatal error: path too long\n");
            exit(1);
        }

        sprintf(pathptr, "/%s", d->d_name);

        if(lstat(path, &s) != 0)
            continue;

        if(S_ISREG(s.st_mode))
            printf("FILE %s\n", path);
        else if(S_ISDIR(s.st_mode))
            read_directory(path);
    }

    closedir(dir);
}

void usage(void) {
    fprintf(stderr, "Usage: walker [-p <startpath>]\n");
}

Chris

--
chris wareham iosystems co uk (work)
cwareham btinternet com (home)




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]