source: trunk/dll/grep.c@ 1208

Last change on this file since 1208 was 1208, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

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