home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 9
/
FreshFishVol9-CD2.bin
/
bbs
/
disk
/
val-2.3.lha
/
Val
/
Val.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-22
|
41KB
|
1,818 lines
/*
* Copyright (C) 1988 Andrew Kemmis
*
* All Rights Reserved
*
* Date: Jan 1988
*/
#include <ak/stdak.h>
char Program_name[] = "Val";
int Version = 2;
int MinorVer = 3;
char Date[] = "Dec 1993";
char CRDate[] = "1988-93";
#include <ak/err.h>
#include <ak/pool.h>
#include <ak/dev.h>
#include <ak/dos.h>
#include <intuition/intuitionbase.h>
#include "val.h"
#include "val.qi"
#define ULONGS(l) ((ulong)(l)*(ulong)sizeof(ulong))
#define ZAlloc(a) PoolAlloc((a), sizeof(*(a)), &GenPoolKey)
#define LAlloc(a,n,z) { if (!Seek)\
PoolAlloc((a), ULONGS(n), &GenPoolKey);\
else\
(char *)(a) = AllocMem(ULONGS(n), 0L);\
}
#define ULONGMAX 4294967295
extern char *strchr();
extern char *strrchr();
extern int strlen();
extern int strcmp();
extern int sscanf();
extern char *AllocMem();
int cli;
struct IBASE *IBASE = (struct IBASE *)NULL;
Static int FileSystem;
#define IS_OFS 0
#define IS_FFS 1
Static char StrRoot[] = "Root";
Static char StrBitMap[] = "BitMap";
Static char StrEtc[] = "Dir,Fil,Lnk";
Static char StrDir[] = "Dir";
Static char StrFil[] = "Fil";
Static char StrExt[] = "Ext";
Static char StrDat[] = "Dat";
Static char StrSoftLnk[] = "SoftLnk";
Static char StrDirLnk[] = "DirLnk";
Static char StrFilLnk[] = "FilLnk";
Static char StrNextD[] = "NextDat";
Static char StrChain[] = "HashChain";
Static char StrNext[] = "Next";
Static char StrPrev[] = "Prev";
Static char StrHuh[] = "Unknown";
Static struct AkDevStuff Stuff = DEVSTUFFINIT;
Static uchar *Buffer;
Static long Dev = -1;
Static struct Names RootName =
{ (struct Names *)NULL, (struct Names *)NULL, ULONGMAX, };
Static struct Links
{ ushort type;
ulong block;
ulong prev;
ulong next;
struct Links *another;
} *LinkHead, *LinkMaybe;
Static uchar *FName;
Static int Inhibited = 0;
Static struct PoolKey BufPoolKey;
Static struct PoolKey GenPoolKey;
Static struct PoolKey ZerPoolKey;
Static ulong ReadCount = 0;
Static struct Info *LastInfo;
Static ulong LastBlk;
Static uchar *MyBitMap;
Static ulong ReadSmall = 0;
Static ulong ReadLarge = 0;
Static ulong ReadLNum = 0;
Static ulong HitSmall = 0;
Static ulong HitLarge = 0;
Static ulong MicSta;
Static ulong MicFin;
Static ulong MicCode;
Static ulong MicRead;
#define BMAP_TST(n) (MyBitMap[(n)>>3]&(1<<((n)&7)))
#define BMAP_SET(n) (MyBitMap[(n)>>3]|=(1<<((n)&7)))
Static Copy(d, s, l, siz)
REG char *d;
REG char *s;
REG ulong l;
REG int siz;
{
REG ulong len = l * (ulong)siz;
while (len--)
*(d++) = *(s++);
}
Static Get(Rem, num)
REG struct Info *Rem;
REG ulong num;
{
if ((Rem - InfoList) >= MaxDepth)
MyError(ERR_TOODEEP, MaxDepth);
getblok(num + Stuff.Info.Begin, Rem);
}
Static LONG DevRead(num, buf, size)
REG ulong num;
REG ulong *buf;
REG LONG size;
{
REG LONG ret;
REG int retry = Retries + 1;
while (retry-- && (ret = AkDevRead(num, buf, &Stuff, size)))
;
if (ret && FailReq)
{ if (!akrequester("Disk Read Error", "Continue", "Abort"))
{ puts("Aborted at users request on Read Error");
Cleanup();
}
}
return(ret);
}
Static int DoCache = !0;
#define CACHE_INVALID -7
Static LONG CacheRead(num, buf)
REG ulong num;
REG ulong **buf;
{
static ulong cache0 = CACHE_INVALID;
static ulong cache1 = CACHE_INVALID;
static ulong cache2 = CACHE_INVALID;
REG LONG ret = 0;
*buf = (ulong *)Buffer;
if (Cache == 1)
ret = DevRead(num, *buf, BLOCK_SIZE);
else
{ if (num == cache0 || num == (cache0 + 1) || (cache1 <= num && num <= cache2))
{ if (StatCache)
MicSta = IBASE->Micros;
if (num == (cache0+1))
*buf = (ulong *)&Buffer[BLOCK_SIZE];
else
if (num != cache0)
*buf = (ulong *)&Buffer[BLOCK_SIZE*(2 + num - cache1)];
if (StatCache)
MicFin = IBASE->Micros;
if (StatCache)
{ if (num == cache0 || num == (cache0+1))
HitSmall++;
else
HitLarge++;
if (MicSta > MicFin)
MicFin += 1000000;
MicCode += (MicFin - MicSta);
}
if (DebugCache)
{ if (num == cache0)
printf("Hit at :0\n");
else
if (num == (cache0+1))
printf("Hit at :1\n");
else
printf("Hit at %lu\n", 2 + num - cache1);
}
}
else
{ if (DebugCache)
{ if (DoCache && num <= (Stuff.Info.End - 2))
printf("Do Cache (miss %ld %ld)\n", num-cache0, num-cache1);
else
printf("Non Cache (miss %ld %ld)\n", num-cache0, num-cache1);
}
if (StatCache)
MicSta = IBASE->Micros;
if (DoCache && num <= (Stuff.Info.End - 2)) /* Must read 3 Blocks! */
{ cache0 = num;
cache1 = num + 2;
cache2 = num + Cache - 1;
if (cache2 > Stuff.Info.End)
cache2 = Stuff.Info.End;
ret = DevRead(num, *buf, BLOCK_SIZE*(1 + cache2 - cache0));
if (ret)
cache0 = cache1 = cache2 = CACHE_INVALID;
}
else
{ if (num != Stuff.Info.End)
cache0 = num;
else
{ cache0 = num - 1;
*buf = (ulong *)&Buffer[BLOCK_SIZE];
}
ret = DevRead(num, (ulong *)Buffer, BLOCK_SIZE*2);
if (ret)
cache0 = CACHE_INVALID;
}
if (StatCache)
MicFin = IBASE->Micros;
if (StatCache)
{ if (DoCache && num <= (Stuff.Info.End - 2))
{ ReadLarge++;
ReadLNum += (1 + cache2 - cache0);
}
else
ReadSmall++;
if (MicSta > MicFin)
MicFin += 1000000;
MicRead += (MicFin - MicSta);
}
}
}
return(ret);
}
Static char *StrType(type)
REG ushort type;
{
REG char *ans;
switch(type)
{
case I_ROOT:
ans = StrRoot;
break;
case I_DIR:
ans = StrDir;
break;
case I_FIL:
ans = StrFil;
break;
case I_EXT:
ans = StrExt;
break;
case I_DAT:
ans = StrDat;
break;
case I_S_LNK:
ans = StrSoftLnk;
break;
case I_H_LNK_DIR:
ans = StrDirLnk;
break;
case I_H_LNK_FIL:
ans = StrFilLnk;
break;
/*
case I_UNK:
case I_UNREADABLE:
*/
default:
ans = StrHuh;
break;
}
return(ans);
}
Static int BaD = 0;
Static int WaR = 0;
Static ulong SeqNum;
Static ulong PrevD = 0;
Static ulong NextD = 0;
#define B_TYP 0
#define B_KEY 1
#define B_CHKSUM 2
#define B_BMAP 3
#define B_PAR 4
#define B_COUNT 5
#define B_FIRST 6
#define B_BYTESIZE 7
#define B_HED 8
#define B_RANGE 9
#define B_SEQ 10
#define B_SHORT 11
#define B_BMFLG 12
#define B_HTSIZ 13
#define B_BITMAP 14
#define B_NEXTD 15
#define B_BADNAME 16
#define B_UNR 17
#define B_BLOCKSIZE 18
#define B_USED 19
#define B_USEDBY 20
#define B_PREVLINK 22
#define B_NEXTLINK 23
#define B_OFSLINK 24
#define B_NOPREVLINK 25
#define B_PREVINV 26
#define B_NOTPREV 27
#define B_PREVDIF 28
#define B_LINKTYPERR 29
#define B_XNOTLINK 30
Static bad(Rem, num, err, typ, ex1, ex2, ex3)
struct Info *Rem;
REG ulong num;
int err;
REG char *typ;
REG ulong ex1;
ulong ex2;
ulong ex3;
{
int idx;
ulong blk;
REG struct Info *CurRem;
REG struct Names *CurName;
ulong *Buf = (ulong *)Buffer;
int seeked = 0;
switch(err)
{
case B_BMFLG:
case B_BITMAP:
case B_HTSIZ:
case B_BMAP:
case B_BLOCKSIZE:
case B_BYTESIZE:
case B_OFSLINK:
WaR++;
printf("War: B %lu %s ", num, typ);
break;
default:
BaD++;
printf("Err: B %lu %s ", num, typ);
break;
}
if (Rem && DosNames && num != Stuff.Info.Root)
{ CurRem = LastInfo;
if (Seek)
idx = CurRem - InfoList;
else
for (idx=0; CurRem != &InfoList[Stuff.Info.Root]; idx++)
CurRem = &InfoList[CurRem->Obj.dir->parent];
/* *** parent in same pos */
CurName = &RootName;
while (idx--)
{ if (CurName->next == (struct Names *)NULL)
{ ZAlloc(CurName->next);
CurName->next->prev = CurName;
CurName->next->next = (struct Names *)NULL;
CurName->next->block = ULONGMAX;
}
CurName = CurName->next;
}
if (CurName->next)
CurName->next->block = ULONGMAX;
CurRem = LastInfo;
blk = LastBlk;
while (CurName)
{ if (CurName->block != blk)
{ CurName->block = blk;
if (!Seek && !seeked)
{ AkMotorOn(&Stuff);
seeked = !0;
}
if (CacheRead(blk + Stuff.Info.Begin, &Buf))
FName = (uchar *)"\011***Bad***";
else
FName = (uchar *)(&Buf[POS_NAME]);
if (*FName >= sizeof(RootName.name))
*FName = sizeof(RootName.name) - 1;
Copy(CurName->name, FName, (long)((*FName) + 1), sizeof(char));
}
if (Seek)
blk = (CurRem--)->Obj.dir->parent;
/* *** parent in same pos, bl