Makistos
4/5/2017 - 12:48 PM

Recursively list files in C. #c #file-handling #recursive

Recursively list files in C. #c #file-handling #recursive

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <libgen.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

static const char short_options [] = "d:";
static const struct option long_options [] = {
	{"dir", required_argument, NULL, 'd' } 
};

static void list_dir(const char *base_dir, const char *dir_name)
{
	DIR *dir;
	struct dirent *dir_entry;
	char full_path[200];
	if (strcmp(dir_name, ".") == 0 || strcmp(dir_name, "..") == 0) {
		return;
	}
	sprintf(full_path, "%s/%s", base_dir, dir_name);

	printf("\nPath: %s\n", full_path);
	if ((dir = opendir(full_path)) == NULL) {
		printf("Could not open %s: %s\n", full_path, strerror(errno));
		return;
	}

	while(dir_entry = readdir(dir)) {
		/* Does not follow links, only cares about directories
		 * and regular files. */
		if (dir_entry->d_type == DT_DIR) {
			list_dir(full_path, dir_entry->d_name);
		}
		else if (dir_entry->d_type == DT_REG) {
			printf("%s ", dir_entry->d_name);
		}
	}
	printf("\n");
	closedir(dir);
}

int main(int argc, char *argv[])
{
	int c;
	int index;
	char *dirname;
	char start_path[PATH_MAX];

	c = getopt_long(argc, argv, short_options, long_options, &index);

	switch (c) {
		case 'd':
			dirname = malloc(strlen(optarg));
			strcpy(dirname, optarg);
			break;		
	}

	chdir(dirname);
	getcwd(start_path, PATH_MAX);
	list_dir(start_path, "");
}