source: trunk/dll/grep.c@ 1564

Last change on this file since 1564 was 1564, checked in by Gregg Young, 14 years ago

Rework filldir and grep directories to correctly support more than 65K records.
Collector was trapping. Added SleepIfNeeded to loops to improve WPS responsiveness.

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