source: trunk/dll/grep.c@ 1029

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

Fixed early memory free; Added free_... functions to make fortify checking easier; Added fortify scopes; Delete now moves to trash can on systems with the xworkplace trash can installed.

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