source: trunk/dll/grep.c@ 1524

Last change on this file since 1524 was 1524, checked in by Gregg Young, 15 years ago

Suppress ERROR_FILENAME_EXCED_RANGE error message on NTFS (Ticket 435)

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