home *** CD-ROM | disk | FTP | other *** search
- #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 */
- }
-