source: trunk/dll/grep.c@ 1498

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

Changes to get FM2 to compile with the latest watcom 1.9 beta (mostly type casts of CHAR CONSTANT * to CHAR *). Changes to get the environment settings working everywhere again (broken by the change that moved commands to the INI); Added an environment size variable (set to 2048 which was the largest I found hard coded). Still need to find everywhere the environment size is set and use this variable.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.6 KB
RevLine 
[51]1
2/***********************************************************************
3
4 $Id: grep.c 1498 2010-01-18 00:57:01Z 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.
[1498]35 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
[51]36
37***********************************************************************/
38
[2]39#include <stdlib.h>
40#include <string.h>
41#include <ctype.h>
42#include <share.h>
[163]43
[907]44#define INCL_DOS
45#define INCL_DOSERRORS
46#define INCL_WIN
47#define INCL_LONGLONG
48
[1179]49#include "fm3dll.h"
[1223]50#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1208]51#include "notebook.h" // Data declaration(s)
52#include "newview.h" // Data declarations
[2]53#include "fm3str.h"
54#include "grep.h"
[1157]55#include "pathutil.h" // BldFullPathName
56#include "filldir.h" // FillInRecordFromFFB
57#include "makelist.h" // AddToList
58#include "errutil.h" // Dos_Error...
59#include "strutil.h" // GetPString
60#include "tmrsvcs.h" // ITIMER_DESC
[1179]61#include "common.h" // DecrThreadUsage, IncrThreadUsage
62#include "valid.h" // MakeFullName
63#include "literal.h" // wildcard
64#include "wrappers.h" // xDosFindNext
[1157]65#include "eas.h" // Free_FEAList
[1179]66#include "stristr.h" // findstring
67#include "misc.h" // PostMsg
[1011]68#include "fortify.h"
[1303]69#include "init.h" // Golbal semaphore
[2]70
[948]71static VOID DoAllSubdirs(GREP *grep,
[1157]72 CHAR *searchPath,
73 BOOL recursing,
74 char **fle,
75 UINT numfls,
76 ITIMER_DESC *pitdSleep,
77 ITIMER_DESC *pitdReport);
[948]78static INT DoMatchingFiles(GREP *grep,
[1157]79 CHAR *path,
80 CHAR **fle,
81 UINT numfls,
82 ITIMER_DESC *pitdSleep,
83 ITIMER_DESC *pitdReport);
[948]84static BOOL DoOneFile(GREP *grep,
[1157]85 CHAR *fileName,
86 FILEFINDBUF4L *pffb,
87 ITIMER_DESC *pitdSleep,
88 ITIMER_DESC *pitdReport);
[948]89static BOOL DoInsertion(GREP *grep,
[1157]90 ITIMER_DESC *pitdSleep,
91 ITIMER_DESC *pitdReport);
[841]92static BOOL InsertDupe(GREP *grep, CHAR *dir, FILEFINDBUF4L *pffb);
[948]93static VOID FillDupes(GREP *grep,
[1157]94 ITIMER_DESC *pitdSleep,
95 ITIMER_DESC *pitdReport);
[948]96
[783]97static VOID FreeDupes(GREP *grep);
[2]98
99#define GREPCHARS "*?[] \\"
100
101#define isleap(year) ((((year%4)==0) && ((year%100)!=0)) || \
[1157]102 ((year%400)==0))
[2]103
[1208]104// Data definitions
105#pragma data_seg(DATA2)
106static PSZ pszSrcFile = __FILE__;
[551]107static INT monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
[2]108
[1208]109#pragma data_seg(GLOBAL1)
110HWND hwndStatus;
111
112
[948]113ULONG SecsSince1980(FDATE *date, FTIME *time)
[51]114{
[841]115 ULONG total = 0;
[948]116 UINT x;
[2]117
[551]118 for (x = 1980; x < date->year + 1980; x++) {
119 if (isleap(x))
[841]120 total += (366 * (24 * 60 * 60));
[2]121 else
[841]122 total += (365 * (24 * 60 * 60));
[2]123 }
[551]124 for (x = 1; x < date->month; x++) {
125 if (x == 2 && isleap(date->year + 1980))
[841]126 total += (29 * (24 * 60 * 60));
[2]127 else
[841]128 total += ((long)monthdays[x - 1] * (24 * 60 * 60));
[2]129 }
[841]130 total += (((long)date->day - 1) * (24 * 60 * 60));
131 total += ((long)time->hours * (60 * 60));
132 total += ((long)time->minutes * 60);
133 total += ((long)time->twosecs * 2);
[2]134 return total;
135}
136
137/*
138 * this function originally from C_ECHO's Snippets -- modified
139 * brute force methodology
140 */
141
[948]142static BOOL m_match(CHAR *string, CHAR *pattern, BOOL absolute, BOOL ignore,
[1157]143 LONG len)
[551]144{
[783]145 // return TRUE if pattern found in string
[2]146 register CHAR *tn = pattern;
[551]147 register LONG len2 = 0;
148 LONG lastlen = 0;
149 CHAR lo, hi;
[2]150
[551]151 if (len && string && pattern) {
[1157]152 if (absolute) // no pattern matching
[551]153 return (findstring(pattern, strlen(pattern), string, len,
[1157]154 (ignore == FALSE)) != NULL);
[2]155
[551]156 while (*tn && len2 < len) {
157 switch (*tn) {
158 case ' ':
[1157]159 while (*tn == ' ')
160 tn++;
161 while (len2 < len && isspace(string[len2]))
162 len2++;
163 break;
[2]164
[551]165 case '*':
[1157]166 while (*tn == '*' || *tn == '?')
167 tn++;
168 if (!*tn)
169 return TRUE;
170 if (ignore) {
171 while (len2 < len && string[len2] != *tn)
172 len2++;
173 }
174 else {
175 while (len2 < len && toupper(string[len2] != *tn))
176 len2++;
177 }
178 break;
[2]179
[551]180 case '[':
[1157]181 tn++;
182 if (!*tn)
183 return FALSE;
184 lo = *tn;
185 tn++;
186 if (*tn != '-')
187 return FALSE;
188 tn++;
189 if (!*tn)
190 return FALSE;
191 hi = *tn;
192 tn++;
193 if (*tn != ']')
194 return FALSE;
195 tn++;
196 if (ignore) {
197 if ((toupper(string[len2]) >= toupper(lo)) &&
198 (toupper(string[len2]) <= toupper(hi)))
199 len2++;
200 else {
201 tn = pattern;
202 len2 = lastlen = lastlen + 1;
203 }
204 }
205 else {
206 if ((string[len2] >= lo) && (string[len2] <= hi))
207 len2++;
208 else {
209 tn = pattern;
210 len2 = lastlen = lastlen + 1;
211 }
212 }
213 break;
[2]214
[551]215 case '?':
[1157]216 tn++;
217 len2++;
218 break;
[2]219
[551]220 case '\\':
[1157]221 tn++;
222 if (!*tn)
223 return FALSE;
224 // else intentional fallthru
[551]225 default:
[1157]226 if (ignore) {
227 if (toupper(*tn) == toupper(string[len2])) {
228 tn++;
229 len2++;
230 }
231 else {
232 tn = pattern;
233 len2 = lastlen = lastlen + 1;
234 }
235 }
236 else {
237 if (*tn == string[len2]) {
238 tn++;
239 len2++;
240 }
241 else {
242 tn = pattern;
243 len2 = lastlen = lastlen + 1;
244 }
245 }
246 break;
[2]247 }
248 }
[551]249 while (*tn == '*')
[2]250 tn++;
251
252 if (!*tn)
253 return TRUE;
254 }
255 return FALSE;
256}
257
[948]258static BOOL match(CHAR *string, CHAR *patterns, BOOL absolute, BOOL ignore,
[1157]259 LONG len, ULONG numlines, CHAR *matched, BOOL matchall)
[551]260{
261 BOOL ret = FALSE;
[2]262 register CHAR *p;
263 register ULONG x = 0;
264
265 p = patterns;
[551]266 while (!ret && *p) {
267 ret = m_match(string, p, absolute, ignore, len);
268 if (matchall && ret)
[2]269 break;
[551]270 if (matched && ret && x < numlines)
[2]271 matched[x] = 1;
[1157]272 p += strlen(p); // check each pattern in 0-terminated list
[2]273 p++;
274 x++;
275 }
276 return ret;
277}
278
[948]279VOID GrepThread(VOID *arg)
[51]280{
[551]281 HAB ghab;
282 HMQ ghmq;
283 GREP grep;
[948]284 UINT x;
285 UINT numfls;
[1157]286 static CHAR *fle[512]; // 06 Feb 08 SHL fixme to not be static
[551]287 CHAR *p, *pp, searchPath[CCHMAXPATH * 2];
[2]288
[1157]289 ITIMER_DESC itdSleep = { 0 }; // 06 Feb 08 SHL
[948]290 ITIMER_DESC itdReport = { 0 };
291
[783]292 if (!arg) {
[1398]293 Runtime_Error(pszSrcFile, __LINE__, NULL);
[2]294 return;
[783]295 }
296
[1038]297# ifdef FORTIFY
298 Fortify_EnterScope();
[1063]299# endif
[783]300 grep = *(GREP *)arg;
[1157]301 *grep.stopflag = 0; // reset thread-killing flag
[2]302 DosError(FERR_DISABLEHARDERR);
303 priority_normal();
304
305 ghab = WinInitialize(0);
[551]306 if (ghab) {
[2]307 grep.ghab = ghab;
[551]308 ghmq = WinCreateMsgQueue(ghab, 0);
309 if (ghmq) {
310 WinCancelShutdown(ghmq, TRUE);
[528]311 IncrThreadUsage();
[1157]312 // DosSleep(100); //05 Aug 07 GKY 128 // 07 Feb 08 SHL
[948]313 // hwndStatus does not exist for applet
314 WinSetWindowText(hwndStatus ? hwndStatus : grep.hwndCurFile,
[1498]315 (CHAR *) GetPString(grep.finddupes ? IDS_GREPDUPETEXT :
[1157]316 IDS_GREPSCANTEXT));
[2]317
318 pp = grep.searchPattern;
[551]319 while (*pp) {
[1157]320 if (!grep.absFlag) {
321 p = GREPCHARS; // see if any sense in pattern matching
322 while (*p) {
323 if (strchr(pp, *p))
324 break;
325 p++;
326 }
327 if (!*p) // nope, turn it off
328 grep.absFlag = TRUE;
329 }
330 pp = pp + strlen(pp) + 1;
[2]331 }
332
333 grep.attrFile &= (~FILE_DIRECTORY);
334 grep.antiattr &= (~FILE_DIRECTORY);
[551]335 if (grep.antiattr & FILE_READONLY)
[1157]336 grep.antiattr |= MUST_HAVE_READONLY;
[551]337 if (grep.antiattr & FILE_HIDDEN)
[1157]338 grep.antiattr |= MUST_HAVE_HIDDEN;
[551]339 if (grep.antiattr & FILE_SYSTEM)
[1157]340 grep.antiattr |= MUST_HAVE_SYSTEM;
[551]341 if (grep.antiattr & FILE_ARCHIVED)
[1157]342 grep.antiattr |= MUST_HAVE_ARCHIVED;
[2]343
344 grep.anyexcludes = FALSE;
[948]345 numfls = 0;
[551]346 fle[numfls++] = strtok(grep.tosearch, ";");
[948]347
[551]348 while ((fle[numfls] = strtok(NULL, ";")) != NULL && numfls < 511) {
[1157]349 if (*fle[numfls] == '/')
350 grep.anyexcludes = TRUE;
351 numfls++;
[2]352 }
353
[1157]354 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
355 InitITimer(&itdReport, 2000); // Report every 2 sec
[2]356
[948]357 // loop through search masks
358 for (x = 0; x < numfls; x++) {
359
[1157]360 if (*fle[x] == '/') // is an exclude mask only
361 goto ExcludeSkip;
[2]362
[1157]363 // first, separate any path from mask
[2]364
[1157]365 p = (char *)(fle[x] + (strlen(fle[x]) - 1));
366 while (*p != '\\' && *p != ':' && p != fle[x])
367 --p;
[2]368
[1157]369 if (p == fle[x]) { // no path
370 strcpy(searchPath, grep.curdir);
371 strncpy(grep.fileMask, fle[x], CCHMAXPATH);
372 grep.fileMask[CCHMAXPATH - 1] = 0;
373 }
374 else { // got to deal with a path
375 if (*p == ':') { // just a drive, start in root dir
376 *p = 0;
377 p++;
378 strncpy(searchPath, fle[x], CCHMAXPATH - 2);
379 searchPath[CCHMAXPATH - 3] = 0;
380 strcat(searchPath, ":\\");
381 strcpy(grep.fileMask, p);
382 }
383 if (*p == '\\') {
384 // got a 'full' path
385 CHAR temp;
[2]386
[1157]387 p++;
388 temp = *p;
389 *p = 0;
390 strncpy(searchPath, fle[x], CCHMAXPATH);
391 searchPath[CCHMAXPATH - 1] = 0;
392 *p = temp;
393 strcpy(grep.fileMask, p);
394 }
395 if (!*grep.fileMask)
396 strcpy(grep.fileMask, "*");
397 }
398 if (*grep.stopflag)
399 break;
400 // do single directory
401 DoMatchingFiles(&grep, searchPath, fle, numfls, &itdSleep, &itdReport);
402 if (grep.dirFlag) // do subdirs
403 DoAllSubdirs(&grep, searchPath, FALSE, fle, numfls, &itdSleep, &itdReport);
[551]404 ExcludeSkip:
[1157]405 if (*grep.stopflag)
406 break;
407 if (WinIsWindow(grep.ghab, grep.hwndFiles))
408 DoInsertion(&grep, &itdSleep, &itdReport); // insert any remaining objects
[948]409 } // for
[2]410
[551]411 if (WinIsWindow(grep.ghab, grep.hwndFiles))
[1157]412 DoInsertion(&grep, &itdSleep, &itdReport); // insert any remaining objects
[2]413
[948]414 if (WinIsWindow(grep.ghab, grep.hwndFiles) &&
[1157]415 grep.finddupes &&
416 !*grep.stopflag)
[948]417 {
[1157]418 FillDupes(&grep, &itdSleep, &itdReport);
[948]419 }
[2]420
[1157]421 if (!PostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID)) // tell window we're done
422 WinSendMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]423 WinDestroyMsgQueue(ghmq);
424 }
[528]425 DecrThreadUsage();
[2]426 WinTerminate(ghab);
427 }
[551]428 if (!ghmq || !ghab)
429 WinPostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
430 if (grep.dupehead)
[2]431 FreeDupes(&grep);
[1032]432 if (grep.numlines && grep.matched) {
[2]433 free(grep.matched);
[1032]434 }
[948]435 // 07 Feb 08 SHL fixme to free grep here when not static
[1029]436# ifdef FORTIFY
437 Fortify_LeaveScope();
[1063]438# endif
[2]439 DosPostEventSem(CompactSem);
440}
441
[948]442static BOOL IsExcluded(CHAR *name, CHAR **fle, UINT numfls)
[51]443{
[948]444 UINT x;
445 CHAR *n;
[2]446
[551]447 n = strrchr(name, '\\');
448 if (!n)
449 n = strrchr(name, ':');
450 if (n)
[2]451 n++;
452 else
453 n = name;
[551]454 for (x = 0; x < numfls; x++) {
455 if (*fle[x] == '/' &&
[1157]456 wildcard((strchr(fle[x], '\\') ||
457 strchr(fle[x], ':')) ? name : n, fle[x] + 1, FALSE))
[2]458 return TRUE;
459 }
460 return FALSE;
461}
462
[948]463static VOID DoAllSubdirs(GREP *grep,
[1157]464 CHAR *searchPath,
465 BOOL recursing,
466 CHAR **fle,
467 UINT numfls,
468 ITIMER_DESC *pitdSleep,
469 ITIMER_DESC *pitdReport)
[551]470{
[783]471 // process all subdirectories
[2]472
[847]473 FILEFINDBUF4 ffb;
[551]474 HDIR findHandle = HDIR_CREATE;
[783]475 LONG ulFindCnt = 1;
[551]476 CHAR *p = NULL;
[2]477
[783]478 // add a mask to search path
[1438]479 AddBackslashToPath(searchPath);
480 //if (searchPath[strlen(searchPath) - 1] != '\\')
481 // strcat(searchPath, "\\");
[551]482 strcat(searchPath, "*");
[783]483 // step through all subdirectories
[2]484 DosError(FERR_DISABLEHARDERR);
[847]485 if (!DosFindFirst(searchPath, &findHandle, (MUST_HAVE_DIRECTORY |
[1157]486 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY),
487 &ffb, (ULONG) sizeof(ffb),
488 (PULONG) & ulFindCnt, FIL_QUERYEASIZE)) {
[2]489
[783]490 // get rid of mask portion, save end-of-directory
[2]491
[551]492 p = strrchr(searchPath, '\\');
493 if (p)
[2]494 p++;
495 else
496 p = searchPath;
[1157]497 do { // Process each directory that matches the mask
[2]498 priority_normal();
[551]499 if (*grep->stopflag)
[1157]500 break;
[517]501 // Skip . and ..
[783]502 if (ffb.achName[0] != '.' ||
[1157]503 (ffb.achName[1] &&
504 (ffb.achName[1] != '.' || ffb.achName[2]))) {
505 strcpy(p, ffb.achName);
506 if (!grep->anyexcludes || !IsExcluded(searchPath, fle, numfls)) {
507 // 07 Feb 08 SHL
508 if (IsITimerExpired(pitdReport)) {
509 if (!hwndStatus)
510 WinSetWindowText(grep->hwndCurFile, searchPath);
511 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
512 CHAR s[CCHMAXPATH + 64];
513 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), searchPath);
514 WinSetWindowText(hwndStatus, s);
515 }
516 }
517 DoMatchingFiles(grep, searchPath, fle, numfls, pitdSleep, pitdReport);
518 // 07 Feb 08 SHL
519 if (IsITimerExpired(pitdReport)) {
520 if (!hwndStatus)
521 WinSetWindowText(grep->hwndCurFile, searchPath);
522 else {
523 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
524 CHAR s[CCHMAXPATH + 64];
525 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), searchPath);
526 WinSetWindowText(hwndStatus, s);
527 }
528 }
529 }
530 DoAllSubdirs(grep, searchPath, TRUE, fle, numfls, pitdSleep, pitdReport);
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 ULONG ulBufBytes = FilesToGet * sizeof(FILEFINDBUF4L);
[839]566 static BOOL fDone;
[2]567
[783]568 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
569 if (!pffbArray)
[2]570 return 0;
571
[783]572 BldFullPathName(szFindPath, path, grep->fileMask);
[2]573
[783]574 MakeFullName(szFindPath);
[2]575
[783]576 // find and save end-of-dir position
577 p = strrchr(szFindPath, '\\');
[551]578 if (p)
[2]579 p++;
580 else
[783]581 p = szFindPath;
[2]582
[783]583 // step through matching files
[2]584 DosError(FERR_DISABLEHARDERR);
[785]585 ulFindCnt = FilesToGet;
[848]586 rc = xDosFindFirst(szFindPath,
[1157]587 &findHandle,
588 FILE_NORMAL | grep->attrFile | grep->antiattr,
589 pffbArray,
590 ulBufBytes,
591 &ulFindCnt,
592 FIL_QUERYEASIZEL);
[783]593 if (!rc) {
594 do {
595 // Process each file that matches the mask
[2]596 priority_normal();
[783]597 pffbFile = pffbArray;
598 for (x = 0; x < ulFindCnt; x++) {
[1157]599 if (*grep->stopflag)
600 break;
601 if (*pffbFile->achName != '.' ||
602 (pffbFile->achName[1] && pffbFile->achName[1] != '.')) {
603 strcpy(p, pffbFile->achName); // build filename
604 if (strlen(szFindPath) > CCHMAXPATH){
605 // Complain if pathnames exceeds max
606 DosFindClose(findHandle);
607 if (!fDone) {
608 fDone = TRUE;
609 saymsg(MB_OK | MB_ICONASTERISK,
610 HWND_DESKTOP,
611 GetPString(IDS_WARNINGTEXT),
[1402]612 GetPString(IDS_LENGTHEXCEEDSMAXPATHTEXT));
[1157]613 }
614 return 1;
615 }
[948]616
[1157]617 // 07 Feb 08 SHL
618 if (IsITimerExpired(pitdReport)) {
619 if (!hwndStatus)
620 WinSetWindowText(grep->hwndCurFile, szFindPath);
621 else {
622 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
623 CHAR s[CCHMAXPATH + 64];
624 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), szFindPath);
625 WinSetWindowText(hwndStatus, s);
626 }
627 }
628 }
[948]629
[1157]630 if (!grep->anyexcludes || !IsExcluded(szFindPath, fle, numfls)) {
631 if (!grep->finddupes)
632 DoOneFile(grep, szFindPath, pffbFile, pitdSleep, pitdReport);
633 else if (!InsertDupe(grep, szFindPath, pffbFile)) {
634 DosFindClose(findHandle);
635 free(pffbArray);
[1063]636# ifdef FORTIFY
637 Fortify_LeaveScope();
638# endif
[1157]639 return 1;
640 }
641 }
642 }
643 if (!pffbFile->oNextEntryOffset)
644 break;
645 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]646 } // for
647 if (*grep->stopflag)
[1157]648 break;
[948]649 SleepIfNeeded(pitdSleep, 1);
[1157]650 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[785]651 ulFindCnt = FilesToGet;
[850]652 rc = xDosFindNext(findHandle, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[551]653 } while (!rc);
[783]654
[2]655 DosFindClose(findHandle);
656 priority_normal();
[783]657 } // if
658
659 if (rc && rc != ERROR_NO_MORE_FILES) {
660 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
[1157]661 GetPString(IDS_CANTFINDDIRTEXT), szFindPath);
[2]662 }
[783]663
[1039]664 free(pffbArray);
[1029]665# ifdef FORTIFY
666 Fortify_LeaveScope();
[1063]667# endif
[551]668 return 0;
[2]669}
670
[948]671static VOID freegreplist(GREP *grep)
[51]672{
[948]673 UINT x;
[2]674
[551]675 if (grep) {
676 if (grep->insertffb) {
[1032]677 for (x = 0; grep->insertffb[x]; x++) {
678 free(grep->insertffb[x]);
679 }
[1039]680 free(grep->insertffb);
[2]681 }
[551]682 if (grep->dir) {
[1032]683 for (x = 0; grep->dir[x]; x++) {
684 free(grep->dir[x]);
685 }
[1039]686 free(grep->dir);
[2]687 }
688 grep->dir = NULL;
689 grep->insertffb = NULL;
690 grep->toinsert = 0L;
691 grep->insertedbytes = 0L;
[1063]692# ifdef FORTIFY
693 Fortify_LeaveScope();
694# endif
[2]695 }
696}
697
[948]698/**
[1471]699 * Insert one or more records into container
[948]700 */
701
702static BOOL DoInsertion(GREP *grep,
[1157]703 ITIMER_DESC *pitdSleep,
704 ITIMER_DESC *pitdReport)
[51]705{
[2]706 RECORDINSERT ri;
[551]707 DIRCNRDATA *dcd;
708 PCNRITEM pci, pciFirst;
[948]709 UINT x;
[2]710
[551]711 if (!grep || !grep->toinsert || !grep->insertffb || !grep->dir)
[2]712 return FALSE;
[948]713
[2]714 pci = WinSendMsg(grep->hwndFiles,
[1157]715 CM_ALLOCRECORD,
716 MPFROMLONG(EXTRA_RECORD_BYTES),
717 MPFROMLONG(grep->toinsert));
[948]718 if (!pci) {
719 Win_Error(grep->hwndFiles, grep->hwndFiles, pszSrcFile, __LINE__,
[1402]720 PCSZ_CM_ALLOCRECORD);
[948]721 }
722 else {
723 if (grep->sayfiles) {
724 if (!hwndStatus)
[1498]725 WinSetWindowText(grep->hwndCurFile, (CHAR *) GetPString(IDS_GREPINSERTINGTEXT));
[948]726 else {
[1157]727 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
[1498]728 WinSetWindowText(hwndStatus, (CHAR *) GetPString(IDS_GREPINSERTINGTEXT));
[948]729 }
730 }
[2]731 pciFirst = pci;
732 dcd = INSTDATA(grep->hwndFiles);
[551]733 for (x = 0; grep->insertffb[x]; x++) {
[2]734 FillInRecordFromFFB(grep->hwndFiles,
[1157]735 pci, grep->dir[x], grep->insertffb[x], FALSE, dcd);
[2]736 pci = (PCNRITEM) pci->rc.preccNextRecord;
[948]737 SleepIfNeeded(pitdSleep, 1);
738 } // for
[551]739 memset(&ri, 0, sizeof(RECORDINSERT));
740 ri.cb = sizeof(RECORDINSERT);
741 ri.pRecordOrder = (PRECORDCORE) CMA_END;
742 ri.pRecordParent = (PRECORDCORE) NULL;
743 ri.zOrder = (USHORT) CMA_TOP;
744 ri.cRecordsInsert = grep->toinsert;
745 ri.fInvalidateRecord = TRUE;
[2]746 WinSendMsg(grep->hwndFiles,
[1157]747 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
[551]748 if (dcd) {
[1303]749 //DosEnterCritSec(); //GKY 11-29-08
750 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
[551]751 dcd->ullTotalBytes += grep->insertedbytes;
[1303]752 DosReleaseMutexSem(hmtxFM2Globals);
753 //DosExitCritSec();
[2]754 }
[948]755 SleepIfNeeded(pitdSleep, 1);
[1157]756 // if (grep->toinsert == FilesToGet) // 07 Feb 08 SHL
757 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[2]758 freegreplist(grep);
[551]759 PostMsg(grep->hwndFiles, UM_RESCAN, MPVOID, MPVOID);
[2]760 return TRUE;
761 }
762 freegreplist(grep);
763 return FALSE;
764}
765
[948]766/**
767 * Insert file ffb and directory name into lists
768 */
769
770static BOOL InsertGrepFile(GREP *grep,
[1157]771 CHAR *pszFileName,
772 PFILEFINDBUF4L pffb,
773 ITIMER_DESC *pitdSleep,
774 ITIMER_DESC *pitdReport)
[51]775{
[783]776 PSZ p;
777 CHAR szDirectory[CCHMAXPATH];
[2]778
[948]779 if (!WinIsWindow(grep->ghab, grep->hwndFiles)) {
780 // Window closed - clean up and go away
781 freegreplist(grep);
782 }
783 else {
[2]784 grep->numfiles++;
[948]785 strcpy(szDirectory, pszFileName);
[551]786 p = strrchr(szDirectory, '\\');
[948]787
[551]788 if (p) {
[948]789 // Got directory
[551]790 if (p < szDirectory + 4)
[1157]791 p++; // Include root backslash
[2]792 *p = 0;
[948]793
[551]794 if (!grep->insertffb) {
[1157]795 // Allocate 1 extra for end marker?
796 grep->insertffb = xmallocz(sizeof(PFILEFINDBUF4L) * (FilesToGet + 1),
797 pszSrcFile, __LINE__);
798 if (!grep->insertffb)
799 return FALSE;
800 grep->dir = xmallocz(sizeof(CHAR *) * (FilesToGet + 1),
801 pszSrcFile, __LINE__);
802 if (!grep->dir) {
803 free(grep->insertffb);
[1063]804# ifdef FORTIFY
805 Fortify_LeaveScope();
806# endif
[1157]807 return FALSE;
808 }
[2]809 }
[948]810
[551]811 grep->insertffb[grep->toinsert] =
[1157]812 xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
[551]813 if (!grep->insertffb[grep->toinsert])
[1157]814 return FALSE;
[841]815 memcpy(grep->insertffb[grep->toinsert], pffb, sizeof(FILEFINDBUF4L));
[948]816
[551]817 grep->dir[grep->toinsert] = xstrdup(szDirectory, pszSrcFile, __LINE__);
818 if (!grep->dir) {
[1039]819 free(grep->insertffb[grep->toinsert]);
[1063]820# ifdef FORTIFY
821 Fortify_LeaveScope();
822# endif
[1157]823 return FALSE;
[2]824 }
[948]825
[783]826 grep->insertedbytes += pffb->cbFile + CBLIST_TO_EASIZE(pffb->cbList);
[2]827 grep->toinsert++;
[1471]828 // 07 Oct 09 SHL honor sync updates
829 if (grep->toinsert == FilesToGet || fSyncUpdates)
[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)
[1498]1332 WinSetWindowText(grep->hwndCurFile, (CHAR *) GetPString(IDS_GREPDUPESORTINGTEXT));
[948]1333 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
[1498]1334 WinSetWindowText(hwndStatus, (CHAR *) 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)
[1498]1368 WinSetWindowText(grep->hwndCurFile, (CHAR *) GetPString(IDS_GREPDUPECOMPARINGTEXT));
[948]1369 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
[1498]1370 WinSetWindowText(hwndStatus, (CHAR *) 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)
[1498]1526 WinSetWindowText(grep->hwndCurFile, (CHAR *) GetPString(IDS_GREPDUPECOMPARINGTEXT));
[948]1527 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
[1498]1528 WinSetWindowText(hwndStatus, (CHAR *) 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.