source: trunk/dll/grep.c@ 783

Last change on this file since 783 was 783, checked in by Steven Levine, 18 years ago

Rework DosFindFirst/Next loops to optimize memory allocation and code paths
Adjust FilesToGet limits
Update configuration notebook scanning page
Start updating #pragma alloc_text positioning for OpenWatcom compatibility

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: grep.c 783 2007-08-14 04:09:54Z stevenhl $
5
6 grep tools
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2007 Steven H. Levine
10
11 12 Feb 03 SHL insert_grepfile: standardize EA math
12 12 Feb 03 SHL doonefile: standardize EA math
13 25 May 05 SHL Rework for ULONGLONG
14 25 May 05 SHL Rework for FillInRecordFromFFB
15 06 Jun 05 SHL Drop unused code
16 24 Oct 05 SHL dononefile: do not free EA list twice
17 22 Jul 06 SHL Use Runtime_Error
18 26 Jul 06 SHL Check more run time errors
19 19 Oct 06 SHL Correct . and .. detect
20 03 Nov 06 SHL Count thread usage
21 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
22 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
23 13 Aug 07 SHL Avoid pointer errors; sanitize code
24 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
25
26***********************************************************************/
27
28#define INCL_DOS
29#define INCL_WIN
30#define INCL_DOSERRORS
31#define INCL_LONGLONG
32#include <os2.h>
33
34#include <stdlib.h>
35#include <string.h>
36#include <ctype.h>
37#include <stdio.h>
38#include <share.h>
39
40#include "fm3dll.h"
41#include "fm3str.h"
42#include "grep.h"
43
44#pragma data_seg(DATA2)
45
46static PSZ pszSrcFile = __FILE__;
47
48static VOID doallsubdirs(GREP *grep, CHAR *searchPath, BOOL recursing,
49 char **fle, int numfls);
50static INT domatchingfiles(GREP *grep, CHAR *path, char **fle, int numfls);
51static BOOL doonefile(GREP *grep, CHAR *fileName, FILEFINDBUF4 *pffb);
52static BOOL doinsertion(GREP *grep);
53static BOOL InsertDupe(GREP *grep, CHAR *dir, FILEFINDBUF4 *pffb);
54static VOID FillDupes(GREP *grep);
55static VOID FreeDupes(GREP *grep);
56
57#define GREPCHARS "*?[] \\"
58
59#define isleap(year) ((((year%4)==0) && ((year%100)!=0)) || \
60 ((year%400)==0))
61
62static INT monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
63
64ULONG SecsSince1980(FDATE * date, FTIME * time)
65{
66 ULONG total = 0L;
67 register int x;
68
69 for (x = 1980; x < date->year + 1980; x++) {
70 if (isleap(x))
71 total += (366L * (24L * 60L * 60L));
72 else
73 total += (365L * (24L * 60L * 60L));
74 }
75 for (x = 1; x < date->month; x++) {
76 if (x == 2 && isleap(date->year + 1980))
77 total += (29L * (24L * 60L * 60L));
78 else
79 total += ((long)monthdays[x - 1] * (24L * 60L * 60L));
80 }
81 total += (((long)date->day - 1L) * (24L * 60L * 60L));
82 total += ((long)time->hours * (60L * 60L));
83 total += ((long)time->minutes * 60L);
84 total += ((long)time->twosecs * 2L);
85 return total;
86}
87
88/*
89 * this function originally from C_ECHO's Snippets -- modified
90 * brute force methodology
91 */
92
93static BOOL m_match(CHAR * string, CHAR * pattern, BOOL absolute, BOOL ignore,
94 LONG len)
95{
96 // return TRUE if pattern found in string
97 register CHAR *tn = pattern;
98 register LONG len2 = 0;
99 LONG lastlen = 0;
100 CHAR lo, hi;
101
102 if (len && string && pattern) {
103 if (absolute) // no pattern matching
104 return (findstring(pattern, strlen(pattern), string, len,
105 (ignore == FALSE)) != NULL);
106
107 while (*tn && len2 < len) {
108 switch (*tn) {
109 case ' ':
110 while (*tn == ' ')
111 tn++;
112 while (len2 < len && isspace(string[len2]))
113 len2++;
114 break;
115
116 case '*':
117 while (*tn == '*' || *tn == '?')
118 tn++;
119 if (!*tn)
120 return TRUE;
121 if (ignore) {
122 while (len2 < len && string[len2] != *tn)
123 len2++;
124 }
125 else {
126 while (len2 < len && toupper(string[len2] != *tn))
127 len2++;
128 }
129 break;
130
131 case '[':
132 tn++;
133 if (!*tn)
134 return FALSE;
135 lo = *tn;
136 tn++;
137 if (*tn != '-')
138 return FALSE;
139 tn++;
140 if (!*tn)
141 return FALSE;
142 hi = *tn;
143 tn++;
144 if (*tn != ']')
145 return FALSE;
146 tn++;
147 if (ignore) {
148 if ((toupper(string[len2]) >= toupper(lo)) &&
149 (toupper(string[len2]) <= toupper(hi)))
150 len2++;
151 else {
152 tn = pattern;
153 len2 = lastlen = lastlen + 1;
154 }
155 }
156 else {
157 if ((string[len2] >= lo) && (string[len2] <= hi))
158 len2++;
159 else {
160 tn = pattern;
161 len2 = lastlen = lastlen + 1;
162 }
163 }
164 break;
165
166 case '?':
167 tn++;
168 len2++;
169 break;
170
171 case '\\':
172 tn++;
173 if (!*tn)
174 return FALSE;
175 // else intentional fallthru
176 default:
177 if (ignore) {
178 if (toupper(*tn) == toupper(string[len2])) {
179 tn++;
180 len2++;
181 }
182 else {
183 tn = pattern;
184 len2 = lastlen = lastlen + 1;
185 }
186 }
187 else {
188 if (*tn == string[len2]) {
189 tn++;
190 len2++;
191 }
192 else {
193 tn = pattern;
194 len2 = lastlen = lastlen + 1;
195 }
196 }
197 break;
198 }
199 }
200 while (*tn == '*')
201 tn++;
202
203 if (!*tn)
204 return TRUE;
205 }
206 return FALSE;
207}
208
209static BOOL match(CHAR * string, CHAR * patterns, BOOL absolute, BOOL ignore,
210 LONG len, ULONG numlines, CHAR * matched, BOOL matchall)
211{
212 BOOL ret = FALSE;
213 register CHAR *p;
214 register ULONG x = 0;
215
216 p = patterns;
217 while (!ret && *p) {
218 ret = m_match(string, p, absolute, ignore, len);
219 if (matchall && ret)
220 break;
221 if (matched && ret && x < numlines)
222 matched[x] = 1;
223 p += strlen(p); // check each pattern in 0-terminated list
224 p++;
225 x++;
226 }
227 return ret;
228}
229
230VOID GrepThread(VOID * arg)
231{
232 HAB ghab;
233 HMQ ghmq;
234 GREP grep;
235 register INT x, numfls;
236 static CHAR *fle[512];
237 CHAR *p, *pp, searchPath[CCHMAXPATH * 2];
238
239 if (!arg) {
240 Runtime_Error(pszSrcFile, __LINE__, "no data");
241 return;
242 }
243
244 grep = *(GREP *)arg;
245 *grep.stopflag = 0; // reset thread-killing flag
246 grep.FilesToGet = FilesToGet;
247 DosError(FERR_DISABLEHARDERR);
248 priority_normal();
249
250 ghab = WinInitialize(0);
251 if (ghab) {
252 grep.ghab = ghab;
253 ghmq = WinCreateMsgQueue(ghab, 0);
254 if (ghmq) {
255 WinCancelShutdown(ghmq, TRUE);
256 IncrThreadUsage();
257 DosSleep(100); //05 Aug 07 GKY 128
258 WinSetWindowText(grep.hwndCurFile,
259 GetPString((grep.finddupes) ?
260 IDS_GREPDUPETEXT : IDS_GREPSCANTEXT));
261
262 pp = grep.searchPattern;
263 while (*pp) {
264 if (!grep.absFlag) {
265 p = GREPCHARS; // see if any sense in pattern matching
266 while (*p) {
267 if (strchr(pp, *p))
268 break;
269 p++;
270 }
271 if (!*p) // nope, turn it off
272 grep.absFlag = TRUE;
273 }
274 pp = pp + strlen(pp) + 1;
275 }
276
277 grep.attrFile &= (~FILE_DIRECTORY);
278 grep.antiattr &= (~FILE_DIRECTORY);
279 if (grep.antiattr & FILE_READONLY)
280 grep.antiattr |= MUST_HAVE_READONLY;
281 if (grep.antiattr & FILE_HIDDEN)
282 grep.antiattr |= MUST_HAVE_HIDDEN;
283 if (grep.antiattr & FILE_SYSTEM)
284 grep.antiattr |= MUST_HAVE_SYSTEM;
285 if (grep.antiattr & FILE_ARCHIVED)
286 grep.antiattr |= MUST_HAVE_ARCHIVED;
287
288 grep.anyexcludes = FALSE;
289 numfls = x = 0;
290 fle[numfls++] = strtok(grep.tosearch, ";");
291 while ((fle[numfls] = strtok(NULL, ";")) != NULL && numfls < 511) {
292 if (*fle[numfls] == '/')
293 grep.anyexcludes = TRUE;
294 numfls++;
295 }
296
297 while (x < numfls) { // loop through search masks
298
299 if (*fle[x] == '/') // is an exclude mask only
300 goto ExcludeSkip;
301
302 // first, separate any path from mask
303
304 p = (char *)(fle[x] + (strlen(fle[x]) - 1));
305 while (*p != '\\' && *p != ':' && p != fle[x])
306 --p;
307
308 if (p == fle[x]) { // no path
309 strcpy(searchPath, grep.curdir);
310 strncpy(grep.fileMask, fle[x], CCHMAXPATH);
311 grep.fileMask[CCHMAXPATH - 1] = 0;
312 }
313 else { // got to deal with a path
314 if (*p == ':') { // just a drive, start in root dir
315 *p = 0;
316 p++;
317 strncpy(searchPath, fle[x], CCHMAXPATH - 2);
318 searchPath[CCHMAXPATH - 3] = 0;
319 strcat(searchPath, ":\\");
320 strcpy(grep.fileMask, p);
321 }
322 if (*p == '\\') { // got a 'full' path
323
324 CHAR temp;
325
326 p++;
327 temp = *p;
328 *p = 0;
329 strncpy(searchPath, fle[x], CCHMAXPATH);
330 searchPath[CCHMAXPATH - 1] = 0;
331 *p = temp;
332 strcpy(grep.fileMask, p);
333 }
334 if (!*grep.fileMask)
335 strcpy(grep.fileMask, "*");
336 }
337 if (*grep.stopflag)
338 break;
339 // do single directory
340 domatchingfiles(&grep, searchPath, fle, numfls);
341 if (grep.dirFlag) // do subdirs
342 doallsubdirs(&grep, searchPath, FALSE, fle, numfls);
343 ExcludeSkip:
344 if (*grep.stopflag)
345 break;
346 x++;
347 if (WinIsWindow(grep.ghab, grep.hwndFiles))
348 doinsertion(&grep); // insert any remaining objects
349 } // while
350
351 if (WinIsWindow(grep.ghab, grep.hwndFiles))
352 doinsertion(&grep); // insert any remaining objects
353
354 if (WinIsWindow(grep.ghab, grep.hwndFiles) && grep.finddupes &&
355 !*grep.stopflag)
356 FillDupes(&grep);
357
358 if (!PostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID)) // tell window we're done
359 WinSendMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
360 WinDestroyMsgQueue(ghmq);
361 }
362 DecrThreadUsage();
363 WinTerminate(ghab);
364 }
365 if (!ghmq || !ghab)
366 WinPostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
367 if (grep.dupehead)
368 FreeDupes(&grep);
369 if (grep.numlines && grep.matched)
370 free(grep.matched);
371 DosPostEventSem(CompactSem);
372}
373
374static BOOL IsExcluded(char *name, char **fle, int numfls)
375{
376 int x;
377 char *n;
378
379 n = strrchr(name, '\\');
380 if (!n)
381 n = strrchr(name, ':');
382 if (n)
383 n++;
384 else
385 n = name;
386 for (x = 0; x < numfls; x++) {
387 if (*fle[x] == '/' &&
388 wildcard((strchr(fle[x], '\\') ||
389 strchr(fle[x], ':')) ? name : n, fle[x] + 1, FALSE))
390 return TRUE;
391 }
392 return FALSE;
393}
394
395static VOID doallsubdirs(GREP * grep, CHAR * searchPath, BOOL recursing,
396 char **fle, int numfls)
397{
398 // process all subdirectories
399
400 FILEFINDBUF4 ffb;
401 HDIR findHandle = HDIR_CREATE;
402 LONG ulFindCnt = 1;
403 CHAR *p = NULL;
404
405 // add a mask to search path
406 if (searchPath[strlen(searchPath) - 1] != '\\')
407 strcat(searchPath, "\\");
408 strcat(searchPath, "*");
409 // step through all subdirectories
410 DosError(FERR_DISABLEHARDERR);
411 if (!DosFindFirst(searchPath, &findHandle, (MUST_HAVE_DIRECTORY |
412 FILE_ARCHIVED | FILE_SYSTEM |
413 FILE_HIDDEN | FILE_READONLY),
414 &ffb, (ULONG) sizeof(ffb),
415 (PULONG) & ulFindCnt, FIL_QUERYEASIZE)) {
416
417 // get rid of mask portion, save end-of-directory
418
419 p = strrchr(searchPath, '\\');
420 if (p)
421 p++;
422 else
423 p = searchPath;
424 do { // Process each directory that matches the mask
425 priority_normal();
426 if (*grep->stopflag)
427 break;
428 // Skip . and ..
429 if (ffb.achName[0] != '.' ||
430 (ffb.achName[1] &&
431 (ffb.achName[1] != '.' || ffb.achName[2]))) {
432 strcpy(p, ffb.achName);
433 if (!grep->anyexcludes || !IsExcluded(searchPath, fle, numfls)) {
434 domatchingfiles(grep, searchPath, fle, numfls);
435 doallsubdirs(grep, searchPath, TRUE, fle, numfls);
436 DosSleep(1);
437 }
438 }
439 ulFindCnt = 1;
440 } while (!DosFindNext(findHandle,
441 &ffb,
442 sizeof(ffb), (PULONG) & ulFindCnt));
443 DosFindClose(findHandle);
444 priority_normal();
445 }
446 if (p) // strip off last directory addition
447 *p = 0;
448}
449
450static INT domatchingfiles(GREP * grep, CHAR * path, char **fle, int numfls)
451{
452 // process all matching files in a directory
453
454 PFILEFINDBUF4 pffbArray;
455 PFILEFINDBUF4 pffbFile;
456 ULONG x;
457 HDIR findHandle = HDIR_CREATE;
458 ULONG ulFindCnt;
459 CHAR szFindPath[CCHMAXPATH];
460 PSZ p;
461 APIRET rc;
462 ULONG ulBufBytes = grep->FilesToGet * sizeof(FILEFINDBUF4);
463
464 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
465 if (!pffbArray)
466 return 0;
467
468 // build filemask
469 BldFullPathName(szFindPath, path, grep->fileMask);
470 // sprintf(szFindPath,
471 // "%s%s%s",
472 // path,
473 // (path[strlen(path) - 1] == '\\') ? NullStr : "\\", grep->fileMask);
474
475 MakeFullName(szFindPath);
476
477 // find and save end-of-dir position
478 p = strrchr(szFindPath, '\\');
479 if (p)
480 p++;
481 else
482 p = szFindPath;
483
484 // step through matching files
485 DosError(FERR_DISABLEHARDERR);
486 ulFindCnt = grep->FilesToGet;
487 rc = DosFindFirst(szFindPath,
488 &findHandle,
489 FILE_NORMAL | grep->attrFile | grep->antiattr,
490 pffbArray,
491 ulBufBytes,
492 &ulFindCnt,
493 FIL_QUERYEASIZE);
494 if (!rc) {
495 do {
496 // Process each file that matches the mask
497 priority_normal();
498 pffbFile = pffbArray;
499 for (x = 0; x < ulFindCnt; x++) {
500 if (*grep->stopflag)
501 break;
502 if (*pffbFile->achName != '.' ||
503 (pffbFile->achName[1] && pffbFile->achName[1] != '.')) {
504 strcpy(p, pffbFile->achName); // build filename
505 if (!grep->anyexcludes || !IsExcluded(szFindPath, fle, numfls)) {
506 if (!grep->finddupes)
507 doonefile(grep, szFindPath, pffbFile);
508 else if (!InsertDupe(grep, szFindPath, pffbFile)) {
509 DosFindClose(findHandle);
510 free(pffbArray);
511 return 1;
512 }
513 }
514 }
515 if (!pffbFile->oNextEntryOffset)
516 break;
517 pffbFile = (PFILEFINDBUF4)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
518 } // for
519 if (*grep->stopflag)
520 break;
521 DosSleep(1);
522 ulFindCnt = grep->FilesToGet;
523 rc = DosFindNext(findHandle, pffbArray, ulBufBytes, &ulFindCnt);
524 } while (!rc);
525
526 DosFindClose(findHandle);
527 priority_normal();
528 } // if
529
530 if (rc && rc != ERROR_NO_MORE_FILES) {
531 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
532 GetPString(IDS_CANTFINDDIRTEXT), szFindPath);
533 }
534
535 free(pffbArray);
536 return 0;
537}
538
539static VOID freegreplist(GREP * grep)
540{
541 INT x;
542
543 if (grep) {
544 if (grep->insertffb) {
545 for (x = 0; grep->insertffb[x]; x++)
546 free(grep->insertffb[x]);
547 free(grep->insertffb);
548 }
549 if (grep->dir) {
550 for (x = 0; grep->dir[x]; x++)
551 free(grep->dir[x]);
552 free(grep->dir);
553 }
554 grep->dir = NULL;
555 grep->insertffb = NULL;
556 grep->toinsert = 0L;
557 grep->insertedbytes = 0L;
558 }
559}
560
561static BOOL doinsertion(GREP * grep)
562{
563 RECORDINSERT ri;
564 DIRCNRDATA *dcd;
565 PCNRITEM pci, pciFirst;
566 INT x;
567
568 if (!grep || !grep->toinsert || !grep->insertffb || !grep->dir)
569 return FALSE;
570 pci = WinSendMsg(grep->hwndFiles,
571 CM_ALLOCRECORD,
572 MPFROMLONG(EXTRA_RECORD_BYTES),
573 MPFROMLONG(grep->toinsert));
574 if (pci) {
575 if (grep->sayfiles)
576 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPINSERTINGTEXT));
577 pciFirst = pci;
578 dcd = INSTDATA(grep->hwndFiles);
579 for (x = 0; grep->insertffb[x]; x++) {
580 FillInRecordFromFFB(grep->hwndFiles,
581 pci, grep->dir[x], grep->insertffb[x], FALSE, dcd);
582 pci = (PCNRITEM) pci->rc.preccNextRecord;
583 }
584 memset(&ri, 0, sizeof(RECORDINSERT));
585 ri.cb = sizeof(RECORDINSERT);
586 ri.pRecordOrder = (PRECORDCORE) CMA_END;
587 ri.pRecordParent = (PRECORDCORE) NULL;
588 ri.zOrder = (USHORT) CMA_TOP;
589 ri.cRecordsInsert = grep->toinsert;
590 ri.fInvalidateRecord = TRUE;
591 WinSendMsg(grep->hwndFiles,
592 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
593 if (dcd) {
594 DosEnterCritSec();
595 dcd->ullTotalBytes += grep->insertedbytes;
596 DosExitCritSec();
597 }
598 if (grep->toinsert == grep->FilesToGet)
599 DosSleep(1);
600 freegreplist(grep);
601 PostMsg(grep->hwndFiles, UM_RESCAN, MPVOID, MPVOID);
602 return TRUE;
603 }
604 freegreplist(grep);
605 return FALSE;
606}
607
608static BOOL insert_grepfile(GREP *grep, CHAR *filename, PFILEFINDBUF4 pffb)
609{
610 PSZ p;
611 CHAR szDirectory[CCHMAXPATH];
612
613 if (WinIsWindow(grep->ghab, grep->hwndFiles)) {
614 grep->numfiles++;
615 strcpy(szDirectory, filename);
616 p = strrchr(szDirectory, '\\');
617 if (p) {
618 if (p < szDirectory + 4)
619 p++;
620 *p = 0;
621 if (!grep->insertffb) {
622 // Allocate 1 extra for end marker?
623 grep->insertffb =
624 xmallocz(sizeof(PFILEFINDBUF4) * (grep->FilesToGet + 1),
625 pszSrcFile, __LINE__);
626 if (!grep->insertffb)
627 return FALSE;
628 grep->dir =
629 xmallocz(sizeof(CHAR *) * (grep->FilesToGet + 1),
630 pszSrcFile, __LINE__);
631 if (!grep->dir) {
632 free(grep->insertffb);
633 return FALSE;
634 }
635 }
636 grep->insertffb[grep->toinsert] =
637 xmalloc(sizeof(FILEFINDBUF4), pszSrcFile, __LINE__);
638 if (!grep->insertffb[grep->toinsert])
639 return FALSE;
640 memcpy(grep->insertffb[grep->toinsert], pffb, sizeof(FILEFINDBUF4));
641 grep->dir[grep->toinsert] = xstrdup(szDirectory, pszSrcFile, __LINE__);
642 if (!grep->dir) {
643 free(grep->insertffb[grep->toinsert]);
644 return FALSE;
645 }
646 grep->insertedbytes += pffb->cbFile + CBLIST_TO_EASIZE(pffb->cbList);
647 grep->toinsert++;
648 if (grep->toinsert == grep->FilesToGet)
649 return doinsertion(grep);
650 return TRUE;
651 }
652 }
653 else
654 freegreplist(grep);
655 return FALSE;
656}
657
658static BOOL doonefile(GREP *grep, CHAR *filename, FILEFINDBUF4 * pffb)
659{
660 // process a single file
661 CHAR *input;
662 FILE *inputFile;
663 ULONG pos;
664 BOOL ret = FALSE, strmatch = FALSE;
665
666 grep->fileCount++;
667 if (grep->sayfiles)
668 WinSetWindowText(grep->hwndCurFile, filename);
669
670 if (grep->greaterthan || grep->lessthan) {
671
672 BOOL keep = TRUE;
673 ULONG adjsize;
674
675 adjsize = pffb->cbFile + (grep->searchEAs ? CBLIST_TO_EASIZE(pffb->cbList) : 0);
676 if (grep->greaterthan) {
677 if (adjsize < grep->greaterthan)
678 keep = FALSE;
679 }
680 if (keep && grep->lessthan) {
681 if (adjsize > grep->lessthan)
682 keep = FALSE;
683 }
684 if (!keep)
685 return ret;
686 }
687
688 if (grep->newerthan || grep->olderthan) {
689
690 BOOL keep = TRUE;
691 ULONG numsecs;
692
693 numsecs = SecsSince1980(&pffb->fdateLastWrite, &pffb->ftimeLastWrite);
694 if (grep->newerthan) {
695 if (numsecs < grep->newerthan)
696 keep = FALSE;
697 }
698 if (keep && grep->olderthan) {
699 if (numsecs > grep->olderthan)
700 keep = FALSE;
701 }
702 if (!keep)
703 return ret;
704 }
705
706 if ((!grep->searchEAs && !grep->searchFiles) || !*grep->searchPattern) // just a find
707 return insert_grepfile(grep, filename, pffb);
708
709 if (grep->searchEAs) {
710
711 HOLDFEA *head, *info;
712 USHORT type, len;
713 BOOL alltext;
714 CHAR *data, temp;
715
716 head = GetFileEAs(filename, FALSE, TRUE);
717 if (head) {
718 info = head;
719 while (info && !strmatch) {
720 alltext = TRUE;
721 switch (*(USHORT *) info->value) {
722 case EAT_ASCII:
723 if (match(info->value + (sizeof(USHORT) * 2),
724 grep->searchPattern, grep->absFlag,
725 (grep->caseFlag == FALSE),
726 info->cbValue - (sizeof(USHORT) * 2),
727 grep->numlines, grep->matched, !grep->findifany)) {
728 strmatch = TRUE;
729 }
730 break;
731 case EAT_MVST:
732 type = *(USHORT *) (info->value + (sizeof(USHORT) * 3));
733 if (type == EAT_ASCII) {
734 data = info->value + (sizeof(USHORT) * 4);
735 len = *(USHORT *) data;
736 data += sizeof(USHORT);
737 while ((data - info->value) + len <= info->cbValue) {
738 temp = *(data + len);
739 *(data + len) = 0;
740 if (match(data,
741 grep->searchPattern,
742 grep->absFlag,
743 (grep->caseFlag == FALSE),
744 len,
745 grep->numlines, grep->matched, !grep->findifany)) {
746 strmatch = TRUE;
747 break;
748 }
749 data += len;
750 if (data - info->value >= info->cbValue)
751 break;
752 *data = temp;
753 len = *(USHORT *) data;
754 data += sizeof(USHORT);
755 }
756 }
757 break;
758 case EAT_MVMT:
759 data = info->value + (sizeof(USHORT) * 3);
760 type = *(USHORT *) data;
761 data += sizeof(USHORT);
762 len = *(USHORT *) data;
763 data += sizeof(USHORT);
764 while ((data - info->value) - len <= info->cbValue) {
765 if (type != EAT_ASCII) {
766 alltext = FALSE;
767 break;
768 }
769 data += len;
770 if (data - info->value >= info->cbValue)
771 break;
772 type = *(USHORT *) data;
773 data += sizeof(USHORT);
774 len = *(USHORT *) data;
775 data += sizeof(USHORT);
776 }
777 if (alltext) {
778 data = info->value + (sizeof(USHORT) * 3);
779 type = *(USHORT *) data;
780 data += sizeof(USHORT);
781 len = *(USHORT *) data;
782 data += sizeof(USHORT);
783 while ((data - info->value) - len <= info->cbValue) {
784 temp = *(data + len);
785 *(data + len) = 0;
786 if (match(data,
787 grep->searchPattern,
788 grep->absFlag,
789 (grep->caseFlag == FALSE),
790 len,
791 grep->numlines, grep->matched, !grep->findifany)) {
792 strmatch = TRUE;
793 break;
794 }
795 data += len;
796 *data = temp;
797 if (data - info->value >= info->cbValue)
798 break;
799 type = *(USHORT *) data;
800 data += sizeof(USHORT);
801 len = *(USHORT *) data;
802 data += sizeof(USHORT);
803 }
804 }
805 break;
806 default:
807 break;
808 }
809 info = info->next;
810 } // while
811 Free_FEAList(head);
812 DosSleep(1);
813 }
814 }
815
816 if (grep->searchFiles) {
817 input = xmalloc(65537, pszSrcFile, __LINE__);
818 if (input) {
819 LONG len;
820
821 inputFile = _fsopen(filename, "rb", SH_DENYNO);
822 if (inputFile) {
823 pos = ftell(inputFile);
824 while (!feof(inputFile)) {
825 if (pos)
826 fseek(inputFile, pos - 1024, SEEK_SET);
827 len = fread(input, 1, 65536, inputFile);
828 if (len >= 0) {
829 if (*grep->stopflag)
830 break;
831 if (match(input,
832 grep->searchPattern,
833 grep->absFlag,
834 (grep->caseFlag == FALSE),
835 len, grep->numlines, grep->matched, !grep->findifany)) {
836 strmatch = TRUE;
837 break;
838 }
839 }
840 else
841 break;
842 }
843 fclose(inputFile);
844 }
845 free(input);
846 DosSleep(1);
847 }
848 } // if
849
850 if (strmatch)
851 ret = insert_grepfile(grep, filename, pffb);
852 return ret;
853}
854
855static LONG cr3tab[] = { // CRC polynomial 0xEDB88320
856
857 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
858 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
859 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
860 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
861 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
862 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
863 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
864 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
865 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
866 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
867 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
868 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
869 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
870 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
871 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
872 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
873 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
874 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
875 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
876 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
877 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
878 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
879 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
880 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
881 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
882 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
883 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
884 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
885 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
886 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
887 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
888 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
889 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
890 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
891 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
892 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
893 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
894 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
895 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
896 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
897 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
898 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
899 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
900 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
901 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
902 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
903 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
904 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
905 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
906 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
907 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
908 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
909 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
910 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
911 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
912 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
913 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
914 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
915 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
916 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
917 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
918 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
919 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
920 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
921};
922
923LONG CRCBlock(register CHAR * str, register INT blklen, register LONG crc)
924{
925 while (blklen--) {
926 crc =
927 cr3tab[((INT) crc ^ *str) & 0xff] ^ (((ULONG) crc >> 8) & 0x00FFFFFF);
928 str++;
929 }
930 return crc;
931}
932
933LONG CRCFile(CHAR * filename, INT * error)
934{
935 LONG CRC = -1L, len;
936 FILE *fp;
937 CHAR *buffer;
938
939 *error = 0;
940 buffer = xmalloc(65535, pszSrcFile, __LINE__);
941 if (!buffer)
942 *error = -1;
943 else {
944 fp = _fsopen(filename, "rb", SH_DENYNO);
945 if (!fp)
946 *error = -2;
947 else {
948 while (!feof(fp)) {
949 len = fread(buffer, 1, 65535, fp);
950 if (len && len < 65536L)
951 CRC = CRCBlock(buffer, len, CRC);
952 else
953 break;
954 DosSleep(1);
955 }
956 fclose(fp);
957 DosSleep(1);
958 }
959 free(buffer);
960 }
961 return CRC;
962}
963
964static VOID FreeDupes(GREP *grep)
965{
966 DUPES *i, *next;
967
968 i = grep->dupehead;
969 while (i) {
970 next = i->next;
971 if (i->name)
972 free(i->name);
973 free(i);
974 i = next;
975 }
976 grep->dupehead = grep->dupelast = NULL;
977 if (grep->dupenames)
978 free(grep->dupenames);
979 if (grep->dupesizes)
980 free(grep->dupesizes);
981 grep->dupesizes = grep->dupenames = NULL;
982}
983
984int comparenamesq(const void *v1, const void *v2)
985{
986 DUPES *d1 = *(DUPES **) v1;
987 DUPES *d2 = *(DUPES **) v2;
988 CHAR *p1, *p2;
989
990 p1 = strrchr(d1->name, '\\');
991 if (p1)
992 p1++;
993 else
994 p1 = d1->name;
995 p2 = strrchr(d2->name, '\\');
996 if (p2)
997 p2++;
998 else
999 p2 = d2->name;
1000 return stricmp(p1, p2);
1001}
1002
1003int comparenamesqe(const void *v1, const void *v2)
1004{
1005 DUPES *d1 = *(DUPES **) v1;
1006 DUPES *d2 = *(DUPES **) v2;
1007 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
1008 int ret;
1009
1010 p1 = strrchr(d1->name, '\\');
1011 if (p1)
1012 p1++;
1013 else
1014 p1 = d1->name;
1015 p1e = strrchr(p1, '.');
1016 if (p1e) {
1017 e1 = *p1e;
1018 *p1e = 0;
1019 }
1020 p2 = strrchr(d2->name, '\\');
1021 if (p2)
1022 p2++;
1023 else
1024 p2 = d2->name;
1025 p2e = strrchr(p2, '.');
1026 if (p2e) {
1027 e2 = *p2e;
1028 *p2e = 0;
1029 }
1030 ret = stricmp(p1, p2);
1031 if (p1e)
1032 *p1e = e1;
1033 if (p2e)
1034 *p2e = e2;
1035 return ret;
1036}
1037
1038int comparesizesq(const void *v1, const void *v2)
1039{
1040 DUPES *d1 = *(DUPES **) v1;
1041 DUPES *d2 = *(DUPES **) v2;
1042
1043 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1044}
1045
1046int comparenamesb(const void *v1, const void *v2)
1047{
1048 DUPES *d1 = (DUPES *) v1;
1049 DUPES *d2 = *(DUPES **) v2;
1050 CHAR *p1, *p2;
1051
1052 p1 = strrchr(d1->name, '\\');
1053 if (p1)
1054 p1++;
1055 else
1056 p1 = d1->name;
1057 p2 = strrchr(d2->name, '\\');
1058 if (p2)
1059 p2++;
1060 else
1061 p2 = d2->name;
1062 return stricmp(p1, p2);
1063}
1064
1065int comparenamesbe(const void *v1, const void *v2)
1066{
1067 DUPES *d1 = (DUPES *) v1;
1068 DUPES *d2 = *(DUPES **) v2;
1069 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
1070 int ret;
1071
1072 p1 = strrchr(d1->name, '\\');
1073 if (p1)
1074 p1++;
1075 else
1076 p1 = d1->name;
1077 p1e = strrchr(p1, '.');
1078 if (p1e) {
1079 e1 = *p1e;
1080 *p1e = 0;
1081 }
1082 p2 = strrchr(d2->name, '\\');
1083 if (p2)
1084 p2++;
1085 else
1086 p2 = d2->name;
1087 p2e = strrchr(p2, '.');
1088 if (p2e) {
1089 e2 = *p2e;
1090 *p2e = 0;
1091 }
1092 ret = stricmp(p1, p2);
1093 if (p1e)
1094 *p1e = e1;
1095 if (p2e)
1096 *p2e = e2;
1097 return ret;
1098}
1099
1100int comparesizesb(const void *v1, const void *v2)
1101{
1102 DUPES *d1 = (DUPES *) v1;
1103 DUPES *d2 = *(DUPES **) v2;
1104
1105 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1106}
1107
1108static VOID FillDupes(GREP * grep)
1109{
1110 DUPES *c, *i, **r;
1111 register CHAR *pc, *pi;
1112 CHAR **list = NULL;
1113 INT numfiles = 0, numalloced = 0, error;
1114 register ULONG x = 0, y = 0;
1115 ULONG cntr = 100;
1116
1117 if (grep->CRCdupes)
1118 cntr = 50;
1119 i = grep->dupehead;
1120 while (i) {
1121 x++;
1122 i = i->next;
1123 }
1124 if (x) {
1125 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPESORTINGTEXT));
1126 DosSleep(1);
1127 grep->dupenames = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1128 if (!grep->nosizedupes)
1129 grep->dupesizes = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1130 if (grep->dupenames && (grep->nosizedupes || grep->dupesizes)) {
1131 i = grep->dupehead;
1132 while (i) {
1133 grep->dupenames[y] = i;
1134 if (!grep->nosizedupes)
1135 grep->dupesizes[y] = i;
1136 i = i->next;
1137 y++;
1138 }
1139 grep->dupenames[y] = NULL;
1140 if (!grep->nosizedupes)
1141 grep->dupesizes[y] = NULL;
1142 DosSleep(1);
1143 qsort(grep->dupenames,
1144 x,
1145 sizeof(DUPES *),
1146 ((grep->ignoreextdupes) ? comparenamesqe : comparenamesq));
1147 DosSleep(1);
1148 if (!grep->nosizedupes) {
1149 qsort(grep->dupesizes, x, sizeof(DUPES *), comparesizesq);
1150 DosSleep(1);
1151 }
1152 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1153
1154 i = grep->dupehead;
1155 y = 0;
1156 while (i) {
1157 if (*grep->stopflag)
1158 break;
1159 if (!(i->flags & GF_SKIPME)) {
1160 r = (DUPES **) bsearch(i, grep->dupenames, x, sizeof(DUPES *),
1161 ((grep->ignoreextdupes) ? comparenamesbe :
1162 comparenamesb));
1163 if (r) {
1164 while (r > grep->dupenames && ((grep->ignoreextdupes) ?
1165 !comparenamesqe((r - 1), &i) :
1166 !comparenamesq((r - 1), &i)))
1167 r--;
1168 while (*r && ((grep->ignoreextdupes) ?
1169 !comparenamesqe(r, &i) : !comparenamesq(r, &i))) {
1170 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME))) {
1171 r++;
1172 continue;
1173 }
1174 if (grep->CRCdupes) {
1175 if ((*r)->CRC == -1L) {
1176 (*r)->CRC = CRCFile((*r)->name, &error);
1177 if (error)
1178 (*r)->CRC = -1L;
1179 else if ((*r)->CRC == -1L)
1180 (*r)->CRC = 0L;
1181 }
1182 if (i->CRC == -1L) {
1183 i->CRC = CRCFile(i->name, &error);
1184 if (error)
1185 i->CRC = -1L;
1186 else if (i->CRC == -1L)
1187 i->CRC = 0L;
1188 }
1189 if (((*r)->size != i->size) || ((*r)->CRC != -1L &&
1190 i->CRC != -1L
1191 && (*r)->CRC != i->CRC)) {
1192 r++;
1193 continue;
1194 }
1195 }
1196 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
1197 (*r)->flags |= GF_INSERTED;
1198 if (grep->sayfiles)
1199 WinSetWindowText(grep->hwndFiles, (*r)->name);
1200 if ((*r)->size == i->size &&
1201 (i->date.year == (*r)->date.year &&
1202 i->date.month == (*r)->date.month &&
1203 i->date.day == (*r)->date.day &&
1204 i->time.hours == (*r)->time.hours &&
1205 i->time.minutes == (*r)->time.minutes &&
1206 i->time.twosecs == (*r)->time.twosecs))
1207 (*r)->flags |= GF_SKIPME;
1208 }
1209 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1210 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1211 i->flags |= GF_INSERTED;
1212 if ((*r)->flags & GF_SKIPME)
1213 i->flags |= GF_SKIPME;
1214 }
1215 }
1216 r++;
1217 }
1218 }
1219 if (!grep->nosizedupes) {
1220 r = (DUPES **) bsearch(i,
1221 grep->dupesizes,
1222 x, sizeof(DUPES *), comparesizesb);
1223 if (r) {
1224 while (r > grep->dupesizes && !comparesizesq((r - 1), &i))
1225 r--;
1226 while (*r && !comparesizesq(r, &i)) {
1227 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME)) ||
1228 (i->date.year != (*r)->date.year ||
1229 i->date.month != (*r)->date.month ||
1230 i->date.day != (*r)->date.day ||
1231 i->time.hours != (*r)->time.hours ||
1232 i->time.minutes != (*r)->time.minutes ||
1233 i->time.twosecs != (*r)->time.twosecs)) {
1234 r++;
1235 continue;
1236 }
1237 if (grep->CRCdupes) {
1238 if ((*r)->CRC == -1L) {
1239 (*r)->CRC = CRCFile((*r)->name, &error);
1240 if (error)
1241 (*r)->CRC = -1L;
1242 else if ((*r)->CRC == -1L)
1243 (*r)->CRC = 0L;
1244 }
1245 if (i->CRC == -1L) {
1246 i->CRC = CRCFile(i->name, &error);
1247 if (error)
1248 i->CRC = -1L;
1249 else if (i->CRC == -1L)
1250 i->CRC = 0L;
1251 }
1252 if ((*r)->CRC != -1L && i->CRC != -1L &&
1253 (*r)->CRC != i->CRC) {
1254 *r += 1;
1255 continue;
1256 }
1257 }
1258 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
1259 if (grep->sayfiles)
1260 WinSetWindowText(grep->hwndCurFile, (*r)->name);
1261 (*r)->flags |= GF_INSERTED;
1262 if (((grep->ignoreextdupes) ?
1263 comparenamesqe(r, &i) : comparenamesq(r, &i)))
1264 (*r)->flags |= GF_SKIPME;
1265 }
1266 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1267 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1268 i->flags |= GF_INSERTED;
1269 if ((*r)->flags & GF_SKIPME)
1270 i->flags |= GF_SKIPME;
1271 }
1272 }
1273 r++;
1274 }
1275 }
1276 }
1277 }
1278 i = i->next;
1279 y++;
1280 if (!(y % cntr)) {
1281
1282 CHAR s[44];
1283
1284 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, grep->numfiles);
1285 WinSetWindowText(grep->hwndCurFile, s);
1286 DosSleep(100); //05 Aug 07 GKY 128
1287 }
1288 DosSleep(y % 2);
1289 }
1290 }
1291 else {
1292 // Insufficient memory - fall back
1293 DosBeep(50, 100);
1294 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1295 x = y = 0;
1296 if (grep->dupenames) {
1297 free(grep->dupenames);
1298 grep->dupenames = NULL;
1299 }
1300 if (grep->dupesizes) {
1301 free(grep->dupesizes);
1302 grep->dupesizes = NULL;
1303 }
1304 i = grep->dupehead;
1305 while (i) {
1306 if (*grep->stopflag)
1307 break;
1308 if (!(i->flags & GF_SKIPME)) {
1309 if (!(y % cntr)) {
1310
1311 CHAR s[44];
1312
1313 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, grep->numfiles);
1314 WinSetWindowText(grep->hwndCurFile, s);
1315 DosSleep(1);
1316 }
1317 y++;
1318 pi = strrchr(i->name, '\\');
1319 if (pi)
1320 pi++;
1321 else
1322 pi = i->name;
1323 c = grep->dupehead;
1324 while (c) {
1325 if (*grep->stopflag)
1326 break;
1327 if (c != i && !(c->flags & (GF_INSERTED | GF_SKIPME))) {
1328 x++;
1329 pc = strrchr(c->name, '\\');
1330 if (pc)
1331 pc++;
1332 else
1333 pc = c->name;
1334 if ((!grep->nosizedupes && i->size == c->size && i->date.year == c->date.year && i->date.month == c->date.month && i->date.day == c->date.day && i->time.hours == c->time.hours && i->time.minutes == c->time.minutes && i->time.twosecs == c->time.twosecs) || !stricmp(pc, pi)) { // potential dupe
1335 if (grep->CRCdupes) {
1336 if (grep->CRCdupes) {
1337 if (c->CRC == -1L) {
1338 c->CRC = CRCFile(c->name, &error);
1339 if (error)
1340 c->CRC = -1L;
1341 else if (c->CRC == -1L)
1342 c->CRC = 0L;
1343 }
1344 if (i->CRC == -1L) {
1345 i->CRC = CRCFile(i->name, &error);
1346 if (error)
1347 i->CRC = -1L;
1348 else if (i->CRC == -1L)
1349 i->CRC = 0L;
1350 }
1351 if ((c->size != i->size) || (c->CRC != -1L &&
1352 i->CRC != -1L
1353 && c->CRC != i->CRC)) {
1354 c = c->next;
1355 continue;
1356 }
1357 }
1358 }
1359 if (AddToList(c->name, &list, &numfiles, &numalloced))
1360 goto BreakOut; // Failed
1361 if (!(i->flags & GF_INSERTED)) {
1362 if (AddToList(i->name, &list, &numfiles, &numalloced))
1363 goto BreakOut; // Failed
1364 }
1365 if (grep->sayfiles)
1366 WinSetWindowText(grep->hwndCurFile, pc);
1367 c->flags |= GF_INSERTED;
1368 i->flags |= GF_INSERTED;
1369 if (!stricmp(pc, pi)) {
1370 c->flags |= GF_SKIPME;
1371 i->flags |= GF_SKIPME;
1372 }
1373 }
1374 else if (!(x % 100))
1375 DosSleep(1);
1376 }
1377 c = c->next;
1378 }
1379 }
1380 i = i->next;
1381 }
1382 }
1383 }
1384BreakOut:
1385 FreeDupes(grep);
1386 if (numfiles && list) {
1387 if (!PostMsg(grep->hwndFiles,
1388 WM_COMMAND, MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list)))
1389 FreeList(list);
1390 }
1391 else
1392 DosPostEventSem(CompactSem);
1393}
1394
1395static BOOL InsertDupe(GREP *grep, CHAR *dir, FILEFINDBUF4 *pffb)
1396{
1397 DUPES *info;
1398
1399 if (*dir) {
1400 info = xmallocz(sizeof(DUPES), pszSrcFile, __LINE__);
1401 if (!info)
1402 return FALSE;
1403
1404 info->name = xstrdup(dir, pszSrcFile, __LINE__);
1405 if (!info->name) {
1406 free(info);
1407 return FALSE;
1408 }
1409
1410 info->size = pffb->cbFile;
1411 info->date = pffb->fdateLastWrite;
1412 info->time = pffb->ftimeLastWrite;
1413 info->CRC = -1L;
1414 grep->numfiles++;
1415 if (!grep->dupehead)
1416 grep->dupehead = info;
1417 if (grep->dupelast)
1418 grep->dupelast->next = info;
1419 grep->dupelast = info;
1420 info->next = NULL;
1421 }
1422 return TRUE;
1423}
1424
1425#pragma alloc_text(GREP,insert_grepfile,doonefile,doinsertion,freegreplist)
1426#pragma alloc_text(GREP,SecsSince1980,match,mmatch,GrepThread)
1427#pragma alloc_text(GREP,doallsubdirs,domatchingfiles,InsertDupes,FreeDupes)
1428
1429#pragma alloc_text(DUPES,InsertDupe,FillDupes,FreeDupes,CRCFile,CRCBlock)
1430#pragma alloc_text(DUPES,comparenamesq,comparenamesqe,comparenamesb)
1431#pragma alloc_text(DUPES,comparenamesbe,comparesizesq,comparesizesb)
Note: See TracBrowser for help on using the repository browser.