depthFirstTraversal.c
/*************************************************************************/
/*    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
/*                                                                       */
/*  depthFirstTraversal                                                  */
/*                                                                       */
/*  A non recursive depth first traversal of a directory tree useful in  */
/*  the event that the stack size is limited relative to the heap size.  */
/*                                                                       */
/*************************************************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
 
#include "stringQueue.h"
 
#ifndef S_ISDIR
#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif
 
/*************************************************************************/
/*    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
/* Concatenates two filesystem paths a and b together.                    */
/*************************************************************************/
char *pathCombine(char *a, char *b) {
    size_t sa = strlen(a);
    size_t sb = strlen(b);
    char *rt = (char*)calloc(sa + sb + 1, sizeof(char *));
    memcpy(rt, a, sa);
    switch (a[sa - 1]) {
        case '/':
            break;
        default:
            rt = (char*)realloc(rt, (strlen(rt) + 1) * sizeof(char *));
            rt[sa] = '/';
        break;
    }
    memcpy(rt + strlen(rt), b, sb + 1);
    return rt;
}
 
int main(int argc, char **argv) {
    DIR *dir;
    struct dirent *de;
    struct stat st;
    stringQueue *dirQueue = stringQueueCreate(1);
    char *path;
    char *file;
 
    if (argc != 2) {
        printf("Syntax: %s [DIRECTORY]\n", argv[0]);
        return 1;
    }
 
    /* Enqueue the current working directory path. */
    stringQueueEnqueue(dirQueue, strdup(argv[1]));
 
    /* While there are still directories to be processed. */
    while ((path = stringQueueDequeue(dirQueue)) != NULL) {
        /* If we cannot open a directory, warn and continue. */
        if ((dir = opendir(path)) == NULL) {
            printf("Unable to open directory: %s\n", path);
            continue;
        }
 
        /* Read the contents of the current directory. */
        while ((de = readdir(dir))) {
            /* Combine path with file. */
            file = pathCombine(path, de->d_name);
 
            /* If we fail to get the stats for the file, skip it. */
            if(stat(file, &st) != 0) {
                free(file);
                continue;
            }
 
            /* If the file is not a directory, skip it. */
            if(!S_ISDIR(st.st_mode)) {
                free(file);
                continue;
            }
 
            /* If the directory starts with "." or "..", then skip it. */
            if(strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) {
                free(file);
                continue;
            }
 
            /* Print the directory. */
            printf("Directory: %s\n", file);
 
            /* Enqueue the directory. */
            stringQueueEnqueue(dirQueue, file);
 
            /* And release the file. */
            free(file);
        }
 
        /* And close the directory. */
        closedir(dir);
    }
 
    return 0;
}

fuss/c/path_traversal/depth-first/non-recursive/depthfirsttraversal.c.txt ยท Last modified: 2017/02/22 18:30 (external edit)

Access website using Tor Access website using i2p


For the copyright, license, warranty and privacy terms for the usage of this website please see the license, privacy and plagiarism pages.