HuntnGather – Diff between revs 24 and 26
?pathlinks?
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 | } |
|
- | 155 | |
||
- | 156 | /* |
||
- | 157 | * |
||
- | 158 | * Gets the size of a file by name. |
||
- | 159 | */ |
||
- | 160 | int GetFileSize(char *dbFile) { |
||
- | 161 | #if defined ___AsyncIO___ |
||
- | 162 | struct AsyncFile *fp; |
||
- | 163 | LONG size; |
||
- | 164 | #else |
||
- | 165 | FILE *fp; |
||
- | 166 | int size; |
||
- | 167 | #endif |
||
- | 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 |
||
- | 189 | return -1; |
||
- | 190 | } |
||
- | 191 | #if defined ___AsyncIO___ |
||
- | 192 | if((size = SeekAsync(fp, 0, MODE_CURRENT)) == -1) { |
||
- | 193 | fprintf(stderr, "Seek in file %s failed.\n", dbFile); |
||
- | 194 | CloseAsync(fp); |
||
- | 195 | return -1; |
||
- | 196 | } |
||
- | 197 | #else |
||
- | 198 | size = ftell(fp); |
||
- | 199 | #endif |
||
- | 200 | |
||
- | 201 | #if defined ___AsyncIO___ |
||
- | 202 | CloseAsync(fp); |
||
- | 203 | #else |
||
- | 204 | fclose(fp); |
||
- | 205 | #endif |
||
- | 206 | |
||
- | 207 | return size; |
||
- | 208 | } |
||
71 | |
209 | |
|
72 | /* |
210 | /* |
|
73 | * |
211 | * |
|
74 | * Sorts a database file lexicographically. |
212 | * Counts the lines of a file. |
|
75 | */ |
213 | */ |
|
76 | void SortDatabase(char *dbFile) { |
214 | int CountFileLines(char *dbFile) { |
|
77 | #if defined ___AsyncIO___ |
215 | #if defined ___AsyncIO___ |
|
78 | struct AsyncFile *fp; |
- | ||
79 | LONG c; |
- | ||
80 | #else |
- | ||
81 | FILE *fp; |
- | ||
82 | char c; |
216 | struct AsyncFile *fp; |
|
83 | #endif |
- | ||
84 | char *name = NULL; |
- | ||
85 | char *path = NULL; |
- | ||
Line 86... | Line -... | |||
86 | char **database; |
- | ||
87 | int i; |
217 | LONG c; |
|
88 | int side; |
218 | #else |
|
89 | unsigned int line; |
219 | FILE *fp; |
|
90 | int name_size; |
220 | char c; |
|
91 | int path_size; |
221 | #endif |
|
92 | |
222 | int lines; |
|
93 | // Open database file for reading. |
223 | |
|
- | 224 | #if defined ___AsyncIO___ |
||
- | 225 | if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { |
||
- | 226 | #else |
||
- | 227 | if((fp = fopen(dbFile, "r")) == NULL) { |
||
- | 228 | #endif |
||
- | 229 | fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); |
||
- | 230 | return -1; |
||
- | 231 | } |
||
- | 232 | |
||
- | 233 | lines = 0; |
||
- | 234 | #if defined ___AsyncIO___ |
||
- | 235 | while(run && (c = ReadCharAsync(fp)) != -1) { |
||
- | 236 | #else |
||
- | 237 | while(run && fscanf(fp, "%c", &c) == 1) { |
||
- | 238 | #endif |
||
- | 239 | #if defined ___AmigaOS___ |
||
- | 240 | // Check if CTRL+C was pressed and abort the program. |
||
- | 241 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
||
- | 242 | run = FALSE; |
||
- | 243 | continue; |
||
94 | #if defined ___AsyncIO___ |
244 | } |
|
Line 95... | Line 245... | |||
95 | if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { |
245 | #endif |
|
96 | #else |
246 | switch(c) { |
|
97 | if((fp = fopen(dbFile, "r")) == NULL) { |
247 | case '\n': |
|
98 | #endif |
248 | ++lines; |
|
99 | fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); |
249 | break; |
|
Line -... | Line 250... | |||
- | 250 | } |
||
- | 251 | } |
||
- | 252 | |
||
- | 253 | #if defined ___AsyncIO___ |
||
- | 254 | CloseAsync(fp); |
||
- | 255 | #else |
||
- | 256 | fclose(fp); |
||
- | 257 | #endif |
||
100 | return; |
258 | |
|
- | 259 | return lines; |
||
- | 260 | } |
||
- | 261 | |
||
101 | } |
262 | /* |
|
- | 263 | * |
||
- | 264 | * Creates a temporary file and returns its name. |
||
- | 265 | */ |
||
- | 266 | char *CreateTemporaryFile(void) { |
||
- | 267 | char *name; |
||
- | 268 | |
||
- | 269 | name = tmpnam(NULL); |
||
- | 270 | |
||
102 | |
271 | return name; |
|
- | 272 | } |
||
- | 273 | |
||
- | 274 | /* |
||
- | 275 | * |
||
- | 276 | * Create multiple temporary files and return their names. |
||
Line 103... | Line 277... | |||
103 | database = malloc(sizeof(*database)); |
277 | */ |
|
104 | name_size = NAME_BUF; |
278 | char **CreateTemporaryFiles(int files) { |
|
105 | name = malloc(name_size * sizeof(*name)); |
279 | char **tmpNames; |
|
Line -... | Line 280... | |||
- | 280 | int count; |
||
- | 281 | |
||
- | 282 | if((tmpNames = malloc(files * sizeof(*tmpNames))) == NULL) { |
||
- | 283 | fprintf(stderr, "Memory allocation failure.\n"); |
||
- | 284 | return NULL; |
||
- | 285 | } |
||
- | 286 | |
||
- | 287 | if(verbose) { |
||
- | 288 | fprintf(stdout, "Creating temporary files...\r"); |
||
- | 289 | } |
||
- | 290 | |
||
- | 291 | count = files; |
||
- | 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 | |
||
- | 302 | if(verbose) { |
||
- | 303 | fprintf(stdout, "Creating temporary files: %d%%\r", 100 - (int)(((float)count / files) * 100.0)); |
||
- | 304 | } |
||
- | 305 | } |
||
- | 306 | |
||
- | 307 | if(verbose) { |
||
106 | path_size = PATH_BUF; |
308 | fprintf(stdout, "\n"); |
|
- | 309 | } |
||
- | 310 | |
||
107 | path = malloc(path_size * sizeof(*path)); |
311 | return tmpNames; |
|
108 | |
312 | } |
|
- | 313 | |
||
- | 314 | |
||
109 | line = 0; |
315 | /* |
|
110 | side = 0; |
316 | * |
|
111 | i = 0; |
317 | * Skips a line in a file. |
|
112 | |
318 | */ |
|
113 | if(verbose) { |
319 | #if defined ___AsyncIO___ |
|
Line 126... | Line 332... | |||
126 | continue; |
332 | continue; |
|
127 | } |
333 | } |
|
128 | #endif |
334 | #endif |
|
129 | switch(c) { |
335 | switch(c) { |
|
130 | case '\n': |
336 | case '\n': |
|
- | 337 | return; |
||
- | 338 | } |
||
- | 339 | } |
||
- | 340 | } |
||
- | 341 | |
||
- | 342 | /* |
||
- | 343 | * |
||
131 | // Load up the name and path into the database variable. |
344 | * Peeks at a line from a file. |
|
- | 345 | */ |
||
132 | database = realloc(database, (line + 1) * sizeof(*database)); |
346 | #if defined ___AsyncIO___ |
|
133 | database[line] = malloc((strlen(name) + strlen(path) + 1 + 1) * sizeof(*database[line])); |
347 | char *PeekLine(struct AsyncFile *fp) { |
|
- | 348 | LONG c; |
||
- | 349 | #else |
||
134 | sprintf(database[line], "%s\t%s", name, path); |
350 | char *PeekLine(FILE *fp) { |
|
- | 351 | char c; |
||
- | 352 | #endif |
||
135 | ++line; |
353 | char *line; |
|
- | 354 | unsigned int size; |
||
- | 355 | int i; |
||
136 | |
356 | |
|
137 | free(name); |
- | ||
138 | name_size = NAME_BUF; |
357 | size = LINE_BUF; |
|
139 | name = malloc(name_size * sizeof(*name)); |
358 | if((line = malloc(size * sizeof(*line))) == NULL) { |
|
- | 359 | fprintf(stderr, "Memory allocation failure.\n"); |
||
140 | --side; |
360 | return NULL; |
|
141 | i = 0; |
361 | } |
|
Line 142... | Line -... | |||
142 | |
- | ||
143 | break; |
- | ||
144 | case '\t': |
- | ||
145 | free(path); |
- | ||
146 | path_size = PATH_BUF; |
- | ||
147 | path = malloc(path_size * sizeof(*path)); |
- | ||
148 | ++side; |
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) { |
||
149 | i = 0; |
381 | fprintf(stderr, "Could not seek in file.\n"); |
|
- | 382 | free(line); |
||
- | 383 | return NULL; |
||
- | 384 | } |
||
- | 385 | #else |
||
- | 386 | fseek(fp, -(i + 1), SEEK_CUR); |
||
- | 387 | #endif |
||
150 | break; |
388 | return line; |
|
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: |
389 | default: |
|
163 | if(strlen(path) == path_size) { |
390 | if(strlen(line) == size) { |
|
164 | path_size = path_size * 1.5; |
391 | size = size * 1.5; |
|
165 | path = realloc(path, path_size * sizeof(*path)); |
392 | line = realloc(line, size * sizeof(*line)); |
|
166 | } |
- | ||
167 | //path = realloc(path, (i + 1 + 1) * sizeof(char)); |
393 | } |
|
168 | path[i] = c; |
394 | line[i] = c; |
|
169 | path[i + 1] = '\0'; |
395 | line[i + 1] = '\0'; |
|
- | 396 | break; |
||
- | 397 | } |
||
- | 398 | ++i; |
||
- | 399 | } |
||
- | 400 | |
||
- | 401 | return NULL; |
||
- | 402 | } |
||
- | 403 | |
||
- | 404 | /* |
||
- | 405 | * |
||
- | 406 | * Read a line from a file. |
||
- | 407 | */ |
||
- | 408 | #if defined ___AsyncIO___ |
||
- | 409 | char *ReadLine(struct AsyncFile *fp) { |
||
- | 410 | LONG c; |
||
- | 411 | #else |
||
- | 412 | char *ReadLine(FILE *fp) { |
||
- | 413 | char c; |
||
- | 414 | #endif |
||
- | 415 | char *line; |
||
- | 416 | unsigned int size; |
||
- | 417 | unsigned int i; |
||
- | 418 | |
||
- | 419 | size = LINE_BUF; |
||
- | 420 | if((line = malloc(size * sizeof(*line))) == NULL) { |
||
- | 421 | fprintf(stderr, "Memory allication failure.\n"); |
||
- | 422 | return NULL; |
||
- | 423 | } |
||
- | 424 | |
||
- | 425 | i = 0; |
||
- | 426 | #if defined ___AsyncIO___ |
||
- | 427 | while(run && (c = ReadCharAsync(fp)) != -1) { |
||
- | 428 | #else |
||
- | 429 | while(run && fscanf(fp, "%c", &c) == 1) { |
||
- | 430 | #endif |
||
- | 431 | #if defined ___AmigaOS___ |
||
- | 432 | // Check if CTRL+C was pressed and abort the program. |
||
- | 433 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
||
- | 434 | run = FALSE; |
||
- | 435 | continue; |
||
- | 436 | } |
||
- | 437 | #endif |
||
- | 438 | switch(c) { |
||
- | 439 | case '\n': |
||
170 | break; |
440 | return line; |
|
- | 441 | default: |
||
- | 442 | if(strlen(line) == size) { |
||
171 | default: |
443 | size = size * 1.5; |
|
- | 444 | line = realloc(line, size * sizeof(*line)); |
||
- | 445 | } |
||
- | 446 | line[i] = c; |
||
172 | fprintf(stderr, "File '%s' is corrupted.\n", dbFile); |
447 | line[i + 1] = '\0'; |
|
173 | break; |
448 | break; |
|
174 | } |
449 | } |
|
175 | ++i; |
- | ||
176 | break; |
450 | ++i; |
|
- | 451 | } |
||
- | 452 | |
||
177 | } |
453 | return NULL; |
|
Line -... | Line 454... | |||
- | 454 | } |
||
- | 455 | |
||
- | 456 | /* |
||
- | 457 | * |
||
- | 458 | * Delete a file. |
||
- | 459 | */ |
||
- | 460 | #if defined ___AmigaOS___ |
||
- | 461 | BOOL RemoveFile(char *name) { |
||
- | 462 | return DeleteFile(name); |
||
- | 463 | #else |
||
- | 464 | int RemoveFile(char *name) { |
||
- | 465 | return remove(name) == 0; |
||
- | 466 | #endif |
||
- | 467 | } |
||
- | 468 | |
||
- | 469 | /* |
||
- | 470 | * |
||
- | 471 | * Deletes files. |
||
- | 472 | */ |
||
- | 473 | void RemoveFiles(char **names, int count) { |
||
- | 474 | unsigned int i; |
||
- | 475 | for(i = 0; i < count; ++i) { |
||
- | 476 | if(RemoveFile(names[i]) == FALSE) { |
||
- | 477 | fprintf(stderr, "Unable to remove %s...\n", names[i]); |
||
- | 478 | continue; |
||
- | 479 | } |
||
- | 480 | fprintf(stderr, "Removing file: %s\n", names[i]); |
||
- | 481 | } |
||
- | 482 | } |
||
- | 483 | |
||
- | 484 | /* |
||
- | 485 | * |
||
- | 486 | * Copies a file to another file by name. |
||
178 | } |
487 | */ |
|
- | 488 | void CopyFile(char *a, char *b) { |
||
179 | |
489 | #if defined ___AsyncIO___ |
|
- | 490 | struct AsyncFile *ap; |
||
180 | #if defined ___AsyncIO___ |
491 | struct AsyncFile *bp; |
|
- | 492 | LONG c; |
||
181 | CloseAsync(fp); |
493 | #else |
|
- | 494 | FILE *ap; |
||
182 | #else |
495 | FILE *bp; |
|
Line 183... | Line -... | |||
183 | fclose(fp); |
- | ||
184 | #endif |
- | ||
Line 185... | Line 496... | |||
185 | |
496 | char c; |
|
186 | // Sort the database. |
497 | #endif |
|
187 | qsort(database, line, sizeof(char *), compare); |
498 | |
|
188 | |
499 | |
|
189 | // Write the database lines back to the database. |
500 | // Open database file for writing. |
|
190 | #if defined ___AsyncIO___ |
501 | #if defined ___AsyncIO___ |
|
191 | if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { |
502 | if((ap = OpenAsync(a, MODE_READ, ASYNC_BUF)) == NULL) { |
|
192 | #else |
503 | #else |
|
193 | if((fp = fopen(dbFile, "w")) == NULL) { |
504 | if((ap = fopen(a, "r")) == NULL) { |
|
Line -... | Line 505... | |||
- | 505 | #endif |
||
- | 506 | fprintf(stderr, "Unable to open '%s' for reading.\n", a); |
||
- | 507 | return; |
||
- | 508 | } |
||
194 | #endif |
509 | |
|
- | 510 | // Open temporary file for reading. |
||
- | 511 | #if defined ___AsyncIO___ |
||
- | 512 | if((bp = OpenAsync(b, MODE_WRITE, ASYNC_BUF)) == NULL) { |
||
- | 513 | #else |
||
- | 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. |
||
- | 519 | #if defined ___AsyncIO___ |
||
- | 520 | CloseAsync(ap); |
||
- | 521 | #else |
||
- | 522 | fclose(ap); |
||
- | 523 | #endif |
||
- | 524 | |
||
- | 525 | return; |
||
- | 526 | } |
||
- | 527 | |
||
195 | fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); |
528 | #if defined ___AsyncIO___ |
|
196 | return; |
529 | while(run && (c = ReadCharAsync(ap)) != -1) { |
|
197 | } |
530 | #else |
|
198 | |
531 | while(run && fscanf(ap, "%c", &c) == 1) { |
|
199 | for(i = 0; i < line; ++i) { |
532 | #endif |
|
200 | #if defined ___AmigaOS___ |
533 | #if defined ___AmigaOS___ |
|
201 | // Check if CTRL+C was pressed and abort the program. |
534 | // Check if CTRL+C was pressed and abort the program. |
|
202 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
535 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
|
203 | run = FALSE; |
- | ||
204 | continue; |
536 | run = FALSE; |
|
205 | } |
537 | continue; |
|
206 | #endif |
538 | } |
|
207 | #if defined ___AsyncIO___ |
539 | #endif |
|
- | 540 | #if defined ___AsyncIO___ |
||
- | 541 | if(WriteCharAsync(bp, (UBYTE)c) != 1) { |
||
- | 542 | #else |
||
208 | WriteAsync(fp, database[i], (LONG)(strlen(database[i]) * sizeof(char))); |
543 | if(fprintf(bp, "%c", c) != 1) { |
|
Line 209... | Line 544... | |||
209 | WriteAsync(fp, "\n", 1 * sizeof(char)); |
544 | #endif |
|
- | 545 | fprintf(stderr, "Unable to write to '%s'.\n", b); |
||
210 | #else |
546 | break; |
|
211 | fprintf(fp, "%s\n", database[i]); |
547 | } |
|
- | 548 | } |
||
212 | #endif |
549 | |
|
213 | } |
550 | #if defined ___AsyncIO___ |
|
214 | |
- | ||
215 | #if defined ___AsyncIO___ |
- | ||
216 | CloseAsync(fp); |
551 | CloseAsync(ap); |
|
Line 217... | Line 552... | |||
217 | #else |
552 | CloseAsync(bp); |
|
218 | fclose(fp); |
553 | #else |
|
219 | #endif |
554 | fclose(ap); |
|
220 | |
555 | fclose(bp); |
|
221 | free(database); |
556 | #endif |
|
222 | } |
557 | } |
|
223 | |
558 | |
|
224 | /* |
559 | /* |
|
225 | * |
560 | * |
|
226 | * Updates a database file "dbFile". |
561 | * Write lines to a file. |
|
227 | */ |
562 | */ |
|
228 | void CollectFiles(char *dbFile, stringStack *dirStack, stats *stats) { |
- | ||
229 | #if defined ___AsyncIO___ |
- | ||
230 | struct AsyncFile *fp; |
- | ||
231 | #else |
563 | void WriteLinesToFile(char *dbFile, char **lines, unsigned int count) { |
|
232 | FILE *fp; |
- | ||
Line -... | Line 564... | |||
- | 564 | #if defined ___AsyncIO___ |
||
233 | #endif |
565 | struct AsyncFile *fp; |
|
234 | DIR *dir; |
566 | #else |
|
235 | struct dirent *dirEntry; |
567 | FILE *fp; |
|
236 | struct stat dirStat; |
568 | #endif |
|
237 | unsigned int size; |
569 | int i; |
|
238 | char *path; |
570 | char *rem; |
|
239 | char *subPath; |
571 | |
|
240 | |
572 | // Write the database lines back to the database. |
|
Line 241... | Line 573... | |||
241 | #if defined ___AsyncIO___ |
573 | #if defined ___AsyncIO___ |
|
242 | if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { |
- | ||
243 | #else |
- | ||
244 | if((fp = fopen(dbFile, "w")) == NULL) { |
- | ||
245 | #endif |
574 | if((fp = OpenAsync(dbFile, MODE_WRITE, ASYNC_BUF)) == NULL) { |
|
246 | fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); |
575 | #else |
|
247 | return; |
576 | if((fp = fopen(dbFile, "w")) == NULL) { |
|
248 | } |
577 | #endif |
|
249 | |
578 | fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); |
|
250 | if(verbose) { |
579 | return; |
|
251 | fprintf(stdout, "Collecting files...\r"); |
580 | } |
|
252 | } |
581 | |
|
253 | |
- | ||
254 | while(run && !stringStackIsEmpty(dirStack)) { |
- | ||
255 | #if defined ___AmigaOS___ |
- | ||
Line 256... | Line 582... | |||
256 | // Check if CTRL+C was pressed and abort the program. |
582 | rem = NULL; |
|
257 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
- | ||
258 | run = FALSE; |
- | ||
259 | continue; |
- | ||
260 | } |
- | ||
261 | #endif |
- | ||
262 | if((path = stringStackPop(dirStack)) == NULL) { |
583 | for(i = 0; i < count; ++i) { |
|
263 | return; |
584 | #if defined ___AmigaOS___ |
|
- | 585 | // Check if CTRL+C was pressed and abort the program. |
||
264 | } |
586 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
|
265 | |
587 | run = FALSE; |
|
266 | if((dir = opendir(path)) == NULL) { |
588 | continue; |
|
267 | fprintf(stderr, "Unable to open '%s' for reading.\n", path); |
589 | } |
|
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. |
- | ||
274 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
- | ||
275 | run = FALSE; |
- | ||
276 | continue; |
- | ||
277 | } |
- | ||
278 | #endif |
- | ||
279 | size = sizeof(path) + sizeof(dirEntry->d_name) + 1; |
- | ||
280 | switch(path[strlen(path) - 1]) { |
590 | #endif |
|
281 | case '/': |
- | ||
282 | case ':': // This is a drive path. |
- | ||
283 | subPath = malloc(size); |
- | ||
Line -... | Line 591... | |||
- | 591 | |
||
- | 592 | if(rem != NULL) { |
||
284 | sprintf(subPath, "%s%s", path, dirEntry->d_name); |
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) { |
||
Line 285... | Line 597... | |||
285 | break; |
597 | #endif |
|
286 | default: |
598 | continue; |
|
287 | subPath = malloc(size + 1); |
- | ||
288 | sprintf(subPath, "%s/%s", path, dirEntry->d_name); |
- | ||
289 | break; |
- | ||
290 | } |
599 | } |
|
Line 291... | Line 600... | |||
291 | stat(subPath, &dirStat); |
600 | } |
|
292 | if(S_ISDIR(dirStat.st_mode)) { |
601 | |
|
293 | stringStackPush(dirStack, subPath); |
602 | #if defined ___AsyncIO___ |
|
Line 294... | Line -... | |||
294 | |
- | ||
295 | ++stats->dirs; |
- | ||
296 | |
- | ||
297 | if(verbose) { |
- | ||
298 | fprintf(stdout, |
- | ||
299 | "Gathered %d directories and %d files.\r", |
- | ||
300 | stats->dirs, |
603 | WriteAsync(fp, lines[i], (LONG)strlen(lines[i])); |
|
301 | stats->files); |
- | ||
302 | } |
- | ||
303 | |
- | ||
304 | free(subPath); |
604 | WriteAsync(fp, "\n", 1); |
|
305 | continue; |
605 | #else |
|
306 | } |
606 | fprintf(fp, "%s\n", lines[i]); |
|
307 | |
607 | #endif |
|
308 | // Write to database file. |
- | ||
309 | |
- | ||
310 | #if defined ___NOCASE_FS___ |
- | ||
311 | strupr(dirEntry->d_name); |
- | ||
312 | #endif |
- | ||
313 | |
- | ||
314 | #if defined ___AsyncIO___ |
- | ||
315 | WriteAsync(fp, dirEntry->d_name, (LONG)(strlen(dirEntry->d_name) * sizeof(char))); |
608 | |
|
Line -... | Line 609... | |||
- | 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 |
||
316 | WriteAsync(fp, "\t", 1 * sizeof(char)); |
622 | } |
|
317 | WriteAsync(fp, subPath, (LONG)(strlen(subPath) * sizeof(char))); |
623 | |
|
Line -... | Line 624... | |||
- | 624 | /* |
||
318 | WriteAsync(fp, "\n", 1 * sizeof(char)); |
625 | * |
|
319 | #else |
626 | * Create a database entry from a line of text. |
|
320 | fprintf(fp, "%s\t%s\n", dirEntry->d_name, subPath); |
627 | */ |
|
Line -... | Line 628... | |||
- | 628 | dbEntry* CreateDataseEntry(char *line) { |
||
321 | #endif |
629 | dbEntry *entry; |
|
322 | ++stats->files; |
630 | char *ptr; |
|
323 | |
631 | unsigned int side; |
|
Line -... | Line 632... | |||
- | 632 | unsigned int i; |
||
324 | if(verbose) { |
633 | unsigned int j; |
|
- | 634 | |
||
- | 635 | if((entry = malloc(1 * sizeof(*entry))) == NULL) { |
||
325 | fprintf(stdout, |
636 | fprintf(stderr, "Memory allocation failure.\n"); |
|
326 | "Gathered %d directories and %d files.\r", |
637 | return NULL; |
|
327 | stats->dirs, |
638 | } |
|
328 | stats->files); |
639 | |
|
- | 640 | if((entry->name = malloc(strlen(line) * sizeof(*entry->name))) == NULL) { |
||
- | 641 | fprintf(stderr, "Memory allocation failure.\n"); |
||
- | 642 | return NULL; |
||
- | 643 | } |
||
- | 644 | |
||
- | 645 | if((entry->path = malloc(strlen(line) * sizeof(*entry->path))) == NULL) { |
||
- | 646 | fprintf(stderr, "Memory allocation failure.\n"); |
||
- | 647 | return NULL; |
||
- | 648 | } |
||
- | 649 | |
||
- | 650 | for(ptr = line, side = 0, i = 0, j = 0; run && *ptr != '\0'; ++ptr) { |
||
- | 651 | #if defined ___AmigaOS___ |
||
- | 652 | // Check if CTRL+C was pressed and abort the program. |
||
- | 653 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
||
- | 654 | run = FALSE; |
||
- | 655 | continue; |
||
- | 656 | } |
||
- | 657 | #endif |
||
- | 658 | switch(*ptr) { |
||
- | 659 | case '\t': |
||
Line -... | Line 660... | |||
- | 660 | entry->name[i] = '\0'; |
||
329 | } |
661 | ++side; |
|
Line 330... | Line 662... | |||
330 | |
662 | break; |
|
331 | free(subPath); |
663 | case '\n': |
|
332 | } |
- | ||
- | 664 | entry->path[j] = '\0'; |
||
333 | |
665 | return entry; |
|
334 | closedir(dir); |
666 | default: |
|
335 | free(path); |
667 | switch(side) { |
|
336 | } |
668 | case 0: |
|
337 | |
- | ||
338 | if(verbose) { |
669 | entry->name[i++] = *ptr; |
|
339 | fprintf(stdout, "\n"); |
670 | break; |
|
340 | } |
- | ||
341 | |
671 | case 1: |
|
- | 672 | entry->path[j++] = *ptr; |
||
- | 673 | break; |
||
- | 674 | } |
||
- | 675 | break; |
||
- | 676 | } |
||
- | 677 | } |
||
- | 678 | |
||
- | 679 | return entry; |
||
- | 680 | } |
||
Line -... | Line 681... | |||
- | 681 | |
||
342 | #if defined ___AsyncIO___ |
682 | /* |
|
343 | CloseAsync(fp); |
683 | * |
|
344 | #else |
684 | * |
|
345 | fclose(fp); |
685 | */ |
|
346 | #endif |
686 | dbArray *GetDatabaseArray(char *dbFile) { |
|
347 | |
687 | #if defined ___AsyncIO___ |
|
348 | } |
688 | struct AsyncFile *fp; |
|
349 | |
689 | #else |
|
Line -... | Line 690... | |||
- | 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) { |
||
- | 698 | fprintf(stderr, "Memory allocation failure.\n"); |
||
- | 699 | return NULL; |
||
- | 700 | } |
||
350 | /* |
701 | |
|
351 | * |
702 | // Open database file for reading. |
|
352 | * Gets the size of a file "dbFle". |
- | ||
353 | */ |
703 | #if defined ___AsyncIO___ |
|
354 | int GetFileSize(char *dbFile) { |
- | ||
355 | #if defined ___AsyncIO___ |
704 | if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { |
|
356 | struct AsyncFile *fp; |
705 | #else |
|
- | 706 | if((fp = fopen(dbFile, "r")) == NULL) { |
||
- | 707 | #endif |
||
Line -... | Line 708... | |||
- | 708 | fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); |
||
- | 709 | return NULL; |
||
- | 710 | } |
||
- | 711 | |
||
- | 712 | count = 0; |
||
- | 713 | while(run && (line = ReadLine(fp)) != NULL) { |
||
357 | LONG size; |
714 | #if defined ___AmigaOS___ |
|
358 | #else |
715 | // Check if CTRL+C was pressed and abort the program. |
|
359 | FILE *fp; |
716 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
|
360 | int size; |
717 | run = FALSE; |
|
361 | #endif |
718 | continue; |
|
- | 719 | } |
||
- | 720 | #endif |
||
- | 721 | if((entry = CreateDataseEntry(line)) == NULL) { |
||
- | 722 | fprintf(stderr, "Unable to create database entry.\n"); |
||
Line -... | Line 723... | |||
- | 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. |
||
- | 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) { |
||
362 | |
734 | fprintf(stderr, "Memory allocation failure.\n"); |
|
363 | #if defined ___AsyncIO___ |
735 | free(entry); |
|
Line 364... | Line 736... | |||
364 | if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { |
736 | free(line); |
|
365 | #else |
737 | #if defined ___AsyncIO___ |
|
366 | if((fp = fopen(dbFile, "r")) == NULL) { |
738 | CloseAsync(fp); |
|
367 | #endif |
739 | #else |
|
368 | fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); |
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 | |
||
- | 757 | array->count = count; |
||
- | 758 | return array; |
||
- | 759 | } |
||
- | 760 | |
||
- | 761 | /* |
||
- | 762 | * |
||
- | 763 | * Sorts a database file lexicographically. |
||
- | 764 | */ |
||
- | 765 | void SortDatabase(char *dbFile) { |
||
- | 766 | dbArray *array; |
||
369 | return 0; |
767 | |
|
370 | } |
768 | if(verbose) { |
|
371 | |
- | ||
372 | #if defined ___AsyncIO___ |
769 | fprintf(stdout, "Sorting '%s'...\n", dbFile); |
|
373 | SeekAsync(fp, 0, MODE_END); |
770 | } |
|
374 | size = SeekAsync(fp, 0, MODE_CURRENT); |
- | ||
375 | #else |
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 | } |
||
- | 777 | |
||
376 | fseek(fp, 0L, SEEK_END); |
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". |
||
Line 377... | Line 790... | |||
377 | size = ftell(fp); |
790 | */ |
|
378 | #endif |
791 | stats *CollectFiles(char *dbFile, char **paths, unsigned int count) { |
|
379 | |
792 | #if defined ___AsyncIO___ |
|
380 | #if defined ___AsyncIO___ |
793 | struct AsyncFile *fp; |
|
381 | CloseAsync(fp); |
794 | #else |
|
382 | #else |
795 | FILE *fp; |
|
383 | fclose(fp); |
796 | #endif |
|
384 | #endif |
797 | stringStack *stack; |
|
Line 385... | Line 798... | |||
385 | |
798 | stats *stats; |
|
386 | return size; |
799 | DIR *dir; |
|
387 | } |
800 | struct dirent *entry; |
|
388 | |
801 | struct stat dirStat; |
|
389 | /* |
802 | unsigned int size; |
|
390 | * |
803 | int i; |
|
- | 804 | char *path; |
||
- | 805 | char *subPath; |
||
- | 806 | |
||
- | 807 | // Initialize metrics. |
||
- | 808 | if((stats = malloc(sizeof(stats))) == NULL) { |
||
- | 809 | fprintf(stderr, "Memory allocation failure.\n"); |
||
- | 810 | return NULL; |
||
- | 811 | } |
||
- | 812 | |
||
- | 813 | stats->dirs = 0; |
||
- | 814 | stats->files = 0; |
||
- | 815 | |
||
- | 816 | #if defined ___AsyncIO___ |
||
- | 817 | if((fp = OpenAsync(dbFile, MODE_APPEND, ASYNC_BUF)) == NULL) { |
||
- | 818 | #else |
||
- | 819 | if((fp = fopen(dbFile, "r+")) == NULL) { |
||
- | 820 | #endif |
||
- | 821 | fprintf(stderr, "Unable to open '%s' for writing.\n", dbFile); |
||
- | 822 | return stats; |
||
- | 823 | } |
||
391 | * Counts the lines of a file. |
824 | |
|
392 | */ |
825 | // Seek to the end of the database. |
|
393 | int CountFileLines(char *dbFile) { |
826 | #if defined ___AsyncIO___ |
|
394 | #if defined ___AsyncIO___ |
827 | if(SeekAsync(fp, 0, MODE_END) == -1) { |
|
395 | struct AsyncFile *fp; |
828 | #else |
|
396 | LONG c; |
829 | if(fseek(fp, 0, SEEK_END) == 0) { |
|
397 | #else |
830 | #endif |
|
398 | FILE *fp; |
831 | fprintf(stderr, "Unable to seek in '%s' for appending.\n", dbFile); |
|
399 | char c; |
- | ||
400 | #endif |
- | ||
401 | int lines; |
832 | #if defined ___AsyncIO___ |
|
402 | |
833 | CloseAsync(fp); |
|
- | 834 | #else |
||
- | 835 | fclose(fp); |
||
- | 836 | #endif |
||
- | 837 | return stats; |
||
403 | #if defined ___AsyncIO___ |
838 | } |
|
Line -... | Line 839... | |||
- | 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; |
||
404 | if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { |
856 | } |
|
405 | #else |
857 | #endif |
|
406 | if((fp = fopen(dbFile, "r")) == NULL) { |
858 | if((path = stringStackPop(stack)) == NULL) { |
|
407 | #endif |
859 | break; |
|
408 | fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); |
860 | } |
|
409 | return 0; |
- | ||
410 | } |
861 | |
|
411 | |
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); |
||
Line 412... | Line -... | |||
412 | lines = 0; |
- | ||
413 | #if defined ___AsyncIO___ |
- | ||
414 | while(run && (c = ReadCharAsync(fp)) != -1) { |
- | ||
415 | #else |
- | ||
416 | while(run && fscanf(fp, "%c", &c) == 1) { |
- | ||
417 | #endif |
884 | #if defined ___AsyncIO___ |
|
418 | #if defined ___AmigaOS___ |
- | ||
419 | // Check if CTRL+C was pressed and abort the program. |
- | ||
420 | if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { |
- | ||
Line 421... | Line 885... | |||
421 | run = FALSE; |
885 | CloseAsync(fp); |
|
- | 886 | #else |
||
422 | continue; |
887 | fclose(fp); |
|
- | 888 | #endif |
||
- | 889 | return NULL; |
||
423 | } |
890 | } |
|
Line 424... | Line -... | |||
424 | #endif |
- | ||
425 | switch(c) { |
- | ||
426 | case '\n': |
- | ||
427 | ++lines; |
- | ||
428 | break; |
- | ||
429 | } |
891 | sprintf(subPath, "%s%s", path, entry->d_name); |
|
430 | } |
892 | break; |
|
431 | |
893 | default: |
|
432 | #if defined ___AsyncIO___ |
- | ||
433 | CloseAsync(fp); |
- | ||
Line -... | Line 894... | |||
- | 894 | if((subPath = malloc(size + 1)) == NULL) { |
||
- | 895 | fprintf(stderr, "Memory allocation failure.\n"); |
||
- | 896 | closedir(dir); |
||
434 | #else |
897 | free(path); |
|
- | 898 | stringStackDestroy(stack); |
||
- | 899 | #if defined ___AsyncIO___ |
||
- | 900 | CloseAsync(fp); |
||
- | 901 | #else |
||
435 | fclose(fp); |
902 | fclose(fp); |
|
- | 903 | #endif |
||
- | 904 | return NULL; |
||
- | 905 | } |
||
- | 906 | sprintf(subPath, "%s/%s", path, entry->d_name); |
||
Line 436... | Line 907... | |||
436 | #endif |
907 | break; |
|
- | 908 | } |
||
437 | |
909 | stat(subPath, &dirStat); |
|
- | 910 | if(S_ISDIR(dirStat.st_mode)) { |
||
- | 911 | stringStackPush(stack, subPath); |
||
438 | return lines; |
912 | |
|
- | 913 | ++stats->dirs; |
||
- | 914 | |
||
- | 915 | if(verbose) { |
||
- | 916 | fprintf(stdout, |
||
- | 917 | "Gathered %d directories and %d files.\r", |
||
- | 918 | stats->dirs, |
||
439 | } |
919 | stats->files); |
|
Line 440... | Line 920... | |||
440 | |
920 | } |
|
441 | /* |
921 | |
|
442 | * |
922 | free(subPath); |
|
Line -... | Line 923... | |||
- | 923 | continue; |
||
- | 924 | } |
||
- | 925 | |
||
- | 926 | #if defined ___NOCASE_FS___ |
||
- | 927 | strupr(entry->d_name); |
||
- | 928 | #endif |
||
- | 929 | // Write to database file. |
||
- | 930 | #if defined ___AsyncIO___ |
||
443 | * Creates "files" temporary filenames. |
931 | WriteAsync(fp, entry->d_name, (LONG)strlen(entry->d_name)); |
|
- | 932 | WriteAsync(fp, "\t", 1); |
||
444 | */ |
933 | WriteAsync(fp, subPath, (LONG)strlen(subPath)); |
|
Line 445... | Line 934... | |||
445 | char **CreateTemporaryFiles(int files) { |
934 | WriteAsync(fp, "\n", 1); |
|
446 | char **tmpNames; |
935 | #else |
|
447 | int count; |
936 | fprintf(fp, "%s\t%s\n", entry->d_name, subPath); |
|
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 858... | Line 1320... | |||
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 | |
||
873 | remove(tmpNames[i]); |
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 | } |
||
874 | } while(--i > -1); |
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) { |
||
- | 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; |
||
- | 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) { |
1491 | void usage(char *name) { |
|
940 | fprintf(stdout, "Hunt & Gather - %s, a file index generating tool. \n", 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"); |
||
941 | fprintf(stdout, "Version: %s \n", PROGRAM_VERSION); |
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"); |
|
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 | |
1569 | } |
|
993 | #if defined ___AmigaOS___ |
1570 | |
|
994 | path = malloc(PATH_MAX * sizeof(*path)); |
1571 | // Go through all supplied arguments and add paths to search. |
|
995 | lock = Lock(argv[optind], SHARED_LOCK); |
1572 | if((paths = malloc((argc - optind) * sizeof(*paths))) == NULL) { |
|
- | 1573 | fprintf(stderr, "Memory allocation failure.\n"); |
||
996 | NameFromLock(lock, path, PATH_MAX); |
1574 | return 1; |
|
- | 1575 | } |
||
997 | UnLock(lock); |
1576 | for(i = optind, count = 0; i < argc; ++i, ++count) { |
|
- | 1577 | if((path = PathToAbsolute(argv[optind])) == NULL) { |
||
Line -... | Line 1578... | |||
- | 1578 | fprintf(stderr, "Absolute path for '%s' failed to resolve.\n", argv[optind]); |
||
998 | #else |
1579 | continue; |
|
999 | path = realpath(argv[optind], NULL); |
1580 | } |
|
1000 | #endif |
1581 | |
|
- | 1582 | // Check that the path is a directory. |
||
1001 | |
1583 | stat(path, &dirStat); |
|
1002 | stat(path, &dirStat); |
1584 | if(!S_ISDIR(dirStat.st_mode)) { |
|
Line 1003... | Line 1585... | |||
1003 | if(!S_ISDIR(dirStat.st_mode)) { |
1585 | fprintf(stderr, "Path '%s' is not a directory.\n", argv[optind]); |
|
1004 | fprintf(stderr, "Path '%s' is not a directory.\n", argv[optind]); |
1586 | free(path); |
|
1005 | return 1; |
1587 | return 1; |
|
Line -... | Line 1588... | |||
- | 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 | } |
||
- | 1599 | sprintf(paths[count], "%s", path); |
||
- | 1600 | free(path); |
||
- | 1601 | } |
||
- | 1602 | |
||
- | 1603 | if(verbose) { |
||
- | 1604 | fprintf(stdout, "Gathering to: '%s'\n", dbFile); |
||
1006 | } |
1605 | } |
|
- | 1606 | |
||
- | 1607 | #if defined ___AmigaOS___ |
||
- | 1608 | locale = OpenLocale(NULL); |
||
- | 1609 | #endif |
||
- | 1610 | |
||
1007 | |
1611 | // Gather. |
|
- | 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"); |
||
Line -... | Line 1627... | |||
- | 1627 | } |
||
- | 1628 | RemoveDatabaseFiles(dbFile, paths, count); |
||
- | 1629 | break; |
||
- | 1630 | default: |
||
1008 | if(verbose) { |
1631 | break; |
|
Line 1009... | Line 1632... | |||
1009 | fprintf(stdout, "Gathering to %s\n", dbFile); |
1632 | } |
|
1010 | } |
1633 | |