/*  ARC - Archive utility - ARCEXT

    Version 2.19, created on 10/24/86 at 14:53:32

Copyright 1989 Lawrence J. Jones; All Rights Reserved
(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED

    By:  Thom Henderson

    Description:
         This file contains the routines used to extract files from
         an archive.

    Language:
         Computer Innovations Optimizing C86
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "arc.h"

static void extfile PROTO((struct heads *, char *, int));


void extarc(num,arg,prt)               /* extract files from archive */
int num;                               /* number of arguments */
char *arg[];                           /* pointers to arguments */
int prt;                               /* true if printing */
{
    struct heads hdr;                  /* file header */
    int save;                          /* true to save current file */
    int did[MAXARG];                   /* true when argument was used */
    char **name;                       /* name pointer list */
    int n;                             /* index */

    name = (char **)malloc(num*sizeof(char *));/* get storage for name pointers */

    for(n=0; n<num; n++)               /* for each argument */
    {    did[n] = 0;                   /* reset usage flag */
         name[n] = basename(arg[n]);
    }


    openarc(0);                        /* open archive for reading */

    if(num)                            /* if files were named */
    {    while(readhdr(&hdr,arc))      /* while more files to check */
         {    save = 0;                /* reset save flag */
              for(n=0; n<num; n++)     /* for each template given */
              {    if(match(hdr.name,name[n]))
                   {    save = 1;      /* turn on save flag */
                        did[n] = 1;    /* turn on usage flag */
                        break;         /* stop looking */
                   }
              }

              if(save)                 /* extract if desired, else skip */
                   extfile(&hdr,arg[n],prt);
              else fseek(arc,hdr.size,1);
         }
    }

    else while(readhdr(&hdr,arc))      /* else extract all files */
         extfile(&hdr,"",prt);

    closearc(0);                       /* close archive after reading */

    if(note)
    {    for(n=0; n<num; n++)          /* report unused args */
         {    if(!did[n])
              {    printf("File not found: %s\n",arg[n]);
                   nerrs++;
              }
         }
    }

    free(name);
}

static void extfile(hdr,path,prt)      /* extract a file */
struct heads *hdr;                     /* pointer to header data */
char *path;                            /* pointer to path name */
int prt;                               /* true if printing */
{
    FILE *f;                           /* extracted file */
    char fix[STRLEN];                  /* fixed name buffer */

    if(prt)                            /* printing is much easier */
    {    unpack(arc,stdout,hdr);       /* unpack file from archive */
         putchar('\f');                /* eject the form */
         return;                       /* see? I told you! */
    }

    makefnam(hdr->name, path, fix);

    if(note)
         printf("Extracting file: %s\n",fix);

    if(!(f = opnfilwr(fix)))
    {    fseek(arc,hdr->size,1);
         return;
    }

    /* now unpack the file */

    unpack(arc,f,hdr);                 /* unpack file from archive */
    clsfil(f,fix,hdr->date,hdr->time); /* close & set date/time stamp */
}
