HuntnGather – Diff between revs 19 and 22

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 19 Rev 22
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2021 Wizardry and Steamworks - License: MIT // 2 // Copyright (C) 2021 Wizardry and Steamworks - License: MIT //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4   4  
5 #include <stdio.h> 5 #include <stdio.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <string.h> 7 #include <string.h>
8 #include <dirent.h> 8 #include <dirent.h>
9 #include <signal.h> 9 #include <signal.h>
10   10  
11 #include <sys/types.h> 11 #include <sys/types.h>
12 #include <sys/stat.h> 12 #include <sys/stat.h>
13 #include <sys/syslimits.h> 13 #include <sys/syslimits.h>
14   14  
15 #include <proto/dos.h> 15 #include <proto/dos.h>
16 #include <proto/exec.h> 16 #include <proto/exec.h>
-   17  
-   18 #if defined ___AsyncIO___
-   19 #include <asyncio.h>
-   20 #endif
17   21  
18 #include "StringStack.h" 22 #include "StringStack.h"
19   23  
20 #if !defined ___HAVE_GETOPT___ 24 #if !defined ___HAVE_GETOPT___
21 #include "getopt.h" 25 #include "getopt.h"
22 #endif 26 #endif
23   27  
24 #define PROGRAM_VERSION "1.7.2" 28 #define PROGRAM_VERSION "1.7.3"
25   29  
26 #if defined ___AmigaOS___ 30 #if defined ___AmigaOS___
27 /*************************************************************************/ 31 /*************************************************************************/
28 /* Version string used for querrying the program version. */ 32 /* Version string used for querrying the program version. */
29 /*************************************************************************/ 33 /*************************************************************************/
30 TEXT version_string[] = 34 TEXT version_string[] =
31 "\0$VER: Gather " PROGRAM_VERSION " "__DATE__" by Wizardry and Steamworks"; 35 "\0$VER: Gather " PROGRAM_VERSION " "__DATE__" by Wizardry and Steamworks";
32 #endif 36 #endif
33   37  
34 #if !defined TRUE 38 #if !defined TRUE
35 #define TRUE 1; 39 #define TRUE 1;
36 #endif 40 #endif
37   41  
38 #if !defined FALSE 42 #if !defined FALSE
39 #define FALSE 0; 43 #define FALSE 0;
40 #endif 44 #endif
-   45  
41   46 #define ASYNC_BUF 8192
42 #define MAX_MEM 262144 47 #define MAX_MEM 262144
43 #define NAME_BUF 32 48 #define NAME_BUF 32
44 #define PATH_BUF 128 49 #define PATH_BUF 128
45 #define LINE_BUF 256 50 #define LINE_BUF 256
46 #define DEFAULT_DATABASE_FILE "S:gather.db" 51 #define DEFAULT_DATABASE_FILE "S:gather.db"
47   52  
48 typedef struct { 53 typedef struct {
49 unsigned int dirs; 54 unsigned int dirs;
50 unsigned int files; 55 unsigned int files;
51 } stats; 56 } stats;
52   57  
53 int run = TRUE; 58 int run = TRUE;
54 int verbose = TRUE; 59 int verbose = TRUE;
55   60  
56 void SignalHandler(int sig) { 61 void SignalHandler(int sig) {
57 // Toggle the run flag to stop execution. 62 // Toggle the run flag to stop execution.
58 run = FALSE; 63 run = FALSE;
59 } 64 }
60   65  
61 int compare(const void *a, const void *b) { 66 int compare(const void *a, const void *b) {
62 const char **p = (const char **)a; 67 const char **p = (const char **)a;
63 const char **q = (const char **)b; 68 const char **q = (const char **)b;
64 return strncmp(*p, *q, strlen(*p)); 69 return strncmp(*p, *q, strlen(*p));
65 } 70 }
66   71  
67 /* 72 /*
68 * 73 *
69 * Sorts a database file lexicographically. 74 * Sorts a database file lexicographically.
70 */ 75 */
71 void SortDatabase(char *dbFile) { 76 void SortDatabase(char *dbFile) {
-   77 #if defined ___AsyncIO___
-   78 struct AsyncFile *fp;
-   79 LONG c;
-   80 #else
72 FILE *fp; 81 FILE *fp;
-   82 char c;
-   83 #endif
73 char *name = NULL; 84 char *name = NULL;
74 char *path = NULL; 85 char *path = NULL;
75 char **database; 86 char **database;
76 char c; -  
77 int i; 87 int i;
78 int side; 88 int side;
79 unsigned int line; 89 unsigned int line;
80 int name_size; 90 int name_size;
81 int path_size; 91 int path_size;
82   92  
83 // Open database file for reading. 93 // Open database file for reading.
-   94 #if defined ___AsyncIO___
-   95 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
-   96 #else
84 if((fp = fopen(dbFile, "r")) == NULL) { 97 if((fp = fopen(dbFile, "r")) == NULL) {
-   98 #endif
85 fprintf(stderr, "Unable to open gather database for reading.\n"); 99 fprintf(stderr, "Unable to open gather database for reading.\n");
86 return; 100 return;
87 } 101 }
88   102  
89 database = malloc(sizeof(*database)); 103 database = malloc(sizeof(*database));
90 name_size = NAME_BUF; 104 name_size = NAME_BUF;
91 name = malloc(name_size * sizeof(*name)); 105 name = malloc(name_size * sizeof(*name));
92 path_size = PATH_BUF; 106 path_size = PATH_BUF;
93 path = malloc(path_size * sizeof(*path)); 107 path = malloc(path_size * sizeof(*path));
-   108  
94 line = 0; 109 line = 0;
95 side = 0; 110 side = 0;
96 i = 0; 111 i = 0;
97   112  
98 if(verbose) { 113 if(verbose) {
99 fprintf(stdout, "Sorting database: '%s'\n", dbFile); 114 fprintf(stdout, "Sorting database: '%s'\n", dbFile);
100 } 115 }
-   116 #if defined ___AsyncIO___
-   117 while(run && (c = ReadCharAsync(fp)) != -1) {
101   118 #else
102 while(run && fscanf(fp, "%c", &c) == 1) { 119 while(run && fscanf(fp, "%c", &c) == 1) {
-   120 #endif
103 #if defined ___AmigaOS___ 121 #if defined ___AmigaOS___
104 // Check if CTRL+C was pressed and abort the program. 122 // Check if CTRL+C was pressed and abort the program.
105 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 123 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
106 run = FALSE; 124 run = FALSE;
107 continue; 125 continue;
108 } 126 }
109 #endif 127 #endif
110 switch(c) { 128 switch(c) {
111 case '\n': 129 case '\n':
112 // Load up the name and path into the database variable. 130 // Load up the name and path into the database variable.
113 database = realloc(database, (line + 1) * sizeof(*database)); 131 database = realloc(database, (line + 1) * sizeof(*database));
114 database[line] = malloc((strlen(name) + strlen(path) + 1 + 1) * sizeof(*database[line])); 132 database[line] = malloc((strlen(name) + strlen(path) + 1 + 1) * sizeof(*database[line]));
115 sprintf(database[line], "%s\t%s", name, path); 133 sprintf(database[line], "%s\t%s", name, path);
116 ++line; 134 ++line;
117   135  
118 free(name); 136 free(name);
119 name_size = NAME_BUF; 137 name_size = NAME_BUF;
120 name = malloc(name_size * sizeof(*name)); 138 name = malloc(name_size * sizeof(*name));
121 --side; 139 --side;
122 i = 0; 140 i = 0;
123   141  
124 break; 142 break;
125 case '\t': 143 case '\t':
126 free(path); 144 free(path);
127 path_size = PATH_BUF; 145 path_size = PATH_BUF;
128 path = malloc(path_size * sizeof(*path)); 146 path = malloc(path_size * sizeof(*path));
129 ++side; 147 ++side;
130 i = 0; 148 i = 0;
131 break; 149 break;
132 default: 150 default:
133 switch(side) { 151 switch(side) {
134 case 0: 152 case 0:
135 if(strlen(name) == name_size) { 153 if(strlen(name) == name_size) {
136 name_size = name_size * 1.5; 154 name_size = name_size * 1.5;
137 name = realloc(name, name_size * sizeof(*name)); 155 name = realloc(name, name_size * sizeof(*name));
138 } 156 }
139 //name = realloc(name, (i + 1 + 1) * sizeof(char)); 157 //name = realloc(name, (i + 1 + 1) * sizeof(char));
140 name[i] = c; 158 name[i] = c;
141 name[i + 1] = '\0'; 159 name[i + 1] = '\0';
142 break; 160 break;
143 case 1: 161 case 1:
144 if(strlen(path) == path_size) { 162 if(strlen(path) == path_size) {
145 path_size = path_size * 1.5; 163 path_size = path_size * 1.5;
146 path = realloc(path, path_size * sizeof(*path)); 164 path = realloc(path, path_size * sizeof(*path));
147 } 165 }
148 //path = realloc(path, (i + 1 + 1) * sizeof(char)); 166 //path = realloc(path, (i + 1 + 1) * sizeof(char));
149 path[i] = c; 167 path[i] = c;
150 path[i + 1] = '\0'; 168 path[i + 1] = '\0';
151 break; 169 break;
152 default: 170 default:
153 fprintf(stderr, "Database corrupted.\n"); 171 fprintf(stderr, "Database corrupted: %d\n", side);
154 break; 172 break;
155 } 173 }
156 ++i; 174 ++i;
157 break; 175 break;
158 } 176 }
159 } 177 }
-   178  
-   179 #if defined ___AsyncIO___
-   180 CloseAsync(fp);
160   181 #else
-   182 fclose(fp);
161 fclose(fp); 183 #endif
162   184  
163 // Sort the database. 185 // Sort the database.
164 qsort(database, line, sizeof(char *), compare); 186 qsort(database, line, sizeof(char *), compare);
165   187  
166 // Write the database lines back to the database. 188 // Write the database lines back to the database.
-   189 #if defined ___AsyncIO___
-   190 if((fp = OpenAsync(dbFile, MODE_READ|MODE_WRITE, ASYNC_BUF)) == NULL) {
-   191 #else
167 if((fp = fopen(dbFile, "w+")) == NULL) { 192 if((fp = fopen(dbFile, "w+")) == NULL) {
-   193 #endif
168 fprintf(stderr, "Unable to open gather database for writing.\n"); 194 fprintf(stderr, "Unable to open gather database for writing.\n");
169 return; 195 return;
170 } 196 }
171   197  
172 for(i = 0; i < line; ++i) { 198 for(i = 0; i < line; ++i) {
-   199 #if defined ___AsyncIO___
-   200 WriteAsync(fp, database[i], (LONG)(strlen(database[i]) * sizeof(char)));
-   201 WriteAsync(fp, "\n", 1 * sizeof(char));
-   202 #else
173 fprintf(fp, "%s\n", database[i]); 203 fprintf(fp, "%s\n", database[i]);
-   204 #endif
174 } 205 }
-   206  
175   207 #if defined ___AsyncIO___
-   208 CloseAsync(fp);
176 free(database); 209 #else
-   210 fclose(fp);
-   211 #endif
-   212  
177 fclose(fp); 213 free(database);
178 } 214 }
179   215  
180 /* 216 /*
181 * 217 *
182 * Updates a database file "dbFile". 218 * Updates a database file "dbFile".
183 */ 219 */
184 void UpdateDatabase(char *dbFile, stringStack *dirStack, stats *stats) { 220 void UpdateDatabase(char *dbFile, stringStack *dirStack, stats *stats) {
-   221 #if defined ___AsyncIO___
-   222 struct AsyncFile *fp;
-   223 #else
185 FILE *fp; 224 FILE *fp;
-   225 #endif
186 DIR *dir; 226 DIR *dir;
187 struct dirent *dirEntry; 227 struct dirent *dirEntry;
188 struct stat dirStat; 228 struct stat dirStat;
189 unsigned int size; 229 unsigned int size;
190 char *path; 230 char *path;
191 char *subPath; 231 char *subPath;
-   232  
-   233 #if defined ___AsyncIO___
-   234 if((fp = OpenAsync(dbFile, MODE_READ|MODE_WRITE, ASYNC_BUF)) == NULL) {
192   235 #else
-   236 if((fp = fopen(dbFile, "w+")) == NULL) {
193 if((fp = fopen(dbFile, "w+")) == NULL) { 237 #endif
194 fprintf(stderr, "Unable to open gather database for writing.\n"); 238 fprintf(stderr, "Unable to open gather database for writing.\n");
195 return; 239 return;
196 } 240 }
197   241  
198 while(run && !stringStackIsEmpty(dirStack)) { 242 while(run && !stringStackIsEmpty(dirStack)) {
199 #if defined ___AmigaOS___ 243 #if defined ___AmigaOS___
200 // Check if CTRL+C was pressed and abort the program. 244 // Check if CTRL+C was pressed and abort the program.
201 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 245 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
202 run = FALSE; 246 run = FALSE;
203 } 247 }
204 #endif 248 #endif
205 if((path = stringStackPop(dirStack)) == NULL) { 249 if((path = stringStackPop(dirStack)) == NULL) {
206 return; 250 return;
207 } 251 }
208   252  
209 if((dir = opendir(path)) == NULL) { 253 if((dir = opendir(path)) == NULL) {
210 return; 254 return;
211 } 255 }
212   256  
213 while(run && (dirEntry = readdir(dir)) != NULL) { 257 while(run && (dirEntry = readdir(dir)) != NULL) {
214 #if defined ___AmigaOS___ 258 #if defined ___AmigaOS___
215 // Check if CTRL+C was pressed and abort the program. 259 // Check if CTRL+C was pressed and abort the program.
216 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 260 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
217 run = FALSE; 261 run = FALSE;
218 } 262 }
219 #endif 263 #endif
220 size = sizeof(path) + sizeof(dirEntry->d_name) + 1; 264 size = sizeof(path) + sizeof(dirEntry->d_name) + 1;
221 switch(path[strlen(path) - 1]) { 265 switch(path[strlen(path) - 1]) {
222 case '/': 266 case '/':
223 case ':': // This is a drive path. 267 case ':': // This is a drive path.
224 subPath = malloc(size); 268 subPath = malloc(size);
225 sprintf(subPath, "%s%s", path, dirEntry->d_name); 269 sprintf(subPath, "%s%s", path, dirEntry->d_name);
226 break; 270 break;
227 default: 271 default:
228 subPath = malloc(size + 1); 272 subPath = malloc(size + 1);
229 sprintf(subPath, "%s/%s", path, dirEntry->d_name); 273 sprintf(subPath, "%s/%s", path, dirEntry->d_name);
230 break; 274 break;
231 } 275 }
232 stat(subPath, &dirStat); 276 stat(subPath, &dirStat);
233 if(S_ISDIR(dirStat.st_mode)) { 277 if(S_ISDIR(dirStat.st_mode)) {
234 stringStackPush(dirStack, subPath); 278 stringStackPush(dirStack, subPath);
235   279  
236 ++stats->dirs; 280 ++stats->dirs;
237   281  
238 if(verbose) { 282 if(verbose) {
239 fprintf(stdout, 283 fprintf(stdout,
240 "Gathered %d directories and %d files.\r", 284 "Gathered %d directories and %d files.\r",
241 stats->dirs, 285 stats->dirs,
242 stats->files); 286 stats->files);
243 } 287 }
244   288  
245 free(subPath); 289 free(subPath);
246 continue; 290 continue;
247 } 291 }
248   292  
249 // Write to database file. 293 // Write to database file.
250   294  
251 #if defined ___NOCASE_FS___ 295 #if defined ___NOCASE_FS___
252 strupr(dirEntry->d_name); 296 strupr(dirEntry->d_name);
253 #endif 297 #endif
-   298  
-   299 #if defined ___AsyncIO___
-   300 WriteAsync(fp, dirEntry->d_name, (LONG)(strlen(dirEntry->d_name) * sizeof(char)));
-   301 WriteAsync(fp, "\t", 1 * sizeof(char));
-   302 WriteAsync(fp, subPath, (LONG)(strlen(subPath) * sizeof(char)));
-   303 WriteAsync(fp, "\n", 1 * sizeof(char));
254   304 #else
255 fprintf(fp, "%s\t%s\n", dirEntry->d_name, subPath); 305 fprintf(fp, "%s\t%s\n", dirEntry->d_name, subPath);
256   306 #endif
257 ++stats->files; 307 ++stats->files;
258   308  
259 if(verbose) { 309 if(verbose) {
260 fprintf(stdout, 310 fprintf(stdout,
261 "Gathered %d directories and %d files.\r", 311 "Gathered %d directories and %d files.\r",
262 stats->dirs, 312 stats->dirs,
263 stats->files); 313 stats->files);
264 } 314 }
265   315  
266 free(subPath); 316 free(subPath);
267 } 317 }
268   318  
269 closedir(dir); 319 closedir(dir);
270 free(path); 320 free(path);
271 } 321 }
272   322  
273 if(verbose) { 323 if(verbose) {
274 fprintf(stdout, "\n"); 324 fprintf(stdout, "\n");
275 } 325 }
-   326  
-   327 #if defined ___AsyncIO___
-   328 CloseAsync(fp);
276   329 #else
-   330 fclose(fp);
277 fclose(fp); 331 #endif
278   332  
279 } 333 }
280   334  
281 /* 335 /*
282 * 336 *
283 * Gets the size of a database "dbFle". 337 * Gets the size of a database "dbFle".
284 */ 338 */
285 int GetDatabaseSize(char *dbFile) { 339 int GetDatabaseSize(char *dbFile) {
286 FILE *fp; 340 FILE *fp;
287 int size; 341 int size;
288   342  
289 if((fp = fopen(dbFile, "r")) == NULL) { 343 if((fp = fopen(dbFile, "r")) == NULL) {
290 fprintf(stderr, "Unable to open gather database for reading.\n"); 344 fprintf(stderr, "Unable to open gather database for reading.\n");
291 fclose(fp); 345 fclose(fp);
292 return 0; 346 return 0;
293 } 347 }
294   348  
295 fseek(fp, 0L, SEEK_END); 349 fseek(fp, 0L, SEEK_END);
296 size = ftell(fp); 350 size = ftell(fp);
297   351  
298 fclose(fp); 352 fclose(fp);
299 return size; 353 return size;
300 } 354 }
301   355  
302 /* 356 /*
303 * 357 *
304 * Counts the lines in a database file "dbFile". 358 * Counts the lines in a database file "dbFile".
305 */ 359 */
306 int CountDatabaseLines(char *dbFile) { 360 int CountDatabaseLines(char *dbFile) {
-   361 #if defined ___AsyncIO___
-   362 struct AsyncFile *fp;
-   363 LONG c;
-   364 #else
307 FILE *fp; 365 FILE *fp;
308 int lines; -  
309 char c; 366 char c;
-   367 #endif
-   368 int lines;
-   369  
-   370 #if defined ___AsyncIO___
-   371 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
310   372 #else
-   373 if((fp = fopen(dbFile, "r")) == NULL) {
311 if((fp = fopen(dbFile, "r")) == NULL) { 374 #endif
312 fprintf(stderr, "Unable to open gather database for reading.\n"); -  
313 fclose(fp); 375 fprintf(stderr, "Unable to open gather database for reading.\n");
314 return 0; 376 return 0;
315 } 377 }
316   378  
317 lines = 0; 379 lines = 0;
-   380 #if defined ___AsyncIO___
-   381 while((c = ReadCharAsync(fp)) != -1) {
-   382 #else
318 while(fscanf(fp, "%c", &c) == 1) { 383 while(fscanf(fp, "%c", &c) == 1) {
-   384 #endif
319 switch(c) { 385 switch(c) {
320 case '\n': 386 case '\n':
321 ++lines; 387 ++lines;
322 break; 388 break;
323 } 389 }
324 } 390 }
-   391  
-   392 #if defined ___AsyncIO___
-   393 CloseAsync(fp);
325   394 #else
-   395 fclose(fp);
326 fclose(fp); 396 #endif
327   397  
328 return lines; 398 return lines;
329 } 399 }
330   400  
331 /* 401 /*
332 * 402 *
333 * Creates "files" temporary filenames. 403 * Creates "files" temporary filenames.
334 */ 404 */
335 char **CreateTempFiles(int files) { 405 char **CreateTempFiles(int files) {
336 char **tmpNames; 406 char **tmpNames;
337 int count; 407 int count;
338   408  
339 tmpNames = malloc(files * sizeof(char *)); 409 tmpNames = malloc(files * sizeof(char *));
340   410  
341 if(verbose) { 411 if(verbose) {
342 fprintf(stdout, "Creating temporary files.\r"); 412 fprintf(stdout, "Creating temporary files.\r");
343 } 413 }
344   414  
345 count = files; 415 count = files;
346 while(--count > -1) { 416 while(--count > -1) {
347 #if defined ___AmigaOS___ 417 #if defined ___AmigaOS___
348 // Check if CTRL+C was pressed and abort the program. 418 // Check if CTRL+C was pressed and abort the program.
349 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 419 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
350 run = FALSE; 420 run = FALSE;
351 } 421 }
352 #endif 422 #endif
353 tmpNames[count] = tmpnam(NULL); 423 tmpNames[count] = tmpnam(NULL);
354   424  
355 if(verbose) { 425 if(verbose) {
356 fprintf(stdout, "Creating temporary files: %d%%\r", 100 - (int)(((float)count / files) * 100.0)); 426 fprintf(stdout, "Creating temporary files: %d%%\r", 100 - (int)(((float)count / files) * 100.0));
357 } 427 }
358 } 428 }
359   429  
360 if(verbose) { 430 if(verbose) {
361 fprintf(stdout, "\n"); 431 fprintf(stdout, "\n");
362 } 432 }
363   433  
364 return tmpNames; 434 return tmpNames;
365 } 435 }
366   436  
367 /* 437 /*
368 * 438 *
369 * Writes lines from the database "dbFile" to temporary filenames "tmpNames". 439 * Writes lines from the database "dbFile" to temporary filenames "tmpNames".
370 */ 440 */
371 void WriteTempFiles(char *dbFile, char **tmpNames, int tmpFiles, int tmpLines, int total) { 441 void WriteTempFiles(char *dbFile, char **tmpNames, int tmpFiles, int tmpLines, int total) {
-   442 #if defined ___AsyncIO___
-   443 struct AsyncFile *fp, *tp;
-   444 LONG c;
-   445 #else
372 FILE *fp, *tp; 446 FILE *fp, *tp;
373 char c; 447 char c;
-   448 #endif
374 int lines; 449 int lines;
375 int linesWritten; 450 int linesWritten;
-   451  
-   452 #if defined ___AsyncIO___
-   453 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
376   454 #else
-   455 if((fp = fopen(dbFile, "r")) == NULL) {
377 if((fp = fopen(dbFile, "r")) == NULL) { 456 #endif
378 fprintf(stderr, "Unable to open gather database for reading.\n"); 457 fprintf(stderr, "Unable to open gather database for reading.\n");
379 return; 458 return;
380 } 459 }
-   460  
-   461 #if defined ___AsyncIO___
-   462 if((tp = OpenAsync(tmpNames[--tmpFiles], MODE_READ|MODE_WRITE, ASYNC_BUF)) == NULL) {
381   463 #else
-   464 if((tp = fopen(tmpNames[--tmpFiles], "w+")) == NULL) {
382 if((tp = fopen(tmpNames[--tmpFiles], "w+")) == NULL) { 465 #endif
383 fprintf(stderr, "Unable to open temporary file '%s' for writing.\n", tmpNames[tmpFiles]); -  
384 fclose(fp); 466 fprintf(stderr, "Unable to open temporary file '%s' for writing.\n", tmpNames[tmpFiles]);
385 return; 467 return;
386 } 468 }
387   469  
388 if(verbose) { 470 if(verbose) {
389 fprintf(stdout, "Writing to temporary files.\r"); 471 fprintf(stdout, "Writing to temporary files.\r");
390 } 472 }
391   473  
392 linesWritten = 0; 474 linesWritten = 0;
393 lines = 0; 475 lines = 0;
-   476 #if defined ___AsyncIO___
-   477 while(run && (c = ReadCharAsync(fp)) != -1) {
-   478 #else
394 while(run && fscanf(fp, "%c", &c) == 1) { 479 while(run && fscanf(fp, "%c", &c) == 1) {
-   480 #endif
395 #if defined ___AmigaOS___ 481 #if defined ___AmigaOS___
396 // Check if CTRL+C was pressed and abort the program. 482 // Check if CTRL+C was pressed and abort the program.
397 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 483 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
398 run = FALSE; 484 run = FALSE;
399 } 485 }
400 #endif 486 #endif
401 switch(c) { 487 switch(c) {
402 case '\n': 488 case '\n':
403 // Increment the total written lines. 489 // Increment the total written lines.
404 ++linesWritten; 490 ++linesWritten;
405   491  
406 if(verbose) { 492 if(verbose) {
407 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)linesWritten / total) * 100.0)); 493 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)linesWritten / total) * 100.0));
408 } 494 }
409   495  
410 // Write the newline character back. 496 // Write the newline character back.
-   497 #if defined ___AsyncIO___
-   498 if(WriteCharAsync(tp, (UBYTE)c) != 1) {
-   499 #else
411 if(fprintf(tp, "%c", c) != 1) { 500 if(fprintf(tp, "%c", c) != 1) {
-   501 #endif
412 fprintf(stderr, "Unable to write to temporary file '%s'.\n", tmpNames[tmpFiles]); 502 fprintf(stderr, "Unable to write to temporary file '%s'.\n", tmpNames[tmpFiles]);
-   503 #if defined ___AsyncIO___
-   504 CloseAsync(tp);
-   505 CloseAsync(fp);
-   506 #else
413 fclose(tp); 507 fclose(tp);
414 fclose(fp); 508 fclose(fp);
-   509 #endif
415 return; 510 return;
416 } 511 }
417 // Switch to the next temporary file. 512 // Switch to the next temporary file.
418 if(++lines >= tmpLines) { 513 if(++lines >= tmpLines) {
419 // If there are no temporary files left then run till the end. 514 // If there are no temporary files left then run till the end.
420 if(tmpFiles - 1 < 0) { 515 if(tmpFiles - 1 < 0) {
421 break; 516 break;
422 } 517 }
423   518  
424 // Close the previous temporary file and write to the next temporary file. 519 // Close the previous temporary file and write to the next temporary file.
-   520 #if defined ___AsyncIO___
-   521 CloseAsync(tp);
-   522 if((tp = OpenAsync(tmpNames[--tmpFiles], MODE_READ|MODE_WRITE, ASYNC_BUF)) == NULL) {
-   523 #else
425 fclose(tp); 524 fclose(tp);
426 if((tp = fopen(tmpNames[--tmpFiles], "w+")) == NULL) { 525 if((tp = fopen(tmpNames[--tmpFiles], "w+")) == NULL) {
-   526 #endif
427 fprintf(stderr, "Unable to open temporary file '%s' for writing.\n", tmpNames[tmpFiles]); 527 fprintf(stderr, "Unable to open temporary file '%s' for writing.\n", tmpNames[tmpFiles]);
-   528 #if defined ___AsyncIO___
-   529 CloseAsync(tp);
-   530 CloseAsync(fp);
-   531 #else
428 fclose(tp); 532 fclose(tp);
429 fclose(fp); 533 fclose(fp);
-   534 #endif
430 } 535 }
431 lines = 0; 536 lines = 0;
432 break; 537 break;
433 } 538 }
434 break; 539 break;
435 default: 540 default:
-   541 #if defined ___AsyncIO___
-   542 if(WriteCharAsync(tp, (UBYTE)c) != 1) {
-   543 #else
436 if(fprintf(tp, "%c", c) != 1) { 544 if(fprintf(tp, "%c", c) != 1) {
-   545 #endif
437 fprintf(stderr, "Unable to write to temporary file '%s'.\n", tmpNames[tmpFiles]); 546 fprintf(stderr, "Unable to write to temporary file '%s'.\n", tmpNames[tmpFiles]);
-   547 #if defined ___AsyncIO___
-   548 CloseAsync(tp);
-   549 CloseAsync(fp);
-   550 #else
438 fclose(tp); 551 fclose(tp);
439 fclose(fp); 552 fclose(fp);
-   553 #endif
440 return; 554 return;
441 } 555 }
442 break; 556 break;
443 } 557 }
444 } 558 }
445   559  
446 fprintf(stdout, "\n"); 560 fprintf(stdout, "\n");
-   561  
-   562 #if defined ___AsyncIO___
-   563 CloseAsync(tp);
-   564 CloseAsync(fp);
447   565 #else
448 fclose(tp); 566 fclose(tp);
-   567 fclose(fp);
449 fclose(fp); 568 #endif
450 } 569 }
451   570  
452 /* 571 /*
453 * 572 *
454 * Skips a line in a database file "fp". 573 * Skips a line in a database file "fp".
455 */ 574 */
-   575  
-   576 #if defined ___AsyncIO___
-   577 void SkipDatabaseLine(struct AsyncFile *fp) {
-   578 LONG c;
-   579 while((c = ReadCharAsync(fp)) != -1) {
-   580 #else
456 void SkipDatabaseLine(FILE *fp) { 581 void SkipDatabaseLine(FILE *fp) {
457 char c; 582 char c;
458   -  
459 while(fscanf(fp, "%c", &c) == 1) { 583 while(fscanf(fp, "%c", &c) == 1) {
-   584 #endif
-   585 switch(c) {
460 if(c == '\n') { 586 case '\n':
461 break; 587 return;
462 } 588 }
463 } 589 }
464   -  
465 return; -  
466 } 590 }
467   591  
468 /* 592 /*
469 * 593 *
470 * Reads a line from the database file "fp". 594 * Reads a line from the database file "fp".
471 */ 595 */
-   596 #if defined ___AsyncIO___
-   597 char *ReadDatabaseLine(struct AsyncFile *fp) {
-   598 LONG c;
-   599 #else
472 char *ReadDatabaseLine(FILE *fp) { 600 char *ReadDatabaseLine(FILE *fp) {
473 char c; 601 char c;
-   602 #endif
474 char *line; 603 char *line;
475 int line_size; 604 int line_size;
476 int i; 605 int i;
477   606  
478 line_size = LINE_BUF; 607 line_size = LINE_BUF;
479 line = malloc(line_size * sizeof(*line)); 608 line = malloc(line_size * sizeof(*line));
480   609  
481 i = 0; 610 i = 0;
-   611 #if defined ___AsyncIO___
-   612 while(run && (c = ReadCharAsync(fp)) != -1) {
-   613 #else
482 while(run && fscanf(fp, "%c", &c) == 1) { 614 while(run && fscanf(fp, "%c", &c) == 1) {
-   615 #endif
483 #if defined ___AmigaOS___ 616 #if defined ___AmigaOS___
484 // Check if CTRL+C was pressed and abort the program. 617 // Check if CTRL+C was pressed and abort the program.
485 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 618 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
486 run = FALSE; 619 run = FALSE;
487 } 620 }
488 #endif 621 #endif
489 switch(c) { 622 switch(c) {
490 case '\n': 623 case '\n':
491 // Rewind the file by the number of read characters. 624 // Rewind the file by the number of read characters.
-   625 #if defined ___AsyncIO___
-   626 if(SeekAsync(fp, -(i + 1), MODE_CURRENT) == -1) {
-   627 fprintf(stderr, "Could not seek in file.\n");
-   628 return NULL;
-   629 }
-   630 #else
492 fseek(fp, -(i + 1), SEEK_CUR); 631 fseek(fp, -(i + 1), SEEK_CUR);
-   632 #endif
493 return line; 633 return line;
494 default: 634 default:
495 if(strlen(line) == line_size) { 635 if(strlen(line) == line_size) {
496 line_size = line_size * 1.5; 636 line_size = line_size * 1.5;
497 line = realloc(line, line_size * sizeof(*line)); 637 line = realloc(line, line_size * sizeof(*line));
498 } 638 }
499 //line = realloc(line, (chars + 1 + 1) * sizeof(char)); 639 //line = realloc(line, (chars + 1 + 1) * sizeof(char));
500 line[i] = c; 640 line[i] = c;
501 line[i + 1] = '\0'; 641 line[i + 1] = '\0';
502 break; 642 break;
503 } 643 }
504 ++i; 644 ++i;
505 } 645 }
506   646  
507 return NULL; 647 return NULL;
508 } 648 }
509   649  
510 /* 650 /*
511 * 651 *
512 * Merges temporary files "tmpNames" into a database "dbFile". 652 * Merges temporary files "tmpNames" into a database "dbFile".
513 */ 653 */
514 void MergeDatabase(char *dbFile, char **tmpNames, int files, int lines) { 654 void MergeDatabase(char *dbFile, char **tmpNames, int files, int lines) {
-   655 #if defined ___AsyncIO___
-   656 struct AsyncFile *fp;
-   657 struct AsyncFile **tp;
-   658 #else
515 FILE *fp; 659 FILE *fp;
516 FILE **tp; 660 FILE **tp;
-   661 #endif
517 int i; 662 int i;
518 int j; 663 int j;
519 char *tmp; 664 char *tmp;
520 char *min; 665 char *min;
521 int count; 666 int count;
-   667  
-   668 #if defined ___AsyncIO___
-   669 if((fp = OpenAsync(dbFile, MODE_READ|MODE_WRITE, ASYNC_BUF)) == NULL) {
522   670 #else
-   671 if((fp = fopen(dbFile, "w+")) == NULL) {
523 if((fp = fopen(dbFile, "w+")) == NULL) { 672 #endif
524 fprintf(stderr, "Unable to open gather database for writing.\n"); 673 fprintf(stderr, "Unable to open gather database for writing.\n");
525 return; 674 return;
526 } 675 }
527   676  
528 // Allocate as many file pointers as temporary files. 677 // Allocate as many file pointers as temporary files.
529 tp = malloc(files * sizeof(*tp)); 678 tp = malloc(files * sizeof(*tp));
530   679  
531 // Open all temporary files for reading. 680 // Open all temporary files for reading.
532 for(i = 0; i < files; ++i) { 681 for(i = 0; i < files; ++i) {
-   682 #if defined ___AsyncIO___
-   683 if((tp[i] = OpenAsync(tmpNames[i], MODE_READ, ASYNC_BUF)) == NULL) {
-   684 #else
533 if((tp[i] = fopen(tmpNames[i], "r")) == NULL) { 685 if((tp[i] = fopen(tmpNames[i], "r")) == NULL) {
-   686 #endif
534 fprintf(stderr, "Unable to open temporary file '%s' for reading.\n", tmpNames[i]); 687 fprintf(stderr, "Unable to open temporary file '%s' for reading.\n", tmpNames[i]);
535 // Close all temporary files. 688 // Close all temporary files.
536 --i; 689 --i;
537 while(i >= 0) { 690 while(i >= 0) {
-   691 #if defined ___AsyncIO___
-   692 CloseAsync(tp[i]);
-   693 #else
538 fclose(tp[i]); 694 fclose(tp[i]);
-   695 #endif
539 } 696 }
540 return; 697 return;
541 } 698 }
542 } 699 }
543   700  
544 if(verbose) { 701 if(verbose) {
545 fprintf(stdout, "Merging all database lines in temporary files.\r"); 702 fprintf(stdout, "Merging all database lines in temporary files.\r");
546 } 703 }
547   704  
548 count = lines; 705 count = lines;
549 j = 0; 706 j = 0;
550 while(run && --count > -1) { 707 while(run && --count > -1) {
551 #if defined ___AmigaOS___ 708 #if defined ___AmigaOS___
552 // Check if CTRL+C was pressed and abort the program. 709 // Check if CTRL+C was pressed and abort the program.
553 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 710 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
554 run = FALSE; 711 run = FALSE;
555 } 712 }
556 #endif 713 #endif
557 // Find the smallest line in all temporary files. 714 // Find the smallest line in all temporary files.
558 if(verbose) { 715 if(verbose) {
559 fprintf(stdout, "Merging all database lines in temporary files: %d%%.\r", 100 - (int)(((float)count / lines) * 100.0)); 716 fprintf(stdout, "Merging all database lines in temporary files: %d%%.\r", 100 - (int)(((float)count / lines) * 100.0));
560 } 717 }
561   718  
562 min = NULL; 719 min = NULL;
563 for(i = 0; i < files; ++i) { 720 for(i = 0; i < files; ++i) {
564 tmp = ReadDatabaseLine(tp[i]); 721 tmp = ReadDatabaseLine(tp[i]);
565 if(tmp == NULL) { 722 if(tmp == NULL) {
566 continue; 723 continue;
567 } 724 }
568 if(min == NULL || strncmp(tmp, min, strlen(tmp)) < 0) { 725 if(min == NULL || strncmp(tmp, min, strlen(tmp)) < 0) {
569 if(min != NULL) { 726 if(min != NULL) {
570 // Free previous instance. 727 // Free previous instance.
571 free(min); 728 free(min);
572 } 729 }
573 min = malloc((strlen(tmp) + 1) * sizeof(*min)); 730 min = malloc((strlen(tmp) + 1) * sizeof(*min));
574 sprintf(min, "%s", tmp); 731 sprintf(min, "%s", tmp);
575 // Remember the index of the file where the smallest entry has been found. 732 // Remember the index of the file where the smallest entry has been found.
576 j = i; 733 j = i;
577 free(tmp); 734 free(tmp);
578 continue; 735 continue;
579 } 736 }
580 free(tmp); 737 free(tmp);
581 } 738 }
582   739  
583 // Forward the file where the smallest line was found. 740 // Forward the file where the smallest line was found.
584 SkipDatabaseLine(tp[j]); 741 SkipDatabaseLine(tp[j]);
585   742  
586 // Write the smallest line. 743 // Write the smallest line.
587 if(min != NULL) { 744 if(min != NULL) {
-   745 #if defined ___AsyncIO___
-   746 WriteAsync(fp, min, (LONG)(strlen(min) * sizeof(char)));
-   747 WriteAsync(fp, "\n", 1 * sizeof(char));
-   748 #else
588 fprintf(fp, "%s\n", min); 749 fprintf(fp, "%s\n", min);
-   750 #endif
589 free(min); 751 free(min);
590 } 752 }
591 } 753 }
592   754  
593 // Write out any remaining contents from the temporary files. 755 // Write out any remaining contents from the temporary files.
594 for(i = 0; i < files; ++i) { 756 for(i = 0; i < files; ++i) {
595 tmp = ReadDatabaseLine(tp[i]); 757 tmp = ReadDatabaseLine(tp[i]);
596 if(tmp == NULL) { 758 if(tmp == NULL) {
597 continue; 759 continue;
598 } 760 }
-   761 #if defined ___AsyncIO___
-   762 WriteAsync(fp, tmp, (LONG)(strlen(tmp) * sizeof(char)));
-   763 WriteAsync(fp, "\n", 1 * sizeof(char));
-   764 #else
599 fprintf(fp, "%s\n", tmp); 765 fprintf(fp, "%s\n", tmp);
-   766 #endif
600 free(tmp); 767 free(tmp);
601 } 768 }
602   769  
603 // Close and delete all temporary files. 770 // Close and delete all temporary files.
604 for(i = 0; i < files; ++i) { 771 for(i = 0; i < files; ++i) {
-   772 #if defined ___AsyncIO___
-   773 CloseAsync(tp[i]);
-   774 #else
605 fclose(tp[i]); 775 fclose(tp[i]);
-   776 #endif
606 // Delete temporary file. 777 // Delete temporary file.
607 remove(tmpNames[i]); 778 remove(tmpNames[i]);
608 } 779 }
609   780  
610 if(verbose) { 781 if(verbose) {
611 fprintf(stdout, "\n"); 782 fprintf(stdout, "\n");
612 } 783 }
-   784  
-   785 #if defined ___AsyncIO___
-   786 CloseAsync(fp);
613   787 #else
-   788 fclose(fp);
614 fclose(fp); 789 #endif
615 } 790 }
616   791  
617 /* 792 /*
618 * 793 *
619 * Indexes a "path" by creating a database "dbFile". 794 * Indexes a "path" by creating a database "dbFile".
620 */ 795 */
621 void Gather(char *dbFile, char *path) { 796 void Gather(char *dbFile, char *path) {
622 stringStack *stack = stringStackCreate(1); 797 stringStack *stack = stringStackCreate(1);
623 stats *stats = malloc(sizeof(stats)); 798 stats *stats = malloc(sizeof(stats));
624 char **tmpNames; 799 char **tmpNames;
625 int dbSize, dbLines, tmpFiles, tmpLines; 800 int dbSize, dbLines, tmpFiles, tmpLines;
626 int i; 801 int i;
627   802  
628 // Initialize metrics. 803 // Initialize metrics.
629 stats->dirs = 0; 804 stats->dirs = 0;
630 stats->files = 0; 805 stats->files = 0;
631   806  
632 // Push the first path onto the stack. 807 // Push the first path onto the stack.
633 stringStackPush(stack, path); 808 stringStackPush(stack, path);
634   809  
635 // Generate the database file. 810 // Generate the database file.
636 UpdateDatabase(dbFile, stack, stats); 811 UpdateDatabase(dbFile, stack, stats);
637   812  
638 // Get the database metrics. 813 // Get the database metrics.
639 dbSize = GetDatabaseSize(dbFile); 814 dbSize = GetDatabaseSize(dbFile);
640 dbLines = CountDatabaseLines(dbFile); 815 dbLines = CountDatabaseLines(dbFile);
641   816  
642 // Compute the amount of temporary files needed. 817 // Compute the amount of temporary files needed.
643 tmpFiles = dbSize / MAX_MEM; 818 tmpFiles = dbSize / MAX_MEM;
644   819  
645 // In case no temporary files are required, 820 // In case no temporary files are required,
646 // just sort the database and terminate. 821 // just sort the database and terminate.
647 if(tmpFiles <= 1) { 822 if(tmpFiles <= 1) {
648 SortDatabase(dbFile); 823 SortDatabase(dbFile);
649 return; 824 return;
650 } 825 }
651   826  
652 tmpLines = dbLines / tmpFiles; 827 tmpLines = dbLines / tmpFiles;
653   828  
654 // Create temporary files. 829 // Create temporary files.
655 if((tmpNames = CreateTempFiles(tmpFiles)) == NULL) { 830 if((tmpNames = CreateTempFiles(tmpFiles)) == NULL) {
656 fprintf(stderr, "Unable to create temporary files.\n"); 831 fprintf(stderr, "Unable to create temporary files.\n");
657 return; 832 return;
658 } 833 }
659   834  
660 // Write "tmpLines" to temporary files in "tmpFiles" from "dbFile". 835 // Write "tmpLines" to temporary files in "tmpFiles" from "dbFile".
661 WriteTempFiles(dbFile, tmpNames, tmpFiles, tmpLines, dbLines); 836 WriteTempFiles(dbFile, tmpNames, tmpFiles, tmpLines, dbLines);
662   837  
663 // Sort the temporary files. 838 // Sort the temporary files.
664 for(i = 0; i < tmpFiles; ++i) { 839 for(i = 0; i < tmpFiles; ++i) {
665 SortDatabase(tmpNames[i]); 840 SortDatabase(tmpNames[i]);
666 } 841 }
667   842  
668 MergeDatabase(dbFile, tmpNames, tmpFiles, dbLines); 843 MergeDatabase(dbFile, tmpNames, tmpFiles, dbLines);
669 } 844 }
670   845  
671 void usage(char *name) { 846 void usage(char *name) {
672 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name); 847 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name);
673 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION); 848 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION);
674 fprintf(stdout, " \n"); 849 fprintf(stdout, " \n");
675 fprintf(stdout, "SYNTAX: %s [-q] DATABASE \n", name); 850 fprintf(stdout, "SYNTAX: %s [-q] DATABASE \n", name);
676 fprintf(stdout, " \n"); 851 fprintf(stdout, " \n");
677 fprintf(stdout, " -q Do not print out any messages. \n"); 852 fprintf(stdout, " -q Do not print out any messages. \n");
678 fprintf(stdout, " \n"); 853 fprintf(stdout, " \n");
679 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n"); 854 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n");
680 fprintf(stdout, "stored for searching with the Hunt tool. \n"); 855 fprintf(stdout, "stored for searching with the Hunt tool. \n");
681 fprintf(stdout, " \n"); 856 fprintf(stdout, " \n");
682 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n"); 857 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n");
683 } 858 }
684   859  
685 /* 860 /*
686 * 861 *
687 * Main entry point. 862 * Main entry point.
688 */ 863 */
689 int main(int argc, char **argv) { 864 int main(int argc, char **argv) {
690 int option; 865 int option;
691 char *dbFile; 866 char *dbFile;
692 char *path; 867 char *path;
693 struct stat dirStat; 868 struct stat dirStat;
694 #if defined ___AmigaOS___ 869 #if defined ___AmigaOS___
695 BPTR lock; 870 BPTR lock;
696 #endif 871 #endif
697   872  
698 // Bind handler to SIGINT. 873 // Bind handler to SIGINT.
699 signal(SIGINT, SignalHandler); 874 signal(SIGINT, SignalHandler);
700   875  
701 dbFile = DEFAULT_DATABASE_FILE; 876 dbFile = DEFAULT_DATABASE_FILE;
702 while((option = getopt(argc, argv, "hqd:")) != -1) { 877 while((option = getopt(argc, argv, "hqd:")) != -1) {
703 switch(option) { 878 switch(option) {
704 case 'd': 879 case 'd':
705 dbFile = optarg; 880 dbFile = optarg;
706 break; 881 break;
707 case 'q': 882 case 'q':
708 verbose = FALSE; 883 verbose = FALSE;
709 break; 884 break;
710 case 'h': 885 case 'h':
711 usage(argv[0]); 886 usage(argv[0]);
712 return 0; 887 return 0;
713 case '?': 888 case '?':
714 fprintf(stderr, "Invalid option %ct.\n", optopt); 889 fprintf(stderr, "Invalid option %ct.\n", optopt);
715 return 1; 890 return 1;
716 } 891 }
717 } 892 }
718   893  
719   894  
720 if(optind >= argc) { 895 if(optind >= argc) {
721 usage(argv[0]); 896 usage(argv[0]);
722 return 1; 897 return 1;
723 } 898 }
724   899  
725 #if defined ___AmigaOS___ 900 #if defined ___AmigaOS___
726 path = malloc(PATH_MAX * sizeof(*path)); 901 path = malloc(PATH_MAX * sizeof(*path));
727 lock = Lock(argv[optind], SHARED_LOCK); 902 lock = Lock(argv[optind], SHARED_LOCK);
728 NameFromLock(lock, path, PATH_MAX); 903 NameFromLock(lock, path, PATH_MAX);
729 UnLock(lock); 904 UnLock(lock);
730 #else 905 #else
731 path = realpath(argv[optind], NULL); 906 path = realpath(argv[optind], NULL);
732 #endif 907 #endif
733   908  
734 stat(path, &dirStat); 909 stat(path, &dirStat);
735 if(!S_ISDIR(dirStat.st_mode)) { 910 if(!S_ISDIR(dirStat.st_mode)) {
736 fprintf(stderr, "Path '%s' is not a directory.\n", argv[optind]); 911 fprintf(stderr, "Path '%s' is not a directory.\n", argv[optind]);
737 return 1; 912 return 1;
738 } 913 }
739   914  
740 if(verbose) { 915 if(verbose) {
741 fprintf(stdout, "Gathering to database file: %s\n", dbFile); 916 fprintf(stdout, "Gathering to database file: %s\n", dbFile);
742 } 917 }
743   918  
744 // Gather. 919 // Gather.
745 Gather(dbFile, path); 920 Gather(dbFile, path);
746   921  
747 free(path); 922 free(path);
748   923  
749 return 0; 924 return 0;
750 } 925 }
751   926