source: trunk/dll/grep.c@ 1665

Last change on this file since 1665 was 1665, checked in by Gregg Young, 13 years ago

Replace SleepIfNeeded with IdleIfNeeded to improve IU response during long searches; Currently it will switch back an forth between normal and idle priority.

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