HuntnGather – Diff between revs 43 and 44

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