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

  1. /* iffar - IFF CAT archiver extractor 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 extract(archive_name,fnames,nfiles)
  26. char *archive_name;
  27. char *fnames[];
  28. int nfiles;
  29. {
  30.     int archive_fd, outfd;
  31.     ULONG cat_type, chunkid, innerchunkid, subtype;
  32.     long chunksize, innerchunksize, filesize;
  33.     char textbuf[256], *extract_name;
  34.     long placeholder;
  35.     int do_extract, i;
  36.  
  37.     extern int verbose;
  38.  
  39.     if ((archive_fd = OpenCAT(archive_name,&cat_type,&filesize)) == -1)
  40.     {
  41.         fprintf(stderr,"Can't open archive '%s'\n",archive_name);
  42.         return(0);
  43.     }
  44.  
  45.     while ((chunkid = nextCATchunk(archive_fd,&subtype,&textbuf[0],&chunksize,&filesize)) != 0L)
  46.     {
  47.         /* if the chunk type isn't FORM, CAT or LIST, skip it 'cuz it
  48.          * isn't anything we know how to extract */
  49.         if (chunkid != ID_FORM && chunkid != ID_CAT && chunkid != ID_LIST)
  50.         {
  51.             if (!skipchunk(archive_fd,chunksize,&filesize))
  52.             {
  53.                 perror(archive_fd);
  54.                 fprintf(stderr,"extract: skipchunk failed\n");
  55.                 return(0);
  56.             }
  57.             break;
  58.         }
  59.  
  60.         /* if no extract names (nfiles == 0) were specified, extract all
  61.          * files, so extract this one, else search to see if this name
  62.          * is one specified in fnames, an array of pointers to char
  63.          * strings */
  64.         do_extract = 0;
  65.         if (nfiles == 0)
  66.         {
  67.             do_extract = 1;
  68.             extract_name = textbuf;
  69.         }
  70.         else
  71.         {
  72.             for (i = 0; i < nfiles; i++)
  73.             {
  74.                 if (!strnicmp(basename(fnames[i]),textbuf,128))
  75.                 {
  76.                     do_extract = 1;
  77.                     extract_name = fnames[i];
  78.                     break;
  79.                 }
  80.             }
  81.         }
  82.         /* if we did decide to extract it, extract it */
  83.         if (do_extract)
  84.         {
  85.             if (verbose)
  86.                 fprintf(stderr,"extracting %s\n",extract_name);
  87.  
  88.             /* create, open and truncate the extract file */
  89.             if ((outfd = open(extract_name,O_RDWR|O_CREAT|O_TRUNC)) == -1)
  90.             {
  91.                 perror(textbuf);
  92.             }
  93.             else
  94.             {
  95.                 if (!WriteSuperChunkHeader(outfd,chunkid,subtype,chunksize))
  96.                     return(0);
  97.  
  98.                 copychunkbytes(archive_fd,outfd,chunksize,&filesize);
  99.                 close(outfd);
  100.             }
  101.  
  102.             /* if they specified files on the command line, null them
  103.              * out after we retrieve them, later we'll make a pass
  104.              * through and complain about any we don't find with
  105.              * their first bytes nulled out
  106.              */
  107.             if (nfiles != 0)
  108.                 *fnames[i] = '\0';
  109.         }
  110.         /* else we don't want to extract it, so skip it */
  111.         else if (!skipchunk(archive_fd,chunksize,&filesize))
  112.         {
  113.             perror(archive_fd);
  114.             fprintf(stderr,"extract: skipchunk failed\n");
  115.             return(0);
  116.         }
  117.     }
  118.  
  119.     /* complain about any files named that we didn't extract */
  120.     for (i = 0; i < nfiles; i++)
  121.     {
  122.         if (*fnames[i] != '\0')
  123.             fprintf(stderr,"%s: no such archive entry\n",fnames[i]);
  124.     }
  125.  
  126.     /* close the archive file and return success */
  127.     close(archive_fd);
  128.     return(1);
  129. }
  130.  
  131. /* end of extract.c */
  132.  
  133.