HuntnGather – Diff between revs 22 and 23

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