source: trunk/dll/grep.c@ 1303

Last change on this file since 1303 was 1303, checked in by Gregg Young, 17 years ago

Last part of remove or replace with a mutex semaphore DosEnterCriSec where appropriate. (Ticket 308) Note the partial commits for this ticket won't build without this.

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