34 #include "suffix_fnc.h" |
34 #include "suffix_fnc.h" |
35 #include "bfile_heuristics.h" |
35 #include "bfile_heuristics.h" |
36 #include "regex_parser.h" |
36 #include "regex_parser.h" |
37 #include <sys/stat.h> |
37 #include <sys/stat.h> |
38 |
38 |
39 int scanDirectory(scanner_t scanner, settings_t* settings) { |
39 typedef struct filelist filelist_t; |
40 |
40 |
|
41 struct filelist { |
|
42 char *displayname; |
|
43 int displayname_len; |
|
44 char *filename; |
|
45 int st_mode; |
|
46 filelist_t *next; |
|
47 }; |
|
48 |
|
49 filelist_t *buildFileList(scanner_t scanner, settings_t* settings, |
|
50 filelist_t* list) { |
|
51 |
41 DIR *dirf; |
52 DIR *dirf; |
42 struct dirent *entry; |
53 struct dirent *entry; |
43 int entrynamelen; |
|
44 int lines, a; |
|
45 int lineSum = 0; |
|
46 bool bfile; |
|
47 struct stat statbuf; |
54 struct stat statbuf; |
48 |
55 filelist_t *listentry = list; |
|
56 |
49 if ((dirf = opendir(scanner.dir)) == NULL) { |
57 if ((dirf = opendir(scanner.dir)) == NULL) { |
50 printf("%s", scanner.dir); |
58 printf("%s", scanner.dir); |
51 perror(" Directory access failed"); |
59 perror(" Directory access failed"); |
52 return 0; |
60 return 0; |
53 } |
61 } |
54 |
62 |
55 while ((entry = readdir(dirf)) != NULL) { |
63 while ((entry = readdir(dirf)) != NULL) { |
56 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { |
64 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { |
|
65 |
|
66 /* Create new filelist entry */ |
|
67 filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t)); |
|
68 // TODO: don't just append - create a sorted list! |
|
69 if (listentry) { |
|
70 listentry->next = newentry; |
|
71 } |
|
72 listentry = newentry; |
|
73 if (!list) { |
|
74 list = listentry; |
|
75 } |
|
76 |
|
77 listentry->next = NULL; |
|
78 |
|
79 listentry->displayname_len = strlen(entry->d_name); |
|
80 listentry->displayname = (char*) malloc(listentry->displayname_len+1); |
|
81 memcpy(listentry->displayname, entry->d_name, listentry->displayname_len); |
|
82 listentry->displayname[listentry->displayname_len] = 0; |
|
83 |
|
84 listentry->st_mode = 0; |
|
85 |
57 /* Construct absolute pathname string */ |
86 /* Construct absolute pathname string */ |
58 entrynamelen = strlen(entry->d_name); |
87 size_t dirnamelen = strlen(scanner.dir); |
59 char filename[(1+strlen(scanner.dir)+entrynamelen)]; |
88 char *filename = (char*) malloc(2+dirnamelen+listentry->displayname_len); |
60 strcpy(filename, scanner.dir); |
89 memcpy(filename, scanner.dir, dirnamelen); |
61 strncat(filename, &settings->fileSeparator, 1); |
90 filename[dirnamelen] = settings->fileSeparator; |
62 strcat(filename, entry->d_name); |
91 memcpy(filename+dirnamelen+1, entry->d_name, listentry->displayname_len); |
|
92 filename[1+dirnamelen+listentry->displayname_len] = 0; |
|
93 listentry->filename = filename; |
63 |
94 |
64 /* Check for subdirectory */ |
95 /* Check for subdirectory */ |
65 if (stat(filename, &statbuf) == 0) { |
96 if (stat(filename, &statbuf) == 0) { |
66 if (!(statbuf.st_mode & S_IFREG)) { |
97 listentry->st_mode = statbuf.st_mode; |
67 printf("%*s\n", entrynamelen+scanner.spaces, entry->d_name); |
|
68 if (settings->recursive && (statbuf.st_mode & S_IFDIR)) { |
|
69 lineSum += scanDirectory( |
|
70 (scanner_t) {filename, scanner.spaces+1}, settings); |
|
71 } |
|
72 continue; |
|
73 } |
|
74 } else { |
98 } else { |
75 perror(" Error in stat call"); |
99 perror(" Error in stat call"); |
76 continue; |
100 continue; |
77 } |
101 } |
78 |
102 } |
|
103 } |
|
104 |
|
105 closedir(dirf); |
|
106 |
|
107 return list; |
|
108 } |
|
109 |
|
110 int scanDirectory(scanner_t scanner, settings_t* settings) { |
|
111 |
|
112 int lines, a; |
|
113 int lineSum = 0; |
|
114 bool bfile; |
|
115 |
|
116 filelist_t *filelist = buildFileList(scanner, settings, NULL); |
|
117 |
|
118 while (filelist != NULL) { |
|
119 |
|
120 /* Scan subdirectories */ |
|
121 if (!(filelist->st_mode & S_IFREG)) { |
|
122 printf("%*s\n", filelist->displayname_len+scanner.spaces, |
|
123 filelist->displayname); |
|
124 if (settings->recursive && (filelist->st_mode & S_IFDIR)) { |
|
125 scanDirectory((scanner_t) {filelist->filename, scanner.spaces+1}, |
|
126 settings); |
|
127 } |
|
128 } else { |
79 if ((settings->includeSuffixes->count == 0 |
129 if ((settings->includeSuffixes->count == 0 |
80 || testSuffix(filename, settings->includeSuffixes)) |
130 || testSuffix(filelist->displayname, settings->includeSuffixes)) |
81 && !testSuffix(filename, settings->excludeSuffixes)) { |
131 && !testSuffix(filelist->displayname, settings->excludeSuffixes)) { |
|
132 |
82 /* Count lines */ |
133 /* Count lines */ |
83 lines = 0; |
134 lines = 0; |
84 bfile = false; |
135 bfile = false; |
85 bfile_reset(settings->bfileHeuristics); |
136 bfile_reset(settings->bfileHeuristics); |
86 char line_buffer[REGEX_MAX_LINELENGTH]; |
137 char line_buffer[REGEX_MAX_LINELENGTH]; |
87 int line_buffer_offset = 0; |
138 int line_buffer_offset = 0; |
88 |
139 |
89 FILE *file = fopen(filename, "r"); |
140 FILE *file = fopen(filelist->filename, "r"); |
90 if (file == NULL) { |
141 if (file == NULL) { |
91 printf("%*s", entrynamelen+scanner.spaces, entry->d_name); |
142 printf("%*s", filelist->displayname_len+scanner.spaces, |
|
143 filelist->displayname); |
92 perror(" File acces failed"); |
144 perror(" File acces failed"); |
93 continue; |
145 } else { |
94 } |
146 do { |
95 |
147 a = fgetc(file); |
96 do { |
148 |
97 a = fgetc(file); |
149 bfile = bfile_check(settings->bfileHeuristics, a); |
98 |
150 |
99 bfile = bfile_check(settings->bfileHeuristics, a); |
151 if (a == 10 || a == EOF) { |
100 |
152 line_buffer[line_buffer_offset] = 0; |
101 if (a == 10 || a == EOF) { |
153 if (regex_parser_do(settings->regex, line_buffer) == 0) { |
102 line_buffer[line_buffer_offset] = 0; |
154 /* Only subtract lines when matching has finished */ |
103 if (regex_parser_do(settings->regex, line_buffer) == 0) { |
155 if (!regex_parser_matching(settings->regex)) { |
104 /* Only subtract lines when matching has finished */ |
156 lines -= settings->regex->matched_lines; |
105 if (!regex_parser_matching(settings->regex)) { |
157 } |
106 lines -= settings->regex->matched_lines; |
158 } |
|
159 |
|
160 line_buffer_offset = 0; |
|
161 lines++; |
|
162 } else { |
|
163 if (line_buffer_offset < REGEX_MAX_LINELENGTH) { |
|
164 line_buffer[line_buffer_offset] = a; |
|
165 line_buffer_offset++; |
|
166 } else { |
|
167 line_buffer[line_buffer_offset-1] = 0; |
|
168 settings->confusing_lnlen = true; |
107 } |
169 } |
108 } |
170 } |
109 |
171 } while (!bfile && a != EOF); |
110 line_buffer_offset = 0; |
172 fclose(file); |
111 lines++; |
173 |
|
174 /* Print and sum line count */ |
|
175 if (bfile) { |
|
176 if (!settings->matchesOnly) { |
|
177 printf("%*s%*s%19s\n", filelist->displayname_len+scanner.spaces, |
|
178 filelist->displayname, |
|
179 60-filelist->displayname_len-scanner.spaces, "", "binary"); |
|
180 } |
112 } else { |
181 } else { |
113 if (line_buffer_offset < REGEX_MAX_LINELENGTH) { |
182 lineSum += lines; |
114 line_buffer[line_buffer_offset] = a; |
183 printf("%*s%*s%13d lines\n", |
115 line_buffer_offset++; |
184 filelist->displayname_len+scanner.spaces, filelist->displayname, |
116 } else { |
185 60-filelist->displayname_len-scanner.spaces, "", lines); |
117 line_buffer[line_buffer_offset-1] = 0; |
|
118 settings->confusing_lnlen = true; |
|
119 } |
|
120 } |
186 } |
121 } while (!bfile && a != EOF); |
|
122 fclose(file); |
|
123 |
|
124 /* Print and sum line count */ |
|
125 if (bfile) { |
|
126 if (!settings->matchesOnly) { |
|
127 printf("%*s%*s%19s\n", |
|
128 entrynamelen+scanner.spaces, entry->d_name, |
|
129 60-entrynamelen-scanner.spaces, "", "binary"); |
|
130 } |
|
131 } else { |
|
132 lineSum += lines; |
|
133 printf("%*s%*s%13d lines\n", |
|
134 entrynamelen+scanner.spaces, entry->d_name, |
|
135 60-entrynamelen-scanner.spaces, "", lines); |
|
136 } |
187 } |
137 } else { |
188 } else { |
138 if (!settings->matchesOnly) { |
189 if (!settings->matchesOnly) { |
139 /* Print hint */ |
190 /* Print hint */ |
140 printf("%*s%*s%19s\n", |
191 printf("%*s%*s%19s\n", |
141 entrynamelen+scanner.spaces, entry->d_name, |
192 filelist->displayname_len+scanner.spaces, filelist->displayname, |
142 60-entrynamelen-scanner.spaces, "", "no match"); |
193 60-filelist->displayname_len-scanner.spaces, "", "no match"); |
143 } |
194 } |
144 } |
195 } |
145 } |
196 } |
|
197 |
|
198 free(filelist->filename); |
|
199 free(filelist->displayname); |
|
200 filelist_t *freethis = filelist; |
|
201 filelist = filelist->next; |
|
202 free(freethis); |
146 } |
203 } |
147 |
|
148 closedir(dirf); |
|
149 |
204 |
150 return lineSum; |
205 return lineSum; |
151 } |
206 } |