home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 497a.lha / ComSMUS_v2.2 / iffar.src / toc.c < prev   
C/C++ Source or Header  |  1991-04-07  |  4KB  |  157 lines

  1. /* iffar - IFF CAT archiver table of contents functions
  2.  
  3.    By Karl Lehenbauer, version 1.2, release date 5/9/88.
  4.    This code is released to the public domain.
  5.    See the README file for more information.
  6.  
  7. */
  8.  
  9. #include <exec/types.h>
  10. #include <exec/memory.h>
  11. #include <stdio.h>
  12. #include <fcntl.h>
  13. #include "assert.h"
  14. #include "iff.h"
  15.  
  16. #define ID_NAME MakeID('N','A','M','E')
  17. #define ID_AUTH MakeID('A','U','T','H')
  18. #define ID_ANNO MakeID('A','N','N','O')
  19. #define ID_Copyright MakeID('(','c',')',' ')
  20.  
  21. extern long lseek();
  22.  
  23. extern ULONG nextchunk();
  24.  
  25. int table_of_contents(fname)
  26. char *fname;
  27. {
  28.     int fd;
  29.     ULONG cat_type, chunkid, innerchunkid, subtype;
  30.     long chunksize, innerchunksize, filesize;
  31.     char namebuf[256];
  32.  
  33.     extern int verbose;
  34.  
  35.     if ((fd = OpenCAT(fname,&cat_type,&filesize)) == -1)
  36.     {
  37.         fprintf(stderr,"Can't open archive '%s'\n",fname);
  38.         return(0);
  39.     }
  40.  
  41.     if (verbose)
  42.     {
  43.         fprintf(stderr,"CAT subtype is ");
  44.         PutID(cat_type);
  45.         fprintf(stderr,"\n");
  46.     }
  47.  
  48.     while ((chunkid = nextCATchunk(fd,&subtype,&namebuf[0],&chunksize,&filesize)) != 0L)
  49.     {
  50.         /* if the chunk type isn't FORM, CAT or LIST, skip it */
  51.          if (chunkid != ID_FORM && chunkid != ID_CAT && chunkid != ID_LIST)
  52.          {
  53.              if (verbose)
  54.             {
  55.                 PutID(chunkid);
  56.                 fprintf(stderr," chunk is being skipped\n");
  57.             }
  58.             skipchunk(fd,chunksize,&filesize);
  59.             goto bigchunkdone;
  60.         }
  61.  
  62.         if (namebuf[0] == '\0')
  63.         {
  64.             fprintf(stderr,"CAT entry didn't contain an IFAR chunk - skipping\n");
  65.             skipchunk(fd,chunksize,&filesize);
  66.             goto bigchunkdone;
  67.         }
  68.  
  69.         PutID(chunkid);
  70.         fprintf(stderr," ");
  71.         /* print out the chunk length */
  72.         PutID(subtype);
  73.         fprintf(stderr," %6ld  %s\n",chunksize, namebuf);
  74.  
  75.         /* if verbose isn't selected, skip the rest of the chunks in the
  76.          * embedded FORM, CAT or LIST
  77.          */
  78.         if (!verbose)
  79.         {
  80.              skipchunk(fd,chunksize,&filesize);
  81.             goto bigchunkdone;
  82.         }
  83.  
  84.         /* else verbose is selected, dive down into the embedded FORM, 
  85.          * CAT or LIST and print chunks found there and their contents
  86.          * when they're known to be text.
  87.          */
  88.  
  89.         /* follow a good neighbor policy by reducing our (the parent's)
  90.          * chunk size by the size we've found - since we'll be moving
  91.          * through the embedded FORM effectively recursively; that is,
  92.          * we'll be using the same nextchunk, skipchunk, readchunk
  93.          * routines on the chunk nextchunk got for us, we'll
  94.          * decrease parent chunk size by the size we've found,
  95.          * as, when calling nextchunk, skipchunk and readchunk below,
  96.          * we'll be concerned with keeping track of the form's chunk length
  97.          * as a virtual EOF, rather than the whole CAT's as above
  98.          */
  99.         filesize -= chunksize;
  100.         if (chunksize & 1)
  101.             filesize--;
  102.  
  103.         while (chunksize != 0)
  104.         {
  105.             /* get the type and size of the inner chunk */
  106.             innerchunkid = nextchunk(fd,&innerchunksize,&chunksize);
  107.             if (chunksize == 0)
  108.                 break;
  109.  
  110.  
  111.             /* print some presumably useful information */
  112.             fprintf(stderr,"   ");
  113.             PutID(innerchunkid);
  114.  
  115.             switch(innerchunkid)
  116.             {
  117.                 case ID_IFAR:
  118.                     panic("more than one IFAR chunk in an embedded FORM");
  119.  
  120.                 case ID_NAME:
  121.                 case ID_AUTH:
  122.                 case ID_ANNO:
  123.                 case ID_Copyright:
  124.                         if (innerchunksize >= sizeof(namebuf))
  125.                         {
  126.                             fprintf(stderr,"[too long]\n");
  127.                             skipchunk(fd,innerchunksize,&chunksize);
  128.                         }
  129.                         else
  130.                         {
  131.                             if (!readchunk(fd,namebuf,innerchunksize,&chunksize))
  132.                             {
  133.                                 fprintf(stderr,"got into trouble reading chunk text\n");
  134.                                 return(0);
  135.                             }
  136.                             namebuf[innerchunksize] = '\0';
  137.                             fprintf(stderr,", %s\n",namebuf);
  138.                         }
  139.                     break;
  140.  
  141.                 default:
  142.                     fprintf(stderr,", size %ld\n",innerchunksize);
  143.  
  144.                     /* skip the body of the subchunk */
  145.                     skipchunk(fd,innerchunksize,&chunksize);
  146.                 }
  147.         }
  148.         /* we make it to here if the length of all the subchunks equalled
  149.          * the length of their superchunk
  150.          */
  151.          bigchunkdone: ;
  152.     }
  153.     close(fd);
  154. }
  155.  
  156. /* end of toc.c */
  157.