home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
04
/
finddupe.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-05
|
7KB
|
255 lines
// finddupe.cpp
#include<malloc.h>
#include<dir.h>
#include"sort.h"
#include"msgbox.h"
#include"finddupe.h"
#include"makepath.h"
FindDupe::FindDupe(Window *S, Window *P)
{
Path = P;
Status = S;
numFound = 0;
}
int _Cdecl compare(const void far *e1, const void far *e2)
{
return _fstrcmp((*(char far * far*)e1),(*(char far * far*)e2));
}
void FindDupe::PostResults(char *dspec, struct ffblk *f)
{
if(PutDirectoryToTemp(dspec))
DispPath(dspec);
PutIndexToTemp(f->ff_name);
PutDataToTemp(&f->ff_ftime);
Status->Puts(f->ff_name);
numFound++;
}
void FindDupe::DispPath(char *path)
{
char formatbuffer[80];
SetWords((void far *)formatbuffer,0,WordSize(formatbuffer));
Path->Clear();
sprintf(formatbuffer,path);
Path->AtSay(0,0,strupr(formatbuffer));
}
BOOL FindDupe::FindDuplicates(char *searchdirs)
{
TempIndex.Open("wb");
TempData.Open("wb");
int i;
BOOL term;
SetEatKey();
strcpy(filespec,"*.*");
char oldtitle[40];
Status->GetTitle(oldtitle);
Status->SetTitle("Scanning...");
if(GetArgCount() > 0)
for(i = 0; i < GetArgCount(); i++)
{
// strcpy(dirspec,GetArg(i));
makepath(dirspec,GetArg(i));
if(!(isalpha(*dirspec)))
continue;
if(dirspec[1] != ':' && dirspec[2] != '\\')
continue;
strcpy(dirspec,dirspec);
Path->SetTitle(dirspec);
if(term = Run(dirspec,filespec))
break;
}
else
{
char *q = searchdirs;
while(*q)
{
char *p = strchr(q,' ');
if(p)
{
*p = '\0';
p++;
}
strcpy(dirspec,q);
if(!(isalpha(*dirspec)))
continue;
if(dirspec[1] != ':' && dirspec[2] != '\\')
continue;
strcpy(dirspec,dirspec);
Path->SetTitle(dirspec);
if(term = Run(dirspec,filespec))
break;
q = p;
}
}
Status->SetTitle(oldtitle);
TempIndex.Close();
TempData.Close();
if(term || !numFound)
{
TempIndex.Delete();
TempData.Delete();
return terminate(numFound ? "Terminated by user." : "None found");
}
Status->Puts("Scanning complete...");
TempIndex.Open("rb");
long indexsize = TempIndex.Size();
char huge *farbuffer = (char huge *)farmalloc(indexsize);
if(!farbuffer)
{
TempIndex.Delete();
TempData.Delete();
return terminate("Can\'t allocate far buffer");
}
int bytesread;
long offset = 0L;
const BUFFERSIZE = 5000;
char *nearbuffer = new char[BUFFERSIZE];
Status->Puts("Loading temp files...");
while(bytesread = TempIndex._fRead(BUFFERSIZE,&farbuffer[offset],nearbuffer))
offset += bytesread;
delete nearbuffer;
if(offset != indexsize)
{
TempIndex.Delete();
TempData.Delete();
return terminate("Temp file not read");
}
unsigned maxrecords = (unsigned)(indexsize/sizeof(OUTBUF));
unsigned currec;
char far * far *entrytable = (char far * far *)farmalloc((maxrecords*sizeof(char far * far *)));
if(!entrytable)
{
TempIndex.Delete();
TempData.Delete();
return terminate("Can\'t allocate pointer table");
}
Status->Puts("Preparing for sorting...");
for( offset = 0L, currec = 0; currec < maxrecords; currec++, offset += sizeof(OUTBUF))
entrytable[currec] = (char far *)(&farbuffer[offset]);
entrytable[maxrecords] = "";
#ifdef TESTING
Status->Puts("\n");
for(int i = 0; i < 10; i++)
Status->Printf("table[%02d]=%Fp %Fs\n",i,entrytable[i],entrytable[i]);
#endif
Status->Puts("Sorting records...");
Sort qs;
qs.QuickSort(entrytable,maxrecords,sizeof(char far * far *),compare);
Status->Puts("complete.");
#ifdef TESTING
Status->Puts("\n");
for(int i = 0; i < 10; i++)
Status->Printf("table[%02d]=%Fp %Fs\n",i,entrytable[i],entrytable[i]);
#endif
TempIndex.Close(); // close old index file
Status->Puts("Sifting duplicates...");
int WasMatch = FALSE;
numFound = 0;
for(currec = 0; currec < maxrecords; currec++)
{
// if current entry matches the next one, WasMatch = TRUE
if(!_fstrcmp(entrytable[currec],entrytable[currec+1]))
{
WasMatch = TRUE;
numFound++;
}
else // else they didn't match...
{
if(!WasMatch) // and the previous one didn't match -- OUT!
*entrytable[currec] = '\0';
else // or if the previous one DID match
WasMatch = FALSE; // set for no match on next
}
}
if(!numFound)
{
TempIndex.Delete();
TempData.Delete();
return FALSE;
}
IndexFile.Open("wb"); // create new index file
DataFile.Open("wb"); // create the new data file
TempData.Open("rb"); // open old one for reading
OUTBUF far *entry = (OUTBUF far *)entrytable[0];
Status->Printf("Writing %s...",DataFile.GetName());
// write out a data file record for each valid index record
for(offset = 0L, currec = 0; currec < maxrecords; currec++, offset += sizeof(OUTBUF))
{
entry = (OUTBUF far *)&farbuffer[offset];
if(*(entry->buf))
{
GetData(&TempData,entry->offset);
PutDirectoryToData(!currec ? TRUE : FALSE);
entry->offset = DataFile.CurPosition();
PutDataFile();
}
}
Status->Printf("and %s...",IndexFile.GetName());
// write remaining valid entries (the duplicates) to the index file
char nearbuffer2[sizeof(OUTBUF)];
for(currec = 0; currec < maxrecords; currec++)
if(*entrytable[currec])
IndexFile._fWrite(sizeof(OUTBUF),entrytable[currec],nearbuffer2);
farfree(entrytable);
farfree(farbuffer);
DataFile.Close();
IndexFile.Close();
Status->Puts("Deleting temp files...");
TempIndex.Delete();
TempData.Delete();
Status->Puts("Done!");
return TRUE;
}
//#define MAIN
#if defined(MAIN)
void main(void)
{
FindDupe myApp; // check arguments, setup movedir
myApp.FindDuplicates();
}
#endif