home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
294.lha
/
iffar_v1.4
/
extract.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-08
|
3KB
|
133 lines
/* 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 */