home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
bin
/
msvv90sea.exe
/
MSBOOFLS.EXE
/
MSBPCT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-30
|
8KB
|
262 lines
/*
* MSBPCT.C
*
* Howie Kaye -- Columbia University 3/11/86
*
* Sibling program to MSBMKB.C. It is used to unpack BOO files, used for
* encoding binary files into text, and back. This program does the decoding.
* It is meant to replace the program "MSBPCT.BAS", and runs approximately
* 200 times faster.
*
* For documentation on BOO file format, see MSBMKB.C.
* This program runs, as is, under Microsoft C on MSDOS and under UNIX.
*
* Modification history:
*
* 10-AUG-90, Robert Weiner (robert%progplus.uucp@uunet.uu.net)
* Look for [rw] comments
* Moved strlen() out of loop, makes MSBPCT quicker (I've seen 20% quicker)
* Added ferror() check for outputfile, else things like out-of-disk-space
* and write errors go unnoticed. I think ferror() should be a reasonably
* machine independent call.
* There was a "final ^Z" outputted for MSDOS, removed it since we are
* extracting executables here and what we extract should be exactly what
* we put in. If there was a final ^Z in the inputfile (ie. possibly a text
* file) it should have been encoded in the boo file to begin with and
* therefore would be automatically extracted.
* Added proper exit status to go along with the ferror() test.
* exit(0)=good, exit(1)=bad. Added exit status variable 'ret'.
* Tested under MSC 5.1, MSDOS 3.10
*
* 1/26/92, Christian Hemsing. Added OS-9 support. Omit trailing nulls.
* after an idea from Charles Lasner.
* 1/21/92, Frank da Cruz. Fix #ifdef's, remove empty #else clause.
* 6/29/90, Frank da Cruz. Lowercase output filename for Unix.
*
* 1/27/89, Frank da Cruz. Comment out #define MSDOS, since this is already
* predefined for Microsoft C and probably other MS-DOS C compilers.
* put it back if you have trouble.
* Also comment out #define CI86. Uncomment if you're really using CI-86,
* or define CI86 on the compiler command line.
*
* 1/1/88, Frank da Cruz. Remove default input file names -- too
* confusing. Add exit(0) for good return code upon success.
*
* 3/23/86 - Davide P. Cervone -- University of Rochester
* added AMIGA and VAX11C support
*
* 3/24/86 - Martin Knoblauch -- TH-Darmstadt (MK001)
* test if 1. line of inputfile is delimited by "\r\n" instead of "\n"
*
* 5/5/86 - John Matthews, U of Delaware.
* Explicitly close the files.
*
* 5/8/86 - L. John Junod, DTNSRDC.
* Adapt for Computer Innovations MS-DOS CI-86 Compiler
* Improve too many args error message
*
*/
#include <stdio.h>
#ifdef AMIGA
#include <fcntl.h>
#endif /* AMIGA */
#ifdef MSDOS
#ifndef CI86
#include <fcntl.h>
#endif /* CI86 */
#else
#ifdef vax11c
#include <file.h>
#else
#ifndef OSK
#include <sys/file.h>
#endif /* not OSK */
#endif /* vax11c */
#endif /* MSDOS */
#define fixchr(x) ((x) -'0')
#define MYRPTQ '~' /* Repeat count prefix */
yes_or_no_p(arg) char *arg; {
int c,x;
while (1) {
printf("%s",arg);
c = getchar();
if (c == '\n') continue;
while ((x = getchar()) != '\n')
if (x == EOF) return(0);
if ((c == 'Y') || (c == 'y')) return(1);
if ((c == 'N') || (c == 'n') || (c == EOF)) return(0);
printf("Please answer 'Y' or 'N'\n");
}
}
main(argc,argv) char **argv; {
char *infile = ""; /* input file name, with default */
char outfile[100]; /* output file name */
FILE *ifp, *ofp; /* i/o files */
char inline[100];
int f, i, n;
int ret=0; /* [rw] exit status assumed ok */
char last,before_last; /* two byte buffer to omit trailing nulls */
char first=1;
char null_cnt=0; /* #of trailing nulls */
if (argc > 2) { /* check for too many args */
printf("Too many args. Usage: msbpct input-boo-file-name\n");
exit(1);
}
if (argc > 1) { /* check for input file */
infile = argv[1];
} else if (argc < 2) {
printf("Usage: msbpct input-boo-file-name\n");
exit(1);
}
if ((ifp = fopen(infile,"r")) == NULL) { /* open input file */
printf("%s not found.\n",infile); /* failure? */
exit(1);
}
fgets(outfile,100,ifp); /* get output file name */
n = strlen(outfile);
if ((outfile[n-2] == '\r')| /* MK001 */
(outfile[n-2] == '\n')) {
outfile[n-2] = '\0';
} else {
outfile[n-1] = '\0';
}
#ifndef MSDOS
#ifndef vms
/* For UNIX and OSK, convert name to lowercase. */
for (i = 0; i < n; i++) {
if (outfile[i] >= 'A' && outfile[i] <= 'Z') outfile[i] += 32;
}
#endif /* vms */
#endif /* MSDOS */
if ((ofp = fopen(outfile,"r")) != NULL) {
char msg[100];
sprintf(msg,
"output file '%s' already exists. continue (y/n)? ",outfile);
if (!yes_or_no_p(msg)) {
printf("ok. bye\n");
exit(0);
} else {
fclose(ofp);
}
}
#ifndef MSDOS
#ifndef O_BINARY
#define O_BINARY 0
#endif /* O_BINARY */
#endif /* MSDOS */
#ifdef AMIGA
if ((ofp = fopen(outfile,"w")) == NULL) {
printf("could not open %s\n",outfile); /* failure */
exit(0);
}
#else
#ifdef CI86
if((ofp = fopen(outfile,"wb")) == NULL){
printf("could not open %s\n",outfile); /* failure */
exit(0);
}
#else
#ifdef OSK
if ((ofp = fopen(outfile,"w")) == NULL) { /* open it */
#else
f = open(outfile,O_CREAT|O_WRONLY|O_TRUNC|O_BINARY,0x1ff);
if ((ofp = fdopen(f,"w")) == NULL) { /* open it */
#endif
printf("failure to open %s\n",outfile); /* failure? */
exit(1);
}
#endif /* CI86 */
#endif /* AMIGA */
printf("%s ==> %s\n",infile,outfile); /* announce our intentions */
while(fgets(inline,100,ifp) != NULL) { /* till EOF */
int index=0,outindex=0,len; /* [rw] added len */
len=strlen(inline); /* [rw] moved out of loop below */
while (index < len && inline[index] != '\n' &&
inline[index] != '\r') { /* end of line? */
if (inline[index] == MYRPTQ) { /* null compress char... */
int rptcnt;
int i;
index++;
rptcnt = fixchr(inline[index]); /* get repeat count */
index++;
if (rptcnt == 0) { /* additional nulls to be omitted */
null_cnt = null_cnt +1;
continue;
}
if (!first) {
putc(before_last,ofp);
putc(last,ofp);
before_last = '\0';
last = '\0';
} else {
first = 0;
before_last = '\0';
last = '\0';
}
rptcnt = rptcnt - 2;
for (i=0; i<rptcnt; i++) /* output rest of the nulls */
putc('\0',ofp);
} else { /* a quad to decode... */
int a, b, c ,d;
a = fixchr(inline[index]);
index++;
b = fixchr(inline[index]);
index++;
c = fixchr(inline[index]);
index++;
d = fixchr(inline[index]);
index++;
if (!first) {
putc(before_last,ofp);
putc(last,ofp);
putc(((a*4)+(b/16)) & 255,ofp); /* output the bytes */
before_last = ((b*16)+(c/4)) & 255;
last = ((c*64)+d) & 255;
} else {
first = 0;
putc(((a*4)+(b/16)) & 255,ofp); /* output the bytes */
before_last = ((b*16)+(c/4)) & 255;
last = ((c*64)+d) & 255;
}
}
}
if ( ferror(ofp) ) /* [rw] must check for errors here! */
break;
}
if (null_cnt == 0) {
printf("There might be one additional null at eof, because\n");
printf("the BOO file had been encoded with an old encoder.\n");
putc(before_last,ofp);
} else if (null_cnt == 1) {
putc(before_last,ofp);
} else {} /* nothing to do here; just don't output the last two nulls */
#ifdef AMIGA
putc('\032',ofp); /* final ^Z for the Amiga */
#endif /* AMIGA */
if ( ferror(ofp) ) { /* [rw] must check for errors */
printf("error writing output file %s\n",outfile); /* failure */
ret = 1 ; /* [rw] exit status is now bad */
}
fclose(ofp); /* Close the files */
fclose(ifp);
exit(ret); /* [rw] exit with success/failed */
} /* End of program */