source: trunk/dll/grep.c@ 1039

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

Removed unnecessary xfrees and included fortify.h where needed; moved several misplaced (x)frees;

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