home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
mar94
/
disk
/
salv
/
find.lha
/
Find
/
Find.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-22
|
10KB
|
561 lines
/*
* Copyright (C) 1989 Andrew Kemmis
*
* All Rights Reserved
*
* Date: Mar 1989
*/
#include <ak/stdak.h>
char Program_name[] = "Find";
int Version = 2;
int MinorVer = 3;
char Date[] = "Dec 1993";
char CRDate[] = "1989-93";
#include <ak/err.h>
#include <ak/pool.h>
#include <ak/dev.h>
#include <ak/filesystem.h>
#include <intuition/intuition.h>
#define ULONGMAX 4294967295
#define STR_LEN 80
#include "find.qi"
extern int strlen();
extern int strcmp();
extern int sscanf();
int cli;
struct IBASE *IBASE = (struct IBASE *)NULL;
Static struct AkDevStuff Stuff = DEVSTUFFINIT;
Static uchar *Buffer;
Static uchar *NameBuffer;
Static long Dev = -1;
Static struct PoolKey BufPoolKey;
Static ulong ReadCount = 0;
Static uchar *FName;
Static char AString2[STR_LEN+1] = "";
Static int Match = 0;
Static int NameLen;
Static int DoAnyDat;
Static int DoAnyRangeDat;
Static int DoULong;
Static int AStringLen;
Static Copy(t, s, l)
REG char *t;
REG char *s;
REG int l;
{
t += l;
s += l;
while (l--)
*(--t) = *(--s);
}
#define OLD_NAM_LEN 2048
Static LONG CacheRead();
Static char *GetName(num, buf, type)
REG ulong num;
REG ulong *buf;
char **type;
{
static ulong old_num = ULONGMAX;
static char old_nam[OLD_NAM_LEN+1] = " ";
ulong *Buf;
REG char *ptr = old_nam + 1;
REG ulong new_num = num;
REG LONG ret;
REG int done;
uchar *FName;
REG int len = 0;
int fnlen;
ulong typ;
ulong sec_typ;
Buf = buf;
typ = Buf[POS_TYP];
sec_typ = Buf[POS_SEC];
switch(typ)
{
case TYP_CONTROL:
switch(sec_typ)
{
case SEC_ROOT:
*type = "Root";
break;
case SEC_DIR:
*type = "Directory";
break;
case SEC_FIL:
*type = "File";
break;
case SEC_S_LNK:
*type = "Soft Link";
break;
case SEC_H_LNK_DIR:
*type = "Hard Dir Link";
break;
case SEC_H_LNK_FIL:
*type = "Hard File Link";
break;
default:
*type = "Control???";
break;
}
break;
case TYP_EXT:
new_num = Buf[POS_PAR];
*type = "Extension";
break;
case TYP_DAT:
new_num = Buf[POS_KEY];
*type = "Data";
break;
default:
*type = "";
return("(Unknown block type)");
}
if (new_num == old_num)
return(old_nam);
done = 0;
while (!done)
{ if (new_num < Stuff.Info.res || new_num > (Stuff.Info.End - Stuff.Info.Begin))
{ FName = (uchar *)"\022***InvalidBlock***";
done = !0;
}
else
{ if (new_num != num)
{ Buf = (ulong *)NameBuffer;
ret = AkDevRead(new_num + Stuff.Info.Begin, Buf, &Stuff, BLOCK_SIZE);
}
else
{ Buf = buf;
ret = 0;
}
if (ret)
{ FName = (uchar *)"\016***BadBlock***";
done = !0;
}
else
{ FName = (uchar *)(&Buf[POS_NAME]);
if (*FName == 0 || *FName > BLOCKFILENAMELENGTH)
{ FName = (uchar *)"\021***InvalidName***";
done = !0;
}
else
{ FName[*FName+1] = '\0';
if (*FName != strlen(FName+1))
FName = (uchar *)"\022*NameContainsNull*";
}
}
}
fnlen = *FName;
if ((len + fnlen + 1) > OLD_NAM_LEN)
{ Copy(ptr+3+1, ptr, len);
Copy(ptr, "...", 3);
ptr[3] = '//';
done = !0;
}
else
{ if (len)
Copy(ptr+fnlen+1, ptr, len);
Copy(ptr, FName+1, fnlen);
if (new_num == Stuff.Info.Root)
{ ptr[fnlen] = ':';
if (len == 0)
ptr[fnlen + 1] = '\0';
done = !0;
}
else
{ if (len == 0)
ptr[fnlen] = '\0';
else
ptr[fnlen] = '/';
new_num = Buf[POS_PAR];
len += (fnlen + 1);
}
}
}
return(old_nam);
}
Static char one_buf[20+1];
Static GotOne(num, str, Buf)
REG ulong num;
REG char *str;
REG ulong *Buf;
{
REG char *FName;
char *Type;
num -= Stuff.Info.Begin;
if (CheckChecksum)
if (DosChecksum(Buf))
return;
if (FileNames)
FName = GetName(num, Buf, &Type);
else
FName = "";
printf("Match: %20.20s Block Offset: 0x%08lx, (%lu)%s%s%s\n",
str, num, num, *Type ? " Type: " : "", Type, FName);
Match++;
}
Static LONG CacheRead(num, buf)
REG ulong num;
REG ulong **buf;
{
static ulong cache0 = -1;
static ulong cache1 = -1;
REG LONG ret = 0;
*buf = (ulong *)Buffer;
if (Cache == 1)
ret = AkDevRead(num, *buf, &Stuff, BLOCK_SIZE);
else
{ if (cache0 <= num && num <= cache1)
*buf = (ulong *)&Buffer[BLOCK_SIZE*(num - cache0)];
else
{ cache0 = num;
cache1 = num + Cache - 1;
if (cache1 > Stuff.Info.End)
cache1 = Stuff.Info.End;
ret = AkDevRead(num, *buf, &Stuff, BLOCK_SIZE*(1 + cache1 - cache0));
if (ret)
cache0 = cache1 = -1;
}
}
return(ret);
}
Static Try(num)
REG ulong num;
{
REG ulong *Buf;
REG ulong i;
REG ulong *l;
REG char *ch;
ulong *buf;
REG int j;
REG int done;
if (ShowReads && (++ReadCount % Count) == 0)
{ akdeco(ReadCount, 'l', NULL, NULL, NULL, ' ', ' ');
akhexo(num, 'l', NULL, NULL, NULL, '\r', '0');
}
if (Tracks && (ReadCount++ % Stuff.Info.Cyl) == 0)
akdeco(ReadCount / Stuff.Info.Cyl, 'l', NULL, NULL, NULL, '\r', ' ');
CacheRead(num, &buf);
Buf = buf;
if (*Name)
{ FName = (uchar *)(&Buf[POS_NAME]);
if (ICase)
{ if (AkStrNCmpCase(FName+1, Name, NameLen) == 0)
GotOne(num, "Name", Buf);
}
else
{ if (AkStrNCmp(FName+1, Name, NameLen) == 0)
GotOne(num, "Name", Buf);
}
}
if (Parent != ULONGMAX)
{ if (Parent == Buf[POS_PAR])
GotOne(num, "Parent", Buf);
}
if (Key != ULONGMAX)
{ if (Key == Buf[POS_KEY])
GotOne(num, "Key", Buf);
}
if (HashChain != ULONGMAX)
{ if (HashChain == Buf[POS_HASH_CH])
GotOne(num, "HashChain", Buf);
}
if (Extension != ULONGMAX)
{ if (Extension == Buf[POS_EXT])
GotOne(num, "Extension", Buf);
}
if (SequenceNum != ULONGMAX)
{ if (SequenceNum == Buf[POS_D_SEQ_NUM])
GotOne(num, "SequenceNum", Buf);
}
if (ByteSize != ULONGMAX)
{ if (ByteSize == Buf[POS_F_BYTSIZ])
GotOne(num, "ByteSize", Buf);
}
if (BlockCount != ULONGMAX)
{ if (BlockCount == Buf[POS_NUM_BLK])
GotOne(num, "BlockCount", Buf);
}
if (FirstDataBlk != ULONGMAX)
{ if (FirstDataBlk == Buf[POS_FST_DAT])
GotOne(num, "FirstDataBlk(A)", Buf);
if (FirstDataBlk == Buf[POS_FST_BLK])
GotOne(num, "FirstDataBlk(B)", Buf);
}
if (DoAnyDat || DoAnyRangeDat)
if (!ValidOnly || Buf[POS_TYP] == TYP_EXT || Buf[POS_TYP] == TYP_CONTROL)
{ done = 0;
l = &(Buf[POS_FST_BLK]);
for (i = POS_FST_BLK; !done && i <= POS_LST_BLK; l++, i++)
{ if (DoAnyRangeDat)
for (j = 0; !done && j < DoAnyRangeDat; j+=2)
if (AnyRangeData[j] <= *l && *l <= AnyRangeData[j+1])
{ sprintf(one_buf, "AnyRangeD 0x%08lx", *l);
GotOne(num, one_buf, Buf);
done = Once;
}
if (!done && DoAnyDat)
for (j = 0; !done && j < DoAnyDat; j++)
if (AnyDataBlk[j] == *l)
{ sprintf(one_buf, "AnyD 0x%08lx", *l);
GotOne(num, one_buf, Buf);
done = Once;
}
}
}
if (NextDataBlk != ULONGMAX)
{ if (NextDataBlk == Buf[POS_D_NXT_DAT])
GotOne(num, "NextDataBlk", Buf);
}
if (DoULong)
if (!ValidOnly || Buf[POS_TYP] == TYP_EXT || Buf[POS_TYP] == TYP_CONTROL)
{ done = 0;
for (j = 0; !done && j < DoULong; j++)
{ l = Buf;
for (i = 0; !done && i < LBlockSize; l++, i++)
if (ULong[j] == *l)
{ sprintf(one_buf, "ULong 0x%08lx", *l);
GotOne(num, one_buf, Buf);
done = Once;
}
}
}
if (*AString2)
{ ch = (char *)Buf;
for (i = 1 + BLOCK_SIZE - AStringLen; i > 0; i--, ch++) /* i is unsigned! */
if (ICase)
{ if ((toupper(*ch) == toupper(*AString2))
&& (AkStrNCmpCase(ch, AString2, AStringLen) == 0))
{ GotOne(num, AString, Buf);
break;
}
}
else
{ if (*ch == *AString2 && AkStrNCmp(ch, AString2, AStringLen) == 0)
{ GotOne(num, AString, Buf);
break;
}
}
}
}
Static CnvStr()
{
REG char *ptr1;
REG char *ptr2;
uint n;
ptr1 = AString;
ptr2 = AString2;
while (*ptr1)
{ if (*ptr1 == '\\')
switch(*(++ptr1))
{
case '\\':
*(ptr2++) = *(ptr1++);
break;
case 'b':
*(ptr2++) = '\b';
ptr1++;
break;
case 'f':
*(ptr2++) = '\f';
ptr1++;
break;
case 'n':
*(ptr2++) = '\n';
ptr1++;
break;
case 'r':
*(ptr2++) = '\r';
ptr1++;
break;
case 't':
*(ptr2++) = '\t';
ptr1++;
break;
case 'x':
case '0':
case '1':
case '2':
n = 0;
if (*ptr1 == 'x')
sscanf(++ptr1, "%2x", &n);
else
sscanf(ptr1++, "%3o", &n);
*(ptr2++) = n;
if (*ptr1)
ptr1++;
if (*ptr1)
ptr1++;
break;
case '\0':
*(ptr2++) = '\\';
break;
default:
*(ptr2++) = '\\';
*(ptr2++) = *(ptr1++);
break;
}
else
*(ptr2++) = *(ptr1++);
}
*ptr2 = '\0';
}
Static Search()
{
REG ulong l;
if (*AString)
{ CnvStr();
AStringLen = strlen(AString2);
}
if (*Name)
NameLen = strlen(Name);
DoAnyDat = QL_IDX(Q_ANYDATABLK);
DoAnyRangeDat = (QL_IDX(Q_ANYRANGEDATA) & 0xffe); /* Even */
DoULong = QL_IDX(Q_ULONG);
FromBlock += Stuff.Info.Begin;
ToBlock += Stuff.Info.Begin;
if (FromBlock > Stuff.Info.End)
FromBlock = Stuff.Info.End;
if (ToBlock > Stuff.Info.End)
ToBlock = Stuff.Info.End;
ReadCount = FromBlock - Stuff.Info.Begin;
AkMotorOn(&Stuff);
for (l = FromBlock; l <= ToBlock; l++)
Try(l);
AkMotorOff(&Stuff);
printf("Total %d match%s found on %s from %ld to %ld\n",
Match,
(Match == 1) ? "" : "es",
Device,
FromBlock - Stuff.Info.Begin,
ToBlock - Stuff.Info.Begin);
}
Static Find()
{
if (Dev = AkDevOpen(Device, &Stuff))
MyError(Dev, Device);
MPAlloc(Buffer, (long)(BLOCK_SIZE)*Cache, &BufPoolKey);
if (FileNames)
MPAlloc(NameBuffer, (long)(BLOCK_SIZE), &BufPoolKey);
AkDevMsg(&(Stuff.Info));
Search();
}
main(argc, argv)
int argc;
char *argv[];
{
cli = argc;
DO_QUAL();
if (!Quiet && cli)
STARTUP_MSG;
OPEN_LIB(IBASE, "intuition.library", INTUITION_REV);
PoolInit(&BufPoolKey, 0L, MEMF_CHIP);
Find();
Cleanup();
}
MyError(num, why)
REG long num;
REG char *why;
{
ERROR_INIT
if (!Dev)
AkDevClose(&Stuff);
ERROR_TEST
CASE_ERR_AKDEVALL
CASE_ERR_NOVAL
CASE_ERR_NOMEM
CASE_ERR_NOLIB
CASE_ERR_BADFIL
ERROR_END(FACILITY_FIND)
PoolFree(&BufPoolKey);
if (IBASE)
CloseLibrary(IBASE);
CLEANUP_QUAL();
ERROR_EXIT
}