/*
 * De-BOO utility
 *
 * This is a program to convert files in "BOO" format back into their
 * original form. It is substantially as written by Howie Kaye of
 * Columbia University, New York and modified by various others: the
 * changes in this particular incarnation are to remove any Kermit-specific
 * features and defaults.
 *
 * The original program source contained various compilation options for
 * different machines and compilers: this version is specifically tailored
 * for MS-DOS 2 (and later) and is designed to be compiled with the Lattice
 * C compiler, version 3 or later.
 *
 * The usage of the program is:
 *
 *	deboo input-file [output-file]
 *
 *	where:	input-file	is the file in BOO format to be converted
 *
 *		output-file	is the optional name of the converted file. If
 *				it is omitted, the file name given in the first
 *				record of the .BOO file is used.
 */

#include <stdio.h>
#include <strings.h>


#define fixchr(x)	((x) -'0')
#define NULLCHR		fixchr('~')

FILE *ifp, *ofp, *fopen();		/* i/o files */


/*
 * check_file
 *
 * Determines if the proposed output file exists, and asks user what to
 * do if it does. The program is exited if the user does not wish to
 * procede.
 */
check_file(name)
char *name;				/* Name of file */
{
	char ch;			/* reply to prompt */

	if ((ofp = fopen(name,"r")) == NULL)
		return(0);
	else
		fclose(ofp);

	/* File does exist, so abort */

	fprintf(stderr,"Output file %s already exists\n",name);
	exit(1);
}

main(argc, argv)
int argc;
char *argv[];
{
	char outfile[100];		/* output file name */
	char inline[100];		/* input line buffer */
	int index, rptcnt, i;
	int a, b, c, d;

	/*
	 * Check the number of command arguments is reasonable
	 */
	if (argc < 2 | argc > 3) {
		fprintf(stderr, "Usage : deboo input-file [output-file]\n");
		exit(1);
	}
	/*
	 * Then try to open the input file
	 */
	if ((ifp = fopen(argv[1], "r")) == NULL) {
		fprintf(stderr, "Error : Cannot open input file %s\n",argv[1]);
		exit(1);
	}
	/*
	 * Now look at the output file. Read the first record from the input
	 * file, which is the default output file name
	 */
	fgets(outfile, 100, ifp);
	if ((outfile[strlen(outfile) - 2] == '\n'))
		outfile[strlen(outfile) - 2] = '\0';
	else
		outfile[strlen(outfile) - 1] = '\0';
	/*
	 * If the user gave an output file in the command line, we'll replace
	 * what we've just read with what he gave. Otherwise, we'll see if
	 * the file exists, and if it does, ask user what to do
	 */
	if (argc == 3)
		strcpy(outfile, argv[2]);
	else
		check_file(outfile);
	/*
	 * Output file name is now known, so try to open it in binary output
	 * mode
	 */
	if ((ofp = fopen(outfile, "w")) == NULL) {
		fprintf(stderr, "Error : Unable to open output file %s\n",outfile);
		exit(1);
	}
	else
		printf("Converting %s into %s\n", argv[1],outfile);
	/*
	 * And now into the read/decode/write loop
	 */
	while(fgets(inline, 100, ifp) != NULL) {
		index = 0;
		while (index < strlen(inline) && inline[index] != '\n') {
			if (fixchr(inline[index]) == NULLCHR) {
				/*
				 * null compress char
				 */
				index++;
				rptcnt = fixchr(inline[index]); /* get repeat count */
				for (i = 0; i < rptcnt; i++)	/* output the nulls */
					putc('\0', ofp);
				index++;			/* pass the count field */
			}
			else {
				/*
				 * a quad to decode...
				 */
				a = fixchr(inline[index++]);
				b = fixchr(inline[index++]);
				c = fixchr(inline[index++]);
				d = fixchr(inline[index++]);
				/*
				 * output the bytes
				 */
				putc(((a * 4) + (b / 16)) & 255, ofp);
				putc(((b * 16) + (c / 4)) & 255, ofp);
				putc(((c * 64) + d) & 255, ofp);
			}
		}
	}
}
