source: trunk/dll/grep.c@ 1063

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

Fortify ifdef reformat

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.0 KB
RevLine 
[51]1
2/***********************************************************************
3
4 $Id: grep.c 1063 2008-07-11 03:33: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
[1038]278# ifdef FORTIFY
279 Fortify_EnterScope();
[1063]280# endif
[783]281 grep = *(GREP *)arg;
282 *grep.stopflag = 0; // reset thread-killing flag
[2]283 DosError(FERR_DISABLEHARDERR);
284 priority_normal();
285
286 ghab = WinInitialize(0);
[551]287 if (ghab) {
[2]288 grep.ghab = ghab;
[551]289 ghmq = WinCreateMsgQueue(ghab, 0);
290 if (ghmq) {
291 WinCancelShutdown(ghmq, TRUE);
[528]292 IncrThreadUsage();
[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) {
[2]414 free(grep.matched);
[1032]415 }
[948]416 // 07 Feb 08 SHL fixme to free grep here when not static
[1029]417# ifdef FORTIFY
418 Fortify_LeaveScope();
[1063]419# endif
[2]420 DosPostEventSem(CompactSem);
421}
422
[948]423static BOOL IsExcluded(CHAR *name, CHAR **fle, UINT numfls)
[51]424{
[948]425 UINT x;
426 CHAR *n;
[2]427
[551]428 n = strrchr(name, '\\');
429 if (!n)
430 n = strrchr(name, ':');
431 if (n)
[2]432 n++;
433 else
434 n = name;
[551]435 for (x = 0; x < numfls; x++) {
436 if (*fle[x] == '/' &&
437 wildcard((strchr(fle[x], '\\') ||
438 strchr(fle[x], ':')) ? name : n, fle[x] + 1, FALSE))
[2]439 return TRUE;
440 }
441 return FALSE;
442}
443
[948]444static VOID DoAllSubdirs(GREP *grep,
445 CHAR *searchPath,
446 BOOL recursing,
447 CHAR **fle,
448 UINT numfls,
449 ITIMER_DESC *pitdSleep,
450 ITIMER_DESC *pitdReport)
[551]451{
[783]452 // process all subdirectories
[2]453
[847]454 FILEFINDBUF4 ffb;
[551]455 HDIR findHandle = HDIR_CREATE;
[783]456 LONG ulFindCnt = 1;
[551]457 CHAR *p = NULL;
[2]458
[783]459 // add a mask to search path
[551]460 if (searchPath[strlen(searchPath) - 1] != '\\')
461 strcat(searchPath, "\\");
462 strcat(searchPath, "*");
[783]463 // step through all subdirectories
[2]464 DosError(FERR_DISABLEHARDERR);
[847]465 if (!DosFindFirst(searchPath, &findHandle, (MUST_HAVE_DIRECTORY |
466 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY),
467 &ffb, (ULONG) sizeof(ffb),
468 (PULONG) & ulFindCnt, FIL_QUERYEASIZE)) {
[2]469
[783]470 // get rid of mask portion, save end-of-directory
[2]471
[551]472 p = strrchr(searchPath, '\\');
473 if (p)
[2]474 p++;
475 else
476 p = searchPath;
[783]477 do { // Process each directory that matches the mask
[2]478 priority_normal();
[551]479 if (*grep->stopflag)
480 break;
[517]481 // Skip . and ..
[783]482 if (ffb.achName[0] != '.' ||
483 (ffb.achName[1] &&
484 (ffb.achName[1] != '.' || ffb.achName[2]))) {
485 strcpy(p, ffb.achName);
[551]486 if (!grep->anyexcludes || !IsExcluded(searchPath, fle, numfls)) {
[948]487 // 07 Feb 08 SHL
488 if (IsITimerExpired(pitdReport)) {
489 if (!hwndStatus)
490 WinSetWindowText(grep->hwndCurFile, searchPath);
491 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
492 CHAR s[CCHMAXPATH + 64];
493 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), searchPath);
494 WinSetWindowText(hwndStatus, s);
495 }
496 }
497 DoMatchingFiles(grep, searchPath, fle, numfls, pitdSleep, pitdReport);
498 // 07 Feb 08 SHL
499 if (IsITimerExpired(pitdReport)) {
500 if (!hwndStatus)
501 WinSetWindowText(grep->hwndCurFile, searchPath);
502 else {
503 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 }
510 DoAllSubdirs(grep, searchPath, TRUE, fle, numfls, pitdSleep, pitdReport);
511 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[551]512 }
[2]513 }
[783]514 ulFindCnt = 1;
[847]515 } while (!DosFindNext(findHandle,
516 &ffb,
517 sizeof(ffb), (PULONG) & ulFindCnt));
[2]518 DosFindClose(findHandle);
519 priority_normal();
520 }
[783]521 if (p) // strip off last directory addition
[2]522 *p = 0;
523}
524
[948]525/**
526 * Scan for files matching filespecs in single directory
527 */
528
529static INT DoMatchingFiles(GREP *grep,
530 CHAR *path,
531 CHAR **fle,
532 UINT numfls,
533 ITIMER_DESC *pitdSleep,
534 ITIMER_DESC *pitdReport)
[51]535{
[783]536 // process all matching files in a directory
[2]537
[848]538 PFILEFINDBUF4L pffbArray;
539 PFILEFINDBUF4L pffbFile;
[783]540 ULONG x;
[551]541 HDIR findHandle = HDIR_CREATE;
[783]542 ULONG ulFindCnt;
543 CHAR szFindPath[CCHMAXPATH];
544 PSZ p;
[551]545 APIRET rc;
[850]546 // 06 Oct 07 SHL Correct size for xDosFindFirst
547 ULONG ulBufBytes = FilesToGet * sizeof(FILEFINDBUF4L);
[839]548 static BOOL fDone;
[2]549
[783]550 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
551 if (!pffbArray)
[2]552 return 0;
553
[783]554 BldFullPathName(szFindPath, path, grep->fileMask);
[2]555
[783]556 MakeFullName(szFindPath);
[2]557
[783]558 // find and save end-of-dir position
559 p = strrchr(szFindPath, '\\');
[551]560 if (p)
[2]561 p++;
562 else
[783]563 p = szFindPath;
[2]564
[783]565 // step through matching files
[2]566 DosError(FERR_DISABLEHARDERR);
[785]567 ulFindCnt = FilesToGet;
[848]568 rc = xDosFindFirst(szFindPath,
569 &findHandle,
570 FILE_NORMAL | grep->attrFile | grep->antiattr,
571 pffbArray,
572 ulBufBytes,
573 &ulFindCnt,
574 FIL_QUERYEASIZEL);
[783]575 if (!rc) {
576 do {
577 // Process each file that matches the mask
[2]578 priority_normal();
[783]579 pffbFile = pffbArray;
580 for (x = 0; x < ulFindCnt; x++) {
[551]581 if (*grep->stopflag)
582 break;
583 if (*pffbFile->achName != '.' ||
[948]584 (pffbFile->achName[1] && pffbFile->achName[1] != '.')) {
585 strcpy(p, pffbFile->achName); // build filename
586 if (strlen(szFindPath) > CCHMAXPATH){
587 // Complain if pathnames exceeds max
588 DosFindClose(findHandle);
[1017]589 //xfree(pffbArray, pszSrcFile, __LINE__);
[948]590 if (!fDone) {
591 fDone = TRUE;
592 saymsg(MB_OK | MB_ICONASTERISK,
593 HWND_DESKTOP,
[839]594 GetPString(IDS_WARNINGTEXT),
[948]595 "One or more of your files has a full path name that exceeds the OS/2 maximum");
596 }
[837]597 return 1;
[948]598 }
599
600 // 07 Feb 08 SHL
601 if (IsITimerExpired(pitdReport)) {
602 if (!hwndStatus)
603 WinSetWindowText(grep->hwndCurFile, szFindPath);
604 else {
605 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles) {
606 CHAR s[CCHMAXPATH + 64];
607 sprintf(s, "%s %s", GetPString(IDS_SCANNINGTEXT), szFindPath);
608 WinSetWindowText(hwndStatus, s);
609 }
610 }
611 }
612
[783]613 if (!grep->anyexcludes || !IsExcluded(szFindPath, fle, numfls)) {
[551]614 if (!grep->finddupes)
[948]615 DoOneFile(grep, szFindPath, pffbFile, pitdSleep, pitdReport);
[783]616 else if (!InsertDupe(grep, szFindPath, pffbFile)) {
[551]617 DosFindClose(findHandle);
[1039]618 free(pffbArray);
[1063]619# ifdef FORTIFY
620 Fortify_LeaveScope();
621# endif
[551]622 return 1;
623 }
624 }
625 }
626 if (!pffbFile->oNextEntryOffset)
627 break;
[848]628 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]629 } // for
630 if (*grep->stopflag)
631 break;
[948]632 SleepIfNeeded(pitdSleep, 1);
633 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[785]634 ulFindCnt = FilesToGet;
[850]635 rc = xDosFindNext(findHandle, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[551]636 } while (!rc);
[783]637
[2]638 DosFindClose(findHandle);
639 priority_normal();
[783]640 } // if
641
642 if (rc && rc != ERROR_NO_MORE_FILES) {
643 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
644 GetPString(IDS_CANTFINDDIRTEXT), szFindPath);
[2]645 }
[783]646
[1039]647 free(pffbArray);
[1029]648# ifdef FORTIFY
649 Fortify_LeaveScope();
[1063]650# endif
[551]651 return 0;
[2]652}
653
[948]654static VOID freegreplist(GREP *grep)
[51]655{
[948]656 UINT x;
[2]657
[551]658 if (grep) {
659 if (grep->insertffb) {
[1032]660 for (x = 0; grep->insertffb[x]; x++) {
661 free(grep->insertffb[x]);
662 }
[1039]663 free(grep->insertffb);
[2]664 }
[551]665 if (grep->dir) {
[1032]666 for (x = 0; grep->dir[x]; x++) {
667 free(grep->dir[x]);
668 }
[1039]669 free(grep->dir);
[2]670 }
671 grep->dir = NULL;
672 grep->insertffb = NULL;
673 grep->toinsert = 0L;
674 grep->insertedbytes = 0L;
[1063]675# ifdef FORTIFY
676 Fortify_LeaveScope();
677# endif
[2]678 }
679}
680
[948]681/**
682 * Insert record into container
683 */
684
685static BOOL DoInsertion(GREP *grep,
686 ITIMER_DESC *pitdSleep,
687 ITIMER_DESC *pitdReport)
[51]688{
[2]689 RECORDINSERT ri;
[551]690 DIRCNRDATA *dcd;
691 PCNRITEM pci, pciFirst;
[948]692 UINT x;
[2]693
[551]694 if (!grep || !grep->toinsert || !grep->insertffb || !grep->dir)
[2]695 return FALSE;
[948]696
[2]697 pci = WinSendMsg(grep->hwndFiles,
[551]698 CM_ALLOCRECORD,
699 MPFROMLONG(EXTRA_RECORD_BYTES),
700 MPFROMLONG(grep->toinsert));
[948]701 if (!pci) {
702 Win_Error(grep->hwndFiles, grep->hwndFiles, pszSrcFile, __LINE__,
703 "CM_ALLOCRECORD %u failed", grep->toinsert);
704 }
705 else {
706 if (grep->sayfiles) {
707 if (!hwndStatus)
708 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPINSERTINGTEXT));
709 else {
710 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
711 WinSetWindowText(hwndStatus, GetPString(IDS_GREPINSERTINGTEXT));
712 }
713 }
[2]714 pciFirst = pci;
715 dcd = INSTDATA(grep->hwndFiles);
[551]716 for (x = 0; grep->insertffb[x]; x++) {
[2]717 FillInRecordFromFFB(grep->hwndFiles,
[551]718 pci, grep->dir[x], grep->insertffb[x], FALSE, dcd);
[2]719 pci = (PCNRITEM) pci->rc.preccNextRecord;
[948]720 SleepIfNeeded(pitdSleep, 1);
721 } // for
[551]722 memset(&ri, 0, sizeof(RECORDINSERT));
723 ri.cb = sizeof(RECORDINSERT);
724 ri.pRecordOrder = (PRECORDCORE) CMA_END;
725 ri.pRecordParent = (PRECORDCORE) NULL;
726 ri.zOrder = (USHORT) CMA_TOP;
727 ri.cRecordsInsert = grep->toinsert;
728 ri.fInvalidateRecord = TRUE;
[2]729 WinSendMsg(grep->hwndFiles,
[551]730 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
731 if (dcd) {
[2]732 DosEnterCritSec();
[551]733 dcd->ullTotalBytes += grep->insertedbytes;
[2]734 DosExitCritSec();
735 }
[948]736 SleepIfNeeded(pitdSleep, 1);
737 // if (grep->toinsert == FilesToGet) // 07 Feb 08 SHL
738 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[2]739 freegreplist(grep);
[551]740 PostMsg(grep->hwndFiles, UM_RESCAN, MPVOID, MPVOID);
[2]741 return TRUE;
742 }
743 freegreplist(grep);
744 return FALSE;
745}
746
[948]747/**
748 * Insert file ffb and directory name into lists
749 */
750
751static BOOL InsertGrepFile(GREP *grep,
752 CHAR *pszFileName,
753 PFILEFINDBUF4L pffb,
754 ITIMER_DESC *pitdSleep,
755 ITIMER_DESC *pitdReport)
[51]756{
[783]757 PSZ p;
758 CHAR szDirectory[CCHMAXPATH];
[2]759
[948]760 if (!WinIsWindow(grep->ghab, grep->hwndFiles)) {
761 // Window closed - clean up and go away
762 freegreplist(grep);
763 }
764 else {
[2]765 grep->numfiles++;
[948]766 strcpy(szDirectory, pszFileName);
[551]767 p = strrchr(szDirectory, '\\');
[948]768
[551]769 if (p) {
[948]770 // Got directory
[551]771 if (p < szDirectory + 4)
[948]772 p++; // Include root backslash
[2]773 *p = 0;
[948]774
[551]775 if (!grep->insertffb) {
[783]776 // Allocate 1 extra for end marker?
[841]777 grep->insertffb = xmallocz(sizeof(PFILEFINDBUF4L) * (FilesToGet + 1),
[785]778 pszSrcFile, __LINE__);
[551]779 if (!grep->insertffb)
780 return FALSE;
[785]781 grep->dir = xmallocz(sizeof(CHAR *) * (FilesToGet + 1),
782 pszSrcFile, __LINE__);
[551]783 if (!grep->dir) {
[1039]784 free(grep->insertffb);
[1063]785# ifdef FORTIFY
786 Fortify_LeaveScope();
787# endif
[551]788 return FALSE;
789 }
[2]790 }
[948]791
[551]792 grep->insertffb[grep->toinsert] =
[841]793 xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
[551]794 if (!grep->insertffb[grep->toinsert])
795 return FALSE;
[841]796 memcpy(grep->insertffb[grep->toinsert], pffb, sizeof(FILEFINDBUF4L));
[948]797
[551]798 grep->dir[grep->toinsert] = xstrdup(szDirectory, pszSrcFile, __LINE__);
799 if (!grep->dir) {
[1039]800 free(grep->insertffb[grep->toinsert]);
[1063]801# ifdef FORTIFY
802 Fortify_LeaveScope();
803# endif
[551]804 return FALSE;
[2]805 }
[948]806
[783]807 grep->insertedbytes += pffb->cbFile + CBLIST_TO_EASIZE(pffb->cbList);
[2]808 grep->toinsert++;
[785]809 if (grep->toinsert == FilesToGet)
[948]810 return DoInsertion(grep, pitdSleep, pitdReport);
[2]811 return TRUE;
812 }
813 }
814 return FALSE;
815}
816
[948]817/**
818 * Check file matches search criteria
819 */
820
821static BOOL DoOneFile(GREP *grep,
822 CHAR *pszFileName,
823 FILEFINDBUF4L *pffb,
824 ITIMER_DESC *pitdSleep,
825 ITIMER_DESC *pitdReport)
[51]826{
[783]827 // process a single file
[551]828 CHAR *input;
829 FILE *inputFile;
830 ULONG pos;
831 BOOL ret = FALSE, strmatch = FALSE;
[2]832
833 grep->fileCount++;
[948]834 if (grep->sayfiles) {
835 if (!hwndStatus)
836 WinSetWindowText(grep->hwndCurFile, pszFileName);
837 else {
838 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
839 WinSetWindowText(hwndStatus, pszFileName);
840 }
841 }
[2]842
[551]843 if (grep->greaterthan || grep->lessthan) {
[2]844
[551]845 BOOL keep = TRUE;
[2]846 ULONG adjsize;
847
[783]848 adjsize = pffb->cbFile + (grep->searchEAs ? CBLIST_TO_EASIZE(pffb->cbList) : 0);
[551]849 if (grep->greaterthan) {
850 if (adjsize < grep->greaterthan)
851 keep = FALSE;
[2]852 }
[551]853 if (keep && grep->lessthan) {
854 if (adjsize > grep->lessthan)
855 keep = FALSE;
[2]856 }
[551]857 if (!keep)
[2]858 return ret;
859 }
860
[551]861 if (grep->newerthan || grep->olderthan) {
[2]862
[551]863 BOOL keep = TRUE;
[2]864 ULONG numsecs;
865
[783]866 numsecs = SecsSince1980(&pffb->fdateLastWrite, &pffb->ftimeLastWrite);
[551]867 if (grep->newerthan) {
868 if (numsecs < grep->newerthan)
869 keep = FALSE;
[2]870 }
[551]871 if (keep && grep->olderthan) {
872 if (numsecs > grep->olderthan)
873 keep = FALSE;
[2]874 }
[551]875 if (!keep)
[2]876 return ret;
877 }
878
[783]879 if ((!grep->searchEAs && !grep->searchFiles) || !*grep->searchPattern) // just a find
[948]880 return InsertGrepFile(grep, pszFileName, pffb, pitdSleep, pitdReport);
[2]881
[551]882 if (grep->searchEAs) {
[2]883
[551]884 HOLDFEA *head, *info;
885 USHORT type, len;
886 BOOL alltext;
887 CHAR *data, temp;
[2]888
[948]889 head = GetFileEAs(pszFileName, FALSE, TRUE);
[551]890 if (head) {
[2]891 info = head;
[551]892 while (info && !strmatch) {
893 alltext = TRUE;
[948]894 switch (*(USHORT *)info->value) {
[551]895 case EAT_ASCII:
896 if (match(info->value + (sizeof(USHORT) * 2),
897 grep->searchPattern, grep->absFlag,
[948]898 grep->caseFlag == FALSE,
[551]899 info->cbValue - (sizeof(USHORT) * 2),
[948]900 grep->numlines,
901 grep->matched,
902 !grep->findifany)) {
[551]903 strmatch = TRUE;
904 }
905 break;
906 case EAT_MVST:
[948]907 type = *(USHORT *)(info->value + (sizeof(USHORT) * 3));
[551]908 if (type == EAT_ASCII) {
909 data = info->value + (sizeof(USHORT) * 4);
910 len = *(USHORT *) data;
911 data += sizeof(USHORT);
912 while ((data - info->value) + len <= info->cbValue) {
913 temp = *(data + len);
914 *(data + len) = 0;
915 if (match(data,
916 grep->searchPattern,
917 grep->absFlag,
918 (grep->caseFlag == FALSE),
919 len,
920 grep->numlines, grep->matched, !grep->findifany)) {
921 strmatch = TRUE;
922 break;
923 }
924 data += len;
925 if (data - info->value >= info->cbValue)
926 break;
927 *data = temp;
928 len = *(USHORT *) data;
929 data += sizeof(USHORT);
930 }
931 }
932 break;
933 case EAT_MVMT:
934 data = info->value + (sizeof(USHORT) * 3);
935 type = *(USHORT *) data;
936 data += sizeof(USHORT);
937 len = *(USHORT *) data;
938 data += sizeof(USHORT);
939 while ((data - info->value) - len <= info->cbValue) {
940 if (type != EAT_ASCII) {
941 alltext = FALSE;
942 break;
943 }
944 data += len;
945 if (data - info->value >= info->cbValue)
946 break;
947 type = *(USHORT *) data;
948 data += sizeof(USHORT);
949 len = *(USHORT *) data;
950 data += sizeof(USHORT);
951 }
952 if (alltext) {
953 data = info->value + (sizeof(USHORT) * 3);
954 type = *(USHORT *) data;
955 data += sizeof(USHORT);
956 len = *(USHORT *) data;
957 data += sizeof(USHORT);
958 while ((data - info->value) - len <= info->cbValue) {
959 temp = *(data + len);
960 *(data + len) = 0;
961 if (match(data,
962 grep->searchPattern,
963 grep->absFlag,
964 (grep->caseFlag == FALSE),
965 len,
966 grep->numlines, grep->matched, !grep->findifany)) {
967 strmatch = TRUE;
968 break;
969 }
970 data += len;
971 *data = temp;
972 if (data - info->value >= info->cbValue)
973 break;
974 type = *(USHORT *) data;
975 data += sizeof(USHORT);
976 len = *(USHORT *) data;
977 data += sizeof(USHORT);
978 }
979 }
980 break;
981 default:
982 break;
983 }
984 info = info->next;
985 } // while
[2]986 Free_FEAList(head);
[948]987 // DosSleep(1); // 07 Feb 08 SHL
[2]988 }
989 }
990
[551]991 if (grep->searchFiles) {
992 input = xmalloc(65537, pszSrcFile, __LINE__);
993 if (input) {
[2]994 LONG len;
[551]995
[948]996 inputFile = _fsopen(pszFileName, "rb", SH_DENYNO);
[350]997 if (inputFile) {
[551]998 pos = ftell(inputFile);
999 while (!feof(inputFile)) {
1000 if (pos)
1001 fseek(inputFile, pos - 1024, SEEK_SET);
1002 len = fread(input, 1, 65536, inputFile);
1003 if (len >= 0) {
1004 if (*grep->stopflag)
1005 break;
1006 if (match(input,
1007 grep->searchPattern,
1008 grep->absFlag,
1009 (grep->caseFlag == FALSE),
1010 len, grep->numlines, grep->matched, !grep->findifany)) {
1011 strmatch = TRUE;
1012 break;
1013 }
1014 }
1015 else
1016 break;
1017 }
1018 fclose(inputFile);
[2]1019 }
[1039]1020 free(input);
[1063]1021# ifdef FORTIFY
1022 Fortify_LeaveScope();
1023# endif
[948]1024 // DosSleep(1); // 07 Feb 08 SHL
[2]1025 }
[689]1026 } // if
[2]1027
[551]1028 if (strmatch)
[948]1029 ret = InsertGrepFile(grep, pszFileName, pffb, pitdSleep, pitdReport);
[2]1030 return ret;
1031}
1032
[948]1033static LONG cr3tab[] = { // CRC polynomial 0xEDB88320
[2]1034
1035 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
1036 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
1037 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
1038 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
1039 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1040 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
1041 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
1042 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
1043 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
1044 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1045 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
1046 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
1047 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
1048 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
1049 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1050 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
1051 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
1052 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
1053 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
1054 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1055 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
1056 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
1057 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
1058 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
1059 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1060 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
1061 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
1062 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
1063 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
1064 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1065 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
1066 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
1067 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
1068 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
1069 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1070 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
1071 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
1072 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
1073 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
1074 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1075 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
1076 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
1077 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
1078 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
1079 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1080 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
1081 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
1082 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
1083 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
1084 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1085 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
1086 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
1087 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
1088 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
1089 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1090 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
1091 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
1092 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
1093 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
1094 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1095 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
1096 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
1097 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
1098 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
1099};
1100
[948]1101LONG CRCBlock(register CHAR *str, register INT blklen, register LONG crc)
[51]1102{
[2]1103 while (blklen--) {
[551]1104 crc =
1105 cr3tab[((INT) crc ^ *str) & 0xff] ^ (((ULONG) crc >> 8) & 0x00FFFFFF);
[2]1106 str++;
1107 }
1108 return crc;
1109}
1110
[948]1111LONG CRCFile(CHAR *pszFileName, INT *error)
[51]1112{
[551]1113 LONG CRC = -1L, len;
[2]1114 FILE *fp;
1115 CHAR *buffer;
1116
1117 *error = 0;
[551]1118 buffer = xmalloc(65535, pszSrcFile, __LINE__);
[350]1119 if (!buffer)
1120 *error = -1;
1121 else {
[948]1122 fp = _fsopen(pszFileName, "rb", SH_DENYNO);
[350]1123 if (!fp)
1124 *error = -2;
1125 else {
[551]1126 while (!feof(fp)) {
1127 len = fread(buffer, 1, 65535, fp);
1128 if (len && len < 65536L)
1129 CRC = CRCBlock(buffer, len, CRC);
1130 else
1131 break;
[948]1132 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[2]1133 }
1134 fclose(fp);
[948]1135 // DosSleep(1); // 07 Feb 08 SHL
[2]1136 }
[1039]1137 free(buffer);
[1063]1138# ifdef FORTIFY
1139 Fortify_LeaveScope();
1140# endif
[2]1141 }
1142 return CRC;
1143}
1144
[783]1145static VOID FreeDupes(GREP *grep)
[51]1146{
[551]1147 DUPES *i, *next;
[2]1148
[783]1149 i = grep->dupehead;
[551]1150 while (i) {
[2]1151 next = i->next;
[1032]1152 if (i->name) {
[2]1153 free(i->name);
[1032]1154 }
[2]1155 free(i);
1156 i = next;
1157 }
[783]1158 grep->dupehead = grep->dupelast = NULL;
[1009]1159 xfree(grep->dupenames, pszSrcFile, __LINE__);
1160 xfree(grep->dupesizes, pszSrcFile, __LINE__);
[783]1161 grep->dupesizes = grep->dupenames = NULL;
[1029]1162# ifdef FORTIFY
1163 Fortify_LeaveScope();
[1063]1164# endif
[2]1165}
1166
[948]1167INT comparenamesq(const VOID *v1, const VOID *v2)
[51]1168{
[551]1169 DUPES *d1 = *(DUPES **) v1;
1170 DUPES *d2 = *(DUPES **) v2;
1171 CHAR *p1, *p2;
[2]1172
[551]1173 p1 = strrchr(d1->name, '\\');
1174 if (p1)
[2]1175 p1++;
1176 else
1177 p1 = d1->name;
[551]1178 p2 = strrchr(d2->name, '\\');
1179 if (p2)
[2]1180 p2++;
1181 else
1182 p2 = d2->name;
[551]1183 return stricmp(p1, p2);
[2]1184}
1185
[948]1186INT comparenamesqe(const VOID *v1, const VOID *v2)
[51]1187{
[551]1188 DUPES *d1 = *(DUPES **) v1;
1189 DUPES *d2 = *(DUPES **) v2;
1190 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
[948]1191 INT ret;
[2]1192
[551]1193 p1 = strrchr(d1->name, '\\');
1194 if (p1)
[2]1195 p1++;
1196 else
1197 p1 = d1->name;
[551]1198 p1e = strrchr(p1, '.');
1199 if (p1e) {
[2]1200 e1 = *p1e;
1201 *p1e = 0;
1202 }
[551]1203 p2 = strrchr(d2->name, '\\');
1204 if (p2)
[2]1205 p2++;
1206 else
1207 p2 = d2->name;
[551]1208 p2e = strrchr(p2, '.');
1209 if (p2e) {
[2]1210 e2 = *p2e;
1211 *p2e = 0;
1212 }
[551]1213 ret = stricmp(p1, p2);
1214 if (p1e)
[2]1215 *p1e = e1;
[551]1216 if (p2e)
[2]1217 *p2e = e2;
1218 return ret;
1219}
1220
[948]1221INT comparesizesq(const void *v1, const void *v2)
[51]1222{
[551]1223 DUPES *d1 = *(DUPES **) v1;
1224 DUPES *d2 = *(DUPES **) v2;
[2]1225
1226 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1227}
1228
[948]1229INT comparenamesb(const void *v1, const void *v2)
[51]1230{
[551]1231 DUPES *d1 = (DUPES *) v1;
1232 DUPES *d2 = *(DUPES **) v2;
1233 CHAR *p1, *p2;
[2]1234
[551]1235 p1 = strrchr(d1->name, '\\');
1236 if (p1)
[2]1237 p1++;
1238 else
1239 p1 = d1->name;
[551]1240 p2 = strrchr(d2->name, '\\');
1241 if (p2)
[2]1242 p2++;
1243 else
1244 p2 = d2->name;
[551]1245 return stricmp(p1, p2);
[2]1246}
1247
[948]1248INT comparenamesbe(const VOID *v1, const VOID *v2)
[51]1249{
[551]1250 DUPES *d1 = (DUPES *) v1;
1251 DUPES *d2 = *(DUPES **) v2;
1252 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
[948]1253 INT ret;
[2]1254
[551]1255 p1 = strrchr(d1->name, '\\');
1256 if (p1)
[2]1257 p1++;
1258 else
1259 p1 = d1->name;
[551]1260 p1e = strrchr(p1, '.');
1261 if (p1e) {
[2]1262 e1 = *p1e;
1263 *p1e = 0;
1264 }
[551]1265 p2 = strrchr(d2->name, '\\');
1266 if (p2)
[2]1267 p2++;
1268 else
1269 p2 = d2->name;
[551]1270 p2e = strrchr(p2, '.');
1271 if (p2e) {
[2]1272 e2 = *p2e;
1273 *p2e = 0;
1274 }
[551]1275 ret = stricmp(p1, p2);
1276 if (p1e)
[2]1277 *p1e = e1;
[551]1278 if (p2e)
[2]1279 *p2e = e2;
1280 return ret;
1281}
1282
[948]1283INT comparesizesb(const VOID *v1, const VOID *v2)
[51]1284{
[551]1285 DUPES *d1 = (DUPES *) v1;
1286 DUPES *d2 = *(DUPES **) v2;
[2]1287
1288 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1289}
1290
[948]1291static VOID FillDupes(GREP *grep,
1292 ITIMER_DESC *pitdSleep,
1293 ITIMER_DESC *pitdReport)
[51]1294{
[551]1295 DUPES *c, *i, **r;
1296 register CHAR *pc, *pi;
1297 CHAR **list = NULL;
[907]1298 UINT numfiles = 0, numalloced = 0;
1299 INT error;
[948]1300 ULONG x;
1301 ULONG y;
1302 // ULONG cntr = 1000; // 09 Feb 08 SHL
[2]1303
[948]1304 // if (grep->CRCdupes) // 09 Feb 08 SHL
1305 // cntr = 100; // 09 Feb 08 SHL
1306 x = 0;
1307 for (i = grep->dupehead; i; i = i->next)
1308 x++; // Count
1309
[350]1310 if (x) {
[948]1311 if (!hwndStatus)
1312 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPESORTINGTEXT));
1313 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1314 WinSetWindowText(hwndStatus, GetPString(IDS_GREPDUPESORTINGTEXT));
1315 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[783]1316 grep->dupenames = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1317 if (!grep->nosizedupes)
1318 grep->dupesizes = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1319 if (grep->dupenames && (grep->nosizedupes || grep->dupesizes)) {
[948]1320 y = 0;
1321 for (i = grep->dupehead; i; i = i->next) {
[783]1322 grep->dupenames[y] = i;
1323 if (!grep->nosizedupes)
1324 grep->dupesizes[y] = i;
[551]1325 y++;
[2]1326 }
[948]1327 grep->dupenames[y] = NULL; // Mark end
[783]1328 if (!grep->nosizedupes)
1329 grep->dupesizes[y] = NULL;
[948]1330
1331 InitITimer(pitdSleep, 0); // Reset rate estimator
1332 SleepIfNeeded(pitdSleep, 1);
1333 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
1334
[783]1335 qsort(grep->dupenames,
[551]1336 x,
1337 sizeof(DUPES *),
[948]1338 grep->ignoreextdupes ? comparenamesqe : comparenamesq);
1339 SleepIfNeeded(pitdSleep, 1);
1340 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[783]1341 if (!grep->nosizedupes) {
1342 qsort(grep->dupesizes, x, sizeof(DUPES *), comparesizesq);
[948]1343 SleepIfNeeded(pitdSleep, 1);
1344 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[2]1345 }
1346
[948]1347 if (!hwndStatus)
1348 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1349 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1350 WinSetWindowText(hwndStatus, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1351
1352 InitITimer(pitdSleep, 0); // Reset rate estimator
[783]1353 i = grep->dupehead;
[766]1354 y = 0;
[551]1355 while (i) {
[783]1356 if (*grep->stopflag)
[551]1357 break;
[948]1358 SleepIfNeeded(pitdSleep, 1); // 07 Feb 08 SHL
[551]1359 if (!(i->flags & GF_SKIPME)) {
[783]1360 r = (DUPES **) bsearch(i, grep->dupenames, x, sizeof(DUPES *),
1361 ((grep->ignoreextdupes) ? comparenamesbe :
[551]1362 comparenamesb));
1363 if (r) {
[783]1364 while (r > grep->dupenames && ((grep->ignoreextdupes) ?
[551]1365 !comparenamesqe((r - 1), &i) :
1366 !comparenamesq((r - 1), &i)))
1367 r--;
[783]1368 while (*r && ((grep->ignoreextdupes) ?
[551]1369 !comparenamesqe(r, &i) : !comparenamesq(r, &i))) {
1370 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME))) {
1371 r++;
1372 continue;
1373 }
[783]1374 if (grep->CRCdupes) {
[551]1375 if ((*r)->CRC == -1L) {
1376 (*r)->CRC = CRCFile((*r)->name, &error);
1377 if (error)
1378 (*r)->CRC = -1L;
1379 else if ((*r)->CRC == -1L)
1380 (*r)->CRC = 0L;
1381 }
1382 if (i->CRC == -1L) {
1383 i->CRC = CRCFile(i->name, &error);
1384 if (error)
1385 i->CRC = -1L;
1386 else if (i->CRC == -1L)
1387 i->CRC = 0L;
1388 }
1389 if (((*r)->size != i->size) || ((*r)->CRC != -1L &&
1390 i->CRC != -1L
1391 && (*r)->CRC != i->CRC)) {
1392 r++;
1393 continue;
1394 }
1395 }
1396 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
1397 (*r)->flags |= GF_INSERTED;
[948]1398 if (grep->sayfiles) {
1399 if (!hwndStatus)
1400 WinSetWindowText(grep->hwndFiles, (*r)->name);
1401 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1402 WinSetWindowText(hwndStatus, (*r)->name);
1403 }
[551]1404 if ((*r)->size == i->size &&
1405 (i->date.year == (*r)->date.year &&
1406 i->date.month == (*r)->date.month &&
1407 i->date.day == (*r)->date.day &&
1408 i->time.hours == (*r)->time.hours &&
1409 i->time.minutes == (*r)->time.minutes &&
1410 i->time.twosecs == (*r)->time.twosecs))
1411 (*r)->flags |= GF_SKIPME;
1412 }
1413 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1414 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1415 i->flags |= GF_INSERTED;
1416 if ((*r)->flags & GF_SKIPME)
1417 i->flags |= GF_SKIPME;
1418 }
1419 }
1420 r++;
1421 }
1422 }
[783]1423 if (!grep->nosizedupes) {
[551]1424 r = (DUPES **) bsearch(i,
[783]1425 grep->dupesizes,
[551]1426 x, sizeof(DUPES *), comparesizesb);
1427 if (r) {
[783]1428 while (r > grep->dupesizes && !comparesizesq((r - 1), &i))
[551]1429 r--;
1430 while (*r && !comparesizesq(r, &i)) {
1431 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME)) ||
1432 (i->date.year != (*r)->date.year ||
1433 i->date.month != (*r)->date.month ||
1434 i->date.day != (*r)->date.day ||
1435 i->time.hours != (*r)->time.hours ||
1436 i->time.minutes != (*r)->time.minutes ||
1437 i->time.twosecs != (*r)->time.twosecs)) {
1438 r++;
1439 continue;
1440 }
[783]1441 if (grep->CRCdupes) {
[551]1442 if ((*r)->CRC == -1L) {
1443 (*r)->CRC = CRCFile((*r)->name, &error);
1444 if (error)
1445 (*r)->CRC = -1L;
1446 else if ((*r)->CRC == -1L)
1447 (*r)->CRC = 0L;
1448 }
1449 if (i->CRC == -1L) {
1450 i->CRC = CRCFile(i->name, &error);
1451 if (error)
1452 i->CRC = -1L;
1453 else if (i->CRC == -1L)
1454 i->CRC = 0L;
1455 }
1456 if ((*r)->CRC != -1L && i->CRC != -1L &&
1457 (*r)->CRC != i->CRC) {
[689]1458 *r += 1;
[551]1459 continue;
1460 }
1461 }
1462 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
[948]1463 if (grep->sayfiles) {
1464 if (!hwndStatus)
1465 WinSetWindowText(grep->hwndCurFile, (*r)->name);
1466 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1467 WinSetWindowText(hwndStatus, (*r)->name);
1468 }
[551]1469 (*r)->flags |= GF_INSERTED;
[783]1470 if (((grep->ignoreextdupes) ?
[551]1471 comparenamesqe(r, &i) : comparenamesq(r, &i)))
1472 (*r)->flags |= GF_SKIPME;
1473 }
1474 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1475 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1476 i->flags |= GF_INSERTED;
1477 if ((*r)->flags & GF_SKIPME)
1478 i->flags |= GF_SKIPME;
1479 }
1480 }
1481 r++;
1482 }
1483 }
1484 }
1485 }
1486 i = i->next;
1487 y++;
[948]1488 // 08 Feb 08 SHL
1489 if (IsITimerExpired(pitdReport)) {
[551]1490 CHAR s[44];
[783]1491 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, grep->numfiles);
[948]1492 if (!hwndStatus)
1493 WinSetWindowText(grep->hwndCurFile, s);
1494 else {
1495 if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1496 WinSetWindowText(hwndStatus, s);
1497 }
[551]1498 }
[948]1499 // DosSleep(0); //26 Aug 07 GKY 1
1500 } // while
[2]1501 }
1502 else {
[948]1503 // Insufficient memory - fall back to slow method - fixme to saymsg?
[551]1504 DosBeep(50, 100);
[948]1505 if (!hwndStatus)
1506 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1507 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1508 WinSetWindowText(hwndStatus, GetPString(IDS_GREPDUPECOMPARINGTEXT));
[766]1509 x = y = 0;
[1009]1510 xfree(grep->dupenames, pszSrcFile, __LINE__);
[985]1511 grep->dupenames = NULL;
[1009]1512 xfree(grep->dupesizes, pszSrcFile, __LINE__);
[985]1513 grep->dupesizes = NULL;
[1063]1514# ifdef FORTIFY
1515 Fortify_LeaveScope();
1516# endif
[948]1517
1518 InitITimer(pitdSleep, 0); // Reset rate estimator
[783]1519 i = grep->dupehead;
[551]1520 while (i) {
[783]1521 if (*grep->stopflag)
[551]1522 break;
[948]1523 SleepIfNeeded(pitdSleep, 1);
[551]1524 if (!(i->flags & GF_SKIPME)) {
[948]1525 if (IsITimerExpired(pitdReport)) {
1526 // if (!(y % cntr)) { }
[551]1527 CHAR s[44];
[783]1528 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, grep->numfiles);
[948]1529 if (!hwndStatus)
1530 WinSetWindowText(grep->hwndCurFile, s);
1531 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1532 WinSetWindowText(hwndStatus, s);
1533 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[551]1534 }
1535 y++;
1536 pi = strrchr(i->name, '\\');
1537 if (pi)
[689]1538 pi++;
[551]1539 else
1540 pi = i->name;
[783]1541 c = grep->dupehead;
[551]1542 while (c) {
[783]1543 if (*grep->stopflag)
[551]1544 break;
1545 if (c != i && !(c->flags & (GF_INSERTED | GF_SKIPME))) {
1546 x++;
1547 pc = strrchr(c->name, '\\');
1548 if (pc)
1549 pc++;
1550 else
1551 pc = c->name;
[783]1552 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
1553 if (grep->CRCdupes) {
1554 if (grep->CRCdupes) {
[551]1555 if (c->CRC == -1L) {
1556 c->CRC = CRCFile(c->name, &error);
1557 if (error)
1558 c->CRC = -1L;
1559 else if (c->CRC == -1L)
1560 c->CRC = 0L;
1561 }
1562 if (i->CRC == -1L) {
1563 i->CRC = CRCFile(i->name, &error);
1564 if (error)
1565 i->CRC = -1L;
1566 else if (i->CRC == -1L)
1567 i->CRC = 0L;
1568 }
1569 if ((c->size != i->size) || (c->CRC != -1L &&
1570 i->CRC != -1L
1571 && c->CRC != i->CRC)) {
1572 c = c->next;
1573 continue;
1574 }
1575 }
1576 }
1577 if (AddToList(c->name, &list, &numfiles, &numalloced))
1578 goto BreakOut; // Failed
1579 if (!(i->flags & GF_INSERTED)) {
1580 if (AddToList(i->name, &list, &numfiles, &numalloced))
1581 goto BreakOut; // Failed
1582 }
[948]1583 if (grep->sayfiles) {
1584 if (!hwndStatus)
1585 WinSetWindowText(grep->hwndCurFile, pc);
1586 else if (WinQueryFocus(HWND_DESKTOP) == grep->hwndFiles)
1587 WinSetWindowText(hwndStatus, pc);
1588 }
[551]1589 c->flags |= GF_INSERTED;
1590 i->flags |= GF_INSERTED;
1591 if (!stricmp(pc, pi)) {
1592 c->flags |= GF_SKIPME;
1593 i->flags |= GF_SKIPME;
1594 }
1595 }
[948]1596 // else if (!(x % 100)) // 07 Feb 08 SHL
1597 // DosSleep(0); //26 Aug 07 GKY 1 // 07 Feb 08 SHL
[551]1598 }
1599 c = c->next;
1600 }
1601 }
1602 i = i->next;
[948]1603 } // while
[2]1604 }
1605 }
1606BreakOut:
[783]1607 FreeDupes(grep);
[551]1608 if (numfiles && list) {
[783]1609 if (!PostMsg(grep->hwndFiles,
[948]1610 WM_COMMAND,
1611 MPFROM2SHORT(IDM_COLLECTOR, 0),
1612 MPFROMP(list)))
[2]1613 FreeList(list);
1614 }
1615 else
1616 DosPostEventSem(CompactSem);
1617}
1618
[841]1619static BOOL InsertDupe(GREP *grep, CHAR *dir, FILEFINDBUF4L *pffb)
[51]1620{
[2]1621 DUPES *info;
1622
[350]1623 if (*dir) {
[551]1624 info = xmallocz(sizeof(DUPES), pszSrcFile, __LINE__);
[350]1625 if (!info)
1626 return FALSE;
[783]1627
1628 info->name = xstrdup(dir, pszSrcFile, __LINE__);
1629 if (!info->name) {
[1039]1630 free(info);
[1063]1631# ifdef FORTIFY
1632 Fortify_LeaveScope();
1633# endif
[783]1634 return FALSE;
[2]1635 }
[783]1636
1637 info->size = pffb->cbFile;
1638 info->date = pffb->fdateLastWrite;
1639 info->time = pffb->ftimeLastWrite;
1640 info->CRC = -1L;
1641 grep->numfiles++;
1642 if (!grep->dupehead)
1643 grep->dupehead = info;
1644 if (grep->dupelast)
1645 grep->dupelast->next = info;
1646 grep->dupelast = info;
1647 info->next = NULL;
[2]1648 }
1649 return TRUE;
1650}
[783]1651
[948]1652#pragma alloc_text(GREP,InsertGrepFile,DoOneFile,DoInsertion,freegreplist)
[783]1653#pragma alloc_text(GREP,SecsSince1980,match,mmatch,GrepThread)
[948]1654#pragma alloc_text(GREP,DoAllSubdirs,DoMatchingFiles,InsertDupes,FreeDupes)
[783]1655
1656#pragma alloc_text(DUPES,InsertDupe,FillDupes,FreeDupes,CRCFile,CRCBlock)
1657#pragma alloc_text(DUPES,comparenamesq,comparenamesqe,comparenamesb)
1658#pragma alloc_text(DUPES,comparenamesbe,comparesizesq,comparesizesb)
Note: See TracBrowser for help on using the repository browser.