source: trunk/dll/grep.c@ 784

Last change on this file since 784 was 783, checked in by Steven Levine, 18 years ago

Rework DosFindFirst/Next loops to optimize memory allocation and code paths
Adjust FilesToGet limits
Update configuration notebook scanning page
Start updating #pragma alloc_text positioning for OpenWatcom compatibility

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