@ -0,0 +1,53 @@ | |||
#include "process_dir.h" | |||
#include <dirent.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
int process_dir_r(filestruct level) { | |||
if (!level.fullname) { | |||
if (level.name) { | |||
level.fullname = level.name; | |||
} else { | |||
level.fullname = "."; | |||
} | |||
} | |||
int errct = 0; | |||
DIR *current = opendir(level.fullname); | |||
if (!current) { | |||
return 1; | |||
} | |||
struct dirent *entry; | |||
while ((entry = readdir(current))) { | |||
if (entry->d_name[0] == '.') { | |||
continue; | |||
} | |||
filestruct next_level = level; | |||
next_level.name = entry->d_name; | |||
(void) asprintf(&next_level.fullname, "%s/%s", level.fullname, entry->d_name); | |||
if (next_level.fullname == NULL) { | |||
return 1; | |||
} | |||
if (entry->d_type == DT_DIR) { | |||
next_level.depth++; | |||
if (level.directory_action) { | |||
level.directory_action(next_level); | |||
} | |||
errct += process_dir_r(next_level); | |||
} else if (entry->d_type == DT_REG && level.file_action) { | |||
level.file_action(next_level); | |||
errct += next_level.error; | |||
} | |||
if (next_level.fullname) { | |||
free(next_level.fullname); | |||
} | |||
} | |||
closedir(current); | |||
return errct; | |||
} |
@ -0,0 +1,17 @@ | |||
struct filestruct; | |||
typedef void (*level_fn)(struct filestruct path); | |||
typedef struct filestruct | |||
{ | |||
char *name, *fullname; | |||
level_fn directory_action, file_action; | |||
int depth, error; | |||
void *data; | |||
} filestruct; | |||
#define process_dir(...) process_dir_r((filestruct){__VA_ARGS__}) | |||
int process_dir_r(filestruct level); |
@ -0,0 +1,29 @@ | |||
#include <stdio.h> | |||
#include "process_dir.h" | |||
void print_dir(filestruct in) { | |||
for (size_t i = 0; i < in.depth-1; ++i) { | |||
printf(" "); | |||
} | |||
printf("├ %s\n", in.name); | |||
for (size_t i = 0; i < in.depth-1; ++i) { | |||
printf(" "); | |||
} | |||
printf("└───┐\n"); | |||
} | |||
void print_file(filestruct in) { | |||
for (size_t i = 0; i < in.depth; ++i) { | |||
printf(" "); | |||
} | |||
printf("│ %s\n", in.name); | |||
} | |||
int main (int argc, char **argv) { | |||
char *start = (argc > 1) ? argv[1] : "."; | |||
printf("Tree for %s:\n", start ? start : "the current directory"); | |||
process_dir(.name=start, .file_action=print_file, .directory_action=print_dir); | |||
} |