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 >
C/C++ Source or Header  |  1993-12-22  |  10KB  |  561 lines

  1. /*
  2.  *    Copyright (C) 1989 Andrew Kemmis
  3.  *
  4.  *    All Rights Reserved
  5.  *
  6.  *    Date:    Mar 1989
  7.  */
  8. #include <ak/stdak.h>
  9.  
  10. char    Program_name[]    = "Find";
  11. int    Version     = 2;
  12. int    MinorVer    = 3;
  13. char    Date[]        = "Dec 1993";
  14. char    CRDate[]    = "1989-93";
  15.  
  16. #include <ak/err.h>
  17. #include <ak/pool.h>
  18. #include <ak/dev.h>
  19. #include <ak/filesystem.h>
  20. #include <intuition/intuition.h>
  21.  
  22. #define ULONGMAX    4294967295
  23. #define STR_LEN 80
  24.  
  25. #include "find.qi"
  26.  
  27. extern    int    strlen();
  28. extern    int    strcmp();
  29. extern    int    sscanf();
  30.  
  31. int    cli;
  32.  
  33. struct    IBASE    *IBASE = (struct IBASE *)NULL;
  34.  
  35. Static    struct    AkDevStuff    Stuff = DEVSTUFFINIT;
  36. Static    uchar    *Buffer;
  37. Static    uchar    *NameBuffer;
  38. Static    long    Dev = -1;
  39.  
  40. Static    struct    PoolKey BufPoolKey;
  41.  
  42. Static    ulong    ReadCount = 0;
  43. Static    uchar    *FName;
  44. Static    char    AString2[STR_LEN+1] = "";
  45.  
  46. Static    int    Match = 0;
  47. Static    int    NameLen;
  48. Static    int    DoAnyDat;
  49. Static    int    DoAnyRangeDat;
  50. Static    int    DoULong;
  51. Static    int    AStringLen;
  52.  
  53. Static Copy(t, s, l)
  54. REG    char    *t;
  55. REG    char    *s;
  56. REG    int    l;
  57. {
  58.     t += l;
  59.     s += l;
  60.     while (l--)
  61.         *(--t) = *(--s);
  62. }
  63.  
  64. #define OLD_NAM_LEN    2048
  65.  
  66. Static LONG CacheRead();
  67.  
  68. Static char *GetName(num, buf, type)
  69. REG    ulong    num;
  70. REG    ulong    *buf;
  71. char    **type;
  72. {
  73.     static    ulong    old_num = ULONGMAX;
  74.     static    char    old_nam[OLD_NAM_LEN+1] = " ";
  75.     ulong    *Buf;
  76.     REG    char    *ptr = old_nam + 1;
  77.     REG    ulong    new_num = num;
  78.     REG    LONG    ret;
  79.     REG    int    done;
  80.     uchar    *FName;
  81.     REG    int    len = 0;
  82.     int    fnlen;
  83.     ulong    typ;
  84.     ulong    sec_typ;
  85.  
  86.     Buf = buf;
  87.  
  88.     typ = Buf[POS_TYP];
  89.     sec_typ = Buf[POS_SEC];
  90.     switch(typ)
  91.     {
  92.     case TYP_CONTROL:
  93.         switch(sec_typ)
  94.         {
  95.         case SEC_ROOT:
  96.             *type = "Root";
  97.             break;
  98.         case SEC_DIR:
  99.             *type = "Directory";
  100.             break;
  101.         case SEC_FIL:
  102.             *type = "File";
  103.             break;
  104.         case SEC_S_LNK:
  105.             *type = "Soft Link";
  106.             break;
  107.         case SEC_H_LNK_DIR:
  108.             *type = "Hard Dir Link";
  109.             break;
  110.         case SEC_H_LNK_FIL:
  111.             *type = "Hard File Link";
  112.             break;
  113.         default:
  114.             *type = "Control???";
  115.             break;
  116.         }
  117.         break;
  118.     case TYP_EXT:
  119.         new_num = Buf[POS_PAR];
  120.         *type = "Extension";
  121.         break;
  122.     case TYP_DAT:
  123.         new_num = Buf[POS_KEY];
  124.         *type = "Data";
  125.         break;
  126.     default:
  127.         *type = "";
  128.         return("(Unknown block type)");
  129.     }
  130.  
  131.     if (new_num == old_num)
  132.         return(old_nam);
  133.  
  134.     done = 0;
  135.     while (!done)
  136.     {    if (new_num < Stuff.Info.res || new_num > (Stuff.Info.End - Stuff.Info.Begin))
  137.         {    FName = (uchar *)"\022***InvalidBlock***";
  138.             done = !0;
  139.         }
  140.         else
  141.         {    if (new_num != num)
  142.             {    Buf = (ulong *)NameBuffer;
  143.                 ret = AkDevRead(new_num + Stuff.Info.Begin, Buf, &Stuff, BLOCK_SIZE);
  144.             }
  145.             else
  146.             {    Buf = buf;
  147.                 ret = 0;
  148.             }
  149.  
  150.             if (ret)
  151.             {    FName = (uchar *)"\016***BadBlock***";
  152.                 done = !0;
  153.             }
  154.             else
  155.             {    FName = (uchar *)(&Buf[POS_NAME]);
  156.  
  157.                 if (*FName == 0 || *FName > BLOCKFILENAMELENGTH)
  158.                 {    FName = (uchar *)"\021***InvalidName***";
  159.                     done = !0;
  160.                 }
  161.                 else
  162.                 {    FName[*FName+1] = '\0';
  163.                     if (*FName != strlen(FName+1))
  164.                         FName = (uchar *)"\022*NameContainsNull*";
  165.                 }
  166.             }
  167.         }
  168.  
  169.         fnlen = *FName;
  170.  
  171.         if ((len + fnlen + 1) > OLD_NAM_LEN)
  172.         {    Copy(ptr+3+1, ptr, len);
  173.             Copy(ptr, "...", 3);
  174.             ptr[3] = '//';
  175.             done = !0;
  176.         }
  177.         else
  178.         {    if (len)
  179.                 Copy(ptr+fnlen+1, ptr, len);
  180.             Copy(ptr, FName+1, fnlen);
  181.  
  182.             if (new_num == Stuff.Info.Root)
  183.             {    ptr[fnlen] = ':';
  184.                 if (len == 0)
  185.                     ptr[fnlen + 1] = '\0';
  186.                 done = !0;
  187.             }
  188.             else
  189.             {    if (len == 0)
  190.                     ptr[fnlen] = '\0';
  191.                 else
  192.                     ptr[fnlen] = '/';
  193.                 new_num = Buf[POS_PAR];
  194.  
  195.                 len += (fnlen + 1);
  196.             }
  197.         }
  198.     }
  199.     return(old_nam);
  200. }
  201.  
  202. Static    char    one_buf[20+1];
  203.  
  204. Static GotOne(num, str, Buf)
  205. REG    ulong    num;
  206. REG    char    *str;
  207. REG    ulong    *Buf;
  208. {
  209.     REG    char    *FName;
  210.     char    *Type;
  211.  
  212.     num -= Stuff.Info.Begin;
  213.  
  214.     if (CheckChecksum)
  215.         if (DosChecksum(Buf))
  216.             return;
  217.  
  218.     if (FileNames)
  219.         FName = GetName(num, Buf, &Type);
  220.     else
  221.         FName = "";
  222.  
  223.     printf("Match: %20.20s Block Offset: 0x%08lx, (%lu)%s%s%s\n",
  224.         str, num, num, *Type ? " Type: " : "", Type, FName);
  225.     Match++;
  226. }
  227.  
  228. Static LONG CacheRead(num, buf)
  229. REG    ulong    num;
  230. REG    ulong    **buf;
  231. {
  232.     static    ulong    cache0 = -1;
  233.     static    ulong    cache1 = -1;
  234.     REG    LONG    ret = 0;
  235.  
  236.     *buf = (ulong *)Buffer;
  237.  
  238.     if (Cache == 1)
  239.         ret = AkDevRead(num, *buf, &Stuff, BLOCK_SIZE);
  240.     else
  241.     {    if (cache0 <= num && num <= cache1)
  242.             *buf = (ulong *)&Buffer[BLOCK_SIZE*(num - cache0)];
  243.         else
  244.         {    cache0 = num;
  245.             cache1 = num + Cache - 1;
  246.             if (cache1 > Stuff.Info.End)
  247.                 cache1 = Stuff.Info.End;
  248.             ret = AkDevRead(num, *buf, &Stuff, BLOCK_SIZE*(1 + cache1 - cache0));
  249.             if (ret)
  250.                 cache0 = cache1 = -1;
  251.         }
  252.     }
  253.     return(ret);
  254. }
  255.  
  256. Static Try(num)
  257. REG    ulong    num;
  258. {
  259.     REG    ulong    *Buf;
  260.     REG    ulong    i;
  261.     REG    ulong    *l;
  262.     REG    char    *ch;
  263.     ulong    *buf;
  264.     REG    int    j;
  265.     REG    int    done;
  266.  
  267.     if (ShowReads && (++ReadCount % Count) == 0)
  268.     {    akdeco(ReadCount, 'l', NULL, NULL, NULL, ' ', ' ');
  269.         akhexo(num, 'l', NULL, NULL, NULL, '\r', '0');
  270.     }
  271.     if (Tracks && (ReadCount++ % Stuff.Info.Cyl) == 0)
  272.         akdeco(ReadCount / Stuff.Info.Cyl, 'l', NULL, NULL, NULL, '\r', ' ');
  273.  
  274.     CacheRead(num, &buf);
  275.     Buf = buf;
  276.  
  277.     if (*Name)
  278.     {    FName = (uchar *)(&Buf[POS_NAME]);
  279.         if (ICase)
  280.         {    if (AkStrNCmpCase(FName+1, Name, NameLen) == 0)
  281.                 GotOne(num, "Name", Buf);
  282.         }
  283.         else
  284.         {    if (AkStrNCmp(FName+1, Name, NameLen) == 0)
  285.                 GotOne(num, "Name", Buf);
  286.         }
  287.     }
  288.  
  289.     if (Parent != ULONGMAX)
  290.     {    if (Parent == Buf[POS_PAR])
  291.             GotOne(num, "Parent", Buf);
  292.     }
  293.  
  294.     if (Key != ULONGMAX)
  295.     {    if (Key == Buf[POS_KEY])
  296.             GotOne(num, "Key", Buf);
  297.     }
  298.  
  299.     if (HashChain != ULONGMAX)
  300.     {    if (HashChain == Buf[POS_HASH_CH])
  301.             GotOne(num, "HashChain", Buf);
  302.     }
  303.  
  304.     if (Extension != ULONGMAX)
  305.     {    if (Extension == Buf[POS_EXT])
  306.             GotOne(num, "Extension", Buf);
  307.     }
  308.  
  309.     if (SequenceNum != ULONGMAX)
  310.     {    if (SequenceNum == Buf[POS_D_SEQ_NUM])
  311.             GotOne(num, "SequenceNum", Buf);
  312.     }
  313.  
  314.     if (ByteSize != ULONGMAX)
  315.     {    if (ByteSize == Buf[POS_F_BYTSIZ])
  316.             GotOne(num, "ByteSize", Buf);
  317.     }
  318.  
  319.     if (BlockCount != ULONGMAX)
  320.     {    if (BlockCount == Buf[POS_NUM_BLK])
  321.             GotOne(num, "BlockCount", Buf);
  322.     }
  323.  
  324.     if (FirstDataBlk != ULONGMAX)
  325.     {    if (FirstDataBlk == Buf[POS_FST_DAT])
  326.             GotOne(num, "FirstDataBlk(A)", Buf);
  327.  
  328.         if (FirstDataBlk == Buf[POS_FST_BLK])
  329.             GotOne(num, "FirstDataBlk(B)", Buf);
  330.     }
  331.  
  332.     if (DoAnyDat || DoAnyRangeDat)
  333.         if (!ValidOnly || Buf[POS_TYP] == TYP_EXT || Buf[POS_TYP] == TYP_CONTROL)
  334.         {    done = 0;
  335.             l = &(Buf[POS_FST_BLK]);
  336.             for (i = POS_FST_BLK; !done && i <= POS_LST_BLK; l++, i++)
  337.             {    if (DoAnyRangeDat)
  338.                     for (j = 0; !done && j < DoAnyRangeDat; j+=2)
  339.                         if (AnyRangeData[j] <= *l && *l <= AnyRangeData[j+1])
  340.                         {    sprintf(one_buf, "AnyRangeD 0x%08lx", *l);
  341.                             GotOne(num, one_buf, Buf);
  342.                             done = Once;
  343.                         }
  344.  
  345.                 if (!done && DoAnyDat)
  346.                     for (j = 0; !done && j < DoAnyDat; j++)
  347.                         if (AnyDataBlk[j] == *l)
  348.                         {    sprintf(one_buf, "AnyD 0x%08lx", *l);
  349.                             GotOne(num, one_buf, Buf);
  350.                             done = Once;
  351.                         }
  352.             }
  353.         }
  354.  
  355.     if (NextDataBlk != ULONGMAX)
  356.     {    if (NextDataBlk == Buf[POS_D_NXT_DAT])
  357.             GotOne(num, "NextDataBlk", Buf);
  358.     }
  359.  
  360.     if (DoULong)
  361.         if (!ValidOnly || Buf[POS_TYP] == TYP_EXT || Buf[POS_TYP] == TYP_CONTROL)
  362.         {    done = 0;
  363.             for (j = 0; !done && j < DoULong; j++)
  364.             {    l = Buf;
  365.                 for (i = 0; !done && i < LBlockSize; l++, i++)
  366.                     if (ULong[j] == *l)
  367.                     {    sprintf(one_buf, "ULong 0x%08lx", *l);
  368.                         GotOne(num, one_buf, Buf);
  369.                         done = Once;
  370.                     }
  371.             }
  372.         }
  373.  
  374.     if (*AString2)
  375.     {    ch = (char *)Buf;
  376.         for (i = 1 + BLOCK_SIZE - AStringLen; i > 0; i--, ch++)         /* i is unsigned! */
  377.             if (ICase)
  378.             {    if ((toupper(*ch) == toupper(*AString2))
  379.                 &&  (AkStrNCmpCase(ch, AString2, AStringLen) == 0))
  380.                 {    GotOne(num, AString, Buf);
  381.                     break;
  382.                 }
  383.             }
  384.             else
  385.             {    if (*ch == *AString2 && AkStrNCmp(ch, AString2, AStringLen) == 0)
  386.                 {    GotOne(num, AString, Buf);
  387.                     break;
  388.                 }
  389.             }
  390.     }
  391. }
  392.  
  393. Static CnvStr()
  394. {
  395.     REG    char    *ptr1;
  396.     REG    char    *ptr2;
  397.     uint    n;
  398.  
  399.     ptr1 = AString;
  400.     ptr2 = AString2;
  401.  
  402.     while (*ptr1)
  403.     {    if (*ptr1 == '\\')
  404.             switch(*(++ptr1))
  405.             {
  406.             case '\\':
  407.                 *(ptr2++) = *(ptr1++);
  408.                 break;
  409.             case 'b':
  410.                 *(ptr2++) = '\b';
  411.                 ptr1++;
  412.                 break;
  413.             case 'f':
  414.                 *(ptr2++) = '\f';
  415.                 ptr1++;
  416.                 break;
  417.             case 'n':
  418.                 *(ptr2++) = '\n';
  419.                 ptr1++;
  420.                 break;
  421.             case 'r':
  422.                 *(ptr2++) = '\r';
  423.                 ptr1++;
  424.                 break;
  425.             case 't':
  426.                 *(ptr2++) = '\t';
  427.                 ptr1++;
  428.                 break;
  429.             case 'x':
  430.             case '0':
  431.             case '1':
  432.             case '2':
  433.                 n = 0;
  434.                 if (*ptr1 == 'x')
  435.                     sscanf(++ptr1, "%2x", &n);
  436.                 else
  437.                     sscanf(ptr1++, "%3o", &n);
  438.                 *(ptr2++) = n;
  439.                 if (*ptr1)
  440.                     ptr1++;
  441.                 if (*ptr1)
  442.                     ptr1++;
  443.                 break;
  444.             case '\0':
  445.                 *(ptr2++) = '\\';
  446.                 break;
  447.             default:
  448.                 *(ptr2++) = '\\';
  449.                 *(ptr2++) = *(ptr1++);
  450.                 break;
  451.             }
  452.         else
  453.             *(ptr2++) = *(ptr1++);
  454.  
  455.     }
  456.     *ptr2 = '\0';
  457. }
  458.  
  459. Static    Search()
  460. {
  461.     REG    ulong    l;
  462.  
  463.     if (*AString)
  464.     {    CnvStr();
  465.         AStringLen = strlen(AString2);
  466.     }
  467.  
  468.     if (*Name)
  469.         NameLen = strlen(Name);
  470.  
  471.     DoAnyDat = QL_IDX(Q_ANYDATABLK);
  472.  
  473.     DoAnyRangeDat = (QL_IDX(Q_ANYRANGEDATA) & 0xffe); /* Even */
  474.  
  475.     DoULong = QL_IDX(Q_ULONG);
  476.  
  477.     FromBlock += Stuff.Info.Begin;
  478.     ToBlock += Stuff.Info.Begin;
  479.  
  480.     if (FromBlock > Stuff.Info.End)
  481.         FromBlock = Stuff.Info.End;
  482.  
  483.     if (ToBlock > Stuff.Info.End)
  484.         ToBlock = Stuff.Info.End;
  485.  
  486.     ReadCount = FromBlock - Stuff.Info.Begin;
  487.  
  488.     AkMotorOn(&Stuff);
  489.     for (l = FromBlock; l <= ToBlock; l++)
  490.         Try(l);
  491.     AkMotorOff(&Stuff);
  492.  
  493.     printf("Total %d match%s found on %s from %ld to %ld\n",
  494.         Match,
  495.         (Match == 1) ? "" : "es",
  496.         Device,
  497.         FromBlock - Stuff.Info.Begin,
  498.         ToBlock - Stuff.Info.Begin);
  499. }
  500.  
  501. Static    Find()
  502. {
  503.     if (Dev = AkDevOpen(Device, &Stuff))
  504.         MyError(Dev, Device);
  505.  
  506.     MPAlloc(Buffer, (long)(BLOCK_SIZE)*Cache, &BufPoolKey);
  507.     if (FileNames)
  508.         MPAlloc(NameBuffer, (long)(BLOCK_SIZE), &BufPoolKey);
  509.  
  510.     AkDevMsg(&(Stuff.Info));
  511.  
  512.     Search();
  513. }
  514.  
  515. main(argc, argv)
  516. int    argc;
  517. char    *argv[];
  518. {
  519.     cli = argc;
  520.  
  521.     DO_QUAL();
  522.  
  523.     if (!Quiet && cli)
  524.         STARTUP_MSG;
  525.  
  526.     OPEN_LIB(IBASE, "intuition.library", INTUITION_REV);
  527.  
  528.     PoolInit(&BufPoolKey, 0L, MEMF_CHIP);
  529.  
  530.     Find();
  531.  
  532.     Cleanup();
  533. }
  534.  
  535. MyError(num, why)
  536. REG    long    num;
  537. REG    char    *why;
  538. {
  539.     ERROR_INIT
  540.  
  541.     if (!Dev)
  542.         AkDevClose(&Stuff);
  543.  
  544.     ERROR_TEST
  545.         CASE_ERR_AKDEVALL
  546.         CASE_ERR_NOVAL
  547.         CASE_ERR_NOMEM
  548.         CASE_ERR_NOLIB
  549.         CASE_ERR_BADFIL
  550.     ERROR_END(FACILITY_FIND)
  551.  
  552.     PoolFree(&BufPoolKey);
  553.  
  554.     if (IBASE)
  555.         CloseLibrary(IBASE);
  556.  
  557.     CLEANUP_QUAL();
  558.  
  559.     ERROR_EXIT
  560. }
  561.