home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Cruncher / XPK416SR.LHA / xpk_Source / shell / xDir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-06  |  4.6 KB  |  214 lines

  1. #define NAME        "xDir"
  2. #define DISTRIBUTION    "(Freeware) "
  3. #define REVISION    "5"
  4.  
  5. /* Programmheader
  6.  
  7.     Name:        xDir
  8.     Author:        SDI (before 1.2 Urban Dominik Müller)
  9.     Distribution:    Freeware
  10.     Description:    xpk file lister
  11.     Compileropts:    -
  12.     Linkeropts:    -l xpkmaster
  13.  
  14.  1.0    : first public release
  15.  1.1    : Enforcer hit fixed, version string added, wrote documentation
  16.  1.2   29.11.96 : reworked for new includes
  17.  1.3   24.04.97 : fixed lots of errors, made a lot shorter, easier
  18.  1.4   12.07.97 : totally rewritten
  19.  1.5   27.97.97 : little fixes
  20. */
  21.  
  22. #include "SDI_defines.h"
  23. #define SDI_TO_ANSI
  24. #include "SDI_ASM_STD_protos.h"
  25. #include <proto/exec.h>
  26. #include <proto/dos.h>
  27. #include <proto/xpkmaster.h>
  28. #include <exec/memory.h>
  29.  
  30. struct DataList {
  31.   struct DataList *    next;
  32.   UWORD            size; /* size of complete list */
  33.   UBYTE             text[0]; /* text data, which follows the structure */
  34. };
  35.  
  36. #define TEXTSIZE    40
  37.  
  38. struct Library *XpkBase = 0;
  39.  
  40. ULONG exitem(STRPTR, ULONG *, ULONG *);
  41. ULONG exfile(struct FileInfoBlock *, struct DataList *, ULONG *, ULONG *);
  42.  
  43. void main(int argc, char *argv[])
  44. {
  45.   ULONG ret = 20;
  46.  
  47.   if(argc == 2 && argv[1][0] == '?')
  48.   {
  49.     printf("Usage: xDir files/dirs\n"); exit(10);
  50.   }
  51.  
  52.   if((XpkBase = OpenLibrary(XPKNAME, 3)))
  53.   {
  54.     ULONG utot = 0, ctot = 0;
  55.  
  56.     printf("Original  Packed  Ratio Type Protection Name\n"
  57.     "-------- -------- ----- ---- ---------- ----\n");
  58.  
  59.     if(argc == 1)
  60.       ret = exitem("", &utot, &ctot);
  61.     else
  62.     {
  63.       ULONG i = 1;
  64.       while(i < argc && !(ret = exitem(argv[i], &utot, &ctot)))
  65.       {
  66.         if(++i < argc)
  67.           printf("\n");
  68.       }
  69.     }
  70.  
  71.     if(!ret)
  72.       printf("-------- -------- -----\n%8ld %8ld  %2ld%%\n", utot, ctot,
  73.       (utot && (utot > ctot)) ? 100 - (100 * ctot) / utot : 0);
  74.   }
  75.   else
  76.     printf("Cannot open xpkmaster.library\n");
  77.  
  78.   if(CTRL_C)
  79.     printf(" *** Break\n");
  80.  
  81.   exit(ret);
  82. }
  83.  
  84. ULONG exitem(STRPTR name, ULONG *utot, ULONG *ctot)
  85. {
  86.   BPTR lock;
  87.   ULONG ret = 20;
  88.  
  89.   if((lock = Lock(name, ACCESS_READ)))
  90.   {
  91.     struct FileInfoBlock *fib;
  92.  
  93.     if((fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), MEMF_ANY)))
  94.     {
  95.       if(Examine(lock, fib))
  96.       {
  97.         struct DataList *list, *d, in = {0,0};
  98.  
  99.     list = ∈
  100.  
  101.         if(fib->fib_DirEntryType < 0)
  102.         {
  103.       BPTR prev;
  104.           name[strlen(name)-strlen(fib->fib_FileName)] = 0; /* cut the filename */
  105.           UnLock(lock);
  106.           if((lock = Lock(name, ACCESS_READ)))
  107.           {
  108.         prev = CurrentDir(lock);
  109.             ret = exfile(fib, list, utot, ctot);
  110.         CurrentDir(prev);
  111.       }
  112.       else
  113.         printf("Error locking %s\n", name);
  114.     }
  115.     else
  116.     {
  117.       BPTR prev;
  118.  
  119.       prev = CurrentDir(lock);
  120.       while(ExNext(lock, fib) && !(ret = exfile(fib, list, utot, ctot)))
  121.         ;
  122.       CurrentDir(prev);
  123.     }
  124.  
  125.     list = list->next; /* skip init entry */
  126.  
  127.     if(!ret)
  128.     {
  129.       for(d = list; !CTRL_C && d; d = d->next)
  130.         printf("%s", d->text);
  131.     }
  132.  
  133.     while(list) /* free the list */
  134.     {
  135.       d = list->next;
  136.       FreeMem(list, list->size);
  137.       list = d;
  138.     }
  139.       }
  140.       else
  141.         printf("Error %ld locking %s\n", IoErr(), name);
  142.  
  143.       FreeMem(fib, sizeof(struct FileInfoBlock));
  144.     }
  145.     else
  146.       printf("Not enough memory\n");
  147.  
  148.     if(lock)
  149.       UnLock(lock);
  150.   }
  151.   else
  152.     printf("Error %ld locking %s\n", IoErr(), name);
  153.  
  154.   return ret;
  155. }
  156.  
  157. ULONG exfile(struct FileInfoBlock *fib, struct DataList *l, ULONG *utot, ULONG *ctot)
  158. {
  159.   struct DataList *dl, *le;
  160.   ULONG listsize, fl;
  161.   struct XpkFib xfib;
  162.   ULONG i, clen = 0, ulen = 0;
  163.  
  164.   fl = strlen(fib->fib_FileName);
  165.   listsize = sizeof(struct DataList) + fl + TEXTSIZE + 2; /* '\n' and '\0' */
  166.  
  167.   if(!(dl = (struct DataList *) AllocMem(listsize, MEMF_ANY|MEMF_CLEAR)))
  168.   {
  169.     printf("Not enough memory\n"); return 20;
  170.   }
  171.  
  172.   memset(dl->text, ' ', 40);
  173.   dl->size = listsize;
  174.  
  175.   if(fib->fib_EntryType >= 0)
  176.     CopyMem("<Dir>", dl->text+3, 5);
  177.   else if(!XpkExamineTags(&xfib, XPK_InName, fib->fib_FileName, TAG_DONE)
  178.   && xfib.xf_Type == XPKTYPE_PACKED)
  179.   {
  180.     sprintf(dl->text, "%8ld %8ld  %2ld%%  %4s",
  181.     ulen = xfib.xf_ULen, clen = xfib.xf_CLen, xfib.xf_Ratio,
  182.     xfib.xf_Packer);
  183.     dl->text[28] = ' ';
  184.   }
  185.   else
  186.   {
  187.     sprintf(dl->text, "%8ld", clen = ulen = fib->fib_Size);
  188.     dl->text[8] = ' ';
  189.   }
  190.  
  191.   dl->text[29] = fib->fib_DirEntryType < 0 ? '-' : 'D';
  192.   for(i = 0; i < 8; i++)
  193.     dl->text[37-i] = (fib->fib_Protection ^ 0x0f) & (1 << i) ? "dewrapsh"[i] : '-';
  194.  
  195.   *utot += ulen;
  196.   *ctot += clen;
  197.  
  198.   CopyMem(fib->fib_FileName, dl->text+40, fl);
  199.   dl->text[40+fl] = '\n';
  200.  
  201.   /* sort and insert the new line, skip &in entry first */
  202.   do
  203.   {
  204.     le = l;
  205.     l = l->next;
  206.   } while(l && stricmp(l->text+40, dl->text+40) > 0);
  207.  
  208.   dl->next = l;
  209.   le->next = dl;
  210.  
  211.   return 0;
  212. }
  213.  
  214.