home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
arc_lbr
/
arcdmp1.arc
/
ARCDMP.C
next >
Wrap
Text File
|
1988-01-01
|
6KB
|
303 lines
/*
* 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 */