source: trunk/dll/grep.c@ 617

Last change on this file since 617 was 551, checked in by Gregg Young, 19 years ago

Indentation cleanup

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