Skip to content

Instantly share code, notes, and snippets.

@akx
Created February 21, 2014 21:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akx/9144125 to your computer and use it in GitHub Desktop.
Save akx/9144125 to your computer and use it in GitHub Desktop.
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
#define MAX_PATH_LEN 1024
static int n_files = 0;
static void emit(const char *full_path) {
struct stat filestat;
if(stat(full_path, &filestat)) {
fprintf(stderr, "Failed statting %s\n", full_path);
return;
}
printf("%zd\t%zd\t%s\n", filestat.st_size, filestat.st_mtime, full_path);
n_files ++;
}
static void recurse_into(const char *path) {
struct stat dirstat;
struct dirent *ent, *entp;
if(stat(path, &dirstat)) {
fprintf(stderr, "failure while dir-statting %s\n", path);
return;
}
if(!S_ISDIR(dirstat.st_mode)) {
fprintf(stderr, "trying to recurse into non-directory %s\n", path);
return;
}
DIR *dh = opendir(path);
if(!dh) {
fprintf(stderr, "unable to open directory %s\n", path);
return;
}
char *full_path = malloc(MAX_PATH_LEN);
ent = (struct dirent *)malloc(sizeof(struct dirent) + MAX_PATH_LEN);
for(;;) {
if(readdir_r(dh, ent, &entp)) {
fprintf(stderr, "readdir_r error in %s\n", path);
break;
}
if(!entp) break;
if(ent->d_type == DT_UNKNOWN) {
fprintf(stderr, "Skipping DT_UNKNOWN entry %s\n", ent->d_name);
continue;
}
if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue;
int p_len = snprintf(full_path, MAX_PATH_LEN - 1, "%s/%s", path, ent->d_name);
if(p_len >= MAX_PATH_LEN - 1) {
fprintf(stderr, "Reached MAX_PATH_LEN of %d with %s in %s\n", MAX_PATH_LEN, ent->d_name, path);
continue;
}
if(strchr(ent->d_name, '\n') || strchr(ent->d_name, '\t')) {
fprintf(stderr, "Detected filename containing newline or tab, skipping.");
continue;
}
if(ent->d_type == DT_DIR) {
recurse_into(full_path);
} else if(ent->d_type == DT_REG) {
emit(full_path);
}
}
closedir(dh);
free(ent);
free(full_path);
}
int main(int argc, char *argv[])
{
for(int i = 1; i < argc; i++) {
recurse_into(realpath(argv[i], NULL));
}
fprintf(stderr, "%d valid files.\n", n_files);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment