HuntnGather – Diff between revs 33 and 37

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 33 Rev 37
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 #if !defined ___AmigaOS___ 8 #if !defined ___AmigaOS___
9 #include <dirent.h> 9 #include <dirent.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
11 #include <signal.h> 11 #include <signal.h>
12 #endif 12 #endif
13   13  
14 #include <sys/types.h> 14 #include <sys/types.h>
15 #include <sys/syslimits.h> 15 #include <sys/syslimits.h>
16   16  
17 #if defined ___AmigaOS___ 17 #if defined ___AmigaOS___
18 #include <proto/dos.h> 18 #include <proto/dos.h>
19 #include <proto/exec.h> 19 #include <proto/exec.h>
20 #include <proto/locale.h> 20 #include <proto/locale.h>
21 #include <clib/utility_protos.h> 21 #include <clib/utility_protos.h>
22 #endif 22 #endif
23   23  
24 #if defined ___AsyncIO___ 24 #if defined ___AsyncIO___
25 #include <asyncio.h> 25 #include <asyncio.h>
26 #endif 26 #endif
27   27  
28 #if !defined ___HAVE_GETOPT___ 28 #if !defined ___HAVE_GETOPT___
29 #include "/shared/getopt.h" 29 #include "/shared/getopt.h"
30 #endif 30 #endif
31   31  
32 #include "StringStack.h" 32 #include "StringStack.h"
33 #include "/shared/utilities.h" 33 #include "/shared/utilities.h"
34   34  
35 #define PROGRAM_VERSION "1.7.4" 35 #define PROGRAM_VERSION "1.7.4"
36   36  
37 #if defined ___AmigaOS___ 37 #if defined ___AmigaOS___
38 /*************************************************************************/ 38 /*************************************************************************/
39 /* Version string used for querrying the program version. */ 39 /* Version string used for querrying the program version. */
40 /*************************************************************************/ 40 /*************************************************************************/
41 TEXT version_string[] = 41 TEXT version_string[] =
42 "\0$VER: Gather " PROGRAM_VERSION " "__DATE__" by Wizardry and Steamworks"; 42 "\0$VER: Gather " PROGRAM_VERSION " "__DATE__" by Wizardry and Steamworks";
43 #endif 43 #endif
44   44  
45 int PROGRAM_RUN = TRUE; 45 int PROGRAM_RUN = TRUE;
46 int PROGRAM_VERBOSE = TRUE; 46 int PROGRAM_VERBOSE = TRUE;
47 int maxmem = MAX_MEM; 47 int maxmem = MAX_MEM;
48   48  
49 // Define global locale for string compare. 49 // Define global locale for string compare.
50 #if defined ___AmigaOS___ 50 #if defined ___AmigaOS___
51 struct Locale *locale; 51 struct Locale *locale;
52 #endif 52 #endif
53   53  
54 void SignalHandler(int sig) { 54 void SignalHandler(int sig) {
55 /* Toggle the run flag to stop execution. */ 55 /* Toggle the run flag to stop execution. */
56 PROGRAM_RUN = FALSE; 56 PROGRAM_RUN = FALSE;
57 } 57 }
58   58  
59 /* 59 /*
60 * 60 *
61 * Used for sorting database lines. 61 * Used for sorting database lines.
62 */ 62 */
63 int QsortCompare(const void *a, const void *b) { 63 int QsortCompare(const void *a, const void *b) {
64 #if defined ___AmigaOS___ 64 #if defined ___AmigaOS___
65 return StrnCmp( 65 return StrnCmp(
66 locale, 66 locale,
67 (STRPTR)(*(const char **)a), 67 (STRPTR)(*(const char **)a),
68 (STRPTR)*((const char **)b), 68 (STRPTR)*((const char **)b),
69 -1, 69 -1,
70 SC_ASCII 70 SC_ASCII
71 ); 71 );
72 #else 72 #else
73 return strcmp(*(const char **)a, *(const char **)b); 73 return strcmp(*(const char **)a, *(const char **)b);
74 #endif 74 #endif
75 } 75 }
76   76  
77 /* 77 /*
78 * 78 *
79 * Sorts a database file lexicographically. 79 * Sorts a database file lexicographically.
80 */ 80 */
81 void SortDatabase(char *dbFile, int lines) { 81 void SortDatabase(char *dbFile, int lines) {
82 #if defined ___AsyncIO___ 82 #if defined ___AsyncIO___
83 struct AsyncFile *fp; 83 struct AsyncFile *fp;
84 #else 84 #else
85 FILE *fp; 85 FILE *fp;
86 #endif 86 #endif
87 char **database; 87 char **database;
88 dbEntry *entry; 88 dbEntry *entry;
89 char *line = NULL; 89 char *line = NULL;
90 char *rem; 90 char *rem;
91 int count; 91 int count;
92 int i; 92 int i;
93   93  
94 // Open database file for reading. 94 // Open database file for reading.
95 #if defined ___AsyncIO___ 95 #if defined ___AsyncIO___
96 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 96 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
97 #else 97 #else
98 if((fp = fopen(dbFile, "r")) == NULL) { 98 if((fp = fopen(dbFile, "r")) == NULL) {
99 #endif 99 #endif
100 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile); 100 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
101 return; 101 return;
102 } 102 }
103   103  
104 if((database = malloc(lines * sizeof(*database))) == NULL) { 104 if((database = malloc(lines * sizeof(*database))) == NULL) {
105 fprintf(stderr, "Memory allocation failure.\n"); 105 fprintf(stderr, "Memory allocation failure.\n");
106 #if defined ___AsyncIO___ 106 #if defined ___AsyncIO___
107 CloseAsync(fp); 107 CloseAsync(fp);
108 #else 108 #else
109 fclose(fp); 109 fclose(fp);
110 #endif 110 #endif
111 return; 111 return;
112 } 112 }
113   113  
114 if(PROGRAM_VERBOSE) { 114 if(PROGRAM_VERBOSE) {
115 fprintf(stdout, "Reading lines from file '%s' to array...\n", dbFile); 115 fprintf(stdout, "Reading lines from file '%s' to array...\n", dbFile);
116 } 116 }
117   117  
118 count = 0; 118 count = 0;
119 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) { 119 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) {
120 #if defined ___AmigaOS___ 120 #if defined ___AmigaOS___
121 // Check if CTRL+C was pressed and abort the program. 121 // Check if CTRL+C was pressed and abort the program.
122 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 122 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
123 PROGRAM_RUN = FALSE; 123 PROGRAM_RUN = FALSE;
124 continue; 124 continue;
125 } 125 }
126 #endif 126 #endif
127 if((entry = CreateDatabaseEntry(line)) == NULL) { 127 if((entry = CreateDatabaseEntry(line)) == NULL) {
128 fprintf(stderr, "Unable to create database entry.\n"); 128 fprintf(stderr, "Unable to create database entry.\n");
129 free(line); 129 free(line);
130 #if defined ___AsyncIO___ 130 #if defined ___AsyncIO___
131 CloseAsync(fp); 131 CloseAsync(fp);
132 #else 132 #else
133 fclose(fp); 133 fclose(fp);
134 #endif 134 #endif
135 return; 135 return;
136 } 136 }
137   137  
138 if((database[count] = malloc((strlen(entry->name) + strlen(entry->path) + 1 + 1) * sizeof(*database[count]))) == NULL) { 138 if((database[count] = malloc((strlen(entry->name) + strlen(entry->path) + 1 + 1) * sizeof(*database[count]))) == NULL) {
139 fprintf(stderr, "Memory allocation failure.\n"); 139 fprintf(stderr, "Memory allocation failure.\n");
140 free(entry->name); 140 free(entry->name);
141 free(entry->path); 141 free(entry->path);
142 free(entry); 142 free(entry);
143 free(line); 143 free(line);
144 #if defined ___AsyncIO___ 144 #if defined ___AsyncIO___
145 CloseAsync(fp); 145 CloseAsync(fp);
146 #else 146 #else
147 fclose(fp); 147 fclose(fp);
148 #endif 148 #endif
149 return; 149 return;
150 } 150 }
151   151  
152 sprintf(database[count], "%s\t%s", entry->name, entry->path); 152 sprintf(database[count], "%s\t%s", entry->name, entry->path);
153 ++count; 153 ++count;
154   154  
155 // Free the database entry. 155 // Free the database entry.
156 free(entry->name); 156 free(entry->name);
157 free(entry->path); 157 free(entry->path);
158 free(entry); 158 free(entry);
159   159  
160 free(line); 160 free(line);
161 } 161 }
162   162  
163 if(line != NULL) { 163 if(line != NULL) {
164 free(line); 164 free(line);
165 } 165 }
166   166  
167 #if defined ___AsyncIO___ 167 #if defined ___AsyncIO___
168 CloseAsync(fp); 168 CloseAsync(fp);
169 #else 169 #else
170 fclose(fp); 170 fclose(fp);
171 #endif 171 #endif
172   172  
173 if(PROGRAM_VERBOSE) { 173 if(PROGRAM_VERBOSE) {
174 fprintf(stdout, "Sorting %d lines in '%s'...\n", count, dbFile); 174 fprintf(stdout, "Sorting %d lines in '%s'...\n", count, dbFile);
175 } 175 }
176   176  
177 // Sort the database. 177 // Sort the database.
178 qsort(database, (unsigned int)count, sizeof(char *), QsortCompare); 178 qsort(database, (unsigned int)count, sizeof(char *), QsortCompare);
179   179  
180 if(PROGRAM_VERBOSE) { 180 if(PROGRAM_VERBOSE) {
181 fprintf(stdout, "Writing %d sorted lines to '%s'...\n", count, dbFile); 181 fprintf(stdout, "Writing %d sorted lines to '%s'...\n", count, dbFile);
182 } 182 }
183   183  
184 // Write the database lines back to the database. 184 // Write the database lines back to the database.
185 #if defined ___AsyncIO___ 185 #if defined ___AsyncIO___
186 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { 186 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) {
187 #else 187 #else
188 if((fp = fopen(dbFile, "w")) == NULL) { 188 if((fp = fopen(dbFile, "w")) == NULL) {
189 #endif 189 #endif
190 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile); 190 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile);
191 return; 191 return;
192 } 192 }
193   193  
194 rem = NULL; 194 rem = NULL;
195 for(i = 0; PROGRAM_RUN && i < count; ++i) { 195 for(i = 0; PROGRAM_RUN && i < count; ++i) {
196 #if defined ___AmigaOS___ 196 #if defined ___AmigaOS___
197 // Check if CTRL+C was pressed and abort the program. 197 // Check if CTRL+C was pressed and abort the program.
198 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 198 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
199 PROGRAM_RUN = FALSE; 199 PROGRAM_RUN = FALSE;
200 continue; 200 continue;
201 } 201 }
202 #endif 202 #endif
203   203  
204 if(rem != NULL) { 204 if(rem != NULL) {
205 #if defined ___AmigaOS___ 205 #if defined ___AmigaOS___
206 if(StrnCmp(locale, database[i], rem, -1, SC_ASCII) == 0) { 206 if(StrnCmp(locale, database[i], rem, -1, SC_ASCII) == 0) {
207 #else 207 #else
208 if(strcmp(database[i], rem) == 0) { 208 if(strcmp(database[i], rem) == 0) {
209 #endif 209 #endif
210 continue; 210 continue;
211 } 211 }
212 } 212 }
213   213  
214 #if defined ___AsyncIO___ 214 #if defined ___AsyncIO___
215 WriteAsync(fp, database[i], (LONG)strlen(database[i])); 215 WriteAsync(fp, database[i], (LONG)strlen(database[i]));
216 WriteAsync(fp, "\n", 1); 216 WriteAsync(fp, "\n", 1);
217 #else 217 #else
218 fprintf(fp, "%s\n", database[i]); 218 fprintf(fp, "%s\n", database[i]);
219 #endif 219 #endif
220   220  
221 if(rem != NULL) { 221 if(rem != NULL) {
222 free(rem); 222 free(rem);
223 } 223 }
224   224  
225 rem = malloc((strlen(database[i]) + 1) * sizeof(*rem)); 225 rem = malloc((strlen(database[i]) + 1) * sizeof(*rem));
226 sprintf(rem, "%s", database[i]); 226 sprintf(rem, "%s", database[i]);
227 } 227 }
228   228  
229 if(rem != NULL) { 229 if(rem != NULL) {
230 free(rem); 230 free(rem);
231 } 231 }
232   232  
233 #if defined ___AsyncIO___ 233 #if defined ___AsyncIO___
234 CloseAsync(fp); 234 CloseAsync(fp);
235 #else 235 #else
236 fclose(fp); 236 fclose(fp);
237 #endif 237 #endif
238   238  
239 if(PROGRAM_VERBOSE) { 239 if(PROGRAM_VERBOSE) {
240 fprintf(stdout, "Disposing %d lines of file '%s'...\n", count, dbFile); 240 fprintf(stdout, "Disposing %d lines of file '%s'...\n", count, dbFile);
241 } 241 }
242   242  
243 // Free up database. 243 // Free up database.
244 for(i = 0; i < count; ++i) { 244 for(i = 0; i < count; ++i) {
245 free(database[i]); 245 free(database[i]);
246 } 246 }
247   247  
248 free(database); 248 free(database);
249 } 249 }
250   250  
251 /* 251 /*
252 * 252 *
253 * Updates a database file "dbFile". 253 * Updates a database file "dbFile".
254 */ 254 */
255 dbStats *CollectFiles(char *dbFile, char **paths, int count) { 255 dbStats *CollectFiles(char *dbFile, char **paths, int count) {
256 #if defined ___AsyncIO___ 256 #if defined ___AsyncIO___
257 struct AsyncFile *fp; 257 struct AsyncFile *fp;
258 #else 258 #else
259 FILE *fp; 259 FILE *fp;
260 #endif 260 #endif
261 #if defined ___AmigaOS___ 261 #if defined ___AmigaOS___
262 struct FileInfoBlock *FIB; 262 struct FileInfoBlock *FIB;
263 BPTR lock; 263 BPTR lock;
264 #else 264 #else
265 DIR *dir; 265 DIR *dir;
266 struct dirent *entry; 266 struct dirent *entry;
267 struct stat dirStat; 267 struct stat dirStat;
268 #endif 268 #endif
269 stringStack *stack; 269 stringStack *stack;
270 dbStats *stats = NULL; 270 dbStats *stats = NULL;
271 int i; 271 int i;
272 char *path; 272 char *path;
273 char *sub; 273 char *sub;
274   274  
275 #if defined ___AsyncIO___ 275 #if defined ___AsyncIO___
276 if((fp = OpenAsync(dbFile, MODE_APPEND, ASYNC_BUF)) == NULL) { 276 if((fp = OpenAsync(dbFile, MODE_APPEND, ASYNC_BUF)) == NULL) {
277 #else 277 #else
278 if((fp = fopen(dbFile, "a")) == NULL) { 278 if((fp = fopen(dbFile, "a")) == NULL) {
279 #endif 279 #endif
280 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile); 280 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile);
281 return NULL; 281 return NULL;
282 } 282 }
283   283  
284 if(PROGRAM_VERBOSE) { 284 if(PROGRAM_VERBOSE) {
285 fprintf(stdout, "Collecting files...\r"); 285 fprintf(stdout, "Collecting files...\r");
286 } 286 }
287   287  
288 // Initialize metrics. 288 // Initialize metrics.
289 if((stats = malloc(sizeof(*stats))) == NULL) { 289 if((stats = malloc(sizeof(*stats))) == NULL) {
290 fprintf(stderr, "Memory allocation failure.\n"); 290 fprintf(stderr, "Memory allocation failure.\n");
291 #if defined ___AsyncIO___ 291 #if defined ___AsyncIO___
292 CloseAsync(fp); 292 CloseAsync(fp);
293 #else 293 #else
294 fclose(fp); 294 fclose(fp);
295 #endif 295 #endif
296 return NULL; 296 return NULL;
297 } 297 }
298   298  
299 stats->dirs = 0; 299 stats->dirs = 0;
300 stats->files = 0; 300 stats->files = 0;
301 stats->lines = 0; 301 stats->lines = 0;
302 stats->size = 0; 302 stats->size = 0;
303   303  
304 // Push the first path onto the stack. 304 // Push the first path onto the stack.
305 stack = stringStackCreate((unsigned int)count); 305 stack = stringStackCreate((unsigned int)count);
306 for(i = 0; PROGRAM_RUN && i < count; ++i) { 306 for(i = 0; PROGRAM_RUN && i < count; ++i) {
307 stringStackPush(stack, paths[i]); 307 stringStackPush(stack, paths[i]);
308 } 308 }
309   309  
310 while(PROGRAM_RUN && !stringStackIsEmpty(stack)) { 310 while(PROGRAM_RUN && !stringStackIsEmpty(stack)) {
311 #if defined ___AmigaOS___ 311 #if defined ___AmigaOS___
312 // Check if CTRL+C was pressed and abort the program. 312 // Check if CTRL+C was pressed and abort the program.
313 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 313 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
314 PROGRAM_RUN = FALSE; 314 PROGRAM_RUN = FALSE;
315 continue; 315 continue;
316 } 316 }
317 #endif 317 #endif
318 if((path = stringStackPop(stack)) == NULL) { 318 if((path = stringStackPop(stack)) == NULL) {
319 break; 319 break;
320 } 320 }
321   321  
322 #if defined ___AmigaOS___ 322 #if defined ___AmigaOS___
323 if((lock = Lock(path, ACCESS_READ)) == NULL) { 323 if((lock = Lock(path, ACCESS_READ)) == NULL) {
324 fprintf(stderr, "Could not lock path '%s' for reading.\n", path); 324 fprintf(stderr, "Could not lock path '%s' for reading.\n", path);
325 free(path); 325 free(path);
326 continue; 326 continue;
327 } 327 }
328   328  
329 if((FIB = AllocDosObject(DOS_FIB, NULL)) == NULL) { 329 if((FIB = AllocDosObject(DOS_FIB, NULL)) == NULL) {
330 fprintf(stderr, "File information block for path '%s' could not be allocated.\n", path); 330 fprintf(stderr, "File information block for path '%s' could not be allocated.\n", path);
331 UnLock(lock); 331 UnLock(lock);
332 free(path); 332 free(path);
333 continue; 333 continue;
334 } 334 }
335   335  
336 if(Examine(lock, FIB) == FALSE) { 336 if(Examine(lock, FIB) == FALSE) {
337 fprintf(stderr, "Path '%s' could not be examined.\n", path); 337 fprintf(stderr, "Path '%s' could not be examined.\n", path);
338 FreeDosObject(DOS_FIB, FIB); 338 FreeDosObject(DOS_FIB, FIB);
339 UnLock(lock); 339 UnLock(lock);
340 free(path); 340 free(path);
341 continue; 341 continue;
342 } 342 }
343   343  
344 while(PROGRAM_RUN && ExNext(lock, FIB)) { 344 while(PROGRAM_RUN && ExNext(lock, FIB)) {
345 // Check if CTRL+C was pressed and abort the program. 345 // Check if CTRL+C was pressed and abort the program.
346 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 346 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
347 PROGRAM_RUN = FALSE; 347 PROGRAM_RUN = FALSE;
348 continue; 348 continue;
349 } 349 }
350 #else 350 #else
351   351  
352 if((dir = opendir(path)) == NULL) { 352 if((dir = opendir(path)) == NULL) {
353 fprintf(stderr, "Directory '%s' could not be opened.\n", path); 353 fprintf(stderr, "Directory '%s' could not be opened.\n", path);
354 free(path); 354 free(path);
355 continue; 355 continue;
356 } 356 }
357   357  
358 while(PROGRAM_RUN && (entry = readdir(dir)) != NULL) { 358 while(PROGRAM_RUN && (entry = readdir(dir)) != NULL) {
359 #endif 359 #endif
360 switch(path[strlen(path) - 1]) { 360 switch(path[strlen(path) - 1]) {
361 case '/': 361 case '/':
362 case ':': // This is a drive path. 362 case ':': // This is a drive path.
363 #if defined ___AmigaOS___ 363 #if defined ___AmigaOS___
364 if((sub = malloc(strlen(path) + strlen(FIB->fib_FileName) + 1)) == NULL) { 364 if((sub = malloc(strlen(path) + strlen(FIB->fib_FileName) + 1)) == NULL) {
365 #else 365 #else
366 if((sub = malloc(strlen(path) + strlen(entry->d_name) + 1)) == NULL) { 366 if((sub = malloc(strlen(path) + strlen(entry->d_name) + 1)) == NULL) {
367 #endif 367 #endif
368 fprintf(stderr, "Memory allocation failure.\n"); 368 fprintf(stderr, "Memory allocation failure.\n");
369 #if defined ___AmigaOS___ 369 #if defined ___AmigaOS___
370 FreeDosObject(DOS_FIB, FIB); 370 FreeDosObject(DOS_FIB, FIB);
371 UnLock(lock); 371 UnLock(lock);
372 #else 372 #else
373 closedir(dir); 373 closedir(dir);
374 #endif 374 #endif
375 free(path); 375 free(path);
376 stringStackDestroy(stack); 376 stringStackDestroy(stack);
377 #if defined ___AsyncIO___ 377 #if defined ___AsyncIO___
378 CloseAsync(fp); 378 CloseAsync(fp);
379 #else 379 #else
380 fclose(fp); 380 fclose(fp);
381 #endif 381 #endif
382 return NULL; 382 return NULL;
383 } 383 }
384 #if defined ___AmigaOS___ 384 #if defined ___AmigaOS___
385 sprintf(sub, "%s%s", path, FIB->fib_FileName); 385 sprintf(sub, "%s%s", path, FIB->fib_FileName);
386 #else 386 #else
387 sprintf(sub, "%s%s", path, entry->d_name); 387 sprintf(sub, "%s%s", path, entry->d_name);
388 #endif 388 #endif
389 break; 389 break;
390 default: 390 default:
391 #if defined ___AmigaOS___ 391 #if defined ___AmigaOS___
392 if((sub = malloc(strlen(path) + strlen(FIB->fib_FileName) + 1 + 1)) == NULL) { 392 if((sub = malloc(strlen(path) + strlen(FIB->fib_FileName) + 1 + 1)) == NULL) {
393 #else 393 #else
394 if((sub = malloc(strlen(path) + strlen(entry->d_name) + 1 + 1)) == NULL) { 394 if((sub = malloc(strlen(path) + strlen(entry->d_name) + 1 + 1)) == NULL) {
395 #endif 395 #endif
396 fprintf(stderr, "Memory allocation failure.\n"); 396 fprintf(stderr, "Memory allocation failure.\n");
397 #if defined ___AmigaOS___ 397 #if defined ___AmigaOS___
398 FreeDosObject(DOS_FIB, FIB); 398 FreeDosObject(DOS_FIB, FIB);
399 UnLock(lock); 399 UnLock(lock);
400 #else 400 #else
401 closedir(dir); 401 closedir(dir);
402 #endif 402 #endif
403 free(path); 403 free(path);
404 stringStackDestroy(stack); 404 stringStackDestroy(stack);
405 #if defined ___AsyncIO___ 405 #if defined ___AsyncIO___
406 CloseAsync(fp); 406 CloseAsync(fp);
407 #else 407 #else
408 fclose(fp); 408 fclose(fp);
409 #endif 409 #endif
410 return NULL; 410 return NULL;
411 } 411 }
412 #if defined ___AmigaOS___ 412 #if defined ___AmigaOS___
413 sprintf(sub, "%s/%s", path, FIB->fib_FileName); 413 sprintf(sub, "%s/%s", path, FIB->fib_FileName);
414 #else 414 #else
415 sprintf(sub, "%s/%s", path, entry->d_name); 415 sprintf(sub, "%s/%s", path, entry->d_name);
416 #endif 416 #endif
417 break; 417 break;
418 } 418 }
419   419  
420 switch(GetFsType(sub)) { 420 switch(GetFsType(sub)) {
421 case UNKNOWN: 421 case UNKNOWN:
422 free(sub); 422 free(sub);
423 continue; 423 continue;
424 case REGULAR: 424 case REGULAR:
425 ++stats->files; 425 ++stats->files;
426   426  
427 if(PROGRAM_VERBOSE) { 427 if(PROGRAM_VERBOSE) {
428 fprintf(stdout, 428 fprintf(stdout,
429 "Gathered %d directories and %d files.\r", 429 "Gathered %d directories and %d files.\r",
430 stats->dirs, 430 stats->dirs,
431 stats->files); 431 stats->files);
432 } 432 }
433 break; 433 break;
434 case DIRECTORY: 434 case DIRECTORY:
435 stringStackPush(stack, sub); 435 stringStackPush(stack, sub);
436   436  
437 ++stats->dirs; 437 ++stats->dirs;
438   438  
439 if(PROGRAM_VERBOSE) { 439 if(PROGRAM_VERBOSE) {
440 fprintf(stdout, 440 fprintf(stdout,
441 "Gathered %d directories and %d files.\r", 441 "Gathered %d directories and %d files.\r",
442 stats->dirs, 442 stats->dirs,
443 stats->files); 443 stats->files);
444 } 444 }
445   445  
446 free(sub); 446 free(sub);
447 continue; 447 continue;
448 } 448 }
449   449  
450 #if defined ___NOCASE_FS___ 450 #if defined ___NOCASE_FS___
451 #if defined ___AmigaOS___ 451 #if defined ___AmigaOS___
452 StrUpr(FIB->fib_FileName); 452 StrUpr(FIB->fib_FileName);
453 #else 453 #else
454 StrUpr(entry->d_name); 454 StrUpr(entry->d_name);
455 #endif 455 #endif
456 #endif 456 #endif
457   457  
458 // Write to database file. 458 // Write to database file.
459 #if defined ___AsyncIO___ 459 #if defined ___AsyncIO___
460 #if defined ___AmigaOS___ 460 #if defined ___AmigaOS___
461 WriteAsync(fp, FIB->fib_FileName, (LONG)strlen(FIB->fib_FileName)); 461 WriteAsync(fp, FIB->fib_FileName, (LONG)strlen(FIB->fib_FileName));
462 stats->size = stats->size + strlen(FIB->fib_FileName); 462 stats->size = stats->size + strlen(FIB->fib_FileName);
463 #else 463 #else
464 WriteAsync(fp, entry->d_name, (LONG)strlen(entry->d_name)); 464 WriteAsync(fp, entry->d_name, (LONG)strlen(entry->d_name));
465 stats->size = stats->size + strlen(entry->d_name); 465 stats->size = stats->size + strlen(entry->d_name);
466 #endif 466 #endif
467 WriteAsync(fp, "\t", 1); 467 WriteAsync(fp, "\t", 1);
468 ++stats->size; 468 ++stats->size;
469 WriteAsync(fp, sub, (LONG)strlen(sub)); 469 WriteAsync(fp, sub, (LONG)strlen(sub));
470 stats->size = stats->size + strlen(sub); 470 stats->size = stats->size + strlen(sub);
471 WriteAsync(fp, "\n", 1); 471 WriteAsync(fp, "\n", 1);
472 ++stats->size; 472 ++stats->size;
473 #else 473 #else
474 #if defined ___AmigaOS___ 474 #if defined ___AmigaOS___
475 fprintf(fp, "%s\t%s\n", FIB->fib_FileName, sub); 475 fprintf(fp, "%s\t%s\n", FIB->fib_FileName, sub);
476 stats->size = stats->size + strlen(FIB->fib_FileName) + strlen(sub) + 1 + 1 + 1; 476 stats->size = stats->size + strlen(FIB->fib_FileName) + strlen(sub) + 1 + 1 + 1;
477 #else 477 #else
478 fprintf(fp, "%s\t%s\n", entry->d_name, sub); 478 fprintf(fp, "%s\t%s\n", entry->d_name, sub);
479 stats->size = stats->size + strlen(entry->d_name) + strlen(sub) + 1 + 1 + 1; 479 stats->size = stats->size + strlen(entry->d_name) + strlen(sub) + 1 + 1 + 1;
480 #endif 480 #endif
481 #endif 481 #endif
482   482  
483 ++stats->lines; 483 ++stats->lines;
484   484  
485 free(sub); 485 free(sub);
486 } 486 }
487   487  
488 #if defined ___AmigaOS___ 488 #if defined ___AmigaOS___
489 FreeDosObject(DOS_FIB, FIB); 489 FreeDosObject(DOS_FIB, FIB);
490 UnLock(lock); 490 UnLock(lock);
491 #else 491 #else
492 closedir(dir); 492 closedir(dir);
493 #endif 493 #endif
494 free(path); 494 free(path);
495 } 495 }
496   496  
497 if(PROGRAM_VERBOSE) { 497 if(PROGRAM_VERBOSE) {
498 fprintf(stdout, "\n"); 498 fprintf(stdout, "\n");
499 } 499 }
500   500  
501 stringStackDestroy(stack); 501 stringStackDestroy(stack);
502   502  
503 #if defined ___AsyncIO___ 503 #if defined ___AsyncIO___
504 CloseAsync(fp); 504 CloseAsync(fp);
505 #else 505 #else
506 fclose(fp); 506 fclose(fp);
507 #endif 507 #endif
508   508  
509 return stats; 509 return stats;
510   510  
511 } 511 }
512   512  
513 /* 513 /*
514 * 514 *
515 * Writes lines from the database "dbFile" to temporary filenames "tmpNames". 515 * Writes lines from the database "dbFile" to temporary filenames "tmpNames".
516 */ 516 */
517 void WriteTemporaryFiles(char *dbFile, char **tmpNames, int tmpFiles, int tmpLines, int total) { 517 void WriteTemporaryFiles(char *dbFile, char **tmpNames, int tmpFiles, int tmpLines, int total) {
518 #if defined ___AsyncIO___ 518 #if defined ___AsyncIO___
519 struct AsyncFile *fp, *tp; 519 struct AsyncFile *fp, *tp;
520 LONG c; 520 LONG c;
521 #else 521 #else
522 FILE *fp, *tp; 522 FILE *fp, *tp;
523 char c; 523 char c;
524 #endif 524 #endif
525 int lines; 525 int lines;
526 int write; 526 int write;
527   527  
528 #if defined ___AsyncIO___ 528 #if defined ___AsyncIO___
529 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 529 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
530 #else 530 #else
531 if((fp = fopen(dbFile, "r")) == NULL) { 531 if((fp = fopen(dbFile, "r")) == NULL) {
532 #endif 532 #endif
533 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile); 533 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
534 return; 534 return;
535 } 535 }
536   536  
537 #if defined ___AsyncIO___ 537 #if defined ___AsyncIO___
538 if((tp = OpenAsync(tmpNames[--tmpFiles], MODE_WRITE, ASYNC_BUF)) == NULL) { 538 if((tp = OpenAsync(tmpNames[--tmpFiles], MODE_WRITE, ASYNC_BUF)) == NULL) {
539 #else 539 #else
540 if((tp = fopen(tmpNames[--tmpFiles], "w")) == NULL) { 540 if((tp = fopen(tmpNames[--tmpFiles], "w")) == NULL) {
541 #endif 541 #endif
542 fprintf(stderr, "Could not open file '%s' for writing.\n", tmpNames[tmpFiles]); 542 fprintf(stderr, "Could not open file '%s' for writing.\n", tmpNames[tmpFiles]);
543 #if defined ___AsyncIO___ 543 #if defined ___AsyncIO___
544 CloseAsync(fp); 544 CloseAsync(fp);
545 #else 545 #else
546 fclose(fp); 546 fclose(fp);
547 #endif 547 #endif
548 return; 548 return;
549 } 549 }
550   550  
551 if(PROGRAM_VERBOSE) { 551 if(PROGRAM_VERBOSE) {
552 fprintf(stdout, "Writing to temporary files...\r"); 552 fprintf(stdout, "Writing to temporary files...\r");
553 } 553 }
554   554  
555 write = 0; 555 write = 0;
556 lines = 0; 556 lines = 0;
557 #if defined ___AsyncIO___ 557 #if defined ___AsyncIO___
558 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) { 558 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
559 #else 559 #else
560 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) { 560 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
561 #endif 561 #endif
562 #if defined ___AmigaOS___ 562 #if defined ___AmigaOS___
563 // Check if CTRL+C was pressed and abort the program. 563 // Check if CTRL+C was pressed and abort the program.
564 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 564 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
565 PROGRAM_RUN = FALSE; 565 PROGRAM_RUN = FALSE;
566 continue; 566 continue;
567 } 567 }
568 #endif 568 #endif
569 switch(c) { 569 switch(c) {
570 case '\n': 570 case '\n':
571 // Increment the total written lines. 571 // Increment the total written lines.
572 ++write; 572 ++write;
573   573  
574 if(PROGRAM_VERBOSE) { 574 if(PROGRAM_VERBOSE) {
575 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)write / total) * 100.0)); 575 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)write / total) * 100.0));
576 } 576 }
577   577  
578 // Write the newline character back. 578 // Write the newline character back.
579 #if defined ___AsyncIO___ 579 #if defined ___AsyncIO___
580 if(WriteCharAsync(tp, (UBYTE)c) != 1) { 580 if(WriteCharAsync(tp, (UBYTE)c) != 1) {
581 #else 581 #else
582 if(fprintf(tp, "%c", c) != 1) { 582 if(fprintf(tp, "%c", c) != 1) {
583 #endif 583 #endif
584 fprintf(stderr, "Unable to write to '%s'.\n", tmpNames[tmpFiles]); 584 fprintf(stderr, "Unable to write to '%s'.\n", tmpNames[tmpFiles]);
585 #if defined ___AsyncIO___ 585 #if defined ___AsyncIO___
586 CloseAsync(tp); 586 CloseAsync(tp);
587 CloseAsync(fp); 587 CloseAsync(fp);
588 #else 588 #else
589 fclose(tp); 589 fclose(tp);
590 fclose(fp); 590 fclose(fp);
591 #endif 591 #endif
592 return; 592 return;
593 } 593 }
594 // Switch to the next temporary file. 594 // Switch to the next temporary file.
595 if(++lines >= tmpLines) { 595 if(++lines >= tmpLines) {
596 // If there are no temporary files left then run till the end. 596 // If there are no temporary files left then run till the end.
597 if(tmpFiles - 1 < 0) { 597 if(tmpFiles - 1 < 0) {
598 break; 598 break;
599 } 599 }
600   600  
601 // Close the previous temporary file and write to the next temporary file. 601 // Close the previous temporary file and write to the next temporary file.
602 #if defined ___AsyncIO___ 602 #if defined ___AsyncIO___
603 CloseAsync(tp); 603 CloseAsync(tp);
604 if((tp = OpenAsync(tmpNames[--tmpFiles], MODE_WRITE, ASYNC_BUF)) == NULL) { 604 if((tp = OpenAsync(tmpNames[--tmpFiles], MODE_WRITE, ASYNC_BUF)) == NULL) {
605 #else 605 #else
606 fclose(tp); 606 fclose(tp);
607 if((tp = fopen(tmpNames[--tmpFiles], "w")) == NULL) { 607 if((tp = fopen(tmpNames[--tmpFiles], "w")) == NULL) {
608 #endif 608 #endif
609 fprintf(stderr, "Could not open '%s' for writing.\n", tmpNames[tmpFiles]); 609 fprintf(stderr, "Could not open '%s' for writing.\n", tmpNames[tmpFiles]);
610 #if defined ___AsyncIO___ 610 #if defined ___AsyncIO___
611 CloseAsync(fp); 611 CloseAsync(fp);
612 #else 612 #else
613 fclose(fp); 613 fclose(fp);
614 #endif 614 #endif
615 return; 615 return;
616 } 616 }
617 lines = 0; 617 lines = 0;
618 break; 618 break;
619 } 619 }
620 break; 620 break;
621 default: 621 default:
622 #if defined ___AsyncIO___ 622 #if defined ___AsyncIO___
623 if(WriteCharAsync(tp, (UBYTE)c) != 1) { 623 if(WriteCharAsync(tp, (UBYTE)c) != 1) {
624 #else 624 #else
625 if(fprintf(tp, "%c", c) != 1) { 625 if(fprintf(tp, "%c", c) != 1) {
626 #endif 626 #endif
627 fprintf(stderr, "Could not write to file '%s'.\n", tmpNames[tmpFiles]); 627 fprintf(stderr, "Could not write to file '%s'.\n", tmpNames[tmpFiles]);
628 #if defined ___AsyncIO___ 628 #if defined ___AsyncIO___
629 CloseAsync(tp); 629 CloseAsync(tp);
630 CloseAsync(fp); 630 CloseAsync(fp);
631 #else 631 #else
632 fclose(tp); 632 fclose(tp);
633 fclose(fp); 633 fclose(fp);
634 #endif 634 #endif
635 return; 635 return;
636 } 636 }
637 break; 637 break;
638 } 638 }
639 } 639 }
640   640  
641 if(PROGRAM_VERBOSE) { 641 if(PROGRAM_VERBOSE) {
642 fprintf(stdout, "\n"); 642 fprintf(stdout, "\n");
643 } 643 }
644   644  
645 #if defined ___AsyncIO___ 645 #if defined ___AsyncIO___
646 CloseAsync(tp); 646 CloseAsync(tp);
647 CloseAsync(fp); 647 CloseAsync(fp);
648 #else 648 #else
649 fclose(tp); 649 fclose(tp);
650 fclose(fp); 650 fclose(fp);
651 #endif 651 #endif
652 } 652 }
653   653  
654 /* 654 /*
655 * 655 *
656 * Merges temporary files "tmpNames" into a database "dbFile". 656 * Merges temporary files "tmpNames" into a database "dbFile".
657 */ 657 */
658 void MergeTemporaryFiles(char *dbFile, char **tmpNames, int files, int lines) { 658 void MergeTemporaryFiles(char *dbFile, char **tmpNames, int files, int lines) {
659 #if defined ___AsyncIO___ 659 #if defined ___AsyncIO___
660 struct AsyncFile *fp; 660 struct AsyncFile *fp;
661 struct AsyncFile **tp; 661 struct AsyncFile **tp;
662 #else 662 #else
663 FILE *fp; 663 FILE *fp;
664 FILE **tp; 664 FILE **tp;
665 #endif 665 #endif
666 int i; 666 int i;
667 int j; 667 int j;
668 char *tmp; 668 char *tmp;
669 char *rem; 669 char *rem;
670 char *min; 670 char *min;
671 int count; 671 int count;
672   672  
673 #if defined ___AsyncIO___ 673 #if defined ___AsyncIO___
674 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { 674 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) {
675 #else 675 #else
676 if((fp = fopen(dbFile, "w")) == NULL) { 676 if((fp = fopen(dbFile, "w")) == NULL) {
677 #endif 677 #endif
678 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile); 678 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile);
679 return; 679 return;
680 } 680 }
681   681  
682 // Allocate as many file pointers as temporary files. 682 // Allocate as many file pointers as temporary files.
683 if((tp = malloc(files * sizeof(*tp))) == NULL) { 683 if((tp = malloc(files * sizeof(*tp))) == NULL) {
684 fprintf(stderr, "Memory allocation failure.\n"); 684 fprintf(stderr, "Memory allocation failure.\n");
685 #if defined ___AsyncIO___ 685 #if defined ___AsyncIO___
686 CloseAsync(fp); 686 CloseAsync(fp);
687 #else 687 #else
688 fclose(fp); 688 fclose(fp);
689 #endif 689 #endif
690 return; 690 return;
691 } 691 }
692   692  
693 // Open all temporary files for reading. 693 // Open all temporary files for reading.
694 for(i = 0; i < files; ++i) { 694 for(i = 0; i < files; ++i) {
695 #if defined ___AsyncIO___ 695 #if defined ___AsyncIO___
696 if((tp[i] = OpenAsync(tmpNames[i], MODE_READ, ASYNC_BUF)) == NULL) { 696 if((tp[i] = OpenAsync(tmpNames[i], MODE_READ, ASYNC_BUF)) == NULL) {
697 #else 697 #else
698 if((tp[i] = fopen(tmpNames[i], "r")) == NULL) { 698 if((tp[i] = fopen(tmpNames[i], "r")) == NULL) {
699 #endif 699 #endif
700 fprintf(stderr, "Could not open file '%s' for reading.\n", tmpNames[i]); 700 fprintf(stderr, "Could not open file '%s' for reading.\n", tmpNames[i]);
701 // Close all temporary files. 701 // Close all temporary files.
702 while(--i > -1) { 702 while(--i > -1) {
703 #if defined ___AsyncIO___ 703 #if defined ___AsyncIO___
704 CloseAsync(tp[i]); 704 CloseAsync(tp[i]);
705 #else 705 #else
706 fclose(tp[i]); 706 fclose(tp[i]);
707 #endif 707 #endif
708 } 708 }
709 #if defined ___AsyncIO___ 709 #if defined ___AsyncIO___
710 CloseAsync(fp); 710 CloseAsync(fp);
711 #else 711 #else
712 fclose(fp); 712 fclose(fp);
713 #endif 713 #endif
714 return; 714 return;
715 } 715 }
716 } 716 }
717   717  
718 if(PROGRAM_VERBOSE) { 718 if(PROGRAM_VERBOSE) {
719 fprintf(stdout, "Merging all files...\r"); 719 fprintf(stdout, "Merging all files...\r");
720 } 720 }
721   721  
722 rem = NULL; 722 rem = NULL;
723 count = lines; 723 count = lines;
724 j = 0; 724 j = 0;
725 while(PROGRAM_RUN && --count > -1) { 725 while(PROGRAM_RUN && --count > -1) {
726 #if defined ___AmigaOS___ 726 #if defined ___AmigaOS___
727 // Check if CTRL+C was pressed and abort the program. 727 // Check if CTRL+C was pressed and abort the program.
728 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 728 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
729 PROGRAM_RUN = FALSE; 729 PROGRAM_RUN = FALSE;
730 continue; 730 continue;
731 } 731 }
732 #endif 732 #endif
733 // Find the smallest line in all temporary files. 733 // Find the smallest line in all temporary files.
734 if(PROGRAM_VERBOSE) { 734 if(PROGRAM_VERBOSE) {
735 fprintf(stdout, "Merging all files: %d%%.\r", 100 - (int)(((float)count / lines) * 100.0)); 735 fprintf(stdout, "Merging all files: %d%%.\r", 100 - (int)(((float)count / lines) * 100.0));
736 } 736 }
737   737  
738 min = NULL; 738 min = NULL;
739 for(i = 0; i < files; ++i) { 739 for(i = 0; i < files; ++i) {
740 tmp = PeekLine(tp[i]); 740 tmp = PeekLine(tp[i]);
741 if(tmp == NULL) { 741 if(tmp == NULL) {
742 continue; 742 continue;
743 } 743 }
744 #if defined ___AmigaOS___ 744 #if defined ___AmigaOS___
745 if(min == NULL || StrnCmp(locale, tmp, min, -1, SC_ASCII) < 0) { 745 if(min == NULL || StrnCmp(locale, tmp, min, -1, SC_ASCII) < 0) {
746 #else 746 #else
747 if(min == NULL || strcmp(tmp, min) < 0) { 747 if(min == NULL || strcmp(tmp, min) < 0) {
748 #endif 748 #endif
749 if(min != NULL) { 749 if(min != NULL) {
750 // Free previous instance. 750 // Free previous instance.
751 free(min); 751 free(min);
752 } 752 }
753 if((min = malloc((strlen(tmp) + 1) * sizeof(*min))) == NULL) { 753 if((min = malloc((strlen(tmp) + 1) * sizeof(*min))) == NULL) {
754 fprintf(stderr, "Memory allocation failure.\n"); 754 fprintf(stderr, "Memory allocation failure.\n");
755 free(tmp); 755 free(tmp);
756 if(min != NULL) { 756 if(min != NULL) {
757 free(min); 757 free(min);
758 } 758 }
759 if(rem != NULL) { 759 if(rem != NULL) {
760 free(rem); 760 free(rem);
761 } 761 }
762 #if defined ___AsyncIO___ 762 #if defined ___AsyncIO___
763 CloseAsync(fp); 763 CloseAsync(fp);
764 #else 764 #else
765 fclose(fp); 765 fclose(fp);
766 #endif 766 #endif
767 return; 767 return;
768 } 768 }
769 sprintf(min, "%s", tmp); 769 sprintf(min, "%s", tmp);
770 // Remember the index of the file where the smallest entry has been found. 770 // Remember the index of the file where the smallest entry has been found.
771 j = i; 771 j = i;
772 } 772 }
773 free(tmp); 773 free(tmp);
774 } 774 }
775   775  
776 // Forward the file where the smallest line was found. 776 // Forward the file where the smallest line was found.
777 SkipLine(tp[j]); 777 SkipLine(tp[j]);
778   778  
779 // Write the smallest line. 779 // Write the smallest line.
780 if(min != NULL) { 780 if(min != NULL) {
781 // If current minimum line is identical to previous minimum line then skip to remove duplicates. 781 // If current minimum line is identical to previous minimum line then skip to remove duplicates.
782 if(rem != NULL) { 782 if(rem != NULL) {
783 #if defined ___AmigaOS___ 783 #if defined ___AmigaOS___
784 if(StrnCmp(locale, min, rem, -1, SC_ASCII) == 0) { 784 if(StrnCmp(locale, min, rem, -1, SC_ASCII) == 0) {
785 #else 785 #else
786 if(strcmp(min, rem) == 0) { 786 if(strcmp(min, rem) == 0) {
787 #endif 787 #endif
788 free(min); 788 free(min);
789 continue; 789 continue;
790 } 790 }
791 } 791 }
792   792  
793 #if defined ___AsyncIO___ 793 #if defined ___AsyncIO___
794 WriteAsync(fp, min, (LONG)strlen(min)); 794 WriteAsync(fp, min, (LONG)strlen(min));
795 WriteAsync(fp, "\n", 1); 795 WriteAsync(fp, "\n", 1);
796 #else 796 #else
797 fprintf(fp, "%s\n", min); 797 fprintf(fp, "%s\n", min);
798 #endif 798 #endif
799   799  
800 if(rem != NULL) { 800 if(rem != NULL) {
801 free(rem); 801 free(rem);
802 } 802 }
803   803  
804 if((rem = malloc((strlen(min) + 1) * sizeof(*rem))) == NULL) { 804 if((rem = malloc((strlen(min) + 1) * sizeof(*rem))) == NULL) {
805 fprintf(stderr, "Memory allocation failure.\n"); 805 fprintf(stderr, "Memory allocation failure.\n");
806 free(min); 806 free(min);
807 #if defined ___AsyncIO___ 807 #if defined ___AsyncIO___
808 CloseAsync(fp); 808 CloseAsync(fp);
809 #else 809 #else
810 fclose(fp); 810 fclose(fp);
811 #endif 811 #endif
812 return; 812 return;
813 } 813 }
814   814  
815 sprintf(rem, "%s", min); 815 sprintf(rem, "%s", min);
816 free(min); 816 free(min);
817 } 817 }
818 } 818 }
819   819  
820 if(rem != NULL) { 820 if(rem != NULL) {
821 free(rem); 821 free(rem);
822 } 822 }
823   823  
824 // Write out any remaining contents from the temporary files. 824 // Write out any remaining contents from the temporary files.
825 for(i = 0; PROGRAM_RUN && i < files; ++i) { 825 for(i = 0; PROGRAM_RUN && i < files; ++i) {
826 #if defined ___AmigaOS___ 826 #if defined ___AmigaOS___
827 // Check if CTRL+C was pressed and abort the program. 827 // Check if CTRL+C was pressed and abort the program.
828 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 828 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
829 PROGRAM_RUN = FALSE; 829 PROGRAM_RUN = FALSE;
830 continue; 830 continue;
831 } 831 }
832 #endif 832 #endif
833 tmp = ReadLine(tp[i]); 833 tmp = ReadLine(tp[i]);
834 if(tmp == NULL) { 834 if(tmp == NULL) {
835 continue; 835 continue;
836 } 836 }
837 #if defined ___AsyncIO___ 837 #if defined ___AsyncIO___
838 WriteAsync(fp, tmp, (LONG)strlen(tmp)); 838 WriteAsync(fp, tmp, (LONG)strlen(tmp));
839 WriteAsync(fp, "\n", 1); 839 WriteAsync(fp, "\n", 1);
840 #else 840 #else
841 fprintf(fp, "%s\n", tmp); 841 fprintf(fp, "%s\n", tmp);
842 #endif 842 #endif
843 free(tmp); 843 free(tmp);
844 } 844 }
845   845  
846 // Close all temporary files. 846 // Close all temporary files.
847 for(i = 0; i < files; ++i) { 847 for(i = 0; i < files; ++i) {
848 #if defined ___AsyncIO___ 848 #if defined ___AsyncIO___
849 CloseAsync(tp[i]); 849 CloseAsync(tp[i]);
850 #else 850 #else
851 fclose(tp[i]); 851 fclose(tp[i]);
852 #endif 852 #endif
853 } 853 }
854   854  
855 #if defined ___AsyncIO___ 855 #if defined ___AsyncIO___
856 CloseAsync(fp); 856 CloseAsync(fp);
857 #else 857 #else
858 fclose(fp); 858 fclose(fp);
859 #endif 859 #endif
860   860  
861 if(PROGRAM_VERBOSE) { 861 if(PROGRAM_VERBOSE) {
862 fprintf(stdout, "\n"); 862 fprintf(stdout, "\n");
863 } 863 }
864 } 864 }
865   865  
866 /* 866 /*
867 * 867 *
868 * Filter the paths inside the database with provided paths. 868 * Filter the paths inside the database with provided paths.
869 */ 869 */
870 void FilterDatabasePaths(char *dbFile, char *tmpName, char **paths, int count) { 870 void FilterDatabasePaths(char *dbFile, char *tmpName, char **paths, int count) {
871 #if defined ___AsyncIO___ 871 #if defined ___AsyncIO___
872 struct AsyncFile *fp; 872 struct AsyncFile *fp;
873 struct AsyncFile *tp; 873 struct AsyncFile *tp;
874 #else 874 #else
875 FILE *fp; 875 FILE *fp;
876 FILE *tp; 876 FILE *tp;
877 #endif 877 #endif
878 char *line; 878 char *line;
879 int lines; 879 int lines;
880 int i; 880 int i;
881 dbEntry *entry; 881 dbEntry *entry;
882   882  
883 // Open database file for reading. 883 // Open database file for reading.
884 #if defined ___AsyncIO___ 884 #if defined ___AsyncIO___
885 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 885 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
886 #else 886 #else
887 if((fp = fopen(dbFile, "r")) == NULL) { 887 if((fp = fopen(dbFile, "r")) == NULL) {
888 #endif 888 #endif
889 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile); 889 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
890 return; 890 return;
891 } 891 }
892   892  
893 // Open temporary file for writing. 893 // Open temporary file for writing.
894 #if defined ___AsyncIO___ 894 #if defined ___AsyncIO___
895 if((tp = OpenAsync(tmpName, MODE_WRITE, ASYNC_BUF)) == NULL) { 895 if((tp = OpenAsync(tmpName, MODE_WRITE, ASYNC_BUF)) == NULL) {
896 #else 896 #else
897 if((tp = fopen(tmpName, "w")) == NULL) { 897 if((tp = fopen(tmpName, "w")) == NULL) {
898 #endif 898 #endif
899 fprintf(stderr, "Copuld not open file '%s' for writing.\n", tmpName); 899 fprintf(stderr, "Copuld not open file '%s' for writing.\n", tmpName);
900   900  
901 // Close database file. 901 // Close database file.
902 #if defined ___AsyncIO___ 902 #if defined ___AsyncIO___
903 CloseAsync(fp); 903 CloseAsync(fp);
904 #else 904 #else
905 fclose(fp); 905 fclose(fp);
906 #endif 906 #endif
907   907  
908 return; 908 return;
909 } 909 }
910   910  
911 if(PROGRAM_VERBOSE) { 911 if(PROGRAM_VERBOSE) {
912 fprintf(stdout, "Removing lines...\r"); 912 fprintf(stdout, "Removing lines...\r");
913 } 913 }
914   914  
915 lines = 0; 915 lines = 0;
916 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) { 916 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) {
917 #if defined ___AmigaOS___ 917 #if defined ___AmigaOS___
918 // Check if CTRL+C was pressed and abort the program. 918 // Check if CTRL+C was pressed and abort the program.
919 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 919 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
920 PROGRAM_RUN = FALSE; 920 PROGRAM_RUN = FALSE;
921 continue; 921 continue;
922 } 922 }
923 #endif 923 #endif
924 if((entry = CreateDatabaseEntry(line)) == NULL) { 924 if((entry = CreateDatabaseEntry(line)) == NULL) {
925 fprintf(stderr, "Unable to create database entry.\n"); 925 fprintf(stderr, "Unable to create database entry.\n");
926 free(line); 926 free(line);
927 continue; 927 continue;
928 } 928 }
929   929  
930 for(i = 0; i < count; ++i) { 930 for(i = 0; i < count; ++i) {
931 if(PathCompare(entry->path, paths[i]) == TRUE) { 931 if(PathCompare(entry->path, paths[i]) == TRUE) {
932 ++lines; 932 ++lines;
933 if(PROGRAM_VERBOSE) { 933 if(PROGRAM_VERBOSE) {
934 fprintf(stdout, "Removing lines: %d.\r", lines); 934 fprintf(stdout, "Removing lines: %d.\r", lines);
935 } 935 }
936 continue; 936 continue;
937 } 937 }
938 #if defined ___AsyncIO___ 938 #if defined ___AsyncIO___
939 WriteAsync(tp, line, (LONG)strlen(line)); 939 WriteAsync(tp, line, (LONG)strlen(line));
940 WriteAsync(tp, "\n", 1); 940 WriteAsync(tp, "\n", 1);
941 #else 941 #else
942 fprintf(tp, "%s\n", line); 942 fprintf(tp, "%s\n", line);
943 #endif 943 #endif
944 break; 944 break;
945 } 945 }
946   946  
947   947  
948 free(entry->name); 948 free(entry->name);
949 free(entry->path); 949 free(entry->path);
950 free(entry); 950 free(entry);
951   951  
952 free(line); 952 free(line);
953 } 953 }
954   954  
955 #if defined ___AsyncIO___ 955 #if defined ___AsyncIO___
956 CloseAsync(fp); 956 CloseAsync(fp);
957 CloseAsync(tp); 957 CloseAsync(tp);
958 #else 958 #else
959 fclose(fp); 959 fclose(fp);
960 fclose(tp); 960 fclose(tp);
961 #endif 961 #endif
962   962  
963 if(PROGRAM_VERBOSE) { 963 if(PROGRAM_VERBOSE) {
964 fprintf(stdout, "\n"); 964 fprintf(stdout, "\n");
965 } 965 }
966 } 966 }
967   967  
968 /* 968 /*
969 * 969 *
970 * Indexes a "path" by creating a database "dbFile". 970 * Indexes a "path" by creating a database "dbFile".
971 */ 971 */
972 void GatherDatabaseFiles(char *dbFile, char **paths, int count) { 972 void GatherDatabaseFiles(char *dbFile, char **paths, int count) {
973 dbStats *stats; 973 dbStats *stats;
974 char **tmpNames; 974 char **tmpNames;
975 int tmpFiles; 975 int tmpFiles;
976 int tmpLines; 976 int tmpLines;
977 int i; 977 int i;
978   978  
979 // Generate the database file from the supplied paths. 979 // Generate the database file from the supplied paths.
980 if((stats = CollectFiles(dbFile, paths, count)) == NULL) { 980 if((stats = CollectFiles(dbFile, paths, count)) == NULL) {
981 fprintf(stderr, "Collecting files failed.\n"); 981 fprintf(stderr, "Collecting files failed.\n");
982 return; 982 return;
983 } 983 }
984   984  
985 // Calculate the total number of temporary files required. 985 // Calculate the total number of temporary files required.
986 tmpFiles = stats->size / maxmem; 986 tmpFiles = stats->size / maxmem;
987   987  
988 /* In case no temporary files are required, 988 /* In case no temporary files are required,
989 * just sort the database and terminate. 989 * just sort the database and terminate.
990 */ 990 */
991 if(tmpFiles < 2) { 991 if(tmpFiles < 2) {
992 SortDatabase(dbFile, stats->lines); 992 SortDatabase(dbFile, stats->lines);
993 return; 993 return;
994 } 994 }
995   995  
996 // Calculate the number of lines per temporary file. 996 // Calculate the number of lines per temporary file.
997 tmpLines = stats->lines / tmpFiles; 997 tmpLines = stats->lines / tmpFiles;
998   998  
999 // Create temporary files. 999 // Create temporary files.
1000 if((tmpNames = CreateTemporaryFiles(tmpFiles)) == NULL) { 1000 if((tmpNames = CreateTemporaryFiles(tmpFiles)) == NULL) {
1001 fprintf(stderr, "Unable to create temporary files.\n"); 1001 fprintf(stderr, "Unable to create temporary files.\n");
1002 return; 1002 return;
1003 } 1003 }
1004   1004  
1005 // Write "tmpLines" to temporary files in "tmpNames" from "dbFile". 1005 // Write "tmpLines" to temporary files in "tmpNames" from "dbFile".
1006 WriteTemporaryFiles(dbFile, tmpNames, tmpFiles, tmpLines, stats->lines); 1006 WriteTemporaryFiles(dbFile, tmpNames, tmpFiles, tmpLines, stats->lines);
1007   1007  
1008 // Sort the temporary files. 1008 // Sort the temporary files.
1009 for(i = 0; i < tmpFiles; ++i) { 1009 for(i = 0; i < tmpFiles; ++i) {
1010 tmpLines = CountFileLines(tmpNames[i]); 1010 // Twice the number of computed lines required should cover the last file.
1011 SortDatabase(tmpNames[i], tmpLines); 1011 SortDatabase(tmpNames[i], 2 * tmpLines);
1012 } 1012 }
1013   1013  
1014 // Merge all the temporary files to the database file. 1014 // Merge all the temporary files to the database file.
1015 MergeTemporaryFiles(dbFile, tmpNames, tmpFiles, stats->lines); 1015 MergeTemporaryFiles(dbFile, tmpNames, tmpFiles, stats->lines);
1016   1016  
1017 // Remove all temporary files. 1017 // Remove all temporary files.
1018 RemoveFiles(tmpNames, tmpFiles); 1018 RemoveFiles(tmpNames, tmpFiles);
1019   1019  
1020 // Free temporary file names. 1020 // Free temporary file names.
1021 free(tmpNames); 1021 free(tmpNames);
1022   1022  
1023 // Free statistics. 1023 // Free statistics.
1024 free(stats); 1024 free(stats);
1025 } 1025 }
1026   1026  
1027 void RemoveDatabaseFiles(char *dbFile, char **paths, int count) { 1027 void RemoveDatabaseFiles(char *dbFile, char **paths, int count) {
1028 char *tmpName; 1028 char *tmpName;
1029   1029  
1030 // Create a temporary file to hold the changes. 1030 // Create a temporary file to hold the changes.
1031 if((tmpName = CreateTemporaryFile()) == NULL) { 1031 if((tmpName = CreateTemporaryFile()) == NULL) {
1032 fprintf(stderr, "Unable to create temporary file.\n"); 1032 fprintf(stderr, "Unable to create temporary file.\n");
1033 return; 1033 return;
1034 } 1034 }
1035   1035  
1036 // Filter the database of the provided paths. 1036 // Filter the database of the provided paths.
1037 FilterDatabasePaths(dbFile, tmpName, paths, count); 1037 FilterDatabasePaths(dbFile, tmpName, paths, count);
1038   1038  
1039 // Overwrite the database file with the filtered paths. 1039 // Overwrite the database file with the filtered paths.
1040 CopyFile(tmpName, dbFile); 1040 CopyFile(tmpName, dbFile);
1041   1041  
1042 // Remove temporary file. 1042 // Remove temporary file.
1043 if(RemoveFile(tmpName) == FALSE) { 1043 if(RemoveFile(tmpName) == FALSE) {
1044 fprintf(stderr, "Temporary file could not be removed.\n"); 1044 fprintf(stderr, "Temporary file could not be removed.\n");
1045 return; 1045 return;
1046 } 1046 }
1047 } 1047 }
1048   1048  
1049 void usage(char *name) { 1049 void usage(char *name) {
1050 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name); 1050 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name);
1051 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION); 1051 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION);
1052 fprintf(stdout, " \n"); 1052 fprintf(stdout, " \n");
1053 fprintf(stdout, "SYNTAX: %s [-q] <-a|-r|-c> <PATH PATH PATH...> \n", name); 1053 fprintf(stdout, "SYNTAX: %s [-q] <-a|-r|-c> <PATH PATH PATH...> \n", name);
1054 fprintf(stdout, " \n"); 1054 fprintf(stdout, " \n");
1055 fprintf(stdout, "Required: \n"); 1055 fprintf(stdout, "Required: \n");
1056 fprintf(stdout, " -a [PATH...] Add files. \n"); 1056 fprintf(stdout, " -a [PATH...] Add files. \n");
1057 fprintf(stdout, " -c [PATH...] Create from scratch. \n"); 1057 fprintf(stdout, " -c [PATH...] Create from scratch. \n");
1058 fprintf(stdout, " -r [PATH...] Remove files. \n"); 1058 fprintf(stdout, " -r [PATH...] Remove files. \n");
1059 fprintf(stdout, " \n"); 1059 fprintf(stdout, " \n");
1060 fprintf(stdout, "Optional: \n"); 1060 fprintf(stdout, "Optional: \n");
1061 fprintf(stdout, " -d [FIILE] Where to store the database. \n"); 1061 fprintf(stdout, " -d [FIILE] Where to store the database. \n");
1062 fprintf(stdout, " -m BYTES Memory to use (default: %d). \n", maxmem); 1062 fprintf(stdout, " -m BYTES Memory to use (default: %d). \n", maxmem);
1063 fprintf(stdout, " -q Do not print out any messages. \n"); 1063 fprintf(stdout, " -q Do not print out any messages. \n");
1064 fprintf(stdout, " \n"); 1064 fprintf(stdout, " \n");
1065 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n"); 1065 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n");
1066 fprintf(stdout, "stored for searching with the Hunt tool. \n"); 1066 fprintf(stdout, "stored for searching with the Hunt tool. \n");
1067 fprintf(stdout, " \n"); 1067 fprintf(stdout, " \n");
1068 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n"); 1068 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n");
1069 } 1069 }
1070   1070  
1071 /* 1071 /*
1072 * 1072 *
1073 * Main entry point. 1073 * Main entry point.
1074 */ 1074 */
1075 int main(int argc, char **argv) { 1075 int main(int argc, char **argv) {
1076 int option; 1076 int option;
1077 int i; 1077 int i;
1078 int count; 1078 int count;
1079 char *dbFile; 1079 char *dbFile;
1080 char *path; 1080 char *path;
1081 char **paths; 1081 char **paths;
1082 OPERATION operation = NONE; 1082 OPERATION operation = NONE;
1083   1083  
1084 // Bind handler to SIGINT. 1084 // Bind handler to SIGINT.
1085 #if !defined ___AmigaOS___ 1085 #if !defined ___AmigaOS___
1086 signal(SIGINT, SignalHandler); 1086 signal(SIGINT, SignalHandler);
1087 #endif 1087 #endif
1088   1088  
1089 dbFile = DEFAULT_DATABASE_FILE; 1089 dbFile = DEFAULT_DATABASE_FILE;
1090 while((option = getopt(argc, argv, "hqdm:arc")) != -1) { 1090 while((option = getopt(argc, argv, "hqdm:arc")) != -1) {
1091 switch(option) { 1091 switch(option) {
1092 case 'a': 1092 case 'a':
1093 operation = GATHER; 1093 operation = GATHER;
1094 break; 1094 break;
1095 case 'r': 1095 case 'r':
1096 operation = REMOVE; 1096 operation = REMOVE;
1097 break; 1097 break;
1098 case 'c': 1098 case 'c':
1099 operation = CREATE; 1099 operation = CREATE;
1100 break; 1100 break;
1101 case 'm': 1101 case 'm':
1102 maxmem = strtoul(optarg, NULL, 10); 1102 maxmem = strtoul(optarg, NULL, 10);
1103 break; 1103 break;
1104 case 'd': 1104 case 'd':
1105 dbFile = optarg; 1105 dbFile = optarg;
1106 break; 1106 break;
1107 case 'q': 1107 case 'q':
1108 PROGRAM_VERBOSE = FALSE; 1108 PROGRAM_VERBOSE = FALSE;
1109 break; 1109 break;
1110 case 'h': 1110 case 'h':
1111 usage(argv[0]); 1111 usage(argv[0]);
1112 return 0; 1112 return 0;
1113 case '?': 1113 case '?':
1114 fprintf(stderr, "Invalid option %ct.\n", optopt); 1114 fprintf(stderr, "Invalid option %ct.\n", optopt);
1115 return 1; 1115 return 5;
1116 } 1116 }
1117 } 1117 }
1118   1118  
1119 if(operation == NONE) { 1119 if(operation == NONE) {
1120 usage(argv[0]); 1120 usage(argv[0]);
1121 return 1; 1121 return 5;
1122 } 1122 }
1123   1123  
1124 if(optind >= argc) { 1124 if(optind >= argc) {
1125 usage(argv[0]); 1125 usage(argv[0]);
1126 return 1; 1126 return 5;
1127 } 1127 }
1128   1128  
1129 // Go through all supplied arguments and add paths to search. 1129 // Go through all supplied arguments and add paths to search.
1130 if((paths = malloc((argc - optind) * sizeof(*paths))) == NULL) { 1130 if((paths = malloc((argc - optind) * sizeof(*paths))) == NULL) {
1131 fprintf(stderr, "Memory allocation failure.\n"); 1131 fprintf(stderr, "Memory allocation failure.\n");
1132 return 1; 1132 return 20;
1133 } 1133 }
1134   1134  
1135 count = 0; 1135 count = 0;
1136 for(i = optind, count = 0; i < argc; ++i) { 1136 for(i = optind, count = 0; i < argc; ++i) {
1137 if((path = PathToAbsolute(argv[i])) == NULL) { 1137 if((path = PathToAbsolute(argv[i])) == NULL) {
1138 fprintf(stderr, "Absolute path for '%s' failed to resolve.\n", argv[optind]); 1138 fprintf(stderr, "Absolute path for '%s' failed to resolve.\n", argv[optind]);
1139 continue; 1139 continue;
1140 } 1140 }
1141   1141  
1142 switch(GetFsType(path)) { 1142 switch(GetFsType(path)) {
1143 case UNKNOWN: 1143 case UNKNOWN:
1144 case REGULAR: 1144 case REGULAR:
1145 fprintf(stderr, "Path '%s' is not a directory.\n", path); 1145 fprintf(stderr, "Path '%s' is not a directory.\n", path);
1146 free(path); 1146 free(path);
1147 continue; 1147 continue;
1148 break; 1148 break;
1149 case DIRECTORY: 1149 case DIRECTORY:
1150 break; 1150 break;
1151 } 1151 }
1152   1152  
1153 if(PROGRAM_VERBOSE) { 1153 if(PROGRAM_VERBOSE) {
1154 fprintf(stdout, "Will process path: '%s'\n", path); 1154 fprintf(stdout, "Will process path: '%s'\n", path);
1155 } 1155 }
1156   1156  
1157 // Add the path to the array of paths. 1157 // Add the path to the array of paths.
1158 if((paths[count] = malloc((strlen(path) + 1) * sizeof(*paths[count]))) == NULL) { 1158 if((paths[count] = malloc((strlen(path) + 1) * sizeof(*paths[count]))) == NULL) {
1159 fprintf(stderr, "Memory allocation failure."); 1159 fprintf(stderr, "Memory allocation failure.");
1160 return 1; 1160 return 20;
1161 } 1161 }
1162   1162  
1163 sprintf(paths[count], "%s", path); 1163 sprintf(paths[count], "%s", path);
1164 ++count; 1164 ++count;
1165   1165  
1166 free(path); 1166 free(path);
1167   1167  
1168 } 1168 }
1169   1169  
1170 if(count == 0) { 1170 if(count == 0) {
1171 fprintf(stderr, "No valid paths are available.\n"); 1171 fprintf(stderr, "No valid paths are available.\n");
1172 free(paths); 1172 free(paths);
1173 return 1; 1173 return 5;
1174 } 1174 }
1175   1175  
1176 if(PROGRAM_VERBOSE) { 1176 if(PROGRAM_VERBOSE) {
1177 fprintf(stdout, "Gathering to: '%s'\n", dbFile); 1177 fprintf(stdout, "Gathering to: '%s'\n", dbFile);
1178 } 1178 }
1179   1179  
1180 #if defined ___AmigaOS___ 1180 #if defined ___AmigaOS___
1181 locale = OpenLocale(NULL); 1181 locale = OpenLocale(NULL);
1182 #endif 1182 #endif
1183   1183  
1184 switch(operation) { 1184 switch(operation) {
1185 case CREATE: 1185 case CREATE:
1186 if(PROGRAM_VERBOSE) { 1186 if(PROGRAM_VERBOSE) {
1187 fprintf(stdout, "Removing '%s' and creating a new database.\n", dbFile); 1187 fprintf(stdout, "Removing '%s' and creating a new database.\n", dbFile);
1188 } 1188 }
1189 if(RemoveFile(dbFile) == FALSE) { 1189 RemoveFile(dbFile);
1190 fprintf(stderr, "File '%s' could not be removed.\n", dbFile); -  
1191 break; -  
1192 } -  
1193 case GATHER: 1190 case GATHER:
1194 if(PROGRAM_VERBOSE) { 1191 if(PROGRAM_VERBOSE) {
1195 fprintf(stdout, "Gathering files to database...\n"); 1192 fprintf(stdout, "Gathering files to database...\n");
1196 } 1193 }
1197 GatherDatabaseFiles(dbFile, paths, count); 1194 GatherDatabaseFiles(dbFile, paths, count);
1198 break; 1195 break;
1199 case REMOVE: 1196 case REMOVE:
1200 if(PROGRAM_VERBOSE) { 1197 if(PROGRAM_VERBOSE) {
1201 fprintf(stdout, "Removing files from database...\n"); 1198 fprintf(stdout, "Removing files from database...\n");
1202 } 1199 }
1203 RemoveDatabaseFiles(dbFile, paths, count); 1200 RemoveDatabaseFiles(dbFile, paths, count);
1204 break; 1201 break;
1205 default: 1202 default:
1206 fprintf(stderr, "Unknown operation.\n"); 1203 fprintf(stderr, "Unknown operation.\n");
-   1204 #if defined ___AmigaOS___
-   1205 CloseLocale(locale);
-   1206 #endif
-   1207  
-   1208 free(paths);
1207 break; 1209 return 5;
1208 } 1210 }
1209   1211  
1210 #if defined ___AmigaOS___ 1212 #if defined ___AmigaOS___
1211 CloseLocale(locale); 1213 CloseLocale(locale);
1212 #endif 1214 #endif
1213   1215  
1214 free(paths); 1216 free(paths);
1215   1217  
1216 return 0; 1218 return 0;
1217 } 1219 }
1218   1220