home *** CD-ROM | disk | FTP | other *** search
- /*
- * arcdmp.c
- *
- * V 1.1
- * Original August 1987, Jim Kyle
- * Modified January 1988, S. Sampson
- *
- * This program splits big ARC files into floppy-sized chunks
- *
- * Define ECO for ECO-C88 Compiler, Default is MSC V4.0
- */
-
- /* Includes */
-
- #include <stdio.h>
- #include <string.h>
- #ifdef ECO
- #include <ctype.h>
- #include <malloc.h>
- #else
- #include <dos.h>
- #include <search.h>
- #include <stdlib.h>
- #endif
-
- /* Defines */
-
- #define WORKSPACE 16384
- #ifndef ECO
- #define tempname argv[1]
- #endif
-
- /* Globals */
-
- struct {
- char key; /* always 26 */
- char type; /* 0 for EOF */
- char name[13]; /* filename.ext+NULL */
- long asiz; /* size of ARC member */
- int date; /* date in FCB format */
- int time; /* time in FCB format */
- int CRC; /* CRC value for entry */
- long osiz; /* original file size */
- } header; /* ARC element header */
-
- struct list {
- long size; /* index to ARC file */
- long loc;
- } f1[500], f2[500];
-
- FILE *infl,
- *otfl;
-
- long avl;
-
- int f1c,
- f2c,
- outctr = 0;
-
- char outbas[16],
- outnam[16],
- *outbfr;
-
- /* Prototypes, Forward declarations */
-
- void doarc(void);
- void bldtbl(void);
- void post(long);
- void dump(struct list *, int);
- int cmpsiz(struct list *, struct list *);
- int cmploc(struct list *, struct list *);
- long fill(void);
- void copy(struct list *, struct list *);
- void pack(struct list *);
-
-
- /* Program */
-
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- register char *p;
- #ifdef ECO
- char tempname[64];
- #endif
-
- /* provide help */
-
- if (argc < 2) {
- fprintf(stderr, "Usage: arcdmp archive[.ARC] prefix\n");
- exit(1);
- }
-
- /* convert the archive filename to uppercase */
-
- for (p = argv[1]; *p; p++)
- *p = (char)toupper(*p);
-
- #ifdef ECO
- /* parse the many possibilities */
-
- if ((p = strrchr(argv[1], '.')) == (char *)NULL)
- goto add;
- else if (strcmp(p, ".ARC") == NULL)
- strcpy(tempname, argv[1]);
- else if (*(p+1) == '/' || *(p+1) == '\\') {
- add: strcpy(tempname, argv[1]);
- strcat(tempname, ".ARC");
- } else {
- fprintf(stderr, "File '%s' not an archive\n", argv[1]);
- exit(1);
- }
- #endif
-
- /* open up the archive */
-
- if ((infl = fopen(tempname, "rb")) == (FILE *)NULL) {
- fprintf(stderr, "Can't open '%s' archive\n", tempname);
- exit(1);
- }
-
- /* build the new filename with a given prefix or TMP */
-
- if (argc < 3)
- strcpy (outbas, "TMP");
- else if (strchr(argv[2], ':') == NULL)
- sprintf(outbas, "%.5s", argv[2]);
- else
- sprintf(outbas, "%.7s", argv[2]); /* 5 char plus drive spec */
-
- /* reserve some memory space */
-
- if ((outbfr = calloc(WORKSPACE, sizeof(char))) == NULL) {
- fprintf(stderr, "Not enough memory\n");
- exit(1);
- }
-
- doarc();
-
- /* were done, so cleanup and leave */
-
- free(outbfr);
- fclose(infl);
- exit(0);
- }
-
-
- void doarc()
- {
- int cmploc(), cmpsiz();
-
- bldtbl();
- qsort((char *)&f1[0], (unsigned)f1c, sizeof f1[0], cmpsiz);
-
- while ( f1c ) {
- printf(" Floppy = %lu bytes (%s):\n", fill(), outnam);
- qsort((char *)&f2[0], (unsigned)f2c, sizeof f2[0], cmploc);
- dump(f2, f2c);
- }
- }
-
-
- void bldtbl()
- {
- long curloc;
-
- curloc = 0L;
- while (fread((char *)&header, 1, sizeof header, infl) > 2) {
- if (header.type)
- post(curloc);
-
- if (fseek(infl, header.asiz, 1)) {
- fprintf(stderr, "Seek error\n");
- exit(1);
- }
-
- curloc = ftell(infl);
- }
- }
-
-
- /* post size and location in table */
-
- void post(posn)
- long posn;
- {
- f1[f1c].size = header.asiz + sizeof header;
- f1[f1c++].loc = posn;
- f1[f1c].loc = posn + header.asiz + sizeof header;
- f1[f1c].size = 0L;
- }
-
-
- void dump(f, n)
- struct list *f;
- int n;
- {
- if ((otfl = fopen(outnam, "wb")) == (FILE *)NULL) {
- fprintf(stderr, "Can't produce '%s'\n", outnam);
- exit(1);
- }
-
- while (n--) {
- if (fseek(infl, f->loc, 0)) { /* position to member */
- fprintf(stderr, "Positioning error\n");
- exit(1);
- }
-
- fread((char *)&header, 1, sizeof header, infl);
- printf("%-14s%9lu%9lu\n", header.name, f->size, f->loc);
- fwrite((char *)&header, 1, sizeof header, otfl);
-
- while (header.asiz > 0L) {
- int x;
-
- x = header.asiz > (long)WORKSPACE ? WORKSPACE : (int)header.asiz;
- x = fread( outbfr, 1, x, infl); /* read a chunk */
-
- if (x != fwrite( outbfr, 1, x, otfl)) {
- fprintf(stderr, "Output write error\n");
- exit(1);
- }
-
- header.asiz -= (long)x;
- }
-
- f++;
- }
-
- printf("%-14s%9lu%9lu\n", " Final-->", f->size, f->loc);
- fputc(26, otfl);
- fputc(0, otfl);
-
- fclose(otfl);
- }
-
-
- int cmpsiz(a1, a2)
- struct list *a1, *a2; /* sort biggest ones first */
- {
- return(a1->size > a2->size ? -1 : a1->size < a2->size);
- }
-
-
- int cmploc(a1, a2)
- struct list *a1, *a2; /* restore to alpha sequence */
- {
- return(a1->loc < a2->loc ? -1 : a1->loc > a2->loc);
- }
-
-
- long fill() /* fill up a small ARC table */
- {
- int c;
- long tmp;
-
- sprintf(outnam, "%s%03d.ARC", outbas, ++outctr);
-
- avl = 1024L * 354L - 3L; /* 360K floppy size */
- f2c = c = 0;
- copy(&f1[c], &f2[f2c++]); /* always take first one */
- tmp = f1[c].size;
- f2[f2c].size = 0L;
- pack(&f1[c]); /* and remove from list */
-
- while ( c < f1c ) {
- while (( f1[c].size < avl ) && f1[c].size ) {
- copy(&f1[c], &f2[f2c++]);
- tmp += f1[c].size;
- f2[f2c].size = 0L;
- pack(&f1[c]);
- }
-
- ++c;
- }
-
- return tmp;
- }
-
-
- void copy(a1, a2)
- struct list *a1, *a2;
- {
- a2->size = a1->size;
- a2->loc = a1->loc;
- }
-
-
- void pack(a1)
- struct list *a1;
- {
- avl -= a1->size;
- while (a1->size) {
- copy (a1+1, a1);
- ++a1;
- }
-
- --f1c;
- }
-
- /* EOF */