home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / disk / val-2.3.lha / Val / Val.c < prev    next >
C/C++ Source or Header  |  1993-12-22  |  41KB  |  1,818 lines

  1. /*
  2.  *    Copyright (C) 1988 Andrew Kemmis
  3.  *
  4.  *    All Rights Reserved
  5.  *
  6.  *    Date:    Jan 1988
  7.  */
  8. #include <ak/stdak.h>
  9.  
  10. char    Program_name[]    = "Val";
  11. int    Version     = 2;
  12. int    MinorVer    = 3;
  13. char    Date[]        = "Dec 1993";
  14. char    CRDate[]    = "1988-93";
  15.  
  16. #include <ak/err.h>
  17. #include <ak/pool.h>
  18. #include <ak/dev.h>
  19. #include <ak/dos.h>
  20. #include <intuition/intuitionbase.h>
  21. #include "val.h"
  22.  
  23. #include "val.qi"
  24.  
  25. #define ULONGS(l)       ((ulong)(l)*(ulong)sizeof(ulong))
  26. #define ZAlloc(a)       PoolAlloc((a), sizeof(*(a)), &GenPoolKey)
  27. #define LAlloc(a,n,z)   {       if (!Seek)\
  28.                     PoolAlloc((a), ULONGS(n), &GenPoolKey);\
  29.                 else\
  30.                     (char *)(a) = AllocMem(ULONGS(n), 0L);\
  31.             }
  32.  
  33. #define ULONGMAX    4294967295
  34.  
  35. extern    char    *strchr();
  36. extern    char    *strrchr();
  37. extern    int    strlen();
  38. extern    int    strcmp();
  39. extern    int    sscanf();
  40.  
  41. extern    char    *AllocMem();
  42.  
  43. int    cli;
  44.  
  45. struct    IBASE    *IBASE = (struct IBASE *)NULL;
  46.  
  47. Static    int    FileSystem;
  48.  
  49. #define IS_OFS    0
  50. #define IS_FFS    1
  51.  
  52. Static    char    StrRoot[] = "Root";
  53. Static    char    StrBitMap[] = "BitMap";
  54. Static    char    StrEtc[] = "Dir,Fil,Lnk";
  55. Static    char    StrDir[] = "Dir";
  56. Static    char    StrFil[] = "Fil";
  57. Static    char    StrExt[] = "Ext";
  58. Static    char    StrDat[] = "Dat";
  59. Static    char    StrSoftLnk[] = "SoftLnk";
  60. Static    char    StrDirLnk[] = "DirLnk";
  61. Static    char    StrFilLnk[] = "FilLnk";
  62. Static    char    StrNextD[] = "NextDat";
  63. Static    char    StrChain[] = "HashChain";
  64. Static    char    StrNext[] = "Next";
  65. Static    char    StrPrev[] = "Prev";
  66. Static    char    StrHuh[] = "Unknown";
  67. Static    struct    AkDevStuff    Stuff = DEVSTUFFINIT;
  68. Static    uchar    *Buffer;
  69. Static    long    Dev = -1;
  70. Static    struct    Names    RootName =
  71.     {    (struct Names *)NULL,   (struct Names *)NULL,   ULONGMAX, };
  72. Static    struct    Links
  73. {    ushort    type;
  74.     ulong    block;
  75.     ulong    prev;
  76.     ulong    next;
  77.     struct    Links    *another;
  78. } *LinkHead, *LinkMaybe;
  79. Static    uchar    *FName;
  80. Static    int    Inhibited = 0;
  81.  
  82. Static    struct    PoolKey BufPoolKey;
  83. Static    struct    PoolKey GenPoolKey;
  84. Static    struct    PoolKey ZerPoolKey;
  85.  
  86. Static    ulong    ReadCount = 0;
  87. Static    struct    Info    *LastInfo;
  88. Static    ulong    LastBlk;
  89. Static    uchar    *MyBitMap;
  90.  
  91. Static    ulong    ReadSmall = 0;
  92. Static    ulong    ReadLarge = 0;
  93. Static    ulong    ReadLNum = 0;
  94. Static    ulong    HitSmall = 0;
  95. Static    ulong    HitLarge = 0;
  96. Static    ulong    MicSta;
  97. Static    ulong    MicFin;
  98. Static    ulong    MicCode;
  99. Static    ulong    MicRead;
  100.  
  101. #define BMAP_TST(n)      (MyBitMap[(n)>>3]&(1<<((n)&7)))
  102. #define BMAP_SET(n)      (MyBitMap[(n)>>3]|=(1<<((n)&7)))
  103.  
  104. Static Copy(d, s, l, siz)
  105. REG    char    *d;
  106. REG    char    *s;
  107. REG    ulong    l;
  108. REG    int    siz;
  109. {
  110.     REG    ulong  len = l * (ulong)siz;
  111.  
  112.     while (len--)
  113.         *(d++) = *(s++);
  114. }
  115.  
  116. Static Get(Rem, num)
  117. REG    struct    Info    *Rem;
  118. REG    ulong    num;
  119. {
  120.     if ((Rem - InfoList) >= MaxDepth)
  121.         MyError(ERR_TOODEEP, MaxDepth);
  122.  
  123.     getblok(num + Stuff.Info.Begin, Rem);
  124. }
  125.  
  126. Static LONG DevRead(num, buf, size)
  127. REG    ulong    num;
  128. REG    ulong    *buf;
  129. REG    LONG    size;
  130. {
  131.     REG    LONG    ret;
  132.     REG    int    retry = Retries + 1;
  133.  
  134.     while (retry-- && (ret = AkDevRead(num, buf, &Stuff, size)))
  135.         ;
  136.  
  137.     if (ret && FailReq)
  138.     {    if (!akrequester("Disk Read Error", "Continue", "Abort"))
  139.         {    puts("Aborted at users request on Read Error");
  140.             Cleanup();
  141.         }
  142.     }
  143.  
  144.     return(ret);
  145. }
  146.  
  147. Static    int    DoCache = !0;
  148.  
  149. #define CACHE_INVALID    -7
  150.  
  151. Static LONG CacheRead(num, buf)
  152. REG    ulong    num;
  153. REG    ulong    **buf;
  154. {
  155.     static    ulong    cache0 = CACHE_INVALID;
  156.     static    ulong    cache1 = CACHE_INVALID;
  157.     static    ulong    cache2 = CACHE_INVALID;
  158.     REG    LONG    ret = 0;
  159.  
  160.     *buf = (ulong *)Buffer;
  161.  
  162.     if (Cache == 1)
  163.         ret = DevRead(num, *buf, BLOCK_SIZE);
  164.     else
  165.     {    if (num == cache0 || num == (cache0 + 1) || (cache1 <= num && num <= cache2))
  166.         {    if (StatCache)
  167.                 MicSta = IBASE->Micros;
  168.  
  169.             if (num == (cache0+1))
  170.                 *buf = (ulong *)&Buffer[BLOCK_SIZE];
  171.             else
  172.             if (num != cache0)
  173.                 *buf = (ulong *)&Buffer[BLOCK_SIZE*(2 + num - cache1)];
  174.  
  175.             if (StatCache)
  176.                 MicFin = IBASE->Micros;
  177.  
  178.             if (StatCache)
  179.             {    if (num == cache0 || num == (cache0+1))
  180.                     HitSmall++;
  181.                 else
  182.                     HitLarge++;
  183.  
  184.                 if (MicSta > MicFin)
  185.                     MicFin += 1000000;
  186.                 MicCode += (MicFin - MicSta);
  187.             }
  188.             if (DebugCache)
  189.             {    if (num == cache0)
  190.                     printf("Hit at :0\n");
  191.                 else
  192.                 if (num == (cache0+1))
  193.                     printf("Hit at :1\n");
  194.                 else
  195.                     printf("Hit at %lu\n", 2 + num - cache1);
  196.             }
  197.         }
  198.         else
  199.         {    if (DebugCache)
  200.             {    if (DoCache && num <= (Stuff.Info.End - 2))
  201.                     printf("Do  Cache (miss %ld %ld)\n", num-cache0, num-cache1);
  202.                 else
  203.                     printf("Non Cache (miss %ld %ld)\n", num-cache0, num-cache1);
  204.             }
  205.  
  206.             if (StatCache)
  207.                 MicSta = IBASE->Micros;
  208.  
  209.             if (DoCache && num <= (Stuff.Info.End - 2))     /* Must read 3 Blocks! */
  210.             {    cache0 = num;
  211.                 cache1 = num + 2;
  212.                 cache2 = num + Cache - 1;
  213.                 if (cache2 > Stuff.Info.End)
  214.                     cache2 = Stuff.Info.End;
  215.                 ret = DevRead(num, *buf, BLOCK_SIZE*(1 + cache2 - cache0));
  216.                 if (ret)
  217.                     cache0 = cache1 = cache2 = CACHE_INVALID;
  218.             }
  219.             else
  220.             {    if (num != Stuff.Info.End)
  221.                     cache0 = num;
  222.                 else
  223.                 {    cache0 = num - 1;
  224.                     *buf = (ulong *)&Buffer[BLOCK_SIZE];
  225.                 }
  226.  
  227.                 ret = DevRead(num, (ulong *)Buffer, BLOCK_SIZE*2);
  228.                 if (ret)
  229.                     cache0 = CACHE_INVALID;
  230.             }
  231.  
  232.             if (StatCache)
  233.                 MicFin = IBASE->Micros;
  234.  
  235.             if (StatCache)
  236.             {    if (DoCache && num <= (Stuff.Info.End - 2))
  237.                 {    ReadLarge++;
  238.                     ReadLNum += (1 + cache2 - cache0);
  239.                 }
  240.                 else
  241.                     ReadSmall++;
  242.  
  243.                 if (MicSta > MicFin)
  244.                     MicFin += 1000000;
  245.                 MicRead += (MicFin - MicSta);
  246.             }
  247.         }
  248.     }
  249.     return(ret);
  250. }
  251.  
  252. Static char *StrType(type)
  253. REG    ushort    type;
  254. {
  255.     REG    char    *ans;
  256.  
  257.     switch(type)
  258.     {
  259.     case I_ROOT:
  260.         ans = StrRoot;
  261.         break;
  262.     case I_DIR:
  263.         ans = StrDir;
  264.         break;
  265.     case I_FIL:
  266.         ans = StrFil;
  267.         break;
  268.     case I_EXT:
  269.         ans = StrExt;
  270.         break;
  271.     case I_DAT:
  272.         ans = StrDat;
  273.         break;
  274.     case I_S_LNK:
  275.         ans = StrSoftLnk;
  276.         break;
  277.     case I_H_LNK_DIR:
  278.         ans = StrDirLnk;
  279.         break;
  280.     case I_H_LNK_FIL:
  281.         ans = StrFilLnk;
  282.         break;
  283. /*
  284.     case I_UNK:
  285.     case I_UNREADABLE:
  286. */
  287.     default:
  288.         ans = StrHuh;
  289.         break;
  290.     }
  291.     return(ans);
  292. }
  293.  
  294. Static    int    BaD = 0;
  295. Static    int    WaR = 0;
  296. Static    ulong    SeqNum;
  297. Static    ulong    PrevD = 0;
  298. Static    ulong    NextD = 0;
  299.  
  300. #define B_TYP        0
  301. #define B_KEY        1
  302. #define B_CHKSUM    2
  303. #define B_BMAP        3
  304. #define B_PAR        4
  305. #define B_COUNT     5
  306. #define B_FIRST     6
  307. #define B_BYTESIZE    7
  308. #define B_HED        8
  309. #define B_RANGE     9
  310. #define B_SEQ        10
  311. #define B_SHORT     11
  312. #define B_BMFLG     12
  313. #define B_HTSIZ     13
  314. #define B_BITMAP    14
  315. #define B_NEXTD     15
  316. #define B_BADNAME    16
  317. #define B_UNR        17
  318. #define B_BLOCKSIZE    18
  319. #define B_USED        19
  320. #define B_USEDBY    20
  321.  
  322. #define B_PREVLINK    22
  323. #define B_NEXTLINK    23
  324. #define B_OFSLINK    24
  325. #define B_NOPREVLINK    25
  326. #define B_PREVINV    26
  327. #define B_NOTPREV    27
  328. #define B_PREVDIF    28
  329. #define B_LINKTYPERR    29
  330. #define B_XNOTLINK    30
  331.  
  332. Static bad(Rem, num, err, typ, ex1, ex2, ex3)
  333. struct    Info    *Rem;
  334. REG    ulong    num;
  335. int    err;
  336. REG    char    *typ;
  337. REG    ulong    ex1;
  338. ulong    ex2;
  339. ulong    ex3;
  340. {
  341.     int    idx;
  342.     ulong    blk;
  343.     REG    struct    Info    *CurRem;
  344.     REG    struct    Names    *CurName;
  345.     ulong    *Buf = (ulong *)Buffer;
  346.     int    seeked = 0;
  347.  
  348.     switch(err)
  349.     {
  350.     case B_BMFLG:
  351.     case B_BITMAP:
  352.     case B_HTSIZ:
  353.     case B_BMAP:
  354.     case B_BLOCKSIZE:
  355.     case B_BYTESIZE:
  356.     case B_OFSLINK:
  357.         WaR++;
  358.         printf("War: B %lu %s ", num, typ);
  359.         break;
  360.     default:
  361.         BaD++;
  362.         printf("Err: B %lu %s ", num, typ);
  363.         break;
  364.     }
  365.  
  366.     if (Rem && DosNames && num != Stuff.Info.Root)
  367.     {    CurRem = LastInfo;
  368.         if (Seek)
  369.             idx = CurRem - InfoList;
  370.         else
  371.             for (idx=0; CurRem != &InfoList[Stuff.Info.Root]; idx++)
  372.                 CurRem = &InfoList[CurRem->Obj.dir->parent];
  373.                     /* *** parent in same pos */
  374.  
  375.         CurName = &RootName;
  376.         while (idx--)
  377.         {    if (CurName->next == (struct Names *)NULL)
  378.             {    ZAlloc(CurName->next);
  379.                 CurName->next->prev = CurName;
  380.                 CurName->next->next = (struct Names *)NULL;
  381.                 CurName->next->block = ULONGMAX;
  382.             }
  383.             CurName = CurName->next;
  384.         }
  385.         if (CurName->next)
  386.             CurName->next->block = ULONGMAX;
  387.  
  388.         CurRem = LastInfo;
  389.         blk = LastBlk;
  390.         while (CurName)
  391.         {    if (CurName->block != blk)
  392.             {    CurName->block = blk;
  393.                 if (!Seek && !seeked)
  394.                 {    AkMotorOn(&Stuff);
  395.                     seeked = !0;
  396.                 }
  397.                 if (CacheRead(blk + Stuff.Info.Begin, &Buf))
  398.                     FName = (uchar *)"\011***Bad***";
  399.                 else
  400.                     FName = (uchar *)(&Buf[POS_NAME]);
  401.                 if (*FName >= sizeof(RootName.name))
  402.                     *FName = sizeof(RootName.name) - 1;
  403.                 Copy(CurName->name, FName, (long)((*FName) + 1), sizeof(char));
  404.             }
  405.             if (Seek)
  406.                 blk = (CurRem--)->Obj.dir->parent;
  407.                     /* *** parent in same pos, bl