1#include <dirent.h>
 2#include <stdio.h>
 3#include <stdlib.h>
 4#include <string.h>
 5#include <sys/stat.h>
 6
 7#include "list.h"
 8
 9void add_file_path(Node **head, char *file_path) {
10	Node *new = (Node *)malloc(sizeof(Node));
11	if (new == NULL) {
12		perror("malloc");
13		exit(EXIT_FAILURE);
14	}
15	new->file_path = strdup(file_path);
16	if (new->file_path == NULL) {
17		perror("strdup");
18		free(new);
19		exit(EXIT_FAILURE);
20	}
21	new->next = *head;
22	*head = new;
23}
24
25void list_files_recursively(char *base_path, Node **head, int max_depth, int current_depth) {
26	struct stat statbuf;
27	if (stat(base_path, &statbuf) == -1) {
28		perror("stat");
29		return;
30	}
31
32	if (S_ISREG(statbuf.st_mode)) {
33		add_file_path(head, base_path);
34		return;
35	}
36
37	char path[2048];
38	struct dirent *dp;
39	DIR *dir = opendir(base_path);
40
41	if (!dir)
42		return;
43
44	while ((dp = readdir(dir)) != NULL) {
45		if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
46			int ret = snprintf(path, sizeof(path), "%s%s%s", base_path, (base_path[strlen(base_path) - 1] == '/' ? "" : "/"), dp->d_name);
47
48			if (ret >= (int)sizeof(path)) {
49				fprintf(stderr, "Path too long: %s/%s\n", base_path, dp->d_name);
50				continue;
51			}
52
53			if (stat(path, &statbuf) != -1) {
54				if (S_ISDIR(statbuf.st_mode)) {
55					if (max_depth == -1 || current_depth < max_depth) {
56						list_files_recursively(path, head, max_depth, current_depth + 1);
57					}
58				} else if (S_ISREG(statbuf.st_mode)) {
59					add_file_path(head, path);
60				}
61			}
62		}
63	}
64
65	closedir(dir);
66}
67
68void free_file_list(Node *head) {
69	Node *tmp;
70
71	while (head != NULL) {
72		tmp = head;
73		head = head->next;
74		free(tmp->file_path);
75		free(tmp);
76	}
77}
78
79int size_of_file_list(Node *head) {
80	int count = 0;
81
82	Node *current = head;
83	while (current != NULL) {
84		count++;
85		current = current->next;
86	}
87
88	return count;
89}