home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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
- }
-