1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#define _GNU_SOURCE
#include "search.h"
#include "ll.h"
// Scan a directory
// Sort inputs into files and folders
// Store the full path for each file/folder
// Search new folders
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <stdio.h>
int nodesort(const struct dirent *node, int (*S_IS_CALLBACK)(mode_t)) {
// Ignore . and .. folders
if(strcmp(node->d_name, ".") == 0 || strcmp(node->d_name, "..") == 0 || strcmp(node->d_name, ".config") == 0)
return 0;
// Stat the file
struct stat sb;
if(stat(node->d_name, &sb) < 0) {
error(0, errno, "Couldn't stat file \"%s\"", node->d_name);
return 0;
}
// Check if the mode is correct
if((*S_IS_CALLBACK)(sb.st_mode))
return 1;
// God I love function pointers
// Not what is being checked for, exclude it
return 0;
}
int S_ISDIR_WRAPPER(mode_t mode) {
return S_ISDIR(mode);
}
int S_ISREG_WRAPPER(mode_t mode) {
return (S_ISREG(mode) && !S_ISDIR(mode));
}
int foldersort(const struct dirent *node) {
return nodesort(node, S_ISDIR_WRAPPER);
}
int filesort(const struct dirent *node) {
return nodesort(node, S_ISREG_WRAPPER);
}
struct nodelist* scanfolders(const char *STARTPATH, int (*cmp)(const struct dirent **, const struct dirent **)) {
struct dirent **nodes = NULL;
char *restoredir = NULL;
restoredir = get_current_dir_name();
if(restoredir == NULL) {
error(0, errno, "Couldn't get the current working dir to restore from later");
return NULL;
}
struct nodelist *scanner = nodelist_init(NULL), *holder = NULL, *start = scanner;
scanner->fullpath = realpath(STARTPATH, NULL);
for(; scanner != NULL; scanner = scanner->next) {
if(chdir(scanner->fullpath) < 0) {
error(0, errno, "Couldn't change to dir \"%s\". Skipping scan of that folder", scanner->fullpath);
continue;
}
int n = scandir(scanner->fullpath, &nodes, foldersort, cmp);
if(n >= 0) {
for(int i = 0; i < n; i++) {
holder = nodelist_init(NULL);
holder->fullpath = realpath(nodes[i]->d_name, NULL);
nodelist_append(scanner, holder); // Yeah this is slow but idk rn
}
} else {
error(0, errno, "Couldn't open dir \"%s\"", scanner->fullpath);
return NULL;
}
}
if(chdir(restoredir) < 0) {
error(0, errno, "Couldn't restore to proper working dir");
return NULL;
}
return start;
}
struct nodelist* scanfiles(const char *STARTPATH, int (*cmp)(const struct dirent **, const struct dirent **)) {
struct nodelist *folders = NULL, *files = NULL, *start = files;
folders = scanfolders(STARTPATH, cmp);
struct dirent **nodes;
int n = 0;
char *restoredir = NULL;
restoredir = get_current_dir_name();
if(restoredir == NULL) {
error(0, errno, "Could not get path to current working dir");
nodelist_delete(folders);
return NULL;
}
for(struct nodelist *p = folders; p != NULL; p = p->next) {
if(chdir(p->fullpath) < 0) {
error(0, errno, "Couldn't enter dir \"%s\", skipping...", p->fullpath);
continue;
}
n = scandir(p->fullpath, &nodes, filesort, cmp);
if(n >= 0) {
for(int i = 0; i < n; i++) {
if(files == NULL) {
files = nodelist_init(NULL);
start = files;
}
files->fullpath = realpath(nodes[i]->d_name, NULL);
files->next = nodelist_init(NULL);
files = files->next;
}
} else {
error(0, errno, "Could not scan dir \"%s\", skipping...", p->fullpath);
continue;
}
}
return start;
}
/*
int main(void) {
struct nodelist *files = scanfiles("./", alphasort);
printf("\nafter scan\n");
for(struct nodelist *p = files; p != NULL; p = p->next) {
if(p->fullpath != NULL) // Annoying extra "null" entry at the end of the list
printf("%s\n", p->fullpath);
}
return 0;
}
*/
|