home *** CD-ROM | disk | FTP | other *** search
- /* iffar - IFF CAT archiver table of contents functions
-
- By Karl Lehenbauer, version 1.2, release date 5/9/88.
- This code is released to the public domain.
- See the README file for more information.
-
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include "assert.h"
- #include "iff.h"
-
- #define ID_NAME MakeID('N','A','M','E')
- #define ID_AUTH MakeID('A','U','T','H')
- #define ID_ANNO MakeID('A','N','N','O')
- #define ID_Copyright MakeID('(','c',')',' ')
-
- extern long lseek();
-
- extern ULONG nextchunk();
-
- int table_of_contents(fname)
- char *fname;
- {
- int fd;
- ULONG cat_type, chunkid, innerchunkid, subtype;
- long chunksize, innerchunksize, filesize;
- char namebuf[256];
-
- extern int verbose;
-
- if ((fd = OpenCAT(fname,&cat_type,&filesize)) == -1)
- {
- fprintf(stderr,"Can't open archive '%s'\n",fname);
- return(0);
- }
-
- if (verbose)
- {
- fprintf(stderr,"CAT subtype is ");
- PutID(cat_type);
- fprintf(stderr,"\n");
- }
-
- while ((chunkid = nextCATchunk(fd,&subtype,&namebuf[0],&chunksize,&filesize)) != 0L)
- {
- /* if the chunk type isn't FORM, CAT or LIST, skip it */
- if (chunkid != ID_FORM && chunkid != ID_CAT && chunkid != ID_LIST)
- {
- if (verbose)
- {
- PutID(chunkid);
- fprintf(stderr," chunk is being skipped\n");
- }
- skipchunk(fd,chunksize,&filesize);
- goto bigchunkdone;
- }
-
- if (namebuf[0] == '\0')
- {
- fprintf(stderr,"CAT entry didn't contain a FNAM chunk - skipping\n");
- skipchunk(fd,chunksize,&filesize);
- goto bigchunkdone;
- }
-
- PutID(chunkid);
- fprintf(stderr," ");
- /* print out the chunk length */
- PutID(subtype);
- fprintf(stderr," %6ld %s\n",chunksize, namebuf);
-
- /* if verbose isn't selected, skip the rest of the chunks in the
- * embedded FORM, CAT or LIST
- */
- if (!verbose)
- {
- skipchunk(fd,chunksize,&filesize);
- goto bigchunkdone;
- }
-
- /* else verbose is selected, dive down into the embedded FORM,
- * CAT or LIST and print chunks found there and their contents
- * when they're known to be text.
- */
-
- /* follow a good neighbor policy by reducing our (the parent's)
- * chunk size by the size we've found - since we'll be moving
- * through the embedded FORM effectively recursively; that is,
- * we'll be using the same nextchunk, skipchunk, readchunk
- * routines on the chunk nextchunk got for us, we'll
- * decrease parent chunk size by the size we've found,
- * as, when calling nextchunk, skipchunk and readchunk below,
- * we'll be concerned with keeping track of the form's chunk length
- * as a virtual EOF, rather than the whole CAT's as above
- */
- filesize -= chunksize;
- if (chunksize & 1)
- filesize--;
-
- while (chunksize != 0)
- {
- /* get the type and size of the inner chunk */
- innerchunkid = nextchunk(fd,&innerchunksize,&chunksize);
- if (chunksize == 0)
- break;
-
-
- /* print some presumably useful information */
- fprintf(stderr," ");
- PutID(innerchunkid);
-
- switch(innerchunkid)
- {
- case ID_FNAM:
- panic("more than one FNAM chunk in an embedded FORM");
-
- case ID_NAME:
- case ID_AUTH:
- case ID_ANNO:
- case ID_Copyright:
- if (innerchunksize >= sizeof(namebuf))
- {
- fprintf(stderr,"[too long]\n");
- skipchunk(fd,innerchunksize,&chunksize);
- }
- else
- {
- if (!readchunk(fd,namebuf,innerchunksize,&chunksize))
- {
- fprintf(stderr,"got into trouble reading chunk text\n");
- return(0);
- }
- namebuf[innerchunksize] = '\0';
- fprintf(stderr,", %s\n",namebuf);
- }
- break;
-
- default:
- fprintf(stderr,", size %ld\n",innerchunksize);
-
- /* skip the body of the subchunk */
- skipchunk(fd,innerchunksize,&chunksize);
- }
- }
- /* we make it to here if the length of all the subchunks equalled
- * the length of their superchunk
- */
- bigchunkdone: ;
- }
- close(fd);
- }
-
- /* end of toc.c */
-