source: trunk/dll/grep.c@ 1017

Last change on this file since 1017 was 1017, checked in by Gregg Young, 17 years ago

fortify updates for threads dble free fix

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