source: trunk/dll/grep.c@ 1438

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

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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