home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * arcio.c 1.1
- *
- * Author: Thom Henderson
- * Original System V port: Mike Stump
- * Enhancements, Bug fixes, and cleanup: Chris Seaman
- * Date: Fri Mar 20 09:57:02 1987
- * Last Mod. 3/21/87
- * line 32 unsigned char dummy[30] changed 7-5-87 ja
- *
- */
-
- /*
- * ARC - Archive utility - ARCIO
- *
- * Version 2.30, created on 02/03/86 at 22:56:00
- *
- * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
- *
- * Description:
- * This file contains the file I/O routines used to manipulate
- * an archive.
- */
-
- #include "arc.h"
-
- INT readhdr(hdr,f) /* read a header from an archive */
- struct heads *hdr; /* storage for header */
- FILE *f; /* archive to read header from */
- {
- INT i; /* misc. variables */
- int fnlen; /* file name length */
- char dummy[30]; /* dummy array for header storage */
- #ifdef CPM68K
- char name[FNLEN2+1]; /* filename buffer */
- #else
- char name[FNLEN1]; /* filename buffer */
- #endif
- INT try; /* retry counter */
- register char *p, *q;
- unsigned t;
- long l;
- static INT first = 1; /* true only on first read */
-
- #ifdef CPM68K
- fnlen = FNLEN2;
- #else
- fnlen = (ibmpc) ? FNLEN2 : FNLEN1;
- #endif
- try = 0; /* retry counter */
- if (!f) /* if archive didn't open */
- return(0); /* then pretend it's the end */
-
- if ((t = fgetc(f)) == EOF)
- return(0); /* then signal end of archive */
- if (t != ARCMARK) /* check archive validity */
- {
- if (warn)
- {
- printf("An entry in %s has a bad header.(%02.2x)\n",arcname,t&255);
- nerrs++;
- }
-
- while (t != EOF)
- {
- try++;
- t = fgetc(f);
- if (t == ARCMARK)
- {
- ungetc(hdrver = fgetc(f), f); /* look ahead for version */
- if (hdrver>=0 && hdrver<=ARCVER)
- break;
- }
- }
-
- if ((t==EOF) && first)
- abort("%s is not an archive",arcname);
-
- if (warn)
- printf(" %d bytes skipped.\n",try);
-
- if (t==EOF)
- return(0);
- }
-
- hdrver = fgetc(f); /* get header version */
- if (hdrver<0)
- abort("Invalid header in archive %s",arcname);
- if (hdrver==0)
- return(0); /* note our end of archive marker */
- if (hdrver>ARCVER)
- {
- fread(name,sizeof(char),fnlen,f);
- printf("I don't know how to handle file %s in archive %s\n",
- name,arcname);
- printf("I think you need a newer version of ARC.\n");
- abort("Archive error");
- }
-
- /* amount to read depends on header type */
-
- if (hdrver==1) /* old style is shorter */
- {
- fread(hdr,sizeof(struct heads)-sizeof(long),1,f);
- hdrver = 2; /* convert header to new format */
- hdr->length = hdr->size; /* size is same when not packed */
- }
- else
- {
- fread(dummy,fnlen+14,1,f);
-
- p = hdr->name;
- #ifdef CPM68K
- for (i=0; i<FNLEN2+1; i++)
- #else
- for (i=0; i<FNLEN1; i++)
- #endif
- *p++ = 0;
-
- p = hdr->name;
- q = dummy;
- for (i=0; i<fnlen; i++)
- *p++ = *q++;
-
- p = &dummy[fnlen+3];
- l = 0L;
- for (i=0; i<4; i++) {
- l <<= 8;
- t = *p--;
- l |= (t & 255);
- }
- hdr->size = l;
-
- p = &dummy[fnlen+5];
- t = 0;
- for (i=0; i<2; i++) {
- t <<= 8;
- t |= (*p-- & 255);
- }
- hdr->date = t;
-
- p = &dummy[fnlen+7];
- t = 0;
- for (i=0; i<2; i++) {
- t <<= 8;
- t |= (*p-- & 255);
- }
- hdr->time = t;
-
- p = &dummy[fnlen+9];
- t = 0;
- for (i=0; i<2; i++) {
- t <<= 8;
- t |= (*p-- & 255);
- }
- hdr->crc = t;
-
-
- p = &dummy[fnlen+13];
- l = 0L;
- for (i=0; i<4; i++) {
- l <<= 8;
- t = *p--;
- l |= (t & 255);
- }
- hdr->length = l;
- }
-
- first = 0;
- return(1); /* we read something */
- }
-
- INT writehdr(hdr,f) /* write a header to an archive */
- struct heads *hdr; /* header to write */
- FILE *f; /* archive to write to */
- {
- int i;
- int fnlen; /* file name length */
-
- #ifdef CPM68K
- fnlen = FNLEN2;
- #else
- fnlen = (ibmpc) ? FNLEN2 : FNLEN1;
- #endif
- fputc(ARCMARK,f); /* write out the mark of ARC */
- fputc(hdrver,f); /* write out the header version */
- if (!hdrver) /* if that's the end */
- return; /* then write no more */
-
- for (i = strlen(hdr->name);i < fnlen;i++)
- hdr->name[i] = '\0';
-
- fwrite(hdr->name,1,fnlen,f);
- fputc( (short) (hdr->size & 255), f);
- fputc( (short) ((hdr->size >> 8) & 255), f);
- fputc( (short) ((hdr->size >> 16) & 255), f);
- fputc( (short) ((hdr->size >> 24) & 255), f);
- fputc( (short) (hdr->date & 255), f);
- fputc( (short) ((hdr->date >> 8) & 255), f);
- fputc( (short) (hdr->time & 255), f);
- fputc( (short) ((hdr->time >> 8) & 255), f);
- fputc( (short) (hdr->crc & 255), f);
- fputc( (short) ((hdr->crc >> 8) & 255), f);
- fputc( (short) (hdr->length & 255), f);
- fputc( (short) ((hdr->length >> 8) & 255), f);
- fputc( (short) ((hdr->length >> 16) & 255), f);
- fputc( (short) ((hdr->length >> 24) & 255), f);
-
- /* note the newest file for updating the archive timestamp */
-
- if (hdr->date>arcdate ||
- (hdr->date==arcdate && hdr->time>arctime))
- {
- arcdate = hdr->date;
- arctime = hdr->time;
- }
- }
-
- INT filecopy(f,t,size) /* bulk file copier */
- FILE *f, *t; /* from, to */
- long size; /* number of bytes */
- {
- INT putc_tst();
-
- while (size--) /* while more bytes to move */
- putc_tst(fgetc(f),t);
- }
-
- INT putc_tst(c,t) /* put a character, with tests */
- char c; /* character to output */
- FILE *t; /* file to write to */
- {
- if (t)
- if (fputc(c,t)==EOF)
- {
- perror("system error:");
- abort("Write failed");
- }
- }
-