source: trunk/dll/grep.c@ 1179

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

Ticket 187: Draft 2: Move remaining function declarations

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