home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume32
/
xbbs
/
part07
/
bbscarc.c
next >
Wrap
C/C++ Source or Header
|
1992-09-08
|
5KB
|
177 lines
#include "bbscdef.h"
struct heads { /* archive entry header format */
char name[13]; /* file name */
int size; /* size of file, in bytes */
unsigned short date; /* creation date */
unsigned short time; /* creation time */
unsigned short crc; /* cyclic redundancy check */
int length; /* true file length */
};
#define ARCMARK 26 /* special archive marker */
#define ARCVER 9 /* archive header version code */
#define ARCFNLEN 13 /* file name length */
char hdrver; /* header version */
FILE *arc; /* the old archive */
FILE *inps;
listarc(filename, port_id)
char *filename, *port_id;
{
struct heads hdr; /* header data */
long tnum, tlen, tsize; /* totals */
strcpy(buf128, "/tmp/arclst.");
strcat(buf128, port_id);
inps = fopen(buf128, "w");
strcpy(buf128, filename);
fprintf(inps, "\nArchive: %s\n\n", buf128);
tnum = tlen = tsize = 0; /* reset totals */
fprintf(inps, "Name Length Stowage SF Size now ");
fprintf(inps, "Date Time CRC\n");
fprintf(inps, "============ ======== ======== ==== ======== ");
fprintf(inps, "========= ====== ====\n");
if (!(arc = fopen(buf128, "rb"))) { /* open archive for reading */
fprintf(inps, "Cannot read archive: %s\n", buf128);
return;
}
while (readhdr(&hdr, arc)) { /* else report on all files */
lstfile(&hdr);
tnum++; /* update totals */
tlen += hdr.length;
tsize += hdr.size;
fseek(arc, hdr.size, 1);/* skip to next header */
}
fclose(arc); /* close archive after reading */
fprintf(inps, " ==== ======== ==== ========\n");
fprintf(inps, "Total %6ld %8ld %3ld%% %8ld \n\n",
tnum, tlen, tlen ? 100L - (100L * tsize) / tlen : 0, tsize);
fclose(inps);
}
static lstfile(hdr) /* tell about a file */
struct heads *hdr; /* pointer to header data */
{
int yr, mo, dy; /* parts of a date */
int hh, mm, ss; /* parts of a time */
static char *mon[] = { /* month abbreviations */
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"
};
yr = (hdr -> date >> 9) & 0x7f; /* dissect the date */
mo = (hdr -> date >> 5) & 0x0f;
dy = hdr -> date & 0x1f;
hh = (hdr -> time >> 11) & 0x1f; /* dissect the time */
mm = (hdr -> time >> 5) & 0x3f;
ss = (hdr -> time & 0x1f) * 2;
fprintf(inps, "%-12s %8ld ", hdr -> name, hdr -> length);
switch (hdrver) {
case 1:
case 2:
fprintf(inps, " -- ");
break;
case 3:
fprintf(inps, " Packed ");
break;
case 4:
fprintf(inps, "Squeezed");
break;
case 5:
case 6:
case 7:
fprintf(inps, "crunched");
break;
case 8:
fprintf(inps, "Crunched");
break;
case 9: fprintf(inps, "Squashed");
break;
default:
fprintf(inps, "Unknown!");
}
fprintf(inps, " %3ld%% %8ld %2d %3s %02d %2d:%02d%c %04X\n",
100L - (100L * hdr -> size) / hdr -> length,
hdr -> size,
dy, mon[mo-1], (yr + 80) % 100,
(hh > 12 ? hh - 12 : hh), mm, (hh > 12 ? 'p' : 'a'), hdr -> crc);
}
int readhdr(hdr, f) /* read a header from an archive */
struct heads *hdr; /* storage for header */
FILE *f; /* archive to read header from */
{
char name[ARCFNLEN]; /* filename buffer */
int try = 0; /* retry counter */
static int first = 1; /* true only on first read */
if (!f) /* if archive didn't open */
return 0; /* then pretend it's the end */
if (feof(f)) /* if no more data */
return 0; /* then signal end of archive */
if (fgetc(f) != ARCMARK) { /* check archive validity */
fprintf(inps, "An entry in %s has a bad header.\n", buf128);
while(!feof(f)) {
try++;
if (fgetc(f) == ARCMARK) {
ungetc(hdrver = fgetc(f), f);
if (hdrver >= 0 && hdrver <= ARCVER)
break;
}
}
if (feof(f) && first) {
fprintf(inps,"%s is not an archive.\n", buf128);
return 0;
}
fprintf(inps, " %d bytes skipped.\n", try);
if (feof(f))
return 0;
}
hdrver = fgetc(f); /* get header version */
if (hdrver < 0) {
fprintf(inps, "Invalid header in archive %s\n", buf128);
return 0;
}
if (hdrver == 0)
return 0; /* note our end of archive marker */
if (hdrver > ARCVER) {
fread(name, sizeof(char), ARCFNLEN, f);
fprintf(inps, "I don't know how to handle file %s in archive %s\n",
name, buf128);
fprintf(inps, "I think you need a newer version of ARC.\n");
return 0;
}
/* amount to read depends on header type */
if (hdrver == 1) { /* old style is shorter */
fread(hdr, sizeof (struct heads) - sizeof (long int), 1, f);
hdrver = 2; /* convert header to new format */
hdr -> length = hdr -> size; /* size is same when not packed */
} else
fread(hdr, sizeof (struct heads), 1, f);
first = 0;
return 1; /* we read something */
}