source: trunk/dll/grep.c@ 1402

Last change on this file since 1402 was 1402, checked in by Gregg Young, 16 years ago

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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