source: trunk/dll/grep.c @ 766

Last change on this file since 766 was 766, checked in by Gregg Young, 13 years ago

format cleanup

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