source: trunk/dll/grep.c@ 1402

Last change on this file since 1402 was 1402, checked in by Gregg Young, 16 years ago

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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