source: trunk/dll/grep.c@ 908

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

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

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