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}