HuntnGather – Diff between revs 24 and 26

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 24 Rev 26
Line 10... Line 10...
10   10  
11 #include <sys/types.h> 11 #include <sys/types.h>
12 #include <sys/stat.h> 12 #include <sys/stat.h>
Line -... Line 13...
-   13 #include <sys/syslimits.h>
13 #include <sys/syslimits.h> 14  
14   15 #if defined ___AmigaOS___
-   16 #include <proto/dos.h>
-   17 #include <proto/exec.h>
Line 15... Line 18...
15 #include <proto/dos.h> 18 #include <proto/locale.h>
16 #include <proto/exec.h> 19 #endif
17   20  
Line 23... Line 26...
23   26  
24 #if !defined ___HAVE_GETOPT___ 27 #if !defined ___HAVE_GETOPT___
25 #include "getopt.h" 28 #include "getopt.h"
Line 26... Line 29...
26 #endif 29 #endif
Line 27... Line 30...
27   30  
28 #define PROGRAM_VERSION "1.7.3" 31 #define PROGRAM_VERSION "1.7.4"
29   32  
30 #if defined ___AmigaOS___ 33 #if defined ___AmigaOS___
Line 43... Line 46...
43 #define FALSE 0; 46 #define FALSE 0;
44 #endif 47 #endif
Line 45... Line 48...
45   48  
46 #define ASYNC_BUF 8192 49 #define ASYNC_BUF 8192
47 #define MAX_MEM 262144 -  
48 #define NAME_BUF 32 -  
49 #define PATH_BUF 128 50 #define MAX_MEM 262144
50 #define LINE_BUF 256 51 #define LINE_BUF 256
Line 51... Line 52...
51 #define DEFAULT_DATABASE_FILE "S:gather.db" 52 #define DEFAULT_DATABASE_FILE "S:gather.db"
52   53  
53 typedef struct { 54 typedef struct {
54 unsigned int dirs; 55 unsigned int dirs;
Line -... Line 56...
-   56 unsigned int files;
-   57 } stats;
-   58  
-   59 typedef struct {
-   60 char *name;
-   61 char *path;
-   62 } dbEntry;
-   63  
-   64 typedef struct {
-   65 char **database;
-   66 unsigned int count;
-   67 } dbArray;
-   68  
-   69 enum MODE {
-   70 NONE,
-   71 GATHER,
-   72 REMOVE,
55 unsigned int files; 73 CREATE
56 } stats; 74 } operation;
-   75  
-   76 unsigned int run = TRUE;
-   77 unsigned int verbose = TRUE;
-   78 unsigned int maxmem = MAX_MEM;
-   79 // Define global locale for string compare.
Line 57... Line 80...
57   80 #if defined ___AmigaOS___
58 int run = TRUE; 81 struct Locale *locale;
59 int verbose = TRUE; 82 #endif
60   83  
Line -... Line 84...
-   84 void SignalHandler(int sig) {
-   85 // Toggle the run flag to stop execution.
-   86 run = FALSE;
-   87 }
61 void SignalHandler(int sig) { 88  
62 // Toggle the run flag to stop execution. 89 /*
63 run = FALSE; 90 *
-   91 * Used for sorting database lines.
-   92 */
-   93 int QsortCompare(const void *a, const void *b) {
64 } 94 const char **p = (const char **)a;
-   95 const char **q = (const char **)b;
65   96 #if defined ___AmigaOS___
Line 66... Line 97...
66 int compare(const void *a, const void *b) { 97 return StrnCmp(locale, (STRPTR)*p, (STRPTR)*q, -1, SC_ASCII);
67 const char **p = (const char **)a; 98 #else
68 const char **q = (const char **)b; 99 return strncmp(*p, *q, strlen(*p));
69 return strncmp(*p, *q, strlen(*p)); 100 #endif
-   101 }
-   102  
-   103 /*
-   104 *
-   105 * Gets the absolute path to file by name.
-   106 */
-   107 char *PathToAbsolute(char *path) {
-   108 char *abs;
-   109 #if defined ___AmigaOS___
-   110 BPTR lock;
-   111 #endif
-   112  
-   113 #if defined ___AmigaOS___
-   114 if((abs = malloc(PATH_MAX * sizeof(*abs))) == NULL) {
-   115 fprintf(stderr, "Memory allocation failure.\n");
-   116 return NULL;
-   117 }
-   118 if((lock = Lock(path, SHARED_LOCK)) == 0) {
-   119 fprintf(stderr, "Lock on %s failed.\n", path);
-   120 return NULL;
-   121 }
-   122 if(NameFromLock(lock, abs, PATH_MAX) == FALSE) {
-   123 fprintf(stderr, "Lock on %s failed.\n", path);
-   124 UnLock(lock);
-   125 return NULL;
-   126 }
-   127 UnLock(lock);
-   128 #else
-   129 abs = realpath(path, NULL);
-   130 #endif
-   131  
-   132 return abs;
-   133 }
-   134  
-   135 /*
-   136 *
-   137 * Compares path parts for equality.
-   138 */
-   139 #if defined ___AmigaOS___
-   140 BOOL PathCompare(char *path, char *look) {
-   141 #else
-   142 int PathCompare(char *path, char *look) {
-   143 #endif
-   144 char *a;
-   145 char *b;
-   146  
-   147 for(a = path, b = look; *a != '\0' && *b != '\0'; ++a, ++b) {
-   148 if(*b != '\0' && *a != *b) {
-   149 return FALSE;
-   150 }
-   151 }
-   152  
-   153 return *b == '\0';
70 } 154 }
71   155  
72 /* 156 /*
73 * 157 *
74 * Sorts a database file lexicographically. 158 * Gets the size of a file by name.
75 */ 159 */
76 void SortDatabase(char *dbFile) { 160 int GetFileSize(char *dbFile) {
77 #if defined ___AsyncIO___ 161 #if defined ___AsyncIO___
78 struct AsyncFile *fp; -  
79 LONG c; -  
80 #else -  
81 FILE *fp; -  
82 char c; -  
83 #endif -  
84 char *name = NULL; -  
85 char *path = NULL; -  
Line 86... Line -...
86 char **database; -  
87 int i; 162 struct AsyncFile *fp;
88 int side; 163 LONG size;
89 unsigned int line; 164 #else
90 int name_size; 165 FILE *fp;
91 int path_size; 166 int size;
92   167 #endif
93 // Open database file for reading. 168  
-   169 #if defined ___AsyncIO___
-   170 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
-   171 #else
-   172 if((fp = fopen(dbFile, "r")) == NULL) {
-   173 #endif
-   174 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile);
-   175 return -1;
-   176 }
-   177  
-   178 #if defined ___AsyncIO___
-   179 if(SeekAsync(fp, 0, MODE_END) == -1) {
-   180 #else
-   181 if(fseek(fp, 0L, SEEK_END) == 0) {
-   182 #endif
-   183 fprintf(stderr, "Seek in file %s failed.\n", dbFile);
-   184 #if defined ___AsyncIO___
-   185 CloseAsync(fp);
-   186 #else
-   187 fclose(fp);
-   188 #endif
94 #if defined ___AsyncIO___ 189 return -1;
-   190 }
-   191 #if defined ___AsyncIO___
-   192 if((size = SeekAsync(fp, 0, MODE_CURRENT)) == -1) {
Line 95... Line 193...
95 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 193 fprintf(stderr, "Seek in file %s failed.\n", dbFile);
96 #else 194 CloseAsync(fp);
97 if((fp = fopen(dbFile, "r")) == NULL) { 195 return -1;
98 #endif 196 }
99 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); 197 #else
Line 100... Line -...
100 return; -  
101 } 198 size = ftell(fp);
102   199 #endif
Line -... Line 200...
-   200  
-   201 #if defined ___AsyncIO___
-   202 CloseAsync(fp);
-   203 #else
-   204 fclose(fp);
-   205 #endif
-   206  
-   207 return size;
-   208 }
-   209  
-   210 /*
-   211 *
103 database = malloc(sizeof(*database)); 212 * Counts the lines of a file.
-   213 */
-   214 int CountFileLines(char *dbFile) {
-   215 #if defined ___AsyncIO___
-   216 struct AsyncFile *fp;
-   217 LONG c;
-   218 #else
104 name_size = NAME_BUF; 219 FILE *fp;
-   220 char c;
105 name = malloc(name_size * sizeof(*name)); 221 #endif
Line -... Line 222...
-   222 int lines;
106 path_size = PATH_BUF; 223  
107 path = malloc(path_size * sizeof(*path)); 224 #if defined ___AsyncIO___
108   225 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
109 line = 0; 226 #else
110 side = 0; 227 if((fp = fopen(dbFile, "r")) == NULL) {
111 i = 0; 228 #endif
112   229 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile);
113 if(verbose) { 230 return -1;
114 fprintf(stdout, "Sorting '%s'\n", dbFile); 231 }
115 } 232  
116   233 lines = 0;
117 #if defined ___AsyncIO___ 234 #if defined ___AsyncIO___
118 while(run && (c = ReadCharAsync(fp)) != -1) { 235 while(run && (c = ReadCharAsync(fp)) != -1) {
119 #else 236 #else
120 while(run && fscanf(fp, "%c", &c) == 1) { -  
121 #endif -  
122 #if defined ___AmigaOS___ -  
123 // Check if CTRL+C was pressed and abort the program. -  
124 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 237 while(run && fscanf(fp, "%c", &c) == 1) {
125 run = FALSE; -  
126 continue; -  
127 } -  
128 #endif -  
129 switch(c) { -  
130 case '\n': -  
131 // Load up the name and path into the database variable. -  
132 database = realloc(database, (line + 1) * sizeof(*database)); -  
133 database[line] = malloc((strlen(name) + strlen(path) + 1 + 1) * sizeof(*database[line])); -  
134 sprintf(database[line], "%s\t%s", name, path); -  
135 ++line; -  
136   -  
137 free(name); -  
138 name_size = NAME_BUF; -  
139 name = malloc(name_size * sizeof(*name)); -  
140 --side; -  
141 i = 0; -  
142   -  
143 break; -  
144 case '\t': -  
145 free(path); -  
146 path_size = PATH_BUF; -  
147 path = malloc(path_size * sizeof(*path)); -  
148 ++side; -  
149 i = 0; -  
150 break; -  
151 default: -  
152 switch(side) { -  
153 case 0: -  
154 if(strlen(name) == name_size) { -  
155 name_size = name_size * 1.5; -  
156 name = realloc(name, name_size * sizeof(*name)); -  
157 } -  
158 //name = realloc(name, (i + 1 + 1) * sizeof(char)); -  
159 name[i] = c; -  
160 name[i + 1] = '\0'; -  
161 break; -  
162 case 1: -  
163 if(strlen(path) == path_size) { -  
164 path_size = path_size * 1.5; -  
165 path = realloc(path, path_size * sizeof(*path)); 238 #endif
166 } 239 #if defined ___AmigaOS___
167 //path = realloc(path, (i + 1 + 1) * sizeof(char)); 240 // Check if CTRL+C was pressed and abort the program.
Line 168... Line 241...
168 path[i] = c; 241 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
169 path[i + 1] = '\0'; 242 run = FALSE;
170 break; 243 continue;
171 default: 244 }
172 fprintf(stderr, "File '%s' is corrupted.\n", dbFile); 245 #endif
Line 173... Line 246...
173 break; 246 switch(c) {
174 } -  
-   247 case '\n':
Line -... Line 248...
-   248 ++lines;
-   249 break;
175 ++i; 250 }
-   251 }
-   252  
-   253 #if defined ___AsyncIO___
-   254 CloseAsync(fp);
176 break; 255 #else
-   256 fclose(fp);
-   257 #endif
-   258  
-   259 return lines;
-   260 }
-   261  
-   262 /*
-   263 *
-   264 * Creates a temporary file and returns its name.
-   265 */
-   266 char *CreateTemporaryFile(void) {
-   267 char *name;
177 } 268  
-   269 name = tmpnam(NULL);
-   270  
-   271 return name;
-   272 }
-   273  
-   274 /*
178 } 275 *
-   276 * Create multiple temporary files and return their names.
-   277 */
179   278 char **CreateTemporaryFiles(int files) {
-   279 char **tmpNames;
-   280 int count;
-   281  
-   282 if((tmpNames = malloc(files * sizeof(*tmpNames))) == NULL) {
-   283 fprintf(stderr, "Memory allocation failure.\n");
-   284 return NULL;
180 #if defined ___AsyncIO___ 285 }
-   286  
-   287 if(verbose) {
-   288 fprintf(stdout, "Creating temporary files...\r");
181 CloseAsync(fp); 289 }
182 #else 290  
183 fclose(fp); 291 count = files;
Line -... Line 292...
-   292 while(run && --count > -1) {
-   293 #if defined ___AmigaOS___
-   294 // Check if CTRL+C was pressed and abort the program.
-   295 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
-   296 run = FALSE;
-   297 continue;
-   298 }
-   299 #endif
-   300 tmpNames[count] = CreateTemporaryFile();
-   301  
184 #endif 302 if(verbose) {
-   303 fprintf(stdout, "Creating temporary files: %d%%\r", 100 - (int)(((float)count / files) * 100.0));
-   304 }
-   305 }
-   306  
-   307 if(verbose) {
-   308 fprintf(stdout, "\n");
-   309 }
-   310  
-   311 return tmpNames;
-   312 }
185   313  
186 // Sort the database. 314  
187 qsort(database, line, sizeof(char *), compare); 315 /*
188   316 *
189 // Write the database lines back to the database. 317 * Skips a line in a file.
190 #if defined ___AsyncIO___ 318 */
191 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { 319 #if defined ___AsyncIO___
-   320 void SkipLine(struct AsyncFile *fp) {
-   321 LONG c;
-   322 while(run && (c = ReadCharAsync(fp)) != -1) {
-   323 #else
-   324 void SkipLine(FILE *fp) {
-   325 char c;
-   326 while(run && fscanf(fp, "%c", &c) == 1) {
-   327 #endif
-   328 #if defined ___AmigaOS___
-   329 // Check if CTRL+C was pressed and abort the program.
-   330 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
192 #else 331 run = FALSE;
193 if((fp = fopen(dbFile, "w")) == NULL) { 332 continue;
194 #endif 333 }
195 fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); 334 #endif
196 return; 335 switch(c) {
-   336 case '\n':
197 } 337 return;
-   338 }
-   339 }
-   340 }
-   341  
-   342 /*
-   343 *
-   344 * Peeks at a line from a file.
-   345 */
198   346 #if defined ___AsyncIO___
Line -... Line 347...
-   347 char *PeekLine(struct AsyncFile *fp) {
199 for(i = 0; i < line; ++i) { 348 LONG c;
200 #if defined ___AmigaOS___ 349 #else
201 // Check if CTRL+C was pressed and abort the program. 350 char *PeekLine(FILE *fp) {
202 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 351 char c;
203 run = FALSE; 352 #endif
-   353 char *line;
-   354 unsigned int size;
-   355 int i;
-   356  
-   357 size = LINE_BUF;
-   358 if((line = malloc(size * sizeof(*line))) == NULL) {
-   359 fprintf(stderr, "Memory allocation failure.\n");
-   360 return NULL;
-   361 }
-   362  
-   363 i = 0;
-   364 #if defined ___AsyncIO___
-   365 while(run && (c = ReadCharAsync(fp)) != -1) {
-   366 #else
-   367 while(run && fscanf(fp, "%c", &c) == 1) {
-   368 #endif
-   369 #if defined ___AmigaOS___
-   370 // Check if CTRL+C was pressed and abort the program.
-   371 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
-   372 run = FALSE;
-   373 continue;
-   374 }
-   375 #endif
-   376 switch(c) {
-   377 case '\n':
-   378 // Rewind the file by the number of read characters.
-   379 #if defined ___AsyncIO___
-   380 if(SeekAsync(fp, -(i + 1), MODE_CURRENT) == -1) {
-   381 fprintf(stderr, "Could not seek in file.\n");
-   382 free(line);
-   383 return NULL;
Line 204... Line 384...
204 continue; 384 }
205 } 385 #else
Line 206... Line 386...
206 #endif 386 fseek(fp, -(i + 1), SEEK_CUR);
207 #if defined ___AsyncIO___ 387 #endif
208 WriteAsync(fp, database[i], (LONG)(strlen(database[i]) * sizeof(char))); 388 return line;
209 WriteAsync(fp, "\n", 1 * sizeof(char)); 389 default:
210 #else -  
211 fprintf(fp, "%s\n", database[i]); 390 if(strlen(line) == size) {
212 #endif 391 size = size * 1.5;
-   392 line = realloc(line, size * sizeof(*line));
213 } 393 }
-   394 line[i] = c;
214   395 line[i + 1] = '\0';
215 #if defined ___AsyncIO___ 396 break;
216 CloseAsync(fp); 397 }
217 #else -  
218 fclose(fp); -  
219 #endif 398 ++i;
220   -  
221 free(database); 399 }
Line -... Line 400...
-   400  
-   401 return NULL;
-   402 }
-   403  
-   404 /*
-   405 *
-   406 * Read a line from a file.
222 } 407 */
223   408 #if defined ___AsyncIO___
224 /* 409 char *ReadLine(struct AsyncFile *fp) {
225 * 410 LONG c;
226 * Updates a database file "dbFile". 411 #else
227 */ -  
228 void CollectFiles(char *dbFile, stringStack *dirStack, stats *stats) { -  
229 #if defined ___AsyncIO___ -  
230 struct AsyncFile *fp; -  
231 #else -  
232 FILE *fp; -  
233 #endif -  
234 DIR *dir; -  
235 struct dirent *dirEntry; -  
236 struct stat dirStat; 412 char *ReadLine(FILE *fp) {
237 unsigned int size; 413 char c;
238 char *path; 414 #endif
239 char *subPath; 415 char *line;
240   416 unsigned int size;
241 #if defined ___AsyncIO___ 417 unsigned int i;
242 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { 418  
-   419 size = LINE_BUF;
-   420 if((line = malloc(size * sizeof(*line))) == NULL) {
-   421 fprintf(stderr, "Memory allication failure.\n");
-   422 return NULL;
243 #else 423 }
-   424  
-   425 i = 0;
-   426 #if defined ___AsyncIO___
-   427 while(run && (c = ReadCharAsync(fp)) != -1) {
-   428 #else
244 if((fp = fopen(dbFile, "w")) == NULL) { 429 while(run && fscanf(fp, "%c", &c) == 1) {
245 #endif 430 #endif
-   431 #if defined ___AmigaOS___
-   432 // Check if CTRL+C was pressed and abort the program.
Line 246... Line -...
246 fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); -  
247 return; -  
248 } 433 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
249   434 run = FALSE;
Line -... Line 435...
-   435 continue;
-   436 }
250 if(verbose) { 437 #endif
-   438 switch(c) {
251 fprintf(stdout, "Collecting files...\r"); 439 case '\n':
252 } 440 return line;
253   -  
254 while(run && !stringStackIsEmpty(dirStack)) { -  
255 #if defined ___AmigaOS___ 441 default:
256 // Check if CTRL+C was pressed and abort the program. 442 if(strlen(line) == size) {
-   443 size = size * 1.5;
-   444 line = realloc(line, size * sizeof(*line));
257 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 445 }
258 run = FALSE; -  
259 continue; -  
260 } -  
261 #endif -  
262 if((path = stringStackPop(dirStack)) == NULL) { -  
263 return; -  
264 } -  
265   -  
266 if((dir = opendir(path)) == NULL) { -  
267 fprintf(stderr, "Unable to open '%s' for reading.\n", path); -  
268 return; -  
269 } -  
270   -  
271 while(run && (dirEntry = readdir(dir)) != NULL) { -  
272 #if defined ___AmigaOS___ -  
273 // Check if CTRL+C was pressed and abort the program. 446 line[i] = c;
274 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { -  
Line -... Line 447...
-   447 line[i + 1] = '\0';
-   448 break;
275 run = FALSE; 449 }
-   450 ++i;
-   451 }
276 continue; 452  
-   453 return NULL;
-   454 }
277 } 455  
278 #endif 456 /*
-   457 *
279 size = sizeof(path) + sizeof(dirEntry->d_name) + 1; 458 * Delete a file.
280 switch(path[strlen(path) - 1]) { 459 */
-   460 #if defined ___AmigaOS___
Line -... Line 461...
-   461 BOOL RemoveFile(char *name) {
-   462 return DeleteFile(name);
-   463 #else
-   464 int RemoveFile(char *name) {
-   465 return remove(name) == 0;
-   466 #endif
281 case '/': 467 }
282 case ':': // This is a drive path. 468  
-   469 /*
283 subPath = malloc(size); 470 *
-   471 * Deletes files.
-   472 */
-   473 void RemoveFiles(char **names, int count) {
-   474 unsigned int i;
Line 284... Line -...
284 sprintf(subPath, "%s%s", path, dirEntry->d_name); -  
Line -... Line 475...
-   475 for(i = 0; i < count; ++i) {
285 break; 476 if(RemoveFile(names[i]) == FALSE) {
-   477 fprintf(stderr, "Unable to remove %s...\n", names[i]);
-   478 continue;
286 default: 479 }
287 subPath = malloc(size + 1); 480 fprintf(stderr, "Removing file: %s\n", names[i]);
-   481 }
-   482 }
-   483  
Line -... Line 484...
-   484 /*
288 sprintf(subPath, "%s/%s", path, dirEntry->d_name); 485 *
289 break; -  
290 } -  
291 stat(subPath, &dirStat); -  
292 if(S_ISDIR(dirStat.st_mode)) { 486 * Copies a file to another file by name.
293 stringStackPush(dirStack, subPath); 487 */
294   488 void CopyFile(char *a, char *b) {
295 ++stats->dirs; 489 #if defined ___AsyncIO___
296   -  
297 if(verbose) { -  
298 fprintf(stdout, -  
299 "Gathered %d directories and %d files.\r", -  
300 stats->dirs, 490 struct AsyncFile *ap;
301 stats->files); -  
302 } -  
303   -  
Line -... Line 491...
-   491 struct AsyncFile *bp;
-   492 LONG c;
304 free(subPath); 493 #else
305 continue; 494 FILE *ap;
-   495 FILE *bp;
-   496 char c;
Line 306... Line -...
306 } -  
307   497 #endif
308 // Write to database file. 498  
Line -... Line 499...
-   499  
-   500 // Open database file for writing.
-   501 #if defined ___AsyncIO___
-   502 if((ap = OpenAsync(a, MODE_READ, ASYNC_BUF)) == NULL) {
-   503 #else
-   504 if((ap = fopen(a, "r")) == NULL) {
-   505 #endif
-   506 fprintf(stderr, "Unable to open '%s' for reading.\n", a);
-   507 return;
309   508 }
-   509  
-   510 // Open temporary file for reading.
-   511 #if defined ___AsyncIO___
-   512 if((bp = OpenAsync(b, MODE_WRITE, ASYNC_BUF)) == NULL) {
-   513 #else
310 #if defined ___NOCASE_FS___ 514 if((bp = fopen(b, "w+")) == NULL) {
-   515 #endif
-   516 fprintf(stderr, "Unable to open file '%s' for writing.\n", b);
-   517  
-   518 // Close database file.
311 strupr(dirEntry->d_name); 519 #if defined ___AsyncIO___
Line 312... Line 520...
312 #endif 520 CloseAsync(ap);
-   521 #else
313   522 fclose(ap);
314 #if defined ___AsyncIO___ 523 #endif
-   524  
315 WriteAsync(fp, dirEntry->d_name, (LONG)(strlen(dirEntry->d_name) * sizeof(char))); 525 return;
316 WriteAsync(fp, "\t", 1 * sizeof(char)); 526 }
317 WriteAsync(fp, subPath, (LONG)(strlen(subPath) * sizeof(char))); -  
318 WriteAsync(fp, "\n", 1 * sizeof(char)); 527  
Line 319... Line 528...
319 #else 528 #if defined ___AsyncIO___
320 fprintf(fp, "%s\t%s\n", dirEntry->d_name, subPath); 529 while(run && (c = ReadCharAsync(ap)) != -1) {
321 #endif 530 #else
322 ++stats->files; 531 while(run && fscanf(ap, "%c", &c) == 1) {
323   532 #endif
324 if(verbose) { 533 #if defined ___AmigaOS___
325 fprintf(stdout, 534 // Check if CTRL+C was pressed and abort the program.
326 "Gathered %d directories and %d files.\r", -  
327 stats->dirs, 535 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
328 stats->files); 536 run = FALSE;
329 } -  
330   537 continue;
-   538 }
-   539 #endif
Line -... Line 540...
-   540 #if defined ___AsyncIO___
331 free(subPath); 541 if(WriteCharAsync(bp, (UBYTE)c) != 1) {
332 } 542 #else
333   543 if(fprintf(bp, "%c", c) != 1) {
334 closedir(dir); 544 #endif
335 free(path); 545 fprintf(stderr, "Unable to write to '%s'.\n", b);
336 } 546 break;
337   547 }
338 if(verbose) { 548 }
Line -... Line 549...
-   549  
-   550 #if defined ___AsyncIO___
-   551 CloseAsync(ap);
-   552 CloseAsync(bp);
-   553 #else
-   554 fclose(ap);
-   555 fclose(bp);
-   556 #endif
-   557 }
-   558  
-   559 /*
-   560 *
-   561 * Write lines to a file.
-   562 */
-   563 void WriteLinesToFile(char *dbFile, char **lines, unsigned int count) {
-   564 #if defined ___AsyncIO___
-   565 struct AsyncFile *fp;
-   566 #else
-   567 FILE *fp;
-   568 #endif
339 fprintf(stdout, "\n"); 569 int i;
340 } 570 char *rem;
341   571  
342 #if defined ___AsyncIO___ 572 // Write the database lines back to the database.
343 CloseAsync(fp); 573 #if defined ___AsyncIO___
344 #else -  
345 fclose(fp); 574 if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) {
Line -... Line 575...
-   575 #else
-   576 if((fp = fopen(dbFile, "w")) == NULL) {
-   577 #endif
-   578 fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile);
-   579 return;
-   580 }
-   581  
-   582 rem = NULL;
346 #endif 583 for(i = 0; i < count; ++i) {
347   584 #if defined ___AmigaOS___
348 } 585 // Check if CTRL+C was pressed and abort the program.
349   586 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
350 /* 587 run = FALSE;
-   588 continue;
Line -... Line 589...
-   589 }
-   590 #endif
-   591  
-   592 if(rem != NULL) {
-   593 #if defined ___AmigaOS___
-   594 if(StrnCmp(locale, lines[i], rem, -1, SC_ASCII) == 0) {
-   595 #else
-   596 if(strncmp(lines[i], rem, strlen(rem)) == 0) {
-   597 #endif
-   598 continue;
-   599 }
-   600 }
-   601  
-   602 #if defined ___AsyncIO___
-   603 WriteAsync(fp, lines[i], (LONG)strlen(lines[i]));
-   604 WriteAsync(fp, "\n", 1);
-   605 #else
-   606 fprintf(fp, "%s\n", lines[i]);
-   607 #endif
-   608  
-   609 if(rem != NULL) {
-   610 free(rem);
-   611 }
-   612  
-   613 rem = malloc(strlen(lines[i]) + 1);
-   614 sprintf(rem, "%s", lines[i]);
-   615 }
-   616  
-   617 #if defined ___AsyncIO___
-   618 CloseAsync(fp);
-   619 #else
-   620 fclose(fp);
-   621 #endif
-   622 }
-   623  
-   624 /*
-   625 *
-   626 * Create a database entry from a line of text.
-   627 */
-   628 dbEntry* CreateDataseEntry(char *line) {
-   629 dbEntry *entry;
-   630 char *ptr;
-   631 unsigned int side;
-   632 unsigned int i;
-   633 unsigned int j;
-   634  
-   635 if((entry = malloc(1 * sizeof(*entry))) == NULL) {
-   636 fprintf(stderr, "Memory allocation failure.\n");
-   637 return NULL;
-   638 }
-   639  
-   640 if((entry->name = malloc(strlen(line) * sizeof(*entry->name))) == NULL) {
-   641 fprintf(stderr, "Memory allocation failure.\n");
-   642 return NULL;
-   643 }
351 * 644  
352 * Gets the size of a file "dbFle". 645 if((entry->path = malloc(strlen(line) * sizeof(*entry->path))) == NULL) {
Line 353... Line 646...
353 */ 646 fprintf(stderr, "Memory allocation failure.\n");
354 int GetFileSize(char *dbFile) { 647 return NULL;
355 #if defined ___AsyncIO___ 648 }
356 struct AsyncFile *fp; 649  
357 LONG size; 650 for(ptr = line, side = 0, i = 0, j = 0; run && *ptr != '\0'; ++ptr) {
358 #else 651 #if defined ___AmigaOS___
359 FILE *fp; 652 // Check if CTRL+C was pressed and abort the program.
360 int size; -  
361 #endif 653 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
362   654 run = FALSE;
363 #if defined ___AsyncIO___ -  
364 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 655 continue;
-   656 }
-   657 #endif
365 #else 658 switch(*ptr) {
-   659 case '\t':
Line -... Line 660...
-   660 entry->name[i] = '\0';
-   661 ++side;
-   662 break;
-   663 case '\n':
-   664 entry->path[j] = '\0';
-   665 return entry;
366 if((fp = fopen(dbFile, "r")) == NULL) { 666 default:
367 #endif 667 switch(side) {
368 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); 668 case 0:
369 return 0; 669 entry->name[i++] = *ptr;
370 } 670 break;
371   671 case 1:
372 #if defined ___AsyncIO___ 672 entry->path[j++] = *ptr;
373 SeekAsync(fp, 0, MODE_END); 673 break;
Line 374... Line 674...
374 size = SeekAsync(fp, 0, MODE_CURRENT); 674 }
375 #else -  
376 fseek(fp, 0L, SEEK_END); 675 break;
377 size = ftell(fp); -  
378 #endif -  
379   -  
380 #if defined ___AsyncIO___ 676 }
381 CloseAsync(fp); 677 }
382 #else 678  
383 fclose(fp); 679 return entry;
384 #endif 680 }
385   681  
386 return size; 682 /*
-   683 *
-   684 *
-   685 */
387 } 686 dbArray *GetDatabaseArray(char *dbFile) {
-   687 #if defined ___AsyncIO___
388   688 struct AsyncFile *fp;
-   689 #else
-   690 FILE *fp;
-   691 #endif
-   692 dbArray *array;
-   693 dbEntry *entry;
-   694 char *line;
-   695 unsigned int count;
-   696  
-   697 if((array = malloc(1 * sizeof(*array))) == NULL) {
389 /* 698 fprintf(stderr, "Memory allocation failure.\n");
-   699 return NULL;
-   700 }
-   701  
390 * 702 // Open database file for reading.
-   703 #if defined ___AsyncIO___
-   704 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
391 * Counts the lines of a file. 705 #else
-   706 if((fp = fopen(dbFile, "r")) == NULL) {
-   707 #endif
-   708 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile);
-   709 return NULL;
-   710 }
392 */ 711  
Line 393... Line 712...
393 int CountFileLines(char *dbFile) { 712 count = 0;
394 #if defined ___AsyncIO___ 713 while(run && (line = ReadLine(fp)) != NULL) {
395 struct AsyncFile *fp; 714 #if defined ___AmigaOS___
396 LONG c; 715 // Check if CTRL+C was pressed and abort the program.
397 #else 716 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
Line -... Line 717...
-   717 run = FALSE;
398 FILE *fp; 718 continue;
399 char c; 719 }
Line 400... Line 720...
400 #endif 720 #endif
401 int lines; 721 if((entry = CreateDataseEntry(line)) == NULL) {
402   722 fprintf(stderr, "Unable to create database entry.\n");
403 #if defined ___AsyncIO___ 723 #if defined ___AsyncIO___
-   724 CloseAsync(fp);
-   725 #else
-   726 fclose(fp);
-   727 #endif
-   728 return NULL;
-   729 }
-   730  
-   731 // Load up the name and path into the database variable.
404 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 732 array->database = realloc(array->database, (count + 1) * sizeof(*array->database));
-   733 if((array->database[count] = malloc((strlen(entry->name) + strlen(entry->path) + 1 + 1) * sizeof(*array->database[count]))) == NULL) {
-   734 fprintf(stderr, "Memory allocation failure.\n");
-   735 free(entry);
-   736 free(line);
-   737 #if defined ___AsyncIO___
-   738 CloseAsync(fp);
-   739 #else
-   740 fclose(fp);
-   741 #endif
-   742 return NULL;
-   743 }
-   744 sprintf(array->database[count], "%s\t%s", entry->name, entry->path);
-   745 ++count;
-   746  
-   747 free(entry);
-   748 free(line);
-   749 }
-   750  
-   751 #if defined ___AsyncIO___
-   752 CloseAsync(fp);
-   753 #else
-   754 fclose(fp);
-   755 #endif
-   756  
405 #else 757 array->count = count;
-   758 return array;
-   759 }
-   760  
-   761 /*
406 if((fp = fopen(dbFile, "r")) == NULL) { 762 *
-   763 * Sorts a database file lexicographically.
-   764 */
-   765 void SortDatabase(char *dbFile) {
-   766 dbArray *array;
-   767  
-   768 if(verbose) {
-   769 fprintf(stdout, "Sorting '%s'...\n", dbFile);
-   770 }
Line -... Line 771...
-   771  
-   772 // Retrieve the database as an array.
-   773 if((array = GetDatabaseArray(dbFile)) == NULL) {
-   774 fprintf(stderr, "Unable to read '%s' as a database file.\n", dbFile);
-   775 return;
-   776 }
407 #endif 777  
-   778 // Sort the database.
-   779 qsort(array->database, array->count, sizeof(char *), QsortCompare);
-   780  
-   781 // Write back the database to the database file.
-   782 WriteLinesToFile(dbFile, array->database, array->count);
-   783  
-   784 free(array);
-   785 }
-   786  
-   787 /*
-   788 *
-   789 * Updates a database file "dbFile".
-   790 */
-   791 stats *CollectFiles(char *dbFile, char **paths, unsigned int count) {
-   792 #if defined ___AsyncIO___
-   793 struct AsyncFile *fp;
-   794 #else
-   795 FILE *fp;
-   796 #endif
Line 408... Line 797...
408 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); 797 stringStack *stack;
409 return 0; 798 stats *stats;
410 } 799 DIR *dir;
Line -... Line 800...
-   800 struct dirent *entry;
411   801 struct stat dirStat;
412 lines = 0; 802 unsigned int size;
-   803 int i;
-   804 char *path;
-   805 char *subPath;
-   806  
413 #if defined ___AsyncIO___ 807 // Initialize metrics.
414 while(run && (c = ReadCharAsync(fp)) != -1) { 808 if((stats = malloc(sizeof(stats))) == NULL) {
415 #else 809 fprintf(stderr, "Memory allocation failure.\n");
416 while(run && fscanf(fp, "%c", &c) == 1) { 810 return NULL;
417 #endif 811 }
418 #if defined ___AmigaOS___ 812  
419 // Check if CTRL+C was pressed and abort the program. 813 stats->dirs = 0;
420 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 814 stats->files = 0;
-   815  
421 run = FALSE; 816 #if defined ___AsyncIO___
422 continue; -  
423 } -  
Line 424... Line 817...
424 #endif 817 if((fp = OpenAsync(dbFile, MODE_APPEND, ASYNC_BUF)) == NULL) {
425 switch(c) { 818 #else
-   819 if((fp = fopen(dbFile, "r+")) == NULL) {
426 case '\n': 820 #endif
-   821 fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile);
-   822 return stats;
-   823 }
-   824  
-   825 // Seek to the end of the database.
-   826 #if defined ___AsyncIO___
-   827 if(SeekAsync(fp, 0, MODE_END) == -1) {
-   828 #else
-   829 if(fseek(fp, 0, SEEK_END) == 0) {
-   830 #endif
-   831 fprintf(stderr, "Unable to seek in '%s' for appending.\n", dbFile);
-   832 #if defined ___AsyncIO___
-   833 CloseAsync(fp);
-   834 #else
-   835 fclose(fp);
-   836 #endif
-   837 return stats;
-   838 }
-   839  
-   840 if(verbose) {
-   841 fprintf(stdout, "Collecting files...\r");
-   842 }
-   843  
-   844 // Push the first path onto the stack.
-   845 stack = stringStackCreate(count);
-   846 for(i = 0; run && i < count; ++i) {
-   847 stringStackPush(stack, paths[i]);
-   848 }
-   849  
-   850 while(run && !stringStackIsEmpty(stack)) {
-   851 #if defined ___AmigaOS___
-   852 // Check if CTRL+C was pressed and abort the program.
-   853 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
-   854 run = FALSE;
-   855 continue;
-   856 }
-   857 #endif
-   858 if((path = stringStackPop(stack)) == NULL) {
-   859 break;
-   860 }
-   861  
-   862 if((dir = opendir(path)) == NULL) {
-   863 fprintf(stderr, "Unable to open '%s' for reading.\n", path);
-   864 break;
-   865 }
-   866  
-   867 while(run && (entry = readdir(dir)) != NULL) {
-   868 #if defined ___AmigaOS___
-   869 // Check if CTRL+C was pressed and abort the program.
-   870 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
-   871 run = FALSE;
-   872 continue;
-   873 }
-   874 #endif
-   875 size = sizeof(path) + sizeof(entry->d_name) + 1;
-   876 switch(path[strlen(path) - 1]) {
-   877 case '/':
-   878 case ':': // This is a drive path.
-   879 if((subPath = malloc(size)) == NULL) {
-   880 fprintf(stderr, "Memory allocation failure.\n");
-   881 closedir(dir);
-   882 free(path);
-   883 stringStackDestroy(stack);
-   884 #if defined ___AsyncIO___
-   885 CloseAsync(fp);
-   886 #else
-   887 fclose(fp);
-   888 #endif
-   889 return NULL;
-   890 }
-   891 sprintf(subPath, "%s%s", path, entry->d_name);
-   892 break;
-   893 default:
-   894 if((subPath = malloc(size + 1)) == NULL) {
-   895 fprintf(stderr, "Memory allocation failure.\n");
-   896 closedir(dir);
-   897 free(path);
-   898 stringStackDestroy(stack);
-   899 #if defined ___AsyncIO___
-   900 CloseAsync(fp);
-   901 #else
-   902 fclose(fp);
-   903 #endif
-   904 return NULL;
-   905 }
-   906 sprintf(subPath, "%s/%s", path, entry->d_name);
427 ++lines; 907 break;
Line 428... Line 908...
428 break; 908 }
429 } 909 stat(subPath, &dirStat);
430 } 910 if(S_ISDIR(dirStat.st_mode)) {
Line -... Line 911...
-   911 stringStackPush(stack, subPath);
-   912  
-   913 ++stats->dirs;
-   914  
-   915 if(verbose) {
-   916 fprintf(stdout,
-   917 "Gathered %d directories and %d files.\r",
-   918 stats->dirs,
431   919 stats->files);
-   920 }
432 #if defined ___AsyncIO___ 921  
Line 433... Line 922...
433 CloseAsync(fp); 922 free(subPath);
434 #else 923 continue;
435 fclose(fp); 924 }
Line 489... Line 978...
489 #else 978 #else
490 FILE *fp, *tp; 979 FILE *fp, *tp;
491 char c; 980 char c;
492 #endif 981 #endif
493 int lines; 982 int lines;
494 int linesWritten; 983 int write;
Line 495... Line 984...
495   984  
496 #if defined ___AsyncIO___ 985 #if defined ___AsyncIO___
497 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 986 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
498 #else 987 #else
Line 518... Line 1007...
518   1007  
519 if(verbose) { 1008 if(verbose) {
520 fprintf(stdout, "Writing to temporary files...\r"); 1009 fprintf(stdout, "Writing to temporary files...\r");
Line 521... Line 1010...
521 } 1010 }
522   1011  
523 linesWritten = 0; 1012 write = 0;
524 lines = 0; 1013 lines = 0;
525 #if defined ___AsyncIO___ 1014 #if defined ___AsyncIO___
526 while(run && (c = ReadCharAsync(fp)) != -1) { 1015 while(run && (c = ReadCharAsync(fp)) != -1) {
Line 535... Line 1024...
535 } 1024 }
536 #endif 1025 #endif
537 switch(c) { 1026 switch(c) {
538 case '\n': 1027 case '\n':
539 // Increment the total written lines. 1028 // Increment the total written lines.
540 ++linesWritten; 1029 ++write;
Line 541... Line 1030...
541   1030  
542 if(verbose) { 1031 if(verbose) {
543 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)linesWritten / total) * 100.0)); 1032 fprintf(stdout, "Writing to temporary files: %d%%.\r", (int)(((float)write / total) * 100.0));
Line 544... Line 1033...
544 } 1033 }
545   1034  
546 // Write the newline character back. 1035 // Write the newline character back.
Line 619... Line 1108...
619 #endif 1108 #endif
620 } 1109 }
Line 621... Line 1110...
621   1110  
622 /* 1111 /*
623 * -  
624 * Skips a line in a file. -  
625 */ -  
626   -  
627 #if defined ___AsyncIO___ -  
628 void SkipLine(struct AsyncFile *fp) { -  
629 LONG c; -  
630 while(run && (c = ReadCharAsync(fp)) != -1) { -  
631 #else -  
632 void SkipDatabaseLine(FILE *fp) { -  
633 char c; -  
634 while(run && fscanf(fp, "%c", &c) == 1) { -  
635 #endif -  
636 #if defined ___AmigaOS___ -  
637 // Check if CTRL+C was pressed and abort the program. -  
638 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { -  
639 run = FALSE; -  
640 continue; -  
641 } -  
642 #endif -  
643 switch(c) { -  
644 case '\n': -  
645 return; -  
646 } -  
647 } -  
648 } -  
649   -  
650 /* -  
651 * -  
652 * Reads a line from a file. -  
653 */ -  
654 #if defined ___AsyncIO___ -  
655 char *ReadLine(struct AsyncFile *fp) { -  
656 LONG c; -  
657 #else -  
658 char *ReadLine(FILE *fp) { -  
659 char c; -  
660 #endif -  
661 char *line; -  
662 int line_size; -  
663 int i; -  
664   -  
665 line_size = LINE_BUF; -  
666 line = malloc(line_size * sizeof(*line)); -  
667   -  
668 i = 0; -  
669 #if defined ___AsyncIO___ -  
670 while(run && (c = ReadCharAsync(fp)) != -1) { -  
671 #else -  
672 while(run && fscanf(fp, "%c", &c) == 1) { -  
673 #endif -  
674 #if defined ___AmigaOS___ -  
675 // Check if CTRL+C was pressed and abort the program. -  
676 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { -  
677 run = FALSE; -  
678 continue; -  
679 } -  
680 #endif -  
681 switch(c) { -  
682 case '\n': -  
683 // Rewind the file by the number of read characters. -  
684 #if defined ___AsyncIO___ -  
685 if(SeekAsync(fp, -(i + 1), MODE_CURRENT) == -1) { -  
686 fprintf(stderr, "Could not seek in file.\n"); -  
687 return NULL; -  
688 } -  
689 #else -  
690 fseek(fp, -(i + 1), SEEK_CUR); -  
691 #endif -  
692 return line; -  
693 default: -  
694 if(strlen(line) == line_size) { -  
695 line_size = line_size * 1.5; -  
696 line = realloc(line, line_size * sizeof(*line)); -  
697 } -  
698 //line = realloc(line, (chars + 1 + 1) * sizeof(char)); -  
699 line[i] = c; -  
700 line[i + 1] = '\0'; -  
701 break; -  
702 } -  
703 ++i; -  
704 } -  
705   -  
706 return NULL; -  
707 } -  
708   -  
709 /* -  
710 * 1112 *
711 * Merges temporary files "tmpNames" into a database "dbFile". 1113 * Merges temporary files "tmpNames" into a database "dbFile".
712 */ 1114 */
713 void MergeTemporaryFiles(char *dbFile, char **tmpNames, int files, int lines) { 1115 void MergeTemporaryFiles(char *dbFile, char **tmpNames, int files, int lines) {
714 #if defined ___AsyncIO___ 1116 #if defined ___AsyncIO___
Line 719... Line 1121...
719 FILE **tp; 1121 FILE **tp;
720 #endif 1122 #endif
721 int i; 1123 int i;
722 int j; 1124 int j;
723 char *tmp; 1125 char *tmp;
-   1126 char *rem;
724 char *min; 1127 char *min;
725 int count; 1128 int count;
Line 726... Line 1129...
726   1129  
727 #if defined ___AsyncIO___ 1130 #if defined ___AsyncIO___
Line 732... Line 1135...
732 fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); 1135 fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile);
733 return; 1136 return;
734 } 1137 }
Line 735... Line 1138...
735   1138  
736 // Allocate as many file pointers as temporary files. 1139 // Allocate as many file pointers as temporary files.
-   1140 if((tp = malloc(files * sizeof(*tp))) == NULL) {
-   1141 fprintf(stderr, "Memory allocation failure.\n");
-   1142 #if defined ___AsyncIO___
-   1143 CloseAsync(fp);
-   1144 #else
-   1145 fclose(fp);
-   1146 #endif
-   1147 return;
Line 737... Line 1148...
737 tp = malloc(files * sizeof(*tp)); 1148 }
738   1149  
739 // Open all temporary files for reading. 1150 // Open all temporary files for reading.
740 for(i = 0; i < files; ++i) { 1151 for(i = 0; i < files; ++i) {
Line 763... Line 1174...
763   1174  
764 if(verbose) { 1175 if(verbose) {
765 fprintf(stdout, "Merging all files...\r"); 1176 fprintf(stdout, "Merging all files...\r");
Line -... Line 1177...
-   1177 }
766 } 1178  
767   1179 rem = NULL;
768 count = lines; 1180 count = lines;
769 j = 0; 1181 j = 0;
770 while(run && --count > -1) { 1182 while(run && --count > -1) {
Line 780... Line 1192...
780 fprintf(stdout, "Merging all files: %d%%.\r", 100 - (int)(((float)count / lines) * 100.0)); 1192 fprintf(stdout, "Merging all files: %d%%.\r", 100 - (int)(((float)count / lines) * 100.0));
781 } 1193 }
Line 782... Line 1194...
782   1194  
783 min = NULL; 1195 min = NULL;
784 for(i = 0; i < files; ++i) { 1196 for(i = 0; i < files; ++i) {
785 tmp = ReadLine(tp[i]); 1197 tmp = PeekLine(tp[i]);
786 if(tmp == NULL) { 1198 if(tmp == NULL) {
787 continue; 1199 continue;
-   1200 }
-   1201 #if defined ___AmigaOS___
-   1202 if(min == NULL || StrnCmp(locale, tmp, min, -1, SC_ASCII) < 0) {
788 } 1203 #else
-   1204 if(min == NULL || strncmp(tmp, min, strlen(tmp)) < 0) {
789 if(min == NULL || strncmp(tmp, min, strlen(tmp)) < 0) { 1205 #endif
790 if(min != NULL) { 1206 if(min != NULL) {
791 // Free previous instance. 1207 // Free previous instance.
792 free(min); 1208 free(min);
793 } 1209 }
-   1210 if((min = malloc((strlen(tmp) + 1) * sizeof(*min))) == NULL) {
-   1211 fprintf(stderr, "Memory allication failure.\n");
-   1212 free(tmp);
-   1213 if(min != NULL) {
-   1214 free(min);
-   1215 }
-   1216 if(rem != NULL) {
-   1217 free(rem);
-   1218 }
-   1219 #if defined ___AsyncIO___
-   1220 CloseAsync(fp);
-   1221 #else
-   1222 fclose(fp);
-   1223 #endif
-   1224 return;
794 min = malloc((strlen(tmp) + 1) * sizeof(*min)); 1225 }
795 sprintf(min, "%s", tmp); 1226 sprintf(min, "%s", tmp);
796 // Remember the index of the file where the smallest entry has been found. 1227 // Remember the index of the file where the smallest entry has been found.
797 j = i; -  
798 free(tmp); -  
799 continue; 1228 j = i;
800 } 1229 }
801 free(tmp); 1230 free(tmp);
Line 802... Line 1231...
802 } 1231 }
803   1232  
Line 804... Line 1233...
804 // Forward the file where the smallest line was found. 1233 // Forward the file where the smallest line was found.
805 SkipLine(tp[j]); 1234 SkipLine(tp[j]);
-   1235  
-   1236 // Write the smallest line.
-   1237 if(min != NULL) {
-   1238 // If current minimum line is identical to previous minimum line then skip to remove duplicates.
-   1239 if(rem != NULL) {
-   1240 #if defined ___AmigaOS___
-   1241 if(StrnCmp(locale, min, rem, -1, SC_ASCII) == 0) {
-   1242 #else
-   1243 if(strncmp(min, rem, strlen(rem)) == 0 {
-   1244 #endif
-   1245 free(min);
-   1246 continue;
806   1247 }
807 // Write the smallest line. 1248 }
808 if(min != NULL) { 1249  
809 #if defined ___AsyncIO___ 1250 #if defined ___AsyncIO___
810 WriteAsync(fp, min, (LONG)(strlen(min) * sizeof(char))); 1251 WriteAsync(fp, min, (LONG)strlen(min));
811 WriteAsync(fp, "\n", 1 * sizeof(char)); 1252 WriteAsync(fp, "\n", 1);
-   1253 #else
-   1254 fprintf(fp, "%s\n", min);
-   1255 #endif
-   1256  
-   1257 if(rem != NULL) {
-   1258 free(rem);
-   1259 }
-   1260  
-   1261 if((rem = malloc((strlen(min) + 1) * sizeof(*rem))) == NULL) {
-   1262 fprintf(stderr, "Memory allocation failure.\n");
-   1263 free(min);
-   1264 #if defined ___AsyncIO___
-   1265 CloseAsync(fp);
-   1266 #else
-   1267 fclose(fp);
-   1268 #endif
-   1269 return;
812 #else 1270 }
813 fprintf(fp, "%s\n", min); 1271  
814 #endif 1272 sprintf(rem, "%s", min);
Line -... Line 1273...
-   1273 free(min);
-   1274 }
-   1275 }
-   1276  
815 free(min); 1277 if(rem != NULL) {
816 } 1278 free(rem);
817 } 1279 }
818   1280  
819 // Write out any remaining contents from the temporary files. 1281 // Write out any remaining contents from the temporary files.
Line 828... Line 1290...
828 tmp = ReadLine(tp[i]); 1290 tmp = ReadLine(tp[i]);
829 if(tmp == NULL) { 1291 if(tmp == NULL) {
830 continue; 1292 continue;
831 } 1293 }
832 #if defined ___AsyncIO___ 1294 #if defined ___AsyncIO___
833 WriteAsync(fp, tmp, (LONG)(strlen(tmp) * sizeof(char))); 1295 WriteAsync(fp, tmp, (LONG)strlen(tmp));
834 WriteAsync(fp, "\n", 1 * sizeof(char)); 1296 WriteAsync(fp, "\n", 1);
835 #else 1297 #else
836 fprintf(fp, "%s\n", tmp); 1298 fprintf(fp, "%s\n", tmp);
837 #endif 1299 #endif
838 free(tmp); 1300 free(tmp);
839 } 1301 }
Line 857... Line 1319...
857 fclose(fp); 1319 fclose(fp);
858 #endif 1320 #endif
859 } 1321 }
Line 860... Line 1322...
860   1322  
861 /* 1323 /*
862 * 1324 *
863 * Deletes temporary files. 1325 * Filter the paths inside the database with provided paths.
864 */ 1326 */
-   1327 void FilterDatabasePaths(char *dbFile, char *tmpName, char **paths, unsigned int count) {
-   1328 #if defined ___AsyncIO___
865 void DeleteTemporaryFiles(char **tmpNames, int tmpFiles) { 1329 struct AsyncFile *fp;
-   1330 struct AsyncFile *tp;
-   1331 #else
-   1332 FILE *fp;
-   1333 FILE *tp;
-   1334 #endif
-   1335 char *line;
-   1336 int i;
Line -... Line 1337...
-   1337 dbEntry *entry;
-   1338  
-   1339 // Open database file for reading.
866 int i = tmpFiles; 1340 #if defined ___AsyncIO___
-   1341 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
-   1342 #else
867   1343 if((fp = fopen(dbFile, "r")) == NULL) {
-   1344 #endif
868 if(verbose) { 1345 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile);
Line -... Line 1346...
-   1346 return;
-   1347 }
-   1348  
869 fprintf(stdout, "Deleting temporary files...\r"); 1349 // Open temporary file for writing.
870 } 1350 #if defined ___AsyncIO___
871   1351 if((tp = OpenAsync(tmpName, MODE_WRITE, ASYNC_BUF)) == NULL) {
-   1352 #else
Line -... Line 1353...
-   1353 if((tp = fopen(tmpName, "w")) == NULL) {
-   1354 #endif
-   1355 fprintf(stderr, "Unable to open '%s' for writing.\n", tmpName);
-   1356  
872 do { 1357 // Close database file.
-   1358 #if defined ___AsyncIO___
-   1359 CloseAsync(fp);
-   1360 #else
-   1361 fclose(fp);
-   1362 #endif
-   1363  
-   1364 return;
-   1365 }
-   1366  
-   1367 while(run && (line = ReadLine(fp)) != NULL) {
-   1368 #if defined ___AmigaOS___
-   1369 // Check if CTRL+C was pressed and abort the program.
-   1370 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
-   1371 run = FALSE;
-   1372 continue;
-   1373 }
-   1374 #endif
-   1375 if((entry = CreateDataseEntry(line)) == NULL) {
-   1376 fprintf(stderr, "Unable to create database entry.\n");
-   1377 continue;
-   1378 }
-   1379 for(i = 0; i < count; ++i) {
-   1380 if(PathCompare(entry->path, paths[i]) == TRUE) {
873 remove(tmpNames[i]); 1381 continue;
-   1382 }
-   1383 #if defined ___AsyncIO___
-   1384 WriteAsync(tp, line, (LONG)strlen(line));
-   1385 WriteAsync(tp, "\n", 1);
-   1386 #else
-   1387 fprintf(tp, "%s\n", line);
-   1388 #endif
-   1389 break;
874 } while(--i > -1); 1390 }
-   1391  
-   1392 free(entry);
-   1393 free(line);
-   1394 }
-   1395  
-   1396  
-   1397 #if defined ___AsyncIO___
-   1398 CloseAsync(fp);
-   1399 CloseAsync(tp);
875   1400 #else
Line 876... Line 1401...
876 if(verbose) { 1401 fclose(fp);
877 fprintf(stdout, "\n"); 1402 fclose(tp);
878 } 1403 #endif
879 } 1404 }
880   1405  
881 /* -  
882 * 1406 /*
883 * Indexes a "path" by creating a database "dbFile". 1407 *
-   1408 * Indexes a "path" by creating a database "dbFile".
-   1409 */
-   1410 void GatherDatabaseFiles(char *dbFile, char **paths, unsigned int count) {
884 */ 1411 stats *stats;
885 void Gather(char *dbFile, char *path) { 1412 char **tmpNames;
Line 886... Line -...
886 stringStack *stack = stringStackCreate(1); -  
887 stats *stats = malloc(sizeof(stats)); -  
888 char **tmpNames; -  
889 int dbSize, dbLines, tmpFiles, tmpLines; -  
890 int i; 1413 int dbSize;
891   1414 int dbLines;
892 // Initialize metrics. -  
893 stats->dirs = 0; 1415 int tmpFiles;
894 stats->files = 0; 1416 int tmpLines;
895   1417 int i;
896 // Push the first path onto the stack. 1418  
897 stringStackPush(stack, path); -  
898   -  
Line 899... Line 1419...
899 // Generate the database file. 1419 // Generate the database file from the supplied paths.
-   1420 if((stats = CollectFiles(dbFile, paths, count)) == NULL) {
-   1421 fprintf(stderr, "Collecting files failed.\n");
-   1422 return;
-   1423 }
-   1424 free(stats);
900 CollectFiles(dbFile, stack, stats); 1425  
Line 901... Line 1426...
901   1426 // Compute the amount of temporary files needed.
902 // Get the database metrics. 1427 dbSize = GetFileSize(dbFile);
-   1428 if(dbSize == -1) {
903 dbSize = GetFileSize(dbFile); 1429 fprintf(stderr, "File size for '%s' failed.\n", dbFile);
904 dbLines = CountFileLines(dbFile); 1430 return;
905   1431 }
906 // Compute the amount of temporary files needed. 1432 tmpFiles = dbSize / maxmem;
Line -... Line 1433...
-   1433  
-   1434 /* In case no temporary files are required,
-   1435 * just sort the database and terminate.
-   1436 */
-   1437 if(tmpFiles <= 1) {
907 tmpFiles = dbSize / MAX_MEM; 1438 SortDatabase(dbFile);
Line 908... Line 1439...
908   1439 return;
909 // In case no temporary files are required, 1440 }
910 // just sort the database and terminate. 1441  
Line 931... Line 1462...
931   1462  
932 // Merge all the temporary files to the database file. 1463 // Merge all the temporary files to the database file.
Line 933... Line 1464...
933 MergeTemporaryFiles(dbFile, tmpNames, tmpFiles, dbLines); 1464 MergeTemporaryFiles(dbFile, tmpNames, tmpFiles, dbLines);
934   1465  
-   1466 // Remove all temporary files.
-   1467 RemoveFiles(tmpNames, tmpFiles);
-   1468  
-   1469 free(tmpNames);
-   1470 }
-   1471  
-   1472 void RemoveDatabaseFiles(char *dbFile, char **paths, unsigned int count) {
-   1473 char *tmpName;
-   1474  
-   1475 // Create a temporary file to hold the changes.
-   1476 if((tmpName = CreateTemporaryFile()) == NULL) {
-   1477 fprintf(stderr, "Unable to create temporary file.\n");
-   1478 return;
-   1479 }
-   1480  
-   1481 // Filter the database of the provided paths.
-   1482 FilterDatabasePaths(dbFile, tmpName, paths, count);
-   1483  
-   1484 // Overwrite the database file with the filtered paths.
-   1485 CopyFile(tmpName, dbFile);
-   1486  
935 // Remove all temporary files. 1487 // Remove temporary file.
Line 936... Line 1488...
936 DeleteTemporaryFiles(tmpNames, tmpFiles); 1488 RemoveFile(tmpName);
937 } 1489 }
938   1490  
939 void usage(char *name) { -  
940 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name); -  
941 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION); 1491 void usage(char *name) {
-   1492 fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", name);
-   1493 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION);
-   1494 fprintf(stdout, " \n");
-   1495 fprintf(stdout, "SYNTAX: %s [-q] <-a|-r|-c> <PATH PATH PATH...> \n", name);
-   1496 fprintf(stdout, " \n");
-   1497 fprintf(stdout, "Required: \n");
-   1498 fprintf(stdout, " -a [PATH...] Add files (default). \n");
-   1499 fprintf(stdout, " -c [PATH...] Create database from scratch. \n");
-   1500 fprintf(stdout, " -r [PATH...] Remove files. \n");
-   1501 fprintf(stdout, " \n");
942 fprintf(stdout, " \n"); 1502 fprintf(stdout, "Optional: \n");
943 fprintf(stdout, "SYNTAX: %s [-q] DATABASE \n", name); 1503 fprintf(stdout, " -d [FIILE] Where to store the database. \n");
944 fprintf(stdout, " \n"); 1504 fprintf(stdout, " -m BYTES Memory to use (default: %d). \n", maxmem);
945 fprintf(stdout, " -q Do not print out any messages. \n"); 1505 fprintf(stdout, " -q Do not print out any messages. \n");
946 fprintf(stdout, " \n"); 1506 fprintf(stdout, " \n");
947 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n"); 1507 fprintf(stdout, "DATABASE is a path to where the indexed results will be \n");
948 fprintf(stdout, "stored for searching with the Hunt tool. \n"); 1508 fprintf(stdout, "stored for searching with the Hunt tool. \n");
Line 954... Line 1514...
954 * 1514 *
955 * Main entry point. 1515 * Main entry point.
956 */ 1516 */
957 int main(int argc, char **argv) { 1517 int main(int argc, char **argv) {
958 int option; 1518 int option;
-   1519 unsigned int i;
-   1520 unsigned int count;
959 char *dbFile; 1521 char *dbFile;
960 char *path; 1522 char *path;
-   1523 char **paths;
961 struct stat dirStat; 1524 struct stat dirStat;
962 #if defined ___AmigaOS___ -  
963 BPTR lock; -  
964 #endif -  
Line 965... Line 1525...
965   1525  
-   1526 // Bind handler to SIGINT.
966 // Bind handler to SIGINT. 1527 #if !defined ___AmigaOS___
-   1528 signal(SIGINT, SignalHandler);
Line 967... Line 1529...
967 signal(SIGINT, SignalHandler); 1529 #endif
968   1530  
969 dbFile = DEFAULT_DATABASE_FILE; 1531 dbFile = DEFAULT_DATABASE_FILE;
-   1532 while((option = getopt(argc, argv, "hqdm:arc")) != -1) {
-   1533 switch(option) {
-   1534 case 'a':
-   1535 operation = GATHER;
-   1536 break;
-   1537 case 'r':
-   1538 operation = REMOVE;
-   1539 break;
-   1540 case 'c':
-   1541 operation = CREATE;
-   1542 break;
-   1543 case 'm':
970 while((option = getopt(argc, argv, "hqd:")) != -1) { 1544 maxmem = strtoul(optarg, NULL, 10);
971 switch(option) { 1545 break;
972 case 'd': 1546 case 'd':
973 dbFile = optarg; 1547 dbFile = optarg;
974 break; 1548 break;
Line 982... Line 1556...
982 fprintf(stderr, "Invalid option %ct.\n", optopt); 1556 fprintf(stderr, "Invalid option %ct.\n", optopt);
983 return 1; 1557 return 1;
984 } 1558 }
985 } 1559 }
Line -... Line 1560...
-   1560  
-   1561 if(operation == NONE) {
-   1562 usage(argv[0]);
-   1563 return 1;
Line 986... Line 1564...
986   1564 }
987   1565  
988 if(optind >= argc) { 1566 if(optind >= argc) {
989 usage(argv[0]); 1567 usage(argv[0]);
Line 990... Line -...
990 return 1; -  
991 } 1568 return 1;
992   -  
993 #if defined ___AmigaOS___ -  
994 path = malloc(PATH_MAX * sizeof(*path)); -  
995 lock = Lock(argv[optind], SHARED_LOCK); -  
996 NameFromLock(lock, path, PATH_MAX); 1569 }
997 UnLock(lock); -  
998 #else -  
999 path = realpath(argv[optind], NULL); -  
1000 #endif -  
1001   1570  
1002 stat(path, &dirStat); 1571 // Go through all supplied arguments and add paths to search.
1003 if(!S_ISDIR(dirStat.st_mode)) { 1572 if((paths = malloc((argc - optind) * sizeof(*paths))) == NULL) {
-   1573 fprintf(stderr, "Memory allocation failure.\n");
-   1574 return 1;
-   1575 }
-   1576 for(i = optind, count = 0; i < argc; ++i, ++count) {
-   1577 if((path = PathToAbsolute(argv[optind])) == NULL) {
-   1578 fprintf(stderr, "Absolute path for '%s' failed to resolve.\n", argv[optind]);
-   1579 continue;
-   1580 }
-   1581  
-   1582 // Check that the path is a directory.
-   1583 stat(path, &dirStat);
-   1584 if(!S_ISDIR(dirStat.st_mode)) {
-   1585 fprintf(stderr, "Path '%s' is not a directory.\n", argv[optind]);
-   1586 free(path);
-   1587 return 1;
-   1588 }
-   1589  
-   1590 if(verbose) {
-   1591 fprintf(stdout, "Will process path: '%s'\n", path);
-   1592 }
-   1593  
-   1594 // Add the path to the array of paths.
-   1595 if((paths[count] = malloc(strlen(path) * sizeof(*paths[count]))) == NULL) {
-   1596 fprintf(stderr, "Memory allocation failure.");
-   1597 return 1;
-   1598 }
Line 1004... Line 1599...
1004 fprintf(stderr, "Path '%s' is not a directory.\n", argv[optind]); 1599 sprintf(paths[count], "%s", path);
1005 return 1; 1600 free(path);
1006 } 1601 }
Line -... Line 1602...
-   1602  
-   1603 if(verbose) {
-   1604 fprintf(stdout, "Gathering to: '%s'\n", dbFile);
-   1605 }
1007   1606  
-   1607 #if defined ___AmigaOS___
-   1608 locale = OpenLocale(NULL);
-   1609 #endif
-   1610  
-   1611 // Gather.
1008 if(verbose) { 1612 switch(operation) {
-   1613 case CREATE:
-   1614 if(verbose) {
-   1615 fprintf(stdout, "Removing '%s' and creating a new database.\n", dbFile);
-   1616 }
-   1617 RemoveFile(dbFile);
-   1618 case GATHER:
-   1619 if(verbose) {
-   1620 fprintf(stdout, "Gathering files to database...\n");
-   1621 }
-   1622 GatherDatabaseFiles(dbFile, paths, count);
-   1623 break;
-   1624 case REMOVE:
-   1625 if(verbose) {
-   1626 fprintf(stdout, "Removing files from database...\n");
-   1627 }
-   1628 RemoveDatabaseFiles(dbFile, paths, count);
-   1629 break;
-   1630 default:
-   1631 break;
Line 1009... Line 1632...
1009 fprintf(stdout, "Gathering to %s\n", dbFile); 1632 }
Line 1010... Line 1633...
1010 } 1633  
1011   1634 #if defined ___AmigaOS___