source: trunk/dll/grep.c@ 1010

Last change on this file since 1010 was 1009, checked in by Steven Levine, 17 years ago

Add xfree xstrdup Fortify support
Add MT capable Fortify scope logic

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