home *** CD-ROM | disk | FTP | other *** search
- /* iffar - IFF CAT archiver extractor 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 extract(archive_name,fnames,nfiles)
- char *archive_name;
- char *fnames[];
- int nfiles;
- {
- int archive_fd, outfd;
- ULONG cat_type, chunkid, innerchunkid, subtype;
- long chunksize, innerchunksize, filesize;
- char textbuf[256], *extract_name;
- long placeholder;
- int do_extract, i;
-
- extern int verbose;
-
- if ((archive_fd = OpenCAT(archive_name,&cat_type,&filesize)) == -1)
- {
- fprintf(stderr,"Can't open archive '%s'\n",archive_name);
- return(0);
- }
-
- while ((chunkid = nextCATchunk(archive_fd,&subtype,&textbuf[0],&chunksize,&filesize)) != 0L)
- {
- /* if the chunk type isn't FORM, CAT or LIST, skip it 'cuz it
- * isn't anything we know how to extract */
- if (chunkid != ID_FORM && chunkid != ID_CAT && chunkid != ID_LIST)
- {
- if (!skipchunk(archive_fd,chunksize,&filesize))
- {
- perror(archive_fd);
- fprintf(stderr,"extract: skipchunk failed\n");
- return(0);
- }
- break;
- }
-
- /* if no extract names (nfiles == 0) were specified, extract all
- * files, so extract this one, else search to see if this name
- * is one specified in fnames, an array of pointers to char
- * strings */
- do_extract = 0;
- if (nfiles == 0)
- {
- do_extract = 1;
- extract_name = textbuf;
- }
- else
- {
- for (i = 0; i < nfiles; i++)
- {
- if (!strnicmp(basename(fnames[i]),textbuf,128))
- {
- do_extract = 1;
- extract_name = fnames[i];
- break;
- }
- }
- }
- /* if we did decide to extract it, extract it */
- if (do_extract)
- {
- if (verbose)
- fprintf(stderr,"extracting %s\n",extract_name);
-
- /* create, open and truncate the extract file */
- if ((outfd = open(extract_name,O_RDWR|O_CREAT|O_TRUNC)) == -1)
- {
- perror(textbuf);
- }
- else
- {
- if (!WriteSuperChunkHeader(outfd,chunkid,subtype,chunksize))
- return(0);
-
- copychunkbytes(archive_fd,outfd,chunksize,&filesize);
- close(outfd);
- }
-
- /* if they specified files on the command line, null them
- * out after we retrieve them, later we'll make a pass
- * through and complain about any we don't find with
- * their first bytes nulled out
- */
- if (nfiles != 0)
- *fnames[i] = '\0';
- }
- /* else we don't want to extract it, so skip it */
- else if (!skipchunk(archive_fd,chunksize,&filesize))
- {
- perror(archive_fd);
- fprintf(stderr,"extract: skipchunk failed\n");
- return(0);
- }
- }
-
- /* complain about any files named that we didn't extract */
- for (i = 0; i < nfiles; i++)
- {
- if (*fnames[i] != '\0')
- fprintf(stderr,"%s: no such archive entry\n",fnames[i]);
- }
-
- /* close the archive file and return success */
- close(archive_fd);
- return(1);
- }
-
- /* end of extract.c */
-
-