HuntnGather – Diff between revs 39 and 41

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 39 Rev 41
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.4"
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 LONG c; -  
554 #else 553 #else
555 FILE *fp, *tp; 554 FILE *fp, *tp;
556 char c; -  
557 #endif 555 #endif
558 int lines; 556 int lines;
559 int write; 557 int write;
560 int files; 558 int files;
-   559 dbLine *line = NULL;
561   560  
562 #if defined ___AsyncIO___ 561 #if defined ___AsyncIO___
563 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 562 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
564 #else 563 #else
565 if((fp = fopen(dbFile, "r")) == NULL) { 564 if((fp = fopen(dbFile, "r")) == NULL) {
566 #endif 565 #endif
567 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile); 566 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
568 return; 567 return;
569 } 568 }
570   569  
571 files = tmpNames->length; 570 files = tmpNames->length;
572 #if defined ___AsyncIO___ 571 #if defined ___AsyncIO___
573 if((tp = OpenAsync(tmpNames->array[--files], MODE_WRITE, ASYNC_BUF)) == NULL) { 572 if((tp = OpenAsync(tmpNames->array[--files], MODE_WRITE, ASYNC_BUF)) == NULL) {
574 #else 573 #else
575 if((tp = fopen(tmpNames->array[--files], "w")) == NULL) { 574 if((tp = fopen(tmpNames->array[--files], "w")) == NULL) {
576 #endif 575 #endif
577 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]);
578 #if defined ___AsyncIO___ 577 #if defined ___AsyncIO___
579 CloseAsync(fp); 578 CloseAsync(fp);
580 #else 579 #else
581 fclose(fp); 580 fclose(fp);
582 #endif 581 #endif
583 return; 582 return;
584 } 583 }
585   584  
586 if(PROGRAM_VERBOSE) { 585 if(PROGRAM_VERBOSE) {
587 fprintf(stdout, "Writing to temporary files...\r"); 586 fprintf(stdout, "Writing to temporary files...\r");
588 } 587 }
589   588  
590 write = 0; 589 write = 0;
591 lines = 0; 590 lines = 0;
592 #if defined ___AsyncIO___ -  
593 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) { -  
594 #else 591  
595 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) { 592 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) {
596 #endif -  
597 #if defined ___AmigaOS___ 593 #if defined ___AmigaOS___
598 // Check if CTRL+C was pressed and abort the program. 594 // Check if CTRL+C was pressed and abort the program.
599 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 595 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
-   596 free(line->string);
-   597 free(line);
-   598 line = NULL;
-   599  
600 PROGRAM_RUN = FALSE; 600 PROGRAM_RUN = FALSE;
601 continue; 601 continue;
602 } 602 }
603 #endif 603 #endif
604 switch(c) { -  
605 case '\n': -  
606 // Increment the total written lines. -  
607 ++write; -  
608   -  
609 if(PROGRAM_VERBOSE) { -  
610 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)write / total) * 100.0)); -  
611 } -  
612   -  
613 // Write the newline character back. 604  
-   605 #if defined ___AsyncIO___
614 #if defined ___AsyncIO___ 606 WriteAsync(tp, line->string, (LONG)line->length);
615 if(WriteCharAsync(tp, (UBYTE)c) != 1) { 607 WriteAsync(tp, "\n", 1);
616 #else 608 #else
617 if(fprintf(tp, "%c", c) != 1) { 609 fprintf(tp, "%s\n", line->string);
618 #endif -  
619 fprintf(stderr, "Unable to write to '%s'.\n", (char *)tmpNames->array[files]); -  
620 #if defined ___AsyncIO___ -  
621 CloseAsync(tp); -  
622 CloseAsync(fp); -  
623 #else -  
624 fclose(tp); -  
625 fclose(fp); -  
626 #endif -  
627 return; -  
628 } -  
629 // Switch to the next temporary file. -  
630 if(++lines >= tmpLines) { -  
631 // If there are no temporary files left then run till the end. -  
632 if(files - 1 < 0) { -  
633 break; -  
634 } -  
635   -  
636 // Close the previous temporary file and write to the next temporary file. 610 #endif
637 #if defined ___AsyncIO___ -  
638 CloseAsync(tp); 611  
639 if((tp = OpenAsync(tmpNames->array[--files], MODE_WRITE, ASYNC_BUF)) == NULL) { 612 ++write;
640 #else 613  
641 fclose(tp); 614 if(PROGRAM_VERBOSE) {
-   615 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)write / total) * 100.0));
642 if((tp = fopen(tmpNames->array[--files], "w")) == NULL) { 616 }
643 #endif 617  
-   618 // Switch to the next temporary file.
644 fprintf(stderr, "Could not open '%s' for writing.\n", (char *)tmpNames->array[files]); 619 if(++lines >= tmpLines) {
645 #if defined ___AsyncIO___ -  
646 CloseAsync(fp); 620 // If there are no temporary files left then run till the end.
647 #else -  
648 fclose(fp); 621 if(files - 1 < 0) {
649 #endif -  
650 return; 622 free(line->string);
651 } 623 free(line);
652 lines = 0; 624 line = NULL;
653 break; 625 continue;
654 } 626 }
655 break; 627  
-   628 // Close the previous temporary file and write to the next temporary file.
656 default: 629 #if defined ___AsyncIO___
657 #if defined ___AsyncIO___ 630 CloseAsync(tp);
-   631 if((tp = OpenAsync(tmpNames->array[--files], MODE_WRITE, ASYNC_BUF)) == NULL) {
658 if(WriteCharAsync(tp, (UBYTE)c) != 1) { 632 #else
659 #else 633 fclose(tp);
660 if(fprintf(tp, "%c", c) != 1) { 634 if((tp = fopen(tmpNames->array[--files], "w")) == NULL) {
661 #endif 635 #endif
662 fprintf(stderr, "Could not write to file '%s'.\n", (char *)tmpNames->array[files]); -  
663 #if defined ___AsyncIO___ 636 fprintf(stderr, "Could not open '%s' for writing.\n", (char *)tmpNames->array[files]);
664 CloseAsync(tp); 637 #if defined ___AsyncIO___
665 CloseAsync(fp); -  
666 #else 638 CloseAsync(fp);
667 fclose(tp); 639 #else
-   640 fclose(fp);
-   641 #endif
-   642 free(line->string);
668 fclose(fp); 643 free(line);
669 #endif 644 line = NULL;
670 return; 645 return;
671 } 646 }
-   647 lines = 0;
-   648 }
-   649  
-   650 free(line->string);
-   651 free(line);
-   652 line = NULL;
-   653 }
-   654  
-   655 if(line != NULL) {
-   656 free(line->string);
672 break; 657 free(line);
673 } 658 line = NULL;
674 } 659 }
675   660  
676 if(PROGRAM_VERBOSE) { 661 if(PROGRAM_VERBOSE) {
677 fprintf(stdout, "\n"); 662 fprintf(stdout, "\n");
678 } 663 }
679   664  
680 #if defined ___AsyncIO___ 665 #if defined ___AsyncIO___
681 CloseAsync(tp); 666 CloseAsync(tp);
682 CloseAsync(fp); 667 CloseAsync(fp);
683 #else 668 #else
684 fclose(tp); 669 fclose(tp);
685 fclose(fp); 670 fclose(fp);
686 #endif 671 #endif
687 } 672 }
688   673  
689 /* 674 /*
690 * 675 *
691 * Merges temporary files "tmpNames" into a database "dbFile". 676 * Merges temporary files "tmpNames" into a database "dbFile".
692 */ 677 */
693 void MergeTemporaryFiles(char *dbFile, VECTOR *tmpNames, int lines) { 678 void MergeTemporaryFiles(char *dbFile, VECTOR *tmpNames, int lines) {
694 #if defined ___AsyncIO___ 679 #if defined ___AsyncIO___
695 struct AsyncFile *fp; 680 struct AsyncFile *fp;
696 struct AsyncFile **tp; 681 struct AsyncFile **tp;
697 #else 682 #else
698 FILE *fp; 683 FILE *fp;
699 FILE **tp; 684 FILE **tp;
700 #endif 685 #endif
701 int i; 686 int i;
702 int j; 687 int j;
703 dbLine *tmp; 688 dbLine *tmp;
704 char *rem; 689 char *rem;
705 char *min; 690 char *min;
706 int count; 691 int count;
707   692  
708 #if defined ___AsyncIO___ 693 #if defined ___AsyncIO___
709 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { 694 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) {
710 #else 695 #else
711 if((fp = fopen(dbFile, "w")) == NULL) { 696 if((fp = fopen(dbFile, "w")) == NULL) {
712 #endif 697 #endif
713 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile); 698 fprintf(stderr, "Could not open file '%s' for writing.\n", dbFile);
714 return; 699 return;
715 } 700 }
716   701  
717 // Allocate as many file pointers as temporary files. 702 // Allocate as many file pointers as temporary files.
718 if((tp = malloc(tmpNames->length * sizeof(*tp))) == NULL) { 703 if((tp = malloc(tmpNames->length * sizeof(*tp))) == NULL) {
719 fprintf(stderr, "Memory allocation failure.\n"); 704 fprintf(stderr, "Memory allocation failure.\n");
720 #if defined ___AsyncIO___ 705 #if defined ___AsyncIO___
721 CloseAsync(fp); 706 CloseAsync(fp);
722 #else 707 #else
723 fclose(fp); 708 fclose(fp);
724 #endif 709 #endif
725 return; 710 return;
726 } 711 }
727   712  
728 // Open all temporary files for reading. 713 // Open all temporary files for reading.
729 for(i = 0; i < tmpNames->length; ++i) { 714 for(i = 0; i < tmpNames->length; ++i) {
730 #if defined ___AsyncIO___ 715 #if defined ___AsyncIO___
731 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) {
732 #else 717 #else
733 if((tp[i] = fopen(tmpNames->array[i], "r")) == NULL) { 718 if((tp[i] = fopen(tmpNames->array[i], "r")) == NULL) {
734 #endif 719 #endif
735 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]);
736 // Close all temporary files. 721 // Close all temporary files.
737 while(--i > -1) { 722 while(--i > -1) {
738 #if defined ___AsyncIO___ 723 #if defined ___AsyncIO___
739 CloseAsync(tp[i]); 724 CloseAsync(tp[i]);
740 #else 725 #else
741 fclose(tp[i]); 726 fclose(tp[i]);
742 #endif 727 #endif
743 } 728 }
744 #if defined ___AsyncIO___ 729 #if defined ___AsyncIO___
745 CloseAsync(fp); 730 CloseAsync(fp);
746 #else 731 #else
747 fclose(fp); 732 fclose(fp);
748 #endif 733 #endif
749 return; 734 return;
750 } 735 }
751 } 736 }
752   737  
753 if(PROGRAM_VERBOSE) { 738 if(PROGRAM_VERBOSE) {
754 fprintf(stdout, "Merging all files...\r"); 739 fprintf(stdout, "Merging all files...\r");
755 } 740 }
756   741  
757 rem = NULL; 742 rem = NULL;
758 count = lines; 743 count = lines;
759 j = 0; 744 j = 0;
760 while(PROGRAM_RUN && --count > -1) { 745 while(PROGRAM_RUN && --count > -1) {
761 #if defined ___AmigaOS___ 746 #if defined ___AmigaOS___
762 // Check if CTRL+C was pressed and abort the program. 747 // Check if CTRL+C was pressed and abort the program.
763 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 748 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
764 PROGRAM_RUN = FALSE; 749 PROGRAM_RUN = FALSE;
765 continue; 750 continue;
766 } 751 }
767 #endif 752 #endif
768 // Find the smallest line in all temporary files. 753 // Find the smallest line in all temporary files.
769 if(PROGRAM_VERBOSE) { 754 if(PROGRAM_VERBOSE) {
770 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));
771 } 756 }
772   757  
773 min = NULL; 758 min = NULL;
774 for(i = 0; i < tmpNames->length; ++i) { 759 for(i = 0; i < tmpNames->length; ++i) {
775 tmp = PeekLine(tp[i]); 760 tmp = PeekLine(tp[i]);
776 if(tmp == NULL) { 761 if(tmp == NULL) {
777 continue; 762 continue;
778 } 763 }
779 #if defined ___AmigaOS___ 764 #if defined ___AmigaOS___
780 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) {
781 #else 766 #else
782 if(min == NULL || strcmp(tmp->string, min) < 0) { 767 if(min == NULL || strcmp(tmp->string, min) < 0) {
783 #endif 768 #endif
784 if(min != NULL) { 769 if(min != NULL) {
785 // Free previous instance. 770 // Free previous instance.
786 free(min); 771 free(min);
787 min = NULL; 772 min = NULL;
788 } 773 }
789 if((min = malloc((strlen(tmp->string) + 1) * sizeof(*min))) == NULL) { 774 if((min = malloc((strlen(tmp->string) + 1) * sizeof(*min))) == NULL) {
790 fprintf(stderr, "Memory allocation failure.\n"); 775 fprintf(stderr, "Memory allocation failure.\n");
791   776  
792 free(tmp->string); 777 free(tmp->string);
793 free(tmp); 778 free(tmp);
794 tmp = NULL; 779 tmp = NULL;
795   780  
796 if(min != NULL) { 781 if(min != NULL) {
797 free(min); 782 free(min);
798 min = NULL; 783 min = NULL;
799 } 784 }
800 if(rem != NULL) { 785 if(rem != NULL) {
801 free(rem); 786 free(rem);
802 rem = NULL; 787 rem = NULL;
803 } 788 }
804 #if defined ___AsyncIO___ 789 #if defined ___AsyncIO___
805 CloseAsync(fp); 790 CloseAsync(fp);
806 #else 791 #else
807 fclose(fp); 792 fclose(fp);
808 #endif 793 #endif
809 return; 794 return;
810 } 795 }
811 sprintf(min, "%s", tmp->string); 796 sprintf(min, "%s", tmp->string);
812 // 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.
813 j = i; 798 j = i;
814 } 799 }
815 free(tmp->string); 800 free(tmp->string);
816 free(tmp); 801 free(tmp);
817 tmp = NULL; 802 tmp = NULL;
818 } 803 }
819   804  
820 // Forward the file where the smallest line was found. 805 // Forward the file where the smallest line was found.
821 SkipLine(tp[j]); 806 SkipLine(tp[j]);
822   807  
823 // Write the smallest line. 808 // Write the smallest line.
824 if(min != NULL) { 809 if(min != NULL) {
825 // 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.
826 if(rem != NULL) { 811 if(rem != NULL) {
827 #if defined ___AmigaOS___ 812 #if defined ___AmigaOS___
828 if(StrnCmp(locale, min, rem, -1, SC_ASCII) == 0) { 813 if(StrnCmp(locale, min, rem, -1, SC_ASCII) == 0) {
829 #else 814 #else
830 if(strcmp(min, rem) == 0) { 815 if(strcmp(min, rem) == 0) {
831 #endif 816 #endif
832 free(min); 817 free(min);
833 min = NULL; 818 min = NULL;
834 continue; 819 continue;
835 } 820 }
836 } 821 }
837   822  
838 #if defined ___AsyncIO___ 823 #if defined ___AsyncIO___
839 WriteAsync(fp, min, (LONG)strlen(min)); 824 WriteAsync(fp, min, (LONG)strlen(min));
840 WriteAsync(fp, "\n", 1); 825 WriteAsync(fp, "\n", 1);
841 #else 826 #else
842 fprintf(fp, "%s\n", min); 827 fprintf(fp, "%s\n", min);
843 #endif 828 #endif
844   829  
845 if(rem != NULL) { 830 if(rem != NULL) {
846 free(rem); 831 free(rem);
847 rem = NULL; 832 rem = NULL;
848 } 833 }
849   834  
850 if((rem = malloc((strlen(min) + 1) * sizeof(*rem))) == NULL) { 835 if((rem = malloc((strlen(min) + 1) * sizeof(*rem))) == NULL) {
851 fprintf(stderr, "Memory allocation failure.\n"); 836 fprintf(stderr, "Memory allocation failure.\n");
852   837  
853 free(min); 838 free(min);
854 min = NULL; 839 min = NULL;
855   840  
856 #if defined ___AsyncIO___ 841 #if defined ___AsyncIO___
857 CloseAsync(fp); 842 CloseAsync(fp);
858 #else 843 #else
859 fclose(fp); 844 fclose(fp);
860 #endif 845 #endif
861 return; 846 return;
862 } 847 }
863   848  
864 // Remember the last minimal line. 849 // Remember the last minimal line.
865 sprintf(rem, "%s", min); 850 sprintf(rem, "%s", min);
866   851  
867 free(min); 852 free(min);
868 min = NULL; 853 min = NULL;
869 } 854 }
870 } 855 }
871   856  
872 if(rem != NULL) { 857 if(rem != NULL) {
873 free(rem); 858 free(rem);
874 rem = NULL; 859 rem = NULL;
875 } 860 }
876   861  
877 // Write out any remaining contents from the temporary files. 862 // Write out any remaining contents from the temporary files.
878 for(i = 0; PROGRAM_RUN && i < tmpNames->length; ++i) { 863 for(i = 0; PROGRAM_RUN && i < tmpNames->length; ++i) {
879 #if defined ___AmigaOS___ 864 #if defined ___AmigaOS___
880 // Check if CTRL+C was pressed and abort the program. 865 // Check if CTRL+C was pressed and abort the program.
881 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 866 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
882 PROGRAM_RUN = FALSE; 867 PROGRAM_RUN = FALSE;
883 continue; 868 continue;
884 } 869 }
885 #endif 870 #endif
886 tmp = ReadLine(tp[i]); 871 tmp = ReadLine(tp[i]);
887 if(tmp == NULL) { 872 if(tmp == NULL) {
888 continue; 873 continue;
889 } 874 }
890 #if defined ___AsyncIO___ 875 #if defined ___AsyncIO___
891 WriteAsync(fp, tmp->string, (LONG)strlen(tmp->string)); 876 WriteAsync(fp, tmp->string, (LONG)strlen(tmp->string));
892 WriteAsync(fp, "\n", 1); 877 WriteAsync(fp, "\n", 1);
893 #else 878 #else
894 fprintf(fp, "%s\n", tmp->string); 879 fprintf(fp, "%s\n", tmp->string);
895 #endif 880 #endif
896 free(tmp->string); 881 free(tmp->string);
897 free(tmp); 882 free(tmp);
898 tmp = NULL; 883 tmp = NULL;
899 } 884 }
900   885  
901 // Close all temporary files. 886 // Close all temporary files.
902 for(i = 0; i < tmpNames->length; ++i) { 887 for(i = 0; i < tmpNames->length; ++i) {
903 #if defined ___AsyncIO___ 888 #if defined ___AsyncIO___
904 CloseAsync(tp[i]); 889 CloseAsync(tp[i]);
905 #else 890 #else
906 fclose(tp[i]); 891 fclose(tp[i]);
907 #endif 892 #endif
908 } 893 }
909   894  
910 #if defined ___AsyncIO___ 895 #if defined ___AsyncIO___
911 CloseAsync(fp); 896 CloseAsync(fp);
912 #else 897 #else
913 fclose(fp); 898 fclose(fp);
914 #endif 899 #endif
915   900  
916 if(PROGRAM_VERBOSE) { 901 if(PROGRAM_VERBOSE) {
917 fprintf(stdout, "\n"); 902 fprintf(stdout, "\n");
918 } 903 }
919 } 904 }
920   905  
921 /* 906 /*
922 * 907 *
923 * Filter the paths inside the database with provided paths. 908 * Filter the paths inside the database with provided paths.
924 */ 909 */
925 void FilterDatabasePaths(char *dbFile, char *tmpName, VECTOR *paths) { 910 void FilterDatabasePaths(char *dbFile, char *tmpName, VECTOR *paths) {
926 #if defined ___AsyncIO___ 911 #if defined ___AsyncIO___
927 struct AsyncFile *fp; 912 struct AsyncFile *fp;
928 struct AsyncFile *tp; 913 struct AsyncFile *tp;
929 #else 914 #else
930 FILE *fp; 915 FILE *fp;
931 FILE *tp; 916 FILE *tp;
932 #endif 917 #endif
933 dbLine *line; 918 dbLine *line;
934 dbEntry *entry; 919 dbEntry *entry;
935 int lines; 920 int lines;
936 int i; 921 int i;
937   922  
938 // Open database file for reading. 923 // Open database file for reading.
939 #if defined ___AsyncIO___ 924 #if defined ___AsyncIO___
940 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 925 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
941 #else 926 #else
942 if((fp = fopen(dbFile, "r")) == NULL) { 927 if((fp = fopen(dbFile, "r")) == NULL) {
943 #endif 928 #endif
944 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile); 929 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
945 return; 930 return;
946 } 931 }
947   932  
948 // Open temporary file for writing. 933 // Open temporary file for writing.
949 #if defined ___AsyncIO___ 934 #if defined ___AsyncIO___
950 if((tp = OpenAsync(tmpName, MODE_WRITE, ASYNC_BUF)) == NULL) { 935 if((tp = OpenAsync(tmpName, MODE_WRITE, ASYNC_BUF)) == NULL) {
951 #else 936 #else
952 if((tp = fopen(tmpName, "w")) == NULL) { 937 if((tp = fopen(tmpName, "w")) == NULL) {
953 #endif 938 #endif
954 fprintf(stderr, "Copuld not open file '%s' for writing.\n", tmpName); 939 fprintf(stderr, "Copuld not open file '%s' for writing.\n", tmpName);
955   940  
956 // Close database file. 941 // Close database file.
957 #if defined ___AsyncIO___ 942 #if defined ___AsyncIO___
958 CloseAsync(fp); 943 CloseAsync(fp);
959 #else 944 #else
960 fclose(fp); 945 fclose(fp);
961 #endif 946 #endif
962   947  
963 return; 948 return;
964 } 949 }
965   950  
966 if(PROGRAM_VERBOSE) { 951 if(PROGRAM_VERBOSE) {
967 fprintf(stdout, "Removing lines...\r"); 952 fprintf(stdout, "Removing lines...\r");
968 } 953 }
969   954  
970 lines = 0; 955 lines = 0;
971 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) { 956 while(PROGRAM_RUN && (line = ReadLine(fp)) != NULL) {
972 #if defined ___AmigaOS___ 957 #if defined ___AmigaOS___
973 // Check if CTRL+C was pressed and abort the program. 958 // Check if CTRL+C was pressed and abort the program.
974 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 959 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
975 PROGRAM_RUN = FALSE; 960 PROGRAM_RUN = FALSE;
976 continue; 961 continue;
977 } 962 }
978 #endif 963 #endif
979   964  
980 if((entry = CreateDatabaseEntry(line)) == NULL) { 965 if((entry = CreateDatabaseEntry(line)) == NULL) {
981 fprintf(stderr, "Unable to create database entry.\n"); 966 fprintf(stderr, "Unable to create database entry.\n");
982 free(line->string); 967 free(line->string);
983 free(line); 968 free(line);
984 line = NULL; 969 line = NULL;
985 continue; 970 continue;
986 } 971 }
987   972  
988 for(i = 0; i < paths->length; ++i) { 973 for(i = 0; i < paths->length; ++i) {
989 if(PathCompare(entry->path, paths->array[i]) == TRUE) { 974 if(PathCompare(entry->path, paths->array[i]) == TRUE) {
990 ++lines; 975 ++lines;
991 if(PROGRAM_VERBOSE) { 976 if(PROGRAM_VERBOSE) {
992 fprintf(stdout, "Removing lines: %d.\r", lines); 977 fprintf(stdout, "Removing lines: %d.\r", lines);
993 } 978 }
994 continue; 979 continue;
995 } 980 }
996 #if defined ___AsyncIO___ 981 #if defined ___AsyncIO___
997 WriteAsync(tp, line->string, (LONG)strlen(line->string)); 982 WriteAsync(tp, line->string, (LONG)strlen(line->string));
998 WriteAsync(tp, "\n", 1); 983 WriteAsync(tp, "\n", 1);
999 #else 984 #else
1000 fprintf(tp, "%s\n", line->string); 985 fprintf(tp, "%s\n", line->string);
1001 #endif 986 #endif
1002 break; 987 break;
1003 } 988 }
1004   989  
1005 // Free up database entry. 990 // Free up database entry.
1006 free(entry->name); 991 free(entry->name);
1007 free(entry->path); 992 free(entry->path);
1008 free(entry); 993 free(entry);
1009 entry = NULL; 994 entry = NULL;
1010   995  
1011 // Free up line. 996 // Free up line.
1012 free(line->string); 997 free(line->string);
1013 free(line); 998 free(line);
1014 line = NULL; 999 line = NULL;
1015 } 1000 }
1016   1001  
1017 #if defined ___AsyncIO___ 1002 #if defined ___AsyncIO___
1018 CloseAsync(fp); 1003 CloseAsync(fp);
1019 CloseAsync(tp); 1004 CloseAsync(tp);
1020 #else 1005 #else
1021 fclose(fp); 1006 fclose(fp);
1022 fclose(tp); 1007 fclose(tp);
1023 #endif 1008 #endif
1024   1009  
1025 if(PROGRAM_VERBOSE) { 1010 if(PROGRAM_VERBOSE) {
1026 fprintf(stdout, "\n"); 1011 fprintf(stdout, "\n");
1027 } 1012 }
1028 } 1013 }
1029   1014  
1030 /* 1015 /*
1031 * 1016 *
1032 * Indexes a "path" by creating a database "dbFile". 1017 * Indexes paths and adds to a database file.
1033 */ 1018 */
1034 void GatherDatabaseFiles(char *dbFile, VECTOR *paths) { 1019 void GatherDatabaseFiles(char *dbFile, VECTOR *paths) {
1035 dbStats *stats; 1020 dbStats *stats;
1036 VECTOR *tmpNames; 1021 VECTOR *tmpNames;
1037 int tmpFiles; 1022 int tmpFiles;
1038 int tmpLines; 1023 int tmpLines;
1039 int i; 1024 int i;
-   1025 int line;
-   1026 int size;
-   1027  
-   1028 // Generate the database file from the supplied paths.
-   1029 if((stats = CollectFiles(dbFile, paths)) == NULL) {
-   1030 fprintf(stderr, "Collecting files failed.\n");
-   1031 return;
-   1032 }
-   1033  
-   1034 size = GetFileSize(dbFile);
-   1035 line = CountFileLines(dbFile);
-   1036  
-   1037 // Calculate the total number of temporary files required.
-   1038 tmpFiles = size / maxmem;
-   1039  
-   1040 /* In case no temporary files are required,
-   1041 * just sort the database and terminate.
-   1042 */
-   1043 if(tmpFiles < 2) {
-   1044 SortDatabase(dbFile, line);
-   1045 return;
-   1046 }
-   1047  
-   1048 // Calculate the number of lines per temporary file.
-   1049 tmpLines = ceil(((double)line) / ((double)tmpFiles));
-   1050  
-   1051 // Create temporary files.
-   1052 if((tmpNames = CreateTemporaryFiles(tmpFiles)) == NULL) {
-   1053 fprintf(stderr, "Unable to create temporary files.\n");
-   1054 return;
-   1055 }
-   1056  
-   1057 // Write "tmpLines" to temporary files in "tmpNames" from "dbFile".
-   1058 WriteTemporaryFiles(dbFile, tmpNames, tmpLines, line);
-   1059  
-   1060 // Sort the temporary files.
-   1061 for(i = 0; i < tmpNames->length; ++i) {
-   1062 SortDatabase(tmpNames->array[i], tmpLines);
-   1063 }
-   1064  
-   1065 // Merge all the temporary files to the database file.
-   1066 MergeTemporaryFiles(dbFile, tmpNames, line);
-   1067  
-   1068 // Remove all temporary files.
-   1069 RemoveFiles(tmpNames);
-   1070  
-   1071 // Free temporary file names.
-   1072 free(tmpNames);
-   1073 tmpNames = NULL;
-   1074  
-   1075 // Free statistics.
-   1076 free(stats);
-   1077 stats = NULL;
-   1078 }
-   1079  
-   1080 /*
-   1081 *
-   1082 * Indexes paths and creates a daabase file.
-   1083 */
-   1084 void CreateDatabaseFiles(char *dbFile, VECTOR *paths) {
-   1085 dbStats *stats;
-   1086 VECTOR *tmpNames;
-   1087 int tmpFiles;
-   1088 int tmpLines;
-   1089 int i;
1040   1090  
1041 // Generate the database file from the supplied paths. 1091 // Generate the database file from the supplied paths.
1042 if((stats = CollectFiles(dbFile, paths)) == NULL) { 1092 if((stats = CollectFiles(dbFile, paths)) == NULL) {
1043 fprintf(stderr, "Collecting files failed.\n"); 1093 fprintf(stderr, "Collecting files failed.\n");
1044 return; 1094 return;
1045 } 1095 }
1046   1096  
1047 // Calculate the total number of temporary files required. 1097 // Calculate the total number of temporary files required.
1048 tmpFiles = stats->size / maxmem; 1098 tmpFiles = stats->size / maxmem;
1049   1099  
1050 /* In case no temporary files are required, 1100 /* In case no temporary files are required,
1051 * just sort the database and terminate. 1101 * just sort the database and terminate.
1052 */ 1102 */
1053 if(tmpFiles < 2) { 1103 if(tmpFiles < 2) {
1054 SortDatabase(dbFile, stats->lines); 1104 SortDatabase(dbFile, stats->lines);
1055 return; 1105 return;
1056 } 1106 }
1057   1107  
1058 // Calculate the number of lines per temporary file. 1108 // Calculate the number of lines per temporary file.
1059 tmpLines = ceil(((double)stats->lines) / ((double)tmpFiles)); 1109 tmpLines = ceil(((double)stats->lines) / ((double)tmpFiles));
1060   1110  
1061 // Create temporary files. 1111 // Create temporary files.
1062 if((tmpNames = CreateTemporaryFiles(tmpFiles)) == NULL) { 1112 if((tmpNames = CreateTemporaryFiles(tmpFiles)) == NULL) {
1063 fprintf(stderr, "Unable to create temporary files.\n"); 1113 fprintf(stderr, "Unable to create temporary files.\n");
1064 return; 1114 return;
1065 } 1115 }
1066   1116  
1067 // Write "tmpLines" to temporary files in "tmpNames" from "dbFile". 1117 // Write "tmpLines" to temporary files in "tmpNames" from "dbFile".
1068 WriteTemporaryFiles(dbFile, tmpNames, tmpLines, stats->lines); 1118 WriteTemporaryFiles(dbFile, tmpNames, tmpLines, stats->lines);
1069   1119  
1070 // Sort the temporary files. 1120 // Sort the temporary files.
1071 for(i = 0; i < tmpNames->length; ++i) { 1121 for(i = 0; i < tmpNames->length; ++i) {
1072 SortDatabase(tmpNames->array[i], tmpLines); 1122 SortDatabase(tmpNames->array[i], tmpLines);
1073 } 1123 }
1074   1124  
1075 // Merge all the temporary files to the database file. 1125 // Merge all the temporary files to the database file.
1076 MergeTemporaryFiles(dbFile, tmpNames, stats->lines); 1126 MergeTemporaryFiles(dbFile, tmpNames, stats->lines);
1077   1127  
1078 // Remove all temporary files. 1128 // Remove all temporary files.
1079 RemoveFiles(tmpNames); 1129 RemoveFiles(tmpNames);
1080   1130  
1081 // Free temporary file names. 1131 // Free temporary file names.
1082 free(tmpNames); 1132 free(tmpNames);
1083 tmpNames = NULL; 1133 tmpNames = NULL;
1084   1134  
1085 // Free statistics. 1135 // Free statistics.
1086 free(stats); 1136 free(stats);
1087 stats = NULL; 1137 stats = NULL;
1088 } 1138 }
1089   1139  
1090 void RemoveDatabaseFiles(char *dbFile, VECTOR *paths) { 1140 void RemoveDatabaseFiles(char *dbFile, VECTOR *paths) {
1091 char *tmpName; 1141 char *tmpName;
1092   1142  
1093 // Create a temporary file to hold the changes. 1143 // Create a temporary file to hold the changes.
1094 if((tmpName = CreateTemporaryFile()) == NULL) { 1144 if((tmpName = CreateTemporaryFile()) == NULL) {
1095 fprintf(stderr, "Unable to create temporary file.\n"); 1145 fprintf(stderr, "Unable to create temporary file.\n");
1096 return; 1146 return;
1097 } 1147 }
1098   1148  
1099 // Filter the database of the provided paths. 1149 // Filter the database of the provided paths.
1100 FilterDatabasePaths(dbFile, tmpName, paths); 1150 FilterDatabasePaths(dbFile, tmpName, paths);
1101   1151  
1102 // Overwrite the database file with the filtered paths. 1152 // Overwrite the database file with the filtered paths.
1103 CopyFile(tmpName, dbFile); 1153 CopyFile(tmpName, dbFile);
1104   1154  
1105 // Remove temporary file. 1155 // Remove temporary file.
1106 if(RemoveFile(tmpName) == FALSE) { 1156 if(RemoveFile(tmpName) == FALSE) {
1107 fprintf(stderr, "Temporary file could not be removed.\n"); 1157 fprintf(stderr, "Temporary file could not be removed.\n");
1108 return; 1158 return;
1109 } 1159 }
1110 } 1160 }
1111   1161  
1112 void usage(char *name) { 1162 void usage(char *name) {
1113 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name); 1163 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name);
1114 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION); 1164 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION);
1115 fprintf(stdout, " \n"); 1165 fprintf(stdout, " \n");
1116 fprintf(stdout, "SYNTAX: %s [-q] <-a|-r|-c> <PATH PATH PATH...> \n", name); 1166 fprintf(stdout, "SYNTAX: %s [-q] <-a|-r|-c> <PATH PATH PATH...> \n", name);
1117 fprintf(stdout, " \n"); 1167 fprintf(stdout, " \n");
1118 fprintf(stdout, "Required: \n"); 1168 fprintf(stdout, "Required: \n");
1119 fprintf(stdout, " -a [PATH...] Add files. \n"); 1169 fprintf(stdout, " -a [PATH...] Add files. \n");
1120 fprintf(stdout, " -c [PATH...] Create from scratch. \n"); 1170 fprintf(stdout, " -c [PATH...] Create from scratch. \n");
1121 fprintf(stdout, " -r [PATH...] Remove files. \n"); 1171 fprintf(stdout, " -r [PATH...] Remove files. \n");
1122 fprintf(stdout, " \n"); 1172 fprintf(stdout, " \n");
1123 fprintf(stdout, "Optional: \n"); 1173 fprintf(stdout, "Optional: \n");
1124 fprintf(stdout, " -d [FIILE] Where to store the database. \n"); 1174 fprintf(stdout, " -d [FIILE] Where to store the database. \n");
1125 fprintf(stdout, " -m BYTES Memory to use (default: %d). \n", maxmem); 1175 fprintf(stdout, " -m BYTES Memory to use (default: %d). \n", maxmem);
1126 fprintf(stdout, " -q Do not print out any messages. \n"); 1176 fprintf(stdout, " -q Do not print out any messages. \n");
1127 fprintf(stdout, " \n"); 1177 fprintf(stdout, " \n");
1128 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n"); 1178 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n");
1129 fprintf(stdout, "stored for searching with the Hunt tool. \n"); 1179 fprintf(stdout, "stored for searching with the Hunt tool. \n");
1130 fprintf(stdout, " \n"); 1180 fprintf(stdout, " \n");
1131 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n"); 1181 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n");
1132 } 1182 }
1133   1183  
1134 /* 1184 /*
1135 * 1185 *
1136 * Main entry point. 1186 * Main entry point.
1137 */ 1187 */
1138 int main(int argc, char **argv) { 1188 int main(int argc, char **argv) {
1139 int option; 1189 int option;
1140 int i; 1190 int i;
1141 char *dbFile; 1191 char *dbFile;
1142 char *path; 1192 char *path;
1143 VECTOR *paths; 1193 VECTOR *paths;
1144 OPERATION operation = NONE; 1194 OPERATION operation = NONE;
1145   1195  
1146 // Bind handler to SIGINT. 1196 // Bind handler to SIGINT.
1147 #if !defined ___AmigaOS___ 1197 #if !defined ___AmigaOS___
1148 signal(SIGINT, SignalHandler); 1198 signal(SIGINT, SignalHandler);
1149 #endif 1199 #endif
1150   1200  
1151 dbFile = DEFAULT_DATABASE_FILE; 1201 dbFile = DEFAULT_DATABASE_FILE;
1152 while((option = getopt(argc, argv, "hqdm:arc")) != -1) { 1202 while((option = getopt(argc, argv, "hqdm:arc")) != -1) {
1153 switch(option) { 1203 switch(option) {
1154 case 'a': 1204 case 'a':
1155 operation = GATHER; 1205 operation = GATHER;
1156 break; 1206 break;
1157 case 'r': 1207 case 'r':
1158 operation = REMOVE; 1208 operation = REMOVE;
1159 break; 1209 break;
1160 case 'c': 1210 case 'c':
1161 operation = CREATE; 1211 operation = CREATE;
1162 break; 1212 break;
1163 case 'm': 1213 case 'm':
1164 maxmem = strtoul(optarg, NULL, 10); 1214 maxmem = strtoul(optarg, NULL, 10);
1165 break; 1215 break;
1166 case 'd': 1216 case 'd':
1167 dbFile = optarg; 1217 dbFile = optarg;
1168 break; 1218 break;
1169 case 'q': 1219 case 'q':
1170 PROGRAM_VERBOSE = FALSE; 1220 PROGRAM_VERBOSE = FALSE;
1171 break; 1221 break;
1172 case 'h': 1222 case 'h':
1173 usage(argv[0]); 1223 usage(argv[0]);
1174 return 0; 1224 return 0;
1175 case '?': 1225 case '?':
1176 fprintf(stderr, "Invalid option %ct.\n", optopt); 1226 fprintf(stderr, "Invalid option %ct.\n", optopt);
1177 return 5; 1227 return 5;
1178 } 1228 }
1179 } 1229 }
1180   1230  
1181 if(operation == NONE) { 1231 if(operation == NONE) {
1182 usage(argv[0]); 1232 usage(argv[0]);
1183 return 5; 1233 return 5;
1184 } 1234 }
1185   1235  
1186 if(optind >= argc) { 1236 if(optind >= argc) {
1187 usage(argv[0]); 1237 usage(argv[0]);
1188 return 5; 1238 return 5;
1189 } 1239 }
1190   1240  
1191 // Build the path vector. 1241 // Build the path vector.
1192 if((paths = malloc(1 * sizeof(*paths))) == NULL) { 1242 if((paths = malloc(1 * sizeof(*paths))) == NULL) {
1193 fprintf(stderr, "Memory allocation failure.\n"); 1243 fprintf(stderr, "Memory allocation failure.\n");
1194 return 20; 1244 return 20;
1195 } 1245 }
1196   1246  
1197 // Go through all supplied arguments and add paths to search. 1247 // Go through all supplied arguments and add paths to search.
1198 if((paths->array = malloc((argc - optind) * sizeof(*paths))) == NULL) { 1248 if((paths->array = malloc((argc - optind) * sizeof(*paths))) == NULL) {
1199 fprintf(stderr, "Memory allocation failure.\n"); 1249 fprintf(stderr, "Memory allocation failure.\n");
1200 return 20; 1250 return 20;
1201 } 1251 }
1202   1252  
1203 for(i = optind, paths->length = 0; i < argc; ++i) { 1253 for(i = optind, paths->length = 0; i < argc; ++i) {
1204 if((path = PathToAbsolute(argv[i])) == NULL) { 1254 if((path = PathToAbsolute(argv[i])) == NULL) {
1205 fprintf(stderr, "Absolute path for '%s' failed to resolve.\n", argv[optind]); 1255 fprintf(stderr, "Absolute path for '%s' failed to resolve.\n", argv[optind]);
1206 continue; 1256 continue;
1207 } 1257 }
1208   1258  
1209 switch(GetFsType(path)) { 1259 switch(GetFsType(path)) {
1210 case UNKNOWN: 1260 case UNKNOWN:
1211 case REGULAR: 1261 case REGULAR:
1212 fprintf(stderr, "Path '%s' is not a directory.\n", path); 1262 fprintf(stderr, "Path '%s' is not a directory.\n", path);
1213 free(path); 1263 free(path);
1214 path = NULL; 1264 path = NULL;
1215 continue; 1265 continue;
1216 case DIRECTORY: 1266 case DIRECTORY:
1217 break; 1267 break;
1218 } 1268 }
1219   1269  
1220 if(PROGRAM_VERBOSE) { 1270 if(PROGRAM_VERBOSE) {
1221 fprintf(stdout, "Will process path: '%s'\n", path); 1271 fprintf(stdout, "Will process path: '%s'\n", path);
1222 } 1272 }
1223   1273  
1224 // Add the path to the array of paths. 1274 // Add the path to the array of paths.
1225 if((paths->array[paths->length] = malloc((strlen(path) + 1) * sizeof(*paths->array[paths->length]))) == NULL) { 1275 if((paths->array[paths->length] = malloc((strlen(path) + 1) * sizeof(*paths->array[paths->length]))) == NULL) {
1226 fprintf(stderr, "Memory allocation failure."); 1276 fprintf(stderr, "Memory allocation failure.");
1227 return 20; 1277 return 20;
1228 } 1278 }
1229   1279  
1230 sprintf(paths->array[paths->length], "%s", path); 1280 sprintf(paths->array[paths->length], "%s", path);
1231 ++paths->length; 1281 ++paths->length;
1232   1282  
1233 free(path); 1283 free(path);
1234 path = NULL; 1284 path = NULL;
1235   1285  
1236 } 1286 }
1237   1287  
1238 if(paths->length == 0) { 1288 if(paths->length == 0) {
1239 fprintf(stderr, "No valid paths are available.\n"); 1289 fprintf(stderr, "No valid paths are available.\n");
1240 free(paths->array); 1290 free(paths->array);
1241 free(paths); 1291 free(paths);
1242 paths = NULL; 1292 paths = NULL;
1243 return 5; 1293 return 5;
1244 } 1294 }
1245   1295  
1246 if(PROGRAM_VERBOSE) { 1296 if(PROGRAM_VERBOSE) {
1247 fprintf(stdout, "Gathering to: '%s'\n", dbFile); 1297 fprintf(stdout, "Gathering to: '%s'\n", dbFile);
1248 } 1298 }
1249   1299  
1250 #if defined ___AmigaOS___ 1300 #if defined ___AmigaOS___
1251 locale = OpenLocale(NULL); 1301 locale = OpenLocale(NULL);
1252 #endif 1302 #endif
1253   1303  
1254 switch(operation) { 1304 switch(operation) {
1255 case CREATE: 1305 case CREATE:
1256 if(PROGRAM_VERBOSE) { 1306 if(PROGRAM_VERBOSE) {
1257 fprintf(stdout, "Removing '%s' and creating a new database.\n", dbFile); 1307 fprintf(stdout, "Removing '%s' and creating a new database.\n", dbFile);
1258 } 1308 }
1259 RemoveFile(dbFile); 1309 RemoveFile(dbFile);
-   1310 if(PROGRAM_VERBOSE) {
-   1311 fprintf(stdout, "Gathering files to database...\n");
-   1312 }
-   1313 CreateDatabaseFiles(dbFile, paths);
-   1314 break;
1260 case GATHER: 1315 case GATHER:
1261 if(PROGRAM_VERBOSE) { 1316 if(PROGRAM_VERBOSE) {
1262 fprintf(stdout, "Gathering files to database...\n"); 1317 fprintf(stdout, "Gathering files to database...\n");
1263 } 1318 }
1264 GatherDatabaseFiles(dbFile, paths); 1319 GatherDatabaseFiles(dbFile, paths);
1265 break; 1320 break;
1266 case REMOVE: 1321 case REMOVE:
1267 if(PROGRAM_VERBOSE) { 1322 if(PROGRAM_VERBOSE) {
1268 fprintf(stdout, "Removing files from database...\n"); 1323 fprintf(stdout, "Removing files from database...\n");
1269 } 1324 }
1270 RemoveDatabaseFiles(dbFile, paths); 1325 RemoveDatabaseFiles(dbFile, paths);
1271 break; 1326 break;
1272 default: 1327 default:
1273 fprintf(stderr, "Unknown operation.\n"); 1328 fprintf(stderr, "Unknown operation.\n");
1274 #if defined ___AmigaOS___ 1329 #if defined ___AmigaOS___
1275 CloseLocale(locale); 1330 CloseLocale(locale);
1276 #endif 1331 #endif
-   1332  
1277   1333 free(paths->array);
1278 free(paths); 1334 free(paths);
1279 paths = NULL; 1335 paths = NULL;
1280 return 5; 1336 return 5;
1281 } 1337 }
1282   1338  
1283 #if defined ___AmigaOS___ 1339 #if defined ___AmigaOS___
1284 CloseLocale(locale); 1340 CloseLocale(locale);
1285 #endif 1341 #endif
-   1342  
-   1343 if(paths != NULL) {
1286   1344 free(paths->array);
1287 free(paths); 1345 free(paths);
-   1346 paths = NULL;
-   1347 }
1288 paths = NULL; 1348  
1289 return 0; 1349 return 0;
1290 } 1350 }
1291   1351