home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
network
/
eqtree
/
treeload.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-18
|
6KB
|
278 lines
/*
* TREELOAD.c
*
* Routinen zum einlesen und Bearbeiten von
* Verzeichnisbäumen.
*
* Autor: SG
* Stand: 25.1.93
*
*/
#include <stdio.h>
#include <string.h>
#define INCL_BASE
#define INCL_DOS
#define INCL_NOPM
#include <os2.h>
#include <stdlib.h>
#include <direct.h>
#include <ctype.h>
#include "logfile.h"
#include "treeload.h"
static unsigned long Date2Days(FDATE date)
{
return date.year * 365 + date.month *31 + date.day;
}
static unsigned long Time2Secs(FTIME time)
{
return time.hours * 3600l + time.minutes * 60 + time.twosecs * 2;
}
int TRFree(TRTree *tree)
{
TREntry *help;
if (tree)
{
if (tree->Entries)
{
while (tree->Entries)
{
help = tree->Entries;
tree->Entries = tree->Entries->next;
free(help);
}
}
else
{
free(tree);
return 0;
}
free(tree);
return 1;
}
return 0;
}
static TRTree *TRMalloc(void)
{
TRTree *work = (TRTree *)malloc(sizeof(TRTree));
if (work == NULL)
return NULL;
work->Entries = NULL;
work->EntryCount = 0;
work->LastPos = NULL;
work->Base = NULL;
work->BaseLen = 0;
return work;
}
int TRIsDir(TREntry *entry)
{ return entry->Attrib & FILE_DIRECTORY; }
static char *TRDate2Str(FDATE date)
{
static char buf[20];
sprintf(buf,"%d.%d.%d",date.day,date.month,date.year+1980);
return buf;
}
static TREntry *TRAddEntry(TRTree *tree,PFILEFINDBUF findbuf,const char *Root)
{
register TREntry *entry;
entry = malloc(sizeof(TREntry));
if (entry == NULL)
ERFatal("Not enough memory for tree");
entry->File = malloc(strlen(Root)+strlen(findbuf->achName)+1+1);
if (entry->File == NULL)
{
free(entry);
ERFatal("Not enough memory for tree");
}
strcpy(entry->File,(char *)Root);
strcat(entry->File,"\\");
strcat(entry->File,findbuf->achName);
entry->Attrib = findbuf->attrFile;
entry->Date = findbuf->fdateLastWrite;
entry->Time = findbuf->ftimeLastWrite;
entry->next = NULL;
if (TRIsDir(entry))
fprintf(stdout,"%s %s \r",entry->File,TRDate2Str(entry->Date));
entry->next = tree->Entries;
tree->Entries = entry;
tree->EntryCount++;
return entry;
}
int TRRecLoad(TRTree *tree,char *Root)
{
register int fresult;
HDIR DirHandle = HDIR_CREATE;
FILEFINDBUF findbuf;
USHORT Search;
if (Root[1] == ':')
if (_chdrive(toupper(Root[0])-'A'+1)!=0)
ERFatal("Can't change to drive %c:",toupper(Root[0]));
if ((strlen(Root)==2) && (Root[1]==':'))
chdir("\\");
else
if (chdir(Root)!=0)
ERFatal("Can't change directory to '%s'",Root);
Search = 1;
fresult = DosFindFirst("*",&DirHandle,
FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
&findbuf,sizeof(findbuf),&Search,0);
while (fresult==0)
{
if (*findbuf.achName != '.')
{
register TREntry *newentry;
newentry = TRAddEntry(tree,&findbuf,Root);
if (findbuf.attrFile & FILE_DIRECTORY)
{
TRRecLoad(tree,newentry->File);
}
}
fresult = DosFindNext(DirHandle,&findbuf,sizeof(findbuf),&Search);
}
DosFindClose(DirHandle);
return 1;
}
TRTree *TRLoadTree(const char *Directory)
{
TRTree *work;
LOItem("Scanning directorytree of '%s'",Directory);
if ((work = TRMalloc())==NULL)
{
ERFatal("Not enough memory for tree");
return NULL;
}
work->Base = Directory;
work->BaseLen = strlen(Directory);
if (TRRecLoad(work,(char *)Directory))
{
LOItem("Scanned %lu entries ",work->EntryCount);
return work;
}
free(work);
return NULL;
}
static TREntry *TRSearch(TRTree *tree,char *File,size_t Base2)
{
register TREntry *walk;
if (tree->LastPos)
walk = tree->LastPos;
else
walk = tree->Entries;
while (walk)
{
if (strcmp(walk->File+tree->BaseLen,File+Base2)==0)
{
tree->LastPos = walk->next;
return walk;
}
walk = walk->next;
}
tree->LastPos = NULL;
return NULL;
}
extern unsigned long Date2Days(FDATE date);
extern unsigned long Time2Secs(FTIME time);
int DateCompare(TREntry *Source,TREntry *Dest)
{
if ((Date2Days(Source->Date) == Date2Days(Dest->Date)) &&
(Time2Secs(Source->Time) == Time2Secs(Dest->Time)))
return 0;
if (Date2Days(Source->Date) == Date2Days(Dest->Date))
{ /* Gleicher Tag. Vergleiche Uhrzeit */
if (Time2Secs(Source->Time) > Time2Secs(Dest->Time))
return 1;
else
return 2;
}
/* Datum ist unterschiedlich, Datumsvergleich reicht */
if (Date2Days(Source->Date) > Date2Days(Dest->Date))
return 1;
else
return 2;
}
int TRForEach(TRTree *Tree,TRForEachFunc Function)
{
register TREntry *walk;
walk = Tree->Entries;
Tree->LastPos = NULL;
while (walk)
{
(*Function)(Tree,walk);
walk = walk->next;
}
return 1;
}
int TRCompare(TRTree *Source,TRTree *Dest,TRFuncEntry Functions[])
{
register TREntry *walk,*help;
/* Suche aller Dateien, die in Dest noch vorhanden sind, in Source
aber nicht mehr */
walk = Dest->Entries;
Source->LastPos = NULL;
while (walk)
{
if (TRSearch(Source,walk->File,Dest->BaseLen)==NULL)
(*(Functions[TRNEWDEST]))(Source,NULL,Dest,walk);
walk = walk->next;
}
walk = Source->Entries;
Dest->LastPos = NULL;
while (walk)
{
help = TRSearch(Dest,walk->File,Source->BaseLen);
if (help == NULL)
{ /* Im Zielverzeichnis ist die Datei nicht vorhanden */
(*(Functions[TRNEWSRC]))(Source,walk,Dest,NULL); /* Hack! Tree wird fuer Basis benoetigt */
}
else
{
switch (DateCompare(walk,help))
{
case 0: (*(Functions[TREQUAL]))(Source,walk,Dest,help); break;
case 1: (*(Functions[TRNEWER]))(Source,walk,Dest,help); break;
case 2: (*(Functions[TROLDER]))(Source,walk,Dest,help); break;
}
}
walk = walk->next;
}
return 1;
}