source: trunk/dll/grep.c@ 689

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

Commit OpenWatcom compatibility updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: grep.c 689 2007-06-15 06:33:24Z stevenhl $
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 } // while
352
353 if (WinIsWindow(grep.ghab, grep.hwndFiles))
354 doinsertion(&grep); /* insert any remaining objects */
355
356 if (WinIsWindow(grep.ghab, grep.hwndFiles) && grep.finddupes &&
357 !*grep.stopflag)
358 FillDupes(&grep);
359
360 if (!PostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID)) /* tell window we're done */
361 WinSendMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
362 WinDestroyMsgQueue(ghmq);
363 }
364 DecrThreadUsage();
365 WinTerminate(ghab);
366 }
367 if (!ghmq || !ghab)
368 WinPostMsg(grep.hwndFiles, UM_CONTAINER_FILLED, MPVOID, MPVOID);
369 if (grep.dupehead)
370 FreeDupes(&grep);
371 if (grep.numlines && grep.matched)
372 free(grep.matched);
373 DosPostEventSem(CompactSem);
374}
375
376static BOOL IsExcluded(char *name, char **fle, int numfls)
377{
378 register int x;
379 char *n;
380
381 n = strrchr(name, '\\');
382 if (!n)
383 n = strrchr(name, ':');
384 if (n)
385 n++;
386 else
387 n = name;
388 for (x = 0; x < numfls; x++) {
389 if (*fle[x] == '/' &&
390 wildcard((strchr(fle[x], '\\') ||
391 strchr(fle[x], ':')) ? name : n, fle[x] + 1, FALSE))
392 return TRUE;
393 }
394 return FALSE;
395}
396
397static VOID doallsubdirs(GREP * grep, CHAR * searchPath, BOOL recursing,
398 char **fle, int numfls)
399{
400
401 /* process all subdirectories */
402
403 FILEFINDBUF4 findBuffer;
404 HDIR findHandle = HDIR_CREATE;
405 LONG findCount = 1L;
406 CHAR *p = NULL;
407
408 /* add a mask to search path */
409 if (searchPath[strlen(searchPath) - 1] != '\\')
410 strcat(searchPath, "\\");
411 strcat(searchPath, "*");
412 /* step through all subdirectories */
413 DosError(FERR_DISABLEHARDERR);
414 if (!DosFindFirst(searchPath, &findHandle, (MUST_HAVE_DIRECTORY |
415 FILE_ARCHIVED | FILE_SYSTEM |
416 FILE_HIDDEN | FILE_READONLY),
417 &findBuffer, (ULONG) sizeof(findBuffer),
418 (PULONG) & findCount, FIL_QUERYEASIZE)) {
419
420 /* get rid of mask portion, save end-of-directory */
421
422 p = strrchr(searchPath, '\\');
423 if (p)
424 p++;
425 else
426 p = searchPath;
427 do { /* Process each directory that matches the mask */
428 priority_normal();
429 if (*grep->stopflag)
430 break;
431 // Skip . and ..
432 if (findBuffer.achName[0] != '.' ||
433 (findBuffer.achName[1] &&
434 (findBuffer.achName[1] != '.' || findBuffer.achName[2]))) {
435 strcpy(p, findBuffer.achName);
436 if (!grep->anyexcludes || !IsExcluded(searchPath, fle, numfls)) {
437 domatchingfiles(grep, searchPath, fle, numfls);
438 doallsubdirs(grep, searchPath, TRUE, fle, numfls);
439 DosSleep(0L);
440 }
441 }
442 findCount = 1L;
443 } while (!DosFindNext(findHandle,
444 &findBuffer,
445 sizeof(findBuffer), (PULONG) & findCount));
446 DosFindClose(findHandle);
447 priority_normal();
448 }
449 if (p) /* strip off last directory addition */
450 *p = 0;
451}
452
453static INT domatchingfiles(GREP * grep, CHAR * path, char **fle, int numfls)
454{
455 /* process all matching files in a directory */
456
457 PFILEFINDBUF4 findBuffer;
458 PFILEFINDBUF4 pffbFile;
459 register PBYTE fb;
460 register ULONG x;
461 HDIR findHandle = HDIR_CREATE;
462 ULONG findCount = grep->FilesToGet;
463 CHAR newPath[CCHMAXPATH], *p;
464 APIRET rc;
465
466 findBuffer =
467 xmalloc(grep->FilesToGet * sizeof(FILEFINDBUF4), pszSrcFile, __LINE__);
468 if (!findBuffer)
469 return 0;
470
471 /* build filemask */
472
473 sprintf(newPath,
474 "%s%s%s",
475 path,
476 (path[strlen(path) - 1] == '\\') ? NullStr : "\\", grep->fileMask);
477
478 MakeFullName(newPath);
479
480 /* find and save end-of-dir position */
481 p = strrchr(newPath, '\\');
482 if (p)
483 p++;
484 else
485 p = newPath;
486
487 /* step through matching files */
488 DosError(FERR_DISABLEHARDERR);
489 if (!DosFindFirst(newPath,
490 &findHandle,
491 (FILE_NORMAL | grep->attrFile | grep->antiattr),
492 findBuffer,
493 (ULONG) (grep->FilesToGet * sizeof(FILEFINDBUF4)),
494 (PULONG) & findCount, FIL_QUERYEASIZE)) {
495
496 do { /* Process each file that matches the mask */
497 priority_normal();
498 fb = (PBYTE) findBuffer;
499 for (x = 0L; x < findCount; x++) {
500 pffbFile = (PFILEFINDBUF4) fb;
501 if (*grep->stopflag)
502 break;
503 if (*pffbFile->achName != '.' ||
504 (pffbFile->achName[1] && pffbFile->achName[1] != '.')) {
505 strcpy(p, pffbFile->achName); /* build filename */
506 if (!grep->anyexcludes || !IsExcluded(newPath, fle, numfls)) {
507 if (!grep->finddupes)
508 doonefile(grep, newPath, pffbFile);
509 else if (!InsertDupe(grep, newPath, pffbFile)) {
510 DosFindClose(findHandle);
511 free(findBuffer);
512 return 1;
513 }
514 }
515 }
516 if (!pffbFile->oNextEntryOffset)
517 break;
518 fb += pffbFile->oNextEntryOffset;
519 }
520 findCount = grep->FilesToGet;
521 rc = DosFindNext(findHandle,
522 findBuffer,
523 (ULONG) (grep->FilesToGet * sizeof(FILEFINDBUF4)),
524 (PULONG) & findCount);
525 if (!rc)
526 DosSleep(1L);
527 } while (!rc);
528 DosFindClose(findHandle);
529 priority_normal();
530 }
531 free(findBuffer);
532 return 0;
533}
534
535#pragma alloc_text(GREP,insert_grepfile,doonefile,doinsertion,freegreplist)
536
537static VOID freegreplist(GREP * grep)
538{
539 register INT x;
540
541 if (grep) {
542 if (grep->insertffb) {
543 for (x = 0; grep->insertffb[x]; x++)
544 free(grep->insertffb[x]);
545 free(grep->insertffb);
546 }
547 if (grep->dir) {
548 for (x = 0; grep->dir[x]; x++)
549 free(grep->dir[x]);
550 free(grep->dir);
551 }
552 grep->dir = NULL;
553 grep->insertffb = NULL;
554 grep->toinsert = 0L;
555 grep->insertedbytes = 0L;
556 }
557}
558
559static BOOL doinsertion(GREP * grep)
560{
561 RECORDINSERT ri;
562 DIRCNRDATA *dcd;
563 PCNRITEM pci, pciFirst;
564 INT x;
565
566 if (!grep || !grep->toinsert || !grep->insertffb || !grep->dir)
567 return FALSE;
568 pci = WinSendMsg(grep->hwndFiles,
569 CM_ALLOCRECORD,
570 MPFROMLONG(EXTRA_RECORD_BYTES),
571 MPFROMLONG(grep->toinsert));
572 if (pci) {
573 if (grep->sayfiles)
574 WinSetWindowText(grep->hwndCurFile, GetPString(IDS_GREPINSERTINGTEXT));
575 pciFirst = pci;
576 dcd = INSTDATA(grep->hwndFiles);
577 for (x = 0; grep->insertffb[x]; x++) {
578 FillInRecordFromFFB(grep->hwndFiles,
579 pci, grep->dir[x], grep->insertffb[x], FALSE, dcd);
580 pci = (PCNRITEM) pci->rc.preccNextRecord;
581 }
582 memset(&ri, 0, sizeof(RECORDINSERT));
583 ri.cb = sizeof(RECORDINSERT);
584 ri.pRecordOrder = (PRECORDCORE) CMA_END;
585 ri.pRecordParent = (PRECORDCORE) NULL;
586 ri.zOrder = (USHORT) CMA_TOP;
587 ri.cRecordsInsert = grep->toinsert;
588 ri.fInvalidateRecord = TRUE;
589 WinSendMsg(grep->hwndFiles,
590 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
591 if (dcd) {
592 DosEnterCritSec();
593 dcd->ullTotalBytes += grep->insertedbytes;
594 DosExitCritSec();
595 }
596 if (grep->toinsert == grep->FilesToGet)
597 DosSleep(1L);
598 freegreplist(grep);
599 PostMsg(grep->hwndFiles, UM_RESCAN, MPVOID, MPVOID);
600 return TRUE;
601 }
602 freegreplist(grep);
603 return FALSE;
604}
605
606static BOOL insert_grepfile(GREP * grep, CHAR * filename, FILEFINDBUF4 * f)
607{
608 CHAR *p, szDirectory[CCHMAXPATH];
609
610 if (WinIsWindow(grep->ghab, grep->hwndFiles)) {
611 grep->numfiles++;
612 strcpy(szDirectory, filename);
613 p = strrchr(szDirectory, '\\');
614 if (p) {
615 if (p < szDirectory + 4)
616 p++;
617 *p = 0;
618 if (!grep->insertffb) {
619 grep->insertffb = xmallocz(sizeof(FILEFINDBUF4 *) *
620 (grep->FilesToGet + 1), pszSrcFile,
621 __LINE__);
622 if (!grep->insertffb)
623 return FALSE;
624 grep->dir =
625 xmallocz(sizeof(CHAR *) * (grep->FilesToGet + 1), pszSrcFile,
626 __LINE__);
627 if (!grep->dir) {
628 free(grep->insertffb);
629 return FALSE;
630 }
631 }
632 grep->insertffb[grep->toinsert] =
633 xmalloc(sizeof(FILEFINDBUF4), pszSrcFile, __LINE__);
634 if (!grep->insertffb[grep->toinsert])
635 return FALSE;
636 memcpy(grep->insertffb[grep->toinsert], f, sizeof(FILEFINDBUF4));
637 grep->dir[grep->toinsert] = xstrdup(szDirectory, pszSrcFile, __LINE__);
638 if (!grep->dir) {
639 free(grep->insertffb[grep->toinsert]);
640 return FALSE;
641 }
642 grep->insertedbytes += f->cbFile + CBLIST_TO_EASIZE(f->cbList);
643 grep->toinsert++;
644 if (grep->toinsert == grep->FilesToGet)
645 return doinsertion(grep);
646 return TRUE;
647 }
648 }
649 else
650 freegreplist(grep);
651 return FALSE;
652}
653
654static BOOL doonefile(GREP * grep, CHAR * filename, FILEFINDBUF4 * f)
655{
656 /* process a single file */
657
658 CHAR *input;
659 FILE *inputFile;
660 ULONG pos;
661 BOOL ret = FALSE, strmatch = FALSE;
662
663 grep->fileCount++;
664 if (grep->sayfiles)
665 WinSetWindowText(grep->hwndCurFile, filename);
666
667 if (grep->greaterthan || grep->lessthan) {
668
669 BOOL keep = TRUE;
670 ULONG adjsize;
671
672 adjsize = f->cbFile + (grep->searchEAs ? CBLIST_TO_EASIZE(f->cbList) : 0);
673 if (grep->greaterthan) {
674 if (adjsize < grep->greaterthan)
675 keep = FALSE;
676 }
677 if (keep && grep->lessthan) {
678 if (adjsize > grep->lessthan)
679 keep = FALSE;
680 }
681 if (!keep)
682 return ret;
683 }
684
685 if (grep->newerthan || grep->olderthan) {
686
687 BOOL keep = TRUE;
688 ULONG numsecs;
689
690 numsecs = SecsSince1980(&f->fdateLastWrite, &f->ftimeLastWrite);
691 if (grep->newerthan) {
692 if (numsecs < grep->newerthan)
693 keep = FALSE;
694 }
695 if (keep && grep->olderthan) {
696 if (numsecs > grep->olderthan)
697 keep = FALSE;
698 }
699 if (!keep)
700 return ret;
701 }
702
703 if ((!grep->searchEAs && !grep->searchFiles) || !*grep->searchPattern) /* just a find */
704 return insert_grepfile(grep, filename, f);
705
706 if (grep->searchEAs) {
707
708 HOLDFEA *head, *info;
709 USHORT type, len;
710 BOOL alltext;
711 CHAR *data, temp;
712
713 head = GetFileEAs(filename, FALSE, TRUE);
714 if (head) {
715 info = head;
716 while (info && !strmatch) {
717 alltext = TRUE;
718 switch (*(USHORT *) info->value) {
719 case EAT_ASCII:
720 if (match(info->value + (sizeof(USHORT) * 2),
721 grep->searchPattern, grep->absFlag,
722 (grep->caseFlag == FALSE),
723 info->cbValue - (sizeof(USHORT) * 2),
724 grep->numlines, grep->matched, !grep->findifany)) {
725 strmatch = TRUE;
726 }
727 break;
728 case EAT_MVST:
729 type = *(USHORT *) (info->value + (sizeof(USHORT) * 3));
730 if (type == EAT_ASCII) {
731 data = info->value + (sizeof(USHORT) * 4);
732 len = *(USHORT *) data;
733 data += sizeof(USHORT);
734 while ((data - info->value) + len <= info->cbValue) {
735 temp = *(data + len);
736 *(data + len) = 0;
737 if (match(data,
738 grep->searchPattern,
739 grep->absFlag,
740 (grep->caseFlag == FALSE),
741 len,
742 grep->numlines, grep->matched, !grep->findifany)) {
743 strmatch = TRUE;
744 break;
745 }
746 data += len;
747 if (data - info->value >= info->cbValue)
748 break;
749 *data = temp;
750 len = *(USHORT *) data;
751 data += sizeof(USHORT);
752 }
753 }
754 break;
755 case EAT_MVMT:
756 data = info->value + (sizeof(USHORT) * 3);
757 type = *(USHORT *) data;
758 data += sizeof(USHORT);
759 len = *(USHORT *) data;
760 data += sizeof(USHORT);
761 while ((data - info->value) - len <= info->cbValue) {
762 if (type != EAT_ASCII) {
763 alltext = FALSE;
764 break;
765 }
766 data += len;
767 if (data - info->value >= info->cbValue)
768 break;
769 type = *(USHORT *) data;
770 data += sizeof(USHORT);
771 len = *(USHORT *) data;
772 data += sizeof(USHORT);
773 }
774 if (alltext) {
775 data = info->value + (sizeof(USHORT) * 3);
776 type = *(USHORT *) data;
777 data += sizeof(USHORT);
778 len = *(USHORT *) data;
779 data += sizeof(USHORT);
780 while ((data - info->value) - len <= info->cbValue) {
781 temp = *(data + len);
782 *(data + len) = 0;
783 if (match(data,
784 grep->searchPattern,
785 grep->absFlag,
786 (grep->caseFlag == FALSE),
787 len,
788 grep->numlines, grep->matched, !grep->findifany)) {
789 strmatch = TRUE;
790 break;
791 }
792 data += len;
793 *data = temp;
794 if (data - info->value >= info->cbValue)
795 break;
796 type = *(USHORT *) data;
797 data += sizeof(USHORT);
798 len = *(USHORT *) data;
799 data += sizeof(USHORT);
800 }
801 }
802 break;
803 default:
804 break;
805 }
806 info = info->next;
807 } // while
808 Free_FEAList(head);
809 DosSleep(1L);
810 }
811 }
812
813 if (grep->searchFiles) {
814 input = xmalloc(65537, pszSrcFile, __LINE__);
815 if (input) {
816 LONG len;
817
818 inputFile = _fsopen(filename, "rb", SH_DENYNO);
819 if (inputFile) {
820 pos = ftell(inputFile);
821 while (!feof(inputFile)) {
822 if (pos)
823 fseek(inputFile, pos - 1024, SEEK_SET);
824 len = fread(input, 1, 65536, inputFile);
825 if (len >= 0) {
826 if (*grep->stopflag)
827 break;
828 if (match(input,
829 grep->searchPattern,
830 grep->absFlag,
831 (grep->caseFlag == FALSE),
832 len, grep->numlines, grep->matched, !grep->findifany)) {
833 strmatch = TRUE;
834 break;
835 }
836 }
837 else
838 break;
839 }
840 fclose(inputFile);
841 }
842 free(input);
843 DosSleep(1L);
844 }
845 } // if
846
847 if (strmatch)
848 ret = insert_grepfile(grep, filename, f);
849 return ret;
850}
851
852#pragma alloc_text(DUPES,InsertDupe,FillDupes,FreeDupes,CRCFile,CRCBlock)
853#pragma alloc_text(DUPES,comparenamesq,comparenamesqe,comparenamesb)
854#pragma alloc_text(DUPES,comparenamesbe,comparesizesq,comparesizesb)
855
856static LONG cr3tab[] = { /* CRC polynomial 0xEDB88320 */
857
858 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
859 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
860 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
861 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
862 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
863 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
864 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
865 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
866 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
867 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
868 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
869 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
870 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
871 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
872 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
873 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
874 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
875 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
876 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
877 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
878 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
879 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
880 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
881 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
882 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
883 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
884 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
885 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
886 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
887 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
888 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
889 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
890 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
891 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
892 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
893 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
894 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
895 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
896 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
897 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
898 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
899 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
900 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
901 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
902 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
903 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
904 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
905 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
906 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
907 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
908 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
909 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
910 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
911 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
912 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
913 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
914 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
915 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
916 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
917 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
918 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
919 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
920 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
921 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
922};
923
924LONG CRCBlock(register CHAR * str, register INT blklen, register LONG crc)
925{
926 while (blklen--) {
927 crc =
928 cr3tab[((INT) crc ^ *str) & 0xff] ^ (((ULONG) crc >> 8) & 0x00FFFFFF);
929 str++;
930 }
931 return crc;
932}
933
934LONG CRCFile(CHAR * filename, INT * error)
935{
936 LONG CRC = -1L, len;
937 FILE *fp;
938 CHAR *buffer;
939
940 *error = 0;
941 buffer = xmalloc(65535, pszSrcFile, __LINE__);
942 if (!buffer)
943 *error = -1;
944 else {
945 fp = _fsopen(filename, "rb", SH_DENYNO);
946 if (!fp)
947 *error = -2;
948 else {
949 while (!feof(fp)) {
950 len = fread(buffer, 1, 65535, fp);
951 if (len && len < 65536L)
952 CRC = CRCBlock(buffer, len, CRC);
953 else
954 break;
955 DosSleep(0L);
956 }
957 fclose(fp);
958 DosSleep(1L);
959 }
960 free(buffer);
961 }
962 return CRC;
963}
964
965static VOID FreeDupes(GREP * g)
966{
967 DUPES *i, *next;
968
969 i = g->dupehead;
970 while (i) {
971 next = i->next;
972 if (i->name)
973 free(i->name);
974 free(i);
975 i = next;
976 }
977 g->dupehead = g->dupelast = NULL;
978 if (g->dupenames)
979 free(g->dupenames);
980 if (g->dupesizes)
981 free(g->dupesizes);
982 g->dupesizes = g->dupenames = NULL;
983}
984
985int comparenamesq(const void *v1, const void *v2)
986{
987 DUPES *d1 = *(DUPES **) v1;
988 DUPES *d2 = *(DUPES **) v2;
989 CHAR *p1, *p2;
990
991 p1 = strrchr(d1->name, '\\');
992 if (p1)
993 p1++;
994 else
995 p1 = d1->name;
996 p2 = strrchr(d2->name, '\\');
997 if (p2)
998 p2++;
999 else
1000 p2 = d2->name;
1001 return stricmp(p1, p2);
1002}
1003
1004int comparenamesqe(const void *v1, const void *v2)
1005{
1006 DUPES *d1 = *(DUPES **) v1;
1007 DUPES *d2 = *(DUPES **) v2;
1008 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
1009 int ret;
1010
1011 p1 = strrchr(d1->name, '\\');
1012 if (p1)
1013 p1++;
1014 else
1015 p1 = d1->name;
1016 p1e = strrchr(p1, '.');
1017 if (p1e) {
1018 e1 = *p1e;
1019 *p1e = 0;
1020 }
1021 p2 = strrchr(d2->name, '\\');
1022 if (p2)
1023 p2++;
1024 else
1025 p2 = d2->name;
1026 p2e = strrchr(p2, '.');
1027 if (p2e) {
1028 e2 = *p2e;
1029 *p2e = 0;
1030 }
1031 ret = stricmp(p1, p2);
1032 if (p1e)
1033 *p1e = e1;
1034 if (p2e)
1035 *p2e = e2;
1036 return ret;
1037}
1038
1039int comparesizesq(const void *v1, const void *v2)
1040{
1041 DUPES *d1 = *(DUPES **) v1;
1042 DUPES *d2 = *(DUPES **) v2;
1043
1044 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1045}
1046
1047int comparenamesb(const void *v1, const void *v2)
1048{
1049 DUPES *d1 = (DUPES *) v1;
1050 DUPES *d2 = *(DUPES **) v2;
1051 CHAR *p1, *p2;
1052
1053 p1 = strrchr(d1->name, '\\');
1054 if (p1)
1055 p1++;
1056 else
1057 p1 = d1->name;
1058 p2 = strrchr(d2->name, '\\');
1059 if (p2)
1060 p2++;
1061 else
1062 p2 = d2->name;
1063 return stricmp(p1, p2);
1064}
1065
1066int comparenamesbe(const void *v1, const void *v2)
1067{
1068 DUPES *d1 = (DUPES *) v1;
1069 DUPES *d2 = *(DUPES **) v2;
1070 CHAR *p1, *p2, *p1e, *p2e, e1, e2;
1071 int ret;
1072
1073 p1 = strrchr(d1->name, '\\');
1074 if (p1)
1075 p1++;
1076 else
1077 p1 = d1->name;
1078 p1e = strrchr(p1, '.');
1079 if (p1e) {
1080 e1 = *p1e;
1081 *p1e = 0;
1082 }
1083 p2 = strrchr(d2->name, '\\');
1084 if (p2)
1085 p2++;
1086 else
1087 p2 = d2->name;
1088 p2e = strrchr(p2, '.');
1089 if (p2e) {
1090 e2 = *p2e;
1091 *p2e = 0;
1092 }
1093 ret = stricmp(p1, p2);
1094 if (p1e)
1095 *p1e = e1;
1096 if (p2e)
1097 *p2e = e2;
1098 return ret;
1099}
1100
1101int comparesizesb(const void *v1, const void *v2)
1102{
1103 DUPES *d1 = (DUPES *) v1;
1104 DUPES *d2 = *(DUPES **) v2;
1105
1106 return (d1->size > d2->size) ? 1 : (d1->size == d2->size) ? 0 : -1;
1107}
1108
1109static VOID FillDupes(GREP * g)
1110{
1111 DUPES *c, *i, **r;
1112 register CHAR *pc, *pi;
1113 CHAR **list = NULL;
1114 INT numfiles = 0, numalloced = 0, error;
1115 register ULONG x = 0L, y = 0L;
1116 ULONG cntr = 100;
1117
1118 if (g->CRCdupes)
1119 cntr = 50;
1120 i = g->dupehead;
1121 while (i) {
1122 x++;
1123 i = i->next;
1124 }
1125 if (x) {
1126 WinSetWindowText(g->hwndCurFile, GetPString(IDS_GREPDUPESORTINGTEXT));
1127 DosSleep(1L);
1128 g->dupenames = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1129 if (!g->nosizedupes)
1130 g->dupesizes = xmalloc(sizeof(DUPES *) * (x + 1), pszSrcFile, __LINE__);
1131 if (g->dupenames && (g->nosizedupes || g->dupesizes)) {
1132 i = g->dupehead;
1133 while (i) {
1134 g->dupenames[y] = i;
1135 if (!g->nosizedupes)
1136 g->dupesizes[y] = i;
1137 i = i->next;
1138 y++;
1139 }
1140 g->dupenames[y] = NULL;
1141 if (!g->nosizedupes)
1142 g->dupesizes[y] = NULL;
1143 DosSleep(1L);
1144 qsort(g->dupenames,
1145 x,
1146 sizeof(DUPES *),
1147 ((g->ignoreextdupes) ? comparenamesqe : comparenamesq));
1148 DosSleep(1L);
1149 if (!g->nosizedupes) {
1150 qsort(g->dupesizes, x, sizeof(DUPES *), comparesizesq);
1151 DosSleep(1L);
1152 }
1153 WinSetWindowText(g->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1154
1155 i = g->dupehead;
1156 y = 0L;
1157 while (i) {
1158 if (*g->stopflag)
1159 break;
1160 if (!(i->flags & GF_SKIPME)) {
1161 r = (DUPES **) bsearch(i, g->dupenames, x, sizeof(DUPES *),
1162 ((g->ignoreextdupes) ? comparenamesbe :
1163 comparenamesb));
1164 if (r) {
1165 while (r > g->dupenames && ((g->ignoreextdupes) ?
1166 !comparenamesqe((r - 1), &i) :
1167 !comparenamesq((r - 1), &i)))
1168 r--;
1169 while (*r && ((g->ignoreextdupes) ?
1170 !comparenamesqe(r, &i) : !comparenamesq(r, &i))) {
1171 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME))) {
1172 r++;
1173 continue;
1174 }
1175 if (g->CRCdupes) {
1176 if ((*r)->CRC == -1L) {
1177 (*r)->CRC = CRCFile((*r)->name, &error);
1178 if (error)
1179 (*r)->CRC = -1L;
1180 else if ((*r)->CRC == -1L)
1181 (*r)->CRC = 0L;
1182 }
1183 if (i->CRC == -1L) {
1184 i->CRC = CRCFile(i->name, &error);
1185 if (error)
1186 i->CRC = -1L;
1187 else if (i->CRC == -1L)
1188 i->CRC = 0L;
1189 }
1190 if (((*r)->size != i->size) || ((*r)->CRC != -1L &&
1191 i->CRC != -1L
1192 && (*r)->CRC != i->CRC)) {
1193 r++;
1194 continue;
1195 }
1196 }
1197 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
1198 (*r)->flags |= GF_INSERTED;
1199 if (g->sayfiles)
1200 WinSetWindowText(g->hwndFiles, (*r)->name);
1201 if ((*r)->size == i->size &&
1202 (i->date.year == (*r)->date.year &&
1203 i->date.month == (*r)->date.month &&
1204 i->date.day == (*r)->date.day &&
1205 i->time.hours == (*r)->time.hours &&
1206 i->time.minutes == (*r)->time.minutes &&
1207 i->time.twosecs == (*r)->time.twosecs))
1208 (*r)->flags |= GF_SKIPME;
1209 }
1210 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1211 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1212 i->flags |= GF_INSERTED;
1213 if ((*r)->flags & GF_SKIPME)
1214 i->flags |= GF_SKIPME;
1215 }
1216 }
1217 r++;
1218 }
1219 }
1220 if (!g->nosizedupes) {
1221 r = (DUPES **) bsearch(i,
1222 g->dupesizes,
1223 x, sizeof(DUPES *), comparesizesb);
1224 if (r) {
1225 while (r > g->dupesizes && !comparesizesq((r - 1), &i))
1226 r--;
1227 while (*r && !comparesizesq(r, &i)) {
1228 if (*r == i || ((*r)->flags & (GF_INSERTED | GF_SKIPME)) ||
1229 (i->date.year != (*r)->date.year ||
1230 i->date.month != (*r)->date.month ||
1231 i->date.day != (*r)->date.day ||
1232 i->time.hours != (*r)->time.hours ||
1233 i->time.minutes != (*r)->time.minutes ||
1234 i->time.twosecs != (*r)->time.twosecs)) {
1235 r++;
1236 continue;
1237 }
1238 if (g->CRCdupes) {
1239 if ((*r)->CRC == -1L) {
1240 (*r)->CRC = CRCFile((*r)->name, &error);
1241 if (error)
1242 (*r)->CRC = -1L;
1243 else if ((*r)->CRC == -1L)
1244 (*r)->CRC = 0L;
1245 }
1246 if (i->CRC == -1L) {
1247 i->CRC = CRCFile(i->name, &error);
1248 if (error)
1249 i->CRC = -1L;
1250 else if (i->CRC == -1L)
1251 i->CRC = 0L;
1252 }
1253 if ((*r)->CRC != -1L && i->CRC != -1L &&
1254 (*r)->CRC != i->CRC) {
1255 *r += 1;
1256 continue;
1257 }
1258 }
1259 if (!AddToList((*r)->name, &list, &numfiles, &numalloced)) {
1260 if (g->sayfiles)
1261 WinSetWindowText(g->hwndCurFile, (*r)->name);
1262 (*r)->flags |= GF_INSERTED;
1263 if (((g->ignoreextdupes) ?
1264 comparenamesqe(r, &i) : comparenamesq(r, &i)))
1265 (*r)->flags |= GF_SKIPME;
1266 }
1267 if (!(i->flags & (GF_INSERTED | GF_SKIPME))) {
1268 if (!AddToList(i->name, &list, &numfiles, &numalloced)) {
1269 i->flags |= GF_INSERTED;
1270 if ((*r)->flags & GF_SKIPME)
1271 i->flags |= GF_SKIPME;
1272 }
1273 }
1274 r++;
1275 }
1276 }
1277 }
1278 }
1279 i = i->next;
1280 y++;
1281 if (!(y % cntr)) {
1282
1283 CHAR s[44];
1284
1285 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, g->numfiles);
1286 WinSetWindowText(g->hwndCurFile, s);
1287 DosSleep(128L);
1288 }
1289 DosSleep(y % 2);
1290 }
1291 }
1292 else {
1293 // Insufficient memory - fall back
1294 DosBeep(50, 100);
1295 WinSetWindowText(g->hwndCurFile, GetPString(IDS_GREPDUPECOMPARINGTEXT));
1296 x = y = 0L;
1297 if (g->dupenames) {
1298 free(g->dupenames);
1299 g->dupenames = NULL;
1300 }
1301 if (g->dupesizes) {
1302 free(g->dupesizes);
1303 g->dupesizes = NULL;
1304 }
1305 i = g->dupehead;
1306 while (i) {
1307 if (*g->stopflag)
1308 break;
1309 if (!(i->flags & GF_SKIPME)) {
1310 if (!(y % cntr)) {
1311
1312 CHAR s[44];
1313
1314 sprintf(s, GetPString(IDS_GREPDUPECHECKPROGTEXT), y, g->numfiles);
1315 WinSetWindowText(g->hwndCurFile, s);
1316 DosSleep(0L);
1317 }
1318 y++;
1319 pi = strrchr(i->name, '\\');
1320 if (pi)
1321 pi++;
1322 else
1323 pi = i->name;
1324 c = g->dupehead;
1325 while (c) {
1326 if (*g->stopflag)
1327 break;
1328 if (c != i && !(c->flags & (GF_INSERTED | GF_SKIPME))) {
1329 x++;
1330 pc = strrchr(c->name, '\\');
1331 if (pc)
1332 pc++;
1333 else
1334 pc = c->name;
1335 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 */
1336 if (g->CRCdupes) {
1337 if (g->CRCdupes) {
1338 if (c->CRC == -1L) {
1339 c->CRC = CRCFile(c->name, &error);
1340 if (error)
1341 c->CRC = -1L;
1342 else if (c->CRC == -1L)
1343 c->CRC = 0L;
1344 }
1345 if (i->CRC == -1L) {
1346 i->CRC = CRCFile(i->name, &error);
1347 if (error)
1348 i->CRC = -1L;
1349 else if (i->CRC == -1L)
1350 i->CRC = 0L;
1351 }
1352 if ((c->size != i->size) || (c->CRC != -1L &&
1353 i->CRC != -1L
1354 && c->CRC != i->CRC)) {
1355 c = c->next;
1356 continue;
1357 }
1358 }
1359 }
1360 if (AddToList(c->name, &list, &numfiles, &numalloced))
1361 goto BreakOut; // Failed
1362 if (!(i->flags & GF_INSERTED)) {
1363 if (AddToList(i->name, &list, &numfiles, &numalloced))
1364 goto BreakOut; // Failed
1365 }
1366 if (g->sayfiles)
1367 WinSetWindowText(g->hwndCurFile, pc);
1368 c->flags |= GF_INSERTED;
1369 i->flags |= GF_INSERTED;
1370 if (!stricmp(pc, pi)) {
1371 c->flags |= GF_SKIPME;
1372 i->flags |= GF_SKIPME;
1373 }
1374 }
1375 else if (!(x % 100L))
1376 DosSleep(1L);
1377 }
1378 c = c->next;
1379 }
1380 }
1381 i = i->next;
1382 }
1383 }
1384 }
1385BreakOut:
1386 FreeDupes(g);
1387 if (numfiles && list) {
1388 if (!PostMsg(g->hwndFiles,
1389 WM_COMMAND, MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list)))
1390 FreeList(list);
1391 }
1392 else
1393 DosPostEventSem(CompactSem);
1394}
1395
1396static BOOL InsertDupe(GREP * g, CHAR * dir, FILEFINDBUF4 * f)
1397{
1398 DUPES *info;
1399
1400 if (*dir) {
1401 info = xmallocz(sizeof(DUPES), pszSrcFile, __LINE__);
1402 if (!info)
1403 return FALSE;
1404 else {
1405 info->name = xstrdup(dir, pszSrcFile, __LINE__);
1406 if (!info->name) {
1407 free(info);
1408 return FALSE;
1409 }
1410 else {
1411 info->size = f->cbFile;
1412 info->date = f->fdateLastWrite;
1413 info->time = f->ftimeLastWrite;
1414 info->CRC = -1L;
1415 g->numfiles++;
1416 if (!g->dupehead)
1417 g->dupehead = info;
1418 if (g->dupelast)
1419 g->dupelast->next = info;
1420 g->dupelast = info;
1421 info->next = NULL;
1422 }
1423 }
1424 }
1425 return TRUE;
1426}
Note: See TracBrowser for help on using the repository browser.