/* 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 #include #include #include #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 */