source: trunk/dll/grep.c@ 1036

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

Fortify updates including a leave scope wrapper which frees and in some cases reloads commands, archivers, association, etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.5 KB
RevLine 
[51]1
2/***********************************************************************
3
4 $Id: grep.c 1032 2008-06-30 02:55:36Z 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
[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
[2]44#include "fm3str.h"
45#include "grep.h"
[907]46#include "pathutil.h" // BldFullPathName
47#include "filldir.h" // FillInRecordFromFFB
48#include "makelist.h" // AddToList
49#include "errutil.h" // Dos_Error...
50#include "strutil.h" // GetPString
[948]51#include "tmrsvcs.h" // ITIMER_DESC
[907]52#include "fm3dll.h"
[1011]53#include "fortify.h"
[2]54
55#pragma data_seg(DATA2)
[350]56
57static PSZ pszSrcFile = __FILE__;
58
[948]59static VOID DoAllSubdirs(GREP *grep,
60 CHAR *searchPath,
61 BOOL recursing,
62 char **fle,
63 UINT numfls,
64 ITIMER_DESC *pitdSleep,
65 ITIMER_DESC *pitdReport);
66static INT DoMatchingFiles(GREP *grep,
67 CHAR *path,
68 CHAR **fle,
69 UINT numfls,
70 ITIMER_DESC *pitdSleep,
71 ITIMER_DESC *pitdReport);
72static BOOL DoOneFile(GREP *grep,
73 CHAR *fileName,
74 FILEFINDBUF4L *pffb,
75 ITIMER_DESC *pitdSleep,
76 ITIMER_DESC *pitdReport);
77static BOOL DoInsertion(GREP *grep,
78 ITIMER_DESC *pitdSleep,
79 ITIMER_DESC *pitdReport);
[841]80static BOOL InsertDupe(GREP *grep, CHAR *dir, FILEFINDBUF4L *pffb);
[948]81static VOID FillDupes(GREP *grep,
82 ITIMER_DESC *pitdSleep,
83 ITIMER_DESC *pitdReport);
84
[783]85static VOID FreeDupes(GREP *grep);
[2]86
87#define GREPCHARS "*?[] \\"
88
89#define isleap(year) ((((year%4)==0) && ((year%100)!=0)) || \
[783]90 ((year%400)==0))
[2]91
[551]92static INT monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
[2]93
[948]94ULONG SecsSince1980(FDATE *date, FTIME *time)
[51]95{
[841]96 ULONG total = 0;
[948]97 UINT x;
[2]98
[551]99 for (x = 1980; x < date->year + 1980; x++) {
100 if (isleap(x))
[841]101 total += (366 * (24 * 60 * 60));
[2]102 else
[841]103 total += (365 * (24 * 60 * 60));
[2]104 }
[551]105 for (x = 1; x < date->month; x++) {
106 if (x == 2 && isleap(date->year + 1980))
[841]107 total += (29 * (24 * 60 * 60));
[2]108 else
[841]109 total += ((long)monthdays[x - 1] * (24 * 60 * 60));
[2]110 }
[841]111 total += (((long)date->day - 1) * (24 * 60 * 60));
112 total += ((long)time->hours * (60 * 60));
113 total += ((long)time->minutes * 60);
114 total += ((long)time->twosecs * 2);
[2]115 return total;
116}
117
118/*
119 * this function originally from C_ECHO's Snippets -- modified
120 * brute force methodology
121 */
122
[948]123static BOOL m_match(CHAR *string, CHAR *pattern, BOOL absolute, BOOL ignore,
[551]124 LONG len)
125{
[783]126 // return TRUE if pattern found in string
[2]127 register CHAR *tn = pattern;
[551]128 register LONG len2 = 0;
129 LONG lastlen = 0;
130 CHAR lo, hi;
[2]131
[551]132 if (len && string && pattern) {
[783]133 if (absolute) // no pattern matching
[551]134 return (findstring(pattern, strlen(pattern), string, len,
135 (ignore == FALSE)) != NULL);
[2]136
[551]137 while (*tn && len2 < len) {
138 switch (*tn) {
139 case ' ':
140 while (*tn == ' ')
141 tn++;
142 while (len2 < len && isspace(string[len2]))
143 len2++;
144 break;
[2]145
[551]146 case '*':
147 while (*tn == '*' || *tn == '?')
148 tn++;
149 if (!*tn)
150 return TRUE;
151 if (ignore) {
152 while (len2 < len && string[len2] != *tn)
153 len2++;
154 }
155 else {
156 while (len2 < len && toupper(string[len2] != *tn))
157 len2++;
158 }
159 break;
[2]160
[551]161 case '[':
162 tn++;
163 if (!*tn)
164 return FALSE;
165 lo = *tn;
166 tn++;
167 if (*tn != '-')
168 return FALSE;
169 tn++;
170 if (!*tn)
171 return FALSE;
172 hi = *tn;
173 tn++;
174 if (*tn != ']')
175 return FALSE;
176 tn++;
177 if (ignore) {
178 if ((toupper(string[len2]) >= toupper(lo)) &&
179 (toupper(string[len2]) <= toupper(hi)))
180 len2++;
181 else {
182 tn = pattern;
183 len2 = lastlen = lastlen + 1;
184 }
185 }
186 else {
187 if ((string[len2] >= lo) && (string[len2] <= hi))
188 len2++;
189 else {
190 tn = pattern;
191 len2 = lastlen = lastlen + 1;
192 }
193 }
194 break;
[2]195
[551]196 case '?':
197 tn++;
198 len2++;
199 break;
[2]200
[551]201 case '\\':
202 tn++;
203 if (!*tn)
204 return FALSE;
[783]205 // else intentional fallthru
[551]206 default:
207 if (ignore) {
208 if (toupper(*tn) == toupper(string[len2])) {
209 tn++;
210 len2++;
211 }
212 else {
213 tn = pattern;
214 len2 = lastlen = lastlen + 1;
215 }
216 }
217 else {
218 if (*tn == string[len2]) {
219 tn++;
220 len2++;
221 }
222 else {
223 tn = pattern;
224 len2 = lastlen = lastlen + 1;
225 }
226 }
227 break;
[2]228 }
229 }
[551]230 while (*tn == '*')
[2]231 tn++;
232
233 if (!*tn)
234 return TRUE;
235 }
236 return FALSE;
237}
238
[948]239static BOOL match(CHAR *string, CHAR *patterns, BOOL absolute, BOOL ignore,
240 LONG len, ULONG numlines, CHAR *matched, BOOL matchall)
[551]241{
242 BOOL ret = FALSE;
[2]243 register CHAR *p;
244 register ULONG x = 0;
245
246 p = patterns;
[551]247 while (!ret && *p) {
248 ret = m_match(string, p, absolute, ignore, len);
249 if (matchall && ret)
[2]250 break;
[551]251 if (matched && ret && x < numlines)
[2]252 matched[x] = 1;
[783]253 p += strlen(p); // check each pattern in 0-terminated list
[2]254 p++;
255 x++;
256 }
257 return ret;
258}
259
[948]260VOID GrepThread(VOID *arg)
[51]261{
[551]262 HAB ghab;
263 HMQ ghmq;
264 GREP grep;
[948]265 UINT x;
266 UINT numfls;
267 static CHAR *fle[512]; // 06 Feb 08 SHL fixme to not be static
[551]268 CHAR *p, *pp, searchPath[CCHMAXPATH * 2];
[2]269
[948]270 ITIMER_DESC itdSleep = { 0 }; // 06 Feb 08 SHL
271 ITIMER_DESC itdReport = { 0 };
272
[783]273 if (!arg) {
274 Runtime_Error(pszSrcFile, __LINE__, "no data");
[2]275 return;
[783]276 }
277
278 grep = *(GREP *)arg;
279 *grep.stopflag = 0; // reset thread-killing flag
[2]280 DosError(FERR_DISABLEHARDERR);
281 priority_normal();
282
283 ghab = WinInitialize(0);
[551]284 if (ghab) {
[2]285 grep.ghab = ghab;
[551]286 ghmq = WinCreateMsgQueue(ghab, 0);
287 if (ghmq) {
288 WinCancelShutdown(ghmq, TRUE);
[528]289 IncrThreadUsage();
[1029]290# ifdef FORTIFY
291 Fortify_EnterScope();
292# endif
[948]293 // DosSleep(100); //05 Aug 07 GKY 128 // 07 Feb 08 SHL
294 // hwndStatus does not exist for applet
295 WinSetWindowText(hwndStatus ? hwndStatus : grep.hwndCurFile,
296 GetPString(grep.finddupes ? IDS_GREPDUPETEXT :
297 IDS_GREPSCANTEXT));
[2]298
299 pp = grep.searchPattern;
[551]300 while (*pp) {
301 if (!grep.absFlag) {
[783]302 p = GREPCHARS; // see if any sense in pattern matching
[551]303 while (*p) {
304 if (strchr(pp, *p))
305 break;
306 p++;
307 }
[783]308 if (!*p) // nope, turn it off
[551]309 grep.absFlag = TRUE;
310 }
311 pp = pp + strlen(pp) + 1;
[2]312 }
313
314 grep.attrFile &= (~FILE_DIRECTORY);
315 grep.antiattr &= (~FILE_DIRECTORY);
[551]316 if (grep.antiattr & FILE_READONLY)
317 grep.antiattr |= MUST_HAVE_READONLY;
318 if (grep.antiattr & FILE_HIDDEN)
319 grep.antiattr |= MUST_HAVE_HIDDEN;
320 if (grep.antiattr & FILE_SYSTEM)
321 grep.antiattr |= MUST_HAVE_SYSTEM;
322 if (grep.antiattr & FILE_ARCHIVED)
323 grep.antiattr |= MUST_HAVE_ARCHIVED;
[2]324
325 grep.anyexcludes = FALSE;
[948]326 numfls = 0;
[551]327 fle[numfls++] = strtok(grep.tosearch, ";");
[948]328
[551]329 while ((fle[numfls] = strtok(NULL, ";")) != NULL && numfls < 511) {
330 if (*fle[numfls] == '/')
331 grep.anyexcludes = TRUE;
332 numfls++;
[2]333 }
334
[948]335 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
336 InitITimer(&itdReport, 2000); // Report every 2 sec
[2]337
[948]338 // loop through search masks
339 for (x = 0; x < numfls; x++) {
340
[783]341 if (*fle[x] == '/') // is an exclude mask only
[551]342 goto ExcludeSkip;
[2]343
[783]344 // first, separate any path from mask
[2]345
[551]346 p = (char *)(fle[x] + (strlen(fle[x]) - 1));
347 while (*p != '\\' && *p != ':' && p != fle[x])
348 --p;
[2]349
[783]350 if (p == fle[x]) { // no path
[551]351 strcpy(searchPath, grep.curdir);
352 strncpy(grep.fileMask, fle[x], CCHMAXPATH);
353 grep.fileMask[CCHMAXPATH - 1] = 0;
354 }
[783]355 else { // got to deal with a path
356 if (*p == ':') { // just a drive, start in root dir
[551]357 *p = 0;
358 p++;
359 strncpy(searchPath, fle[x], CCHMAXPATH - 2);
360 searchPath[CCHMAXPATH - 3] = 0;
361 strcat(searchPath, ":\\");
362 strcpy(grep.fileMask, p);
363 }
[948]364 if (*p == '\\') {
365 // got a 'full' path
[551]366 CHAR temp;
[2]367
[551]368 p++;
369 temp = *p;
370 *p = 0;
371 strncpy(searchPath, fle[x], CCHMAXPATH);
372 searchPath[CCHMAXPATH - 1] = 0;
373 *p = temp;
374 strcpy(grep.fileMask, p);
375 }
376 if (!*grep.fileMask)
377 strcpy(grep.fileMask, "*");
378 }
379 if (*grep.stopflag)
380 break;
[783]381 // do single directory
[948]382 DoMatchingFiles(&grep, searchPath, fle, numfls, &itdSleep, &itdReport);
[783]383 if (grep.dirFlag) // do subdirs
[948]384 DoAllSubdirs(&grep, searchPath, FALSE, fle, numfls, &itdSleep, &itdReport);
[551]385 ExcludeSkip:
386 if (*grep.stopflag)
387 break;
388 if (WinIsWindow(grep.ghab, grep.hwndFiles))
[948]389 DoInsertion(&grep, &itdSleep, &itdReport); // insert any remaining objects
390 } // for
[2]391
[551]392 if (WinIsWindow(grep.ghab, grep.hwndFiles))
[948]393 DoInsertion(&grep, &itdSleep, &itdReport); // insert any remaining objects
[2]394
[948]395 if (WinIsWindow(grep.ghab, grep.hwndFiles) &&
396 grep.finddupes &&
[551]397 !*grep.stopflag)
[948]398 {
399 FillDupes(&grep, &itdSleep, &itdReport);
400 }
[2]401
[783]402 if (!PostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID)) // tell window we're done
[551]403 WinSendMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]404 WinDestroyMsgQueue(ghmq);
405 }
[528]406 DecrThreadUsage();
[2]407 WinTerminate(ghab);
408 }
[551]409 if (!ghmq || !ghab)
410 WinPostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
411 if (grep.dupehead)
[2]412 FreeDupes(&grep);
[1032]413 if (grep.numlines && grep.matched) {
414# ifdef FORTIFY
415 xfree(grep.matched, pszSrcFile, __LINE__);
416# else
[2]417 free(grep.matched);
[1032]418# endif
419 }
[948]420 // 07 Feb 08 SHL fixme to free grep here when not static
[1029]421# ifdef FORTIFY
422 Fortify_LeaveScope();
423# endif
[2]424 DosPostEventSem(CompactSem);
425}
426
[948]427static BOOL IsExcluded(CHAR *name, CHAR **fle, UINT numfls)
[51]428{
[948]429 UINT x;
430 CHAR *n;
[2]431
[551]432 n = strrchr(name, '\\');
433 if (!n)
434 n = strrchr(name, ':');
435 if (n)
[2]436 n++;
437 else
438 n = name;
[551]439 for (x = 0; x < numfls; x++) {
440 if (*fle[x] == '/' &&
441 wildcard((strchr(fle[x], '\\') ||
442 strchr(fle[x], ':')) ? name : n, fle[x] + 1, FALSE))
[2]443 return TRUE;
444 }
445 return FALSE;
446}
447
[948]448static VOID DoAllSubdirs(GREP *grep,
449 CHAR *searchPath,
450 BOOL recursing,
451 CHAR **fle,
452 UINT numfls,
453 ITIMER_DESC *pitdSleep,
454 ITIMER_DESC *pitdReport)
[551]455{
[783]456 // process all subdirectories
[2]457
[847]458 FILEFINDBUF4 ffb;
[551]459 HDIR findHandle = HDIR_CREATE;
[783]460 LONG ulFindCnt = 1;
[551]461 CHAR *p = NULL;
[2]462
[783]463 // add a mask to search path
[551]464 if (searchPath[strlen(searchPath) - 1] != '\\')
465 strcat(searchPath, "\\");
466 strcat(searchPath, "*");
[783]467 // step through all subdirectories
[2]468 DosError(FERR_DISABLEHARDERR);
[847]469 if (!DosFindFirst(searchPath, &findHandle, (MUST_HAVE_DIRECTORY |
470 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY),
471 &ffb, (ULONG) sizeof(ffb),
472 (PULONG) & ulFindCnt, FIL_QUERYEASIZE)) {
[2]473
[783]474 // get rid of mask portion, save end-of-directory
[2]475
[551]476 p = strrchr(searchPath, '\\');
477 if (p)
[2]478 p++;
479 else
480 p = searchPath;
[783]481 do { // Process each directory that matches the mask
[2]482 priority_normal();
[551]483 if (*grep->stopflag)
484 break;
[517]485 // Skip . and ..
[783]486 if (ffb.achName[0] != '.' ||
487 (ffb.achName[1] &&
488 (ffb.achName[1] != '.' || ffb.achName[2]))) {
489 strcpy(p, ffb.achName);
[551]490 if (!grep->anyexcludes || !IsExcluded(searchPath, fle, numfls)) {
[948]491 // 07 Feb 08 SHL
492 if (IsITimerExpired(pitdReport)) {
493 if (!hwndStatus)
494 WinSetWindowText(grep->hwndCurFile, searchPath);
495 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
496 CHAR s[CCHMAXPATH + 64];
497 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), searchPath);
498 WinSetWindowText(hwndStatus, s);
499 }
500 }
501 DoMatchingFiles(grep, searchPath, fle, numfls, pitdSleep, pitdReport);
502 // 07 Feb 08 SHL
503 if (IsITimerExpired(pitdReport)) {
504 if (!hwndStatus)
505 WinSetWindowText(grep->hwndCurFile, searchPath);
506 else {
507 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
508 CHAR s[CCHMAXPATH + 64];
509 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), searchPath);
510 WinSetWindowText(hwndStatus, s);
511 }
512 }
513 }
514 DoAllSubdirs(grep, searchPath, TRUE, fle, numfls, pitdSleep, pitdReport);
515 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[551]516 }
[2]517 }
[783]518 ulFindCnt = 1;
[847]519 } while (!DosFindNext(findHandle,
520 &ffb,
521 sizeof(ffb), (PULONG) & ulFindCnt));
[2]522 DosFindClose(findHandle);
523 priority_normal();
524 }
[783]525 if (p) // strip off last directory addition
[2]526 *p = 0;
527}
528
[948]529/**
530 * Scan for files matching filespecs in single directory
531 */
532
533static INT DoMatchingFiles(GREP *grep,
534 CHAR *path,
535 CHAR **fle,
536 UINT numfls,
537 ITIMER_DESC *pitdSleep,
538 ITIMER_DESC *pitdReport)
[51]539{
[783]540 // process all matching files in a directory
[2]541
[848]542 PFILEFINDBUF4L pffbArray;
543 PFILEFINDBUF4L pffbFile;
[783]544 ULONG x;
[551]545 HDIR findHandle = HDIR_CREATE;
[783]546 ULONG ulFindCnt;
547 CHAR szFindPath[CCHMAXPATH];
548 PSZ p;
[551]549 APIRET rc;
[850]550 // 06 Oct 07 SHL Correct size for xDosFindFirst
551 ULONG ulBufBytes = FilesToGet * sizeof(FILEFINDBUF4L);
[839]552 static BOOL fDone;
[2]553
[783]554 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
555 if (!pffbArray)
[2]556 return 0;
557
[783]558 BldFullPathName(szFindPath, path, grep->fileMask);
[2]559
[783]560 MakeFullName(szFindPath);
[2]561
[783]562 // find and save end-of-dir position
563 p = strrchr(szFindPath, '\\');
[551]564 if (p)
[2]565 p++;
566 else
[783]567 p = szFindPath;
[2]568
[783]569 // step through matching files
[2]570 DosError(FERR_DISABLEHARDERR);
[785]571 ulFindCnt = FilesToGet;
[848]572 rc = xDosFindFirst(szFindPath,
573 &findHandle,
574 FILE_NORMAL | grep->attrFile | grep->antiattr,
575 pffbArray,
576 ulBufBytes,
577 &ulFindCnt,
578 FIL_QUERYEASIZEL);
[783]579 if (!rc) {
580 do {
581 // Process each file that matches the mask
[2]582 priority_normal();
[783]583 pffbFile = pffbArray;
584 for (x = 0; x < ulFindCnt; x++) {
[551]585 if (*grep->stopflag)
586 break;
587 if (*pffbFile->achName != '.' ||
[948]588 (pffbFile->achName[1] && pffbFile->achName[1] != '.')) {
589 strcpy(p, pffbFile->achName); // build filename
590 if (strlen(szFindPath) > CCHMAXPATH){
591 // Complain if pathnames exceeds max
592 DosFindClose(findHandle);
[1017]593 //xfree(pffbArray, pszSrcFile, __LINE__);
[948]594 if (!fDone) {
595 fDone = TRUE;
596 saymsg(MB_OK | MB_ICONASTERISK,
597 HWND_DESKTOP,
[839]598 GetPString(IDS_WARNINGTEXT),
[948]599 "One or more of your files has a full path name that exceeds the OS/2 maximum");
600 }
[837]601 return 1;
[948]602 }
603
604 // 07 Feb 08 SHL
605 if (IsITimerExpired(pitdReport)) {
606 if (!hwndStatus)
607 WinSetWindowText(grep->hwndCurFile, szFindPath);
608 else {
609 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
610 CHAR s[CCHMAXPATH + 64];
611 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), szFindPath);
612 WinSetWindowText(hwndStatus, s);
613 }
614 }
615 }
616
[783]617 if (!grep->anyexcludes || !IsExcluded(szFindPath, fle, numfls)) {
[551]618 if (!grep->finddupes)
[948]619 DoOneFile(grep, szFindPath, pffbFile, pitdSleep, pitdReport);
[783]620 else if (!InsertDupe(grep, szFindPath, pffbFile)) {
[551]621 DosFindClose(findHandle);
[1009]622 xfree(pffbArray, pszSrcFile, __LINE__);
[1029]623# ifdef FORTIFY
624 Fortify_LeaveScope();
625# endif
[551]626 return 1;
627 }
628 }
629 }
630 if (!pffbFile->oNextEntryOffset)
631 break;
[848]632 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]633 } // for
634 if (*grep->stopflag)
635 break;
[948]636 SleepIfNeeded(pitdSleep, 1);
637 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[785]638 ulFindCnt = FilesToGet;
[850]639 rc = xDosFindNext(findHandle, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[551]640 } while (!rc);
[783]641
[2]642 DosFindClose(findHandle);
643 priority_normal();
[783]644 } // if
645
646 if (rc && rc != ERROR_NO_MORE_FILES) {
647 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
648 GetPString(IDS_CANTFINDDIRTEXT), szFindPath);
[2]649 }
[783]650
[1009]651 xfree(pffbArray, pszSrcFile, __LINE__);
[1029]652# ifdef FORTIFY
653 Fortify_LeaveScope();
654# endif
[551]655 return 0;
[2]656}
657
[948]658static VOID freegreplist(GREP *grep)
[51]659{
[948]660 UINT x;
[2]661
[551]662 if (grep) {
663 if (grep->insertffb) {
[1032]664 for (x = 0; grep->insertffb[x]; x++) {
665# ifdef FORTIFY
666 xfree(grep->insertffb[x], pszSrcFile, __LINE__);
667# else
668 free(grep->insertffb[x]);
669#endif
670 }
671 xfree(grep->insertffb, pszSrcFile, __LINE__);
[2]672 }
[551]673 if (grep->dir) {
[1032]674 for (x = 0; grep->dir[x]; x++) {
675# ifdef FORTIFY
676 xfree(grep->dir[x], pszSrcFile, __LINE__);
677# else
678 free(grep->dir[x]);
679# endif
680 }
681 xfree(grep->dir, pszSrcFile, __LINE__);
[2]682 }
683 grep->dir = NULL;
684 grep->insertffb = NULL;
685 grep->toinsert = 0L;
686 grep->insertedbytes = 0L;
[1029]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,
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,
[551]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__,
715 "CM_ALLOCRECORD %u failed", grep->toinsert);
716 }
717 else {
718 if (grep->sayfiles) {
719 if (!hwndStatus)
720 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPINSERTINGTEXT));
721 else {
722 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
723 WinSetWindowText(hwndStatus, GetPString(IDS_GREPINSERTINGTEXT));
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,
[551]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,
[551]742 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
743 if (dcd) {
[2]744 DosEnterCritSec();
[551]745 dcd->ullTotalBytes += grep->insertedbytes;
[2]746 DosExitCritSec();
747 }
[948]748 SleepIfNeeded(pitdSleep, 1);
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,
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)
[948]784 p++; // Include root backslash
[2]785 *p = 0;
[948]786
[551]787 if (!grep->insertffb) {
[783]788 // Allocate 1 extra for end marker?
[841]789 grep->insertffb = xmallocz(sizeof(PFILEFINDBUF4L) * (FilesToGet + 1),
[785]790 pszSrcFile, __LINE__);
[551]791 if (!grep->insertffb)
792 return FALSE;
[785]793 grep->dir = xmallocz(sizeof(CHAR *) * (FilesToGet + 1),
794 pszSrcFile, __LINE__);
[551]795 if (!grep->dir) {
[1009]796 xfree(grep->insertffb, pszSrcFile, __LINE__);
[1029]797# ifdef FORTIFY
798 Fortify_LeaveScope();
799# endif
[551]800 return FALSE;
801 }
[2]802 }
[948]803
[551]804 grep->insertffb[grep->toinsert] =
[841]805 xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
[551]806 if (!grep->insertffb[grep->toinsert])
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) {
[1029]812 xfree(grep->insertffb[grep->toinsert], pszSrcFile, __LINE__);
813# ifdef FORTIFY
814 Fortify_LeaveScope();
815# endif
[551]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)
[948]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,
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)
851 WinSetWindowText(hwndStatus, pszFileName);
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)
863 keep = FALSE;
[2]864 }
[551]865 if (keep && grep->lessthan) {
866 if (adjsize > grep->lessthan)
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)
881 keep = FALSE;
[2]882 }
[551]883 if (keep && grep->olderthan) {
884 if (numsecs > grep->olderthan)
885 keep = FALSE;
[2]886 }
[551]887 if (!keep)
[2]888 return ret;
889 }
890
[783]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) {
905 alltext = TRUE;
[948]906 switch (*(USHORT *)info->value) {
[551]907 case EAT_ASCII:
908 if (match(info->value + (sizeof(USHORT) * 2),
909 grep->searchPattern, grep->absFlag,
[948]910 grep->caseFlag == FALSE,
[551]911 info->cbValue - (sizeof(USHORT) * 2),
[948]912 grep->numlines,
913 grep->matched,
914 !grep->findifany)) {
[551]915 strmatch = TRUE;
916 }
917 break;
918 case EAT_MVST:
[948]919 type = *(USHORT *)(info->value + (sizeof(USHORT) * 3));
[551]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);
[948]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) {
[551]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 }
[1009]1032 xfree(input, pszSrcFile, __LINE__);
[1029]1033# ifdef FORTIFY
1034 Fortify_LeaveScope();
1035# endif
[948]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
[948]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)) {
1139 len = fread(buffer, 1, 65535, fp);
1140 if (len && len < 65536L)
1141 CRC = CRCBlock(buffer, len, CRC);
1142 else
1143 break;
[948]1144 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[2]1145 }
1146 fclose(fp);
[948]1147 // DosSleep(1); // 07 Feb 08 SHL
[2]1148 }
[1009]1149 xfree(buffer, pszSrcFile, __LINE__);
[1029]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) {
1165# ifdef FORTIFY
1166 xfree(i->name, pszSrcFile, __LINE__);
1167# else
[2]1168 free(i->name);
[1032]1169# endif
1170 }
1171# ifdef FORTIFY
1172 xfree(i, pszSrcFile, __LINE__);
1173# else
[2]1174 free(i);
[1032]1175# endif
[2]1176 i = next;
1177 }
[783]1178 grep->dupehead = grep->dupelast = NULL;
[1009]1179 xfree(grep->dupenames, pszSrcFile, __LINE__);
1180 xfree(grep->dupesizes, pszSrcFile, __LINE__);
[783]1181 grep->dupesizes = grep->dupenames = NULL;
[1029]1182# ifdef FORTIFY
1183 Fortify_LeaveScope();
1184# endif
[2]1185}
1186
[948]1187INT comparenamesq(const VOID *v1, const VOID *v2)
[51]1188{
[551]1189 DUPES *d1 = *(DUPES **) v1;
1190 DUPES *d2 = *(DUPES **) v2;
1191 CHAR *p1, *p2;
[2]1192
[551]1193 p1 = strrchr(d1->name, '\\');
1194 if (p1)
[2]1195 p1++;
1196 else
1197 p1 = d1->name;
[551]1198 p2 = strrchr(d2->name, '\\');
1199 if (p2)
[2]1200 p2++;
1201 else
1202 p2 = d2->name;
[551]1203 return stricmp(p1, p2);
[2]1204}
1205
[948]1206INT comparenamesqe(const VOID *v1, const VOID *v2)
[51]1207{
[551]1208 DUPES *d1 = *(DUPES **) v1;
1209 DUPES *d2 = *(DUPES **) v2;
1210 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
[948]1211 INT ret;
[2]1212
[551]1213 p1 = strrchr(d1->name, '\\');
1214 if (p1)
[2]1215 p1++;
1216 else
1217 p1 = d1->name;
[551]1218 p1e = strrchr(p1, '.');
1219 if (p1e) {
[2]1220 e1 = *p1e;
1221 *p1e = 0;
1222 }
[551]1223 p2 = strrchr(d2->name, '\\');
1224 if (p2)
[2]1225 p2++;
1226 else
1227 p2 = d2->name;
[551]1228 p2e = strrchr(p2, '.');
1229 if (p2e) {
[2]1230 e2 = *p2e;
1231 *p2e = 0;
1232 }
[551]1233 ret = stricmp(p1, p2);
1234 if (p1e)
[2]1235 *p1e = e1;
[551]1236 if (p2e)
[2]1237 *p2e = e2;
1238 return ret;
1239}
1240
[948]1241INT comparesizesq(const void *v1, const void *v2)
[51]1242{
[551]1243 DUPES *d1 = *(DUPES **) v1;
1244 DUPES *d2 = *(DUPES **) v2;
[2]1245
1246 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1247}
1248
[948]1249INT comparenamesb(const void *v1, const void *v2)
[51]1250{
[551]1251 DUPES *d1 = (DUPES *) v1;
1252 DUPES *d2 = *(DUPES **) v2;
1253 CHAR *p1, *p2;
[2]1254
[551]1255 p1 = strrchr(d1->name, '\\');
1256 if (p1)
[2]1257 p1++;
1258 else
1259 p1 = d1->name;
[551]1260 p2 = strrchr(d2->name, '\\');
1261 if (p2)
[2]1262 p2++;
1263 else
1264 p2 = d2->name;
[551]1265 return stricmp(p1, p2);
[2]1266}
1267
[948]1268INT comparenamesbe(const VOID *v1, const VOID *v2)
[51]1269{
[551]1270 DUPES *d1 = (DUPES *) v1;
1271 DUPES *d2 = *(DUPES **) v2;
1272 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
[948]1273 INT ret;
[2]1274
[551]1275 p1 = strrchr(d1->name, '\\');
1276 if (p1)
[2]1277 p1++;
1278 else
1279 p1 = d1->name;
[551]1280 p1e = strrchr(p1, '.');
1281 if (p1e) {
[2]1282 e1 = *p1e;
1283 *p1e = 0;
1284 }
[551]1285 p2 = strrchr(d2->name, '\\');
1286 if (p2)
[2]1287 p2++;
1288 else
1289 p2 = d2->name;
[551]1290 p2e = strrchr(p2, '.');
1291 if (p2e) {
[2]1292 e2 = *p2e;
1293 *p2e = 0;
1294 }
[551]1295 ret = stricmp(p1, p2);
1296 if (p1e)
[2]1297 *p1e = e1;
[551]1298 if (p2e)
[2]1299 *p2e = e2;
1300 return ret;
1301}
1302
[948]1303INT comparesizesb(const VOID *v1, const VOID *v2)
[51]1304{
[551]1305 DUPES *d1 = (DUPES *) v1;
1306 DUPES *d2 = *(DUPES **) v2;
[2]1307
1308 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1309}
1310
[948]1311static VOID FillDupes(GREP *grep,
1312 ITIMER_DESC *pitdSleep,
1313 ITIMER_DESC *pitdReport)
[51]1314{
[551]1315 DUPES *c, *i, **r;
1316 register CHAR *pc, *pi;
1317 CHAR **list = NULL;
[907]1318 UINT numfiles = 0, numalloced = 0;
1319 INT error;
[948]1320 ULONG x;
1321 ULONG y;
1322 // ULONG cntr = 1000; // 09 Feb 08 SHL
[2]1323
[948]1324 // if (grep->CRCdupes) // 09 Feb 08 SHL
1325 // cntr = 100; // 09 Feb 08 SHL
1326 x = 0;
1327 for (i = grep->dupehead; i; i = i->next)
1328 x++; // Count
1329
[350]1330 if (x) {
[948]1331 if (!hwndStatus)
1332 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPESORTINGTEXT));
1333 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1334 WinSetWindowText(hwndStatus, GetPString(IDS_GREPDUPESORTINGTEXT));
1335 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[783]1336 grep->dupenames = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1337 if (!grep->nosizedupes)
1338 grep->dupesizes = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1339 if (grep->dupenames && (grep->nosizedupes || grep->dupesizes)) {
[948]1340 y = 0;
1341 for (i = grep->dupehead; i; i = i->next) {
[783]1342 grep->dupenames[y] = i;
1343 if (!grep->nosizedupes)
1344 grep->dupesizes[y] = i;
[551]1345 y++;
[2]1346 }
[948]1347 grep->dupenames[y] = NULL; // Mark end
[783]1348 if (!grep->nosizedupes)
1349 grep->dupesizes[y] = NULL;
[948]1350
1351 InitITimer(pitdSleep, 0); // Reset rate estimator
1352 SleepIfNeeded(pitdSleep, 1);
1353 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
1354
[783]1355 qsort(grep->dupenames,
[551]1356 x,
1357 sizeof(DUPES *),
[948]1358 grep->ignoreextdupes ? comparenamesqe : comparenamesq);
1359 SleepIfNeeded(pitdSleep, 1);
1360 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[783]1361 if (!grep->nosizedupes) {
1362 qsort(grep->dupesizes, x, sizeof(DUPES *), comparesizesq);
[948]1363 SleepIfNeeded(pitdSleep, 1);
1364 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[2]1365 }
1366
[948]1367 if (!hwndStatus)
1368 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1369 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1370 WinSetWindowText(hwndStatus, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1371
1372 InitITimer(pitdSleep, 0); // Reset rate estimator
[783]1373 i = grep->dupehead;
[766]1374 y = 0;
[551]1375 while (i) {
[783]1376 if (*grep->stopflag)
[551]1377 break;
[948]1378 SleepIfNeeded(pitdSleep, 1); // 07 Feb 08 SHL
[551]1379 if (!(i->flags & GF_SKIPME)) {
[783]1380 r = (DUPES **) bsearch(i, grep->dupenames, x, sizeof(DUPES *),
1381 ((grep->ignoreextdupes) ? comparenamesbe :
[551]1382 comparenamesb));
1383 if (r) {
[783]1384 while (r > grep->dupenames && ((grep->ignoreextdupes) ?
[551]1385 !comparenamesqe((r - 1), &i) :
1386 !comparenamesq((r - 1), &i)))
1387 r--;
[783]1388 while (*r && ((grep->ignoreextdupes) ?
[551]1389 !comparenamesqe(r, &i) : !comparenamesq(r, &i))) {
1390 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME))) {
1391 r++;
1392 continue;
1393 }
[783]1394 if (grep->CRCdupes) {
[551]1395 if ((*r)->CRC == -1L) {
1396 (*r)->CRC = CRCFile((*r)->name, &error);
1397 if (error)
1398 (*r)->CRC = -1L;
1399 else if ((*r)->CRC == -1L)
1400 (*r)->CRC = 0L;
1401 }
1402 if (i->CRC == -1L) {
1403 i->CRC = CRCFile(i->name, &error);
1404 if (error)
1405 i->CRC = -1L;
1406 else if (i->CRC == -1L)
1407 i->CRC = 0L;
1408 }
1409 if (((*r)->size != i->size) || ((*r)->CRC != -1L &&
1410 i->CRC != -1L
1411 && (*r)->CRC != i->CRC)) {
1412 r++;
1413 continue;
1414 }
1415 }
1416 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
1417 (*r)->flags |= GF_INSERTED;
[948]1418 if (grep->sayfiles) {
1419 if (!hwndStatus)
1420 WinSetWindowText(grep->hwndFiles, (*r)->name);
1421 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1422 WinSetWindowText(hwndStatus, (*r)->name);
1423 }
[551]1424 if ((*r)->size == i->size &&
1425 (i->date.year == (*r)->date.year &&
1426 i->date.month == (*r)->date.month &&
1427 i->date.day == (*r)->date.day &&
1428 i->time.hours == (*r)->time.hours &&
1429 i->time.minutes == (*r)->time.minutes &&
1430 i->time.twosecs == (*r)->time.twosecs))
1431 (*r)->flags |= GF_SKIPME;
1432 }
1433 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1434 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1435 i->flags |= GF_INSERTED;
1436 if ((*r)->flags & GF_SKIPME)
1437 i->flags |= GF_SKIPME;
1438 }
1439 }
1440 r++;
1441 }
1442 }
[783]1443 if (!grep->nosizedupes) {
[551]1444 r = (DUPES **) bsearch(i,
[783]1445 grep->dupesizes,
[551]1446 x, sizeof(DUPES *), comparesizesb);
1447 if (r) {
[783]1448 while (r > grep->dupesizes && !comparesizesq((r - 1), &i))
[551]1449 r--;
1450 while (*r && !comparesizesq(r, &i)) {
1451 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME)) ||
1452 (i->date.year != (*r)->date.year ||
1453 i->date.month != (*r)->date.month ||
1454 i->date.day != (*r)->date.day ||
1455 i->time.hours != (*r)->time.hours ||
1456 i->time.minutes != (*r)->time.minutes ||
1457 i->time.twosecs != (*r)->time.twosecs)) {
1458 r++;
1459 continue;
1460 }
[783]1461 if (grep->CRCdupes) {
[551]1462 if ((*r)->CRC == -1L) {
1463 (*r)->CRC = CRCFile((*r)->name, &error);
1464 if (error)
1465 (*r)->CRC = -1L;
1466 else if ((*r)->CRC == -1L)
1467 (*r)->CRC = 0L;
1468 }
1469 if (i->CRC == -1L) {
1470 i->CRC = CRCFile(i->name, &error);
1471 if (error)
1472 i->CRC = -1L;
1473 else if (i->CRC == -1L)
1474 i->CRC = 0L;
1475 }
1476 if ((*r)->CRC != -1L && i->CRC != -1L &&
1477 (*r)->CRC != i->CRC) {
[689]1478 *r += 1;
[551]1479 continue;
1480 }
1481 }
1482 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
[948]1483 if (grep->sayfiles) {
1484 if (!hwndStatus)
1485 WinSetWindowText(grep->hwndCurFile, (*r)->name);
1486 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1487 WinSetWindowText(hwndStatus, (*r)->name);
1488 }
[551]1489 (*r)->flags |= GF_INSERTED;
[783]1490 if (((grep->ignoreextdupes) ?
[551]1491 comparenamesqe(r, &i) : comparenamesq(r, &i)))
1492 (*r)->flags |= GF_SKIPME;
1493 }
1494 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1495 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1496 i->flags |= GF_INSERTED;
1497 if ((*r)->flags & GF_SKIPME)
1498 i->flags |= GF_SKIPME;
1499 }
1500 }
1501 r++;
1502 }
1503 }
1504 }
1505 }
1506 i = i->next;
1507 y++;
[948]1508 // 08 Feb 08 SHL
1509 if (IsITimerExpired(pitdReport)) {
[551]1510 CHAR s[44];
[783]1511 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, grep->numfiles);
[948]1512 if (!hwndStatus)
1513 WinSetWindowText(grep->hwndCurFile, s);
1514 else {
1515 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1516 WinSetWindowText(hwndStatus, s);
1517 }
[551]1518 }
[948]1519 // DosSleep(0); //26 Aug 07 GKY 1
1520 } // while
[2]1521 }
1522 else {
[948]1523 // Insufficient memory - fall back to slow method - fixme to saymsg?
[551]1524 DosBeep(50, 100);
[948]1525 if (!hwndStatus)
1526 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1527 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1528 WinSetWindowText(hwndStatus, GetPString(IDS_GREPDUPECOMPARINGTEXT));
[766]1529 x = y = 0;
[1009]1530 xfree(grep->dupenames, pszSrcFile, __LINE__);
[985]1531 grep->dupenames = NULL;
[1009]1532 xfree(grep->dupesizes, pszSrcFile, __LINE__);
[985]1533 grep->dupesizes = NULL;
[1029]1534# ifdef FORTIFY
1535 Fortify_LeaveScope();
1536# endif
[948]1537
1538 InitITimer(pitdSleep, 0); // Reset rate estimator
[783]1539 i = grep->dupehead;
[551]1540 while (i) {
[783]1541 if (*grep->stopflag)
[551]1542 break;
[948]1543 SleepIfNeeded(pitdSleep, 1);
[551]1544 if (!(i->flags & GF_SKIPME)) {
[948]1545 if (IsITimerExpired(pitdReport)) {
1546 // if (!(y % cntr)) { }
[551]1547 CHAR s[44];
[783]1548 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, grep->numfiles);
[948]1549 if (!hwndStatus)
1550 WinSetWindowText(grep->hwndCurFile, s);
1551 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1552 WinSetWindowText(hwndStatus, s);
1553 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[551]1554 }
1555 y++;
1556 pi = strrchr(i->name, '\\');
1557 if (pi)
[689]1558 pi++;
[551]1559 else
1560 pi = i->name;
[783]1561 c = grep->dupehead;
[551]1562 while (c) {
[783]1563 if (*grep->stopflag)
[551]1564 break;
1565 if (c != i && !(c->flags & (GF_INSERTED | GF_SKIPME))) {
1566 x++;
1567 pc = strrchr(c->name, '\\');
1568 if (pc)
1569 pc++;
1570 else
1571 pc = c->name;
[783]1572 if ((!grep->nosizedupes && i->size == c->size && i->date.year == c->date.year && i->date.month == c->date.month && i->date.day == c->date.day && i->time.hours == c->time.hours && i->time.minutes == c->time.minutes && i->time.twosecs == c->time.twosecs) || !stricmp(pc, pi)) { // potential dupe
1573 if (grep->CRCdupes) {
1574 if (grep->CRCdupes) {
[551]1575 if (c->CRC == -1L) {
1576 c->CRC = CRCFile(c->name, &error);
1577 if (error)
1578 c->CRC = -1L;
1579 else if (c->CRC == -1L)
1580 c->CRC = 0L;
1581 }
1582 if (i->CRC == -1L) {
1583 i->CRC = CRCFile(i->name, &error);
1584 if (error)
1585 i->CRC = -1L;
1586 else if (i->CRC == -1L)
1587 i->CRC = 0L;
1588 }
1589 if ((c->size != i->size) || (c->CRC != -1L &&
1590 i->CRC != -1L
1591 && c->CRC != i->CRC)) {
1592 c = c->next;
1593 continue;
1594 }
1595 }
1596 }
1597 if (AddToList(c->name, &list, &numfiles, &numalloced))
1598 goto BreakOut; // Failed
1599 if (!(i->flags & GF_INSERTED)) {
1600 if (AddToList(i->name, &list, &numfiles, &numalloced))
1601 goto BreakOut; // Failed
1602 }
[948]1603 if (grep->sayfiles) {
1604 if (!hwndStatus)
1605 WinSetWindowText(grep->hwndCurFile, pc);
1606 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1607 WinSetWindowText(hwndStatus, pc);
1608 }
[551]1609 c->flags |= GF_INSERTED;
1610 i->flags |= GF_INSERTED;
1611 if (!stricmp(pc, pi)) {
1612 c->flags |= GF_SKIPME;
1613 i->flags |= GF_SKIPME;
1614 }
1615 }
[948]1616 // else if (!(x % 100)) // 07 Feb 08 SHL
1617 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[551]1618 }
1619 c = c->next;
1620 }
1621 }
1622 i = i->next;
[948]1623 } // while
[2]1624 }
1625 }
1626BreakOut:
[783]1627 FreeDupes(grep);
[551]1628 if (numfiles && list) {
[783]1629 if (!PostMsg(grep->hwndFiles,
[948]1630 WM_COMMAND,
1631 MPFROM2SHORT(IDM_COLLECTOR, 0),
1632 MPFROMP(list)))
[2]1633 FreeList(list);
1634 }
1635 else
1636 DosPostEventSem(CompactSem);
1637}
1638
[841]1639static BOOL InsertDupe(GREP *grep, CHAR *dir, FILEFINDBUF4L *pffb)
[51]1640{
[2]1641 DUPES *info;
1642
[350]1643 if (*dir) {
[551]1644 info = xmallocz(sizeof(DUPES), pszSrcFile, __LINE__);
[350]1645 if (!info)
1646 return FALSE;
[783]1647
1648 info->name = xstrdup(dir, pszSrcFile, __LINE__);
1649 if (!info->name) {
[1009]1650 xfree(info, pszSrcFile, __LINE__);
[1029]1651# ifdef FORTIFY
1652 Fortify_LeaveScope();
1653# endif
[783]1654 return FALSE;
[2]1655 }
[783]1656
1657 info->size = pffb->cbFile;
1658 info->date = pffb->fdateLastWrite;
1659 info->time = pffb->ftimeLastWrite;
1660 info->CRC = -1L;
1661 grep->numfiles++;
1662 if (!grep->dupehead)
1663 grep->dupehead = info;
1664 if (grep->dupelast)
1665 grep->dupelast->next = info;
1666 grep->dupelast = info;
1667 info->next = NULL;
[2]1668 }
1669 return TRUE;
1670}
[783]1671
[948]1672#pragma alloc_text(GREP,InsertGrepFile,DoOneFile,DoInsertion,freegreplist)
[783]1673#pragma alloc_text(GREP,SecsSince1980,match,mmatch,GrepThread)
[948]1674#pragma alloc_text(GREP,DoAllSubdirs,DoMatchingFiles,InsertDupes,FreeDupes)
[783]1675
1676#pragma alloc_text(DUPES,InsertDupe,FillDupes,FreeDupes,CRCFile,CRCBlock)
1677#pragma alloc_text(DUPES,comparenamesq,comparenamesqe,comparenamesb)
1678#pragma alloc_text(DUPES,comparenamesbe,comparesizesq,comparesizesb)
Note: See TracBrowser for help on using the repository browser.