home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
cpm68k
/
arc68k.arc
/
ARCIO.C
< prev
next >
Wrap
Text File
|
1987-11-27
|
7KB
|
241 lines
/*
* 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");
}
}