/* :ts=8 bk=0 */
/* xxcbc.c */

#include	"cbc.h"

char sccsid[] = "@(#) cbc.c 1.0 dec-88 =C= by David Vincenzetti";

void main(argc, argv)
int argc;
char **argv;
{
	void bad();

	char key[8];
	int optindex;

	short mode;

	if(argc < 2) bad("use: cbc [-{e|d}i] key files..");

	mode = 0;
	mode |= ENCRYPT; /* encrypt by default */

	for(optindex = 1; argv[optindex][0] == '-'; optindex++) {
		int option;

		option = toupper(argv[optindex][1]);
		if(option == '\0' || option == '-') break;
		switch(option) {
			case 'E':
				mode |= ENCRYPT;
				break;
			case 'D':
				mode |= DECRYPT;
				break;
			case 'I':
				mode |= IGNORE;
				break;
			default:
				printf("option -%c ignored\n", option);
				break;
		}
	}

	argv += optindex; argc -= optindex;

	/* key and/or filename is missing */
	if(argc < 2) bad("too few arguments");

	/*
	 * copy key to buffer 
	 */
	setmem(key, 8, 0);
	strncpy(key, argv[0], 8);

	/*
	 * get rid of ps -f or similar
	 */
	while(*argv[0]) *argv[0]++ = 0;
	++argv; --argc;

	/*
	 * set cipherment keys
	 */
	setup(key);

	/*
	 * Create IV Initializing Variable
	 * Its secrecy and key dependency is very important
	 * for CBC security. I think crypt() could be used.
	 */
	dcrypt(key, 0); /* lets scramble twice */
	dcrypt(key, 0);

	/*
	 * main loop
	 */
	for(optindex = 0; optindex < argc; optindex++) {
		int tim;
		int size;
		struct stat fbuf;

		tim = time(NULL);
		stat(argv[optindex], &fbuf);
		size = fbuf.st_size;

		switch(dofile(argv[optindex], key, mode)){
			case OK:
				printf("%s: %d bytes; elapsed: %d\n",
					argv[optindex],
					size,
					time(NULL) - tim);
				break;
			case R_ERR:
			case W_ERR:
				printf("R/W error; %s unencoded\n\n",
					argv[optindex]);
				break;
			/*
			 * something shouldn't had happened HAS happened!
			 * We probabily lost some tmp file or..
			 */
			case BAD:
				printf("BAD error for file %s!!\n\n",
					argv[optindex]);
				break;
			/*
			 * we checked the file header and
			 * we found it mismatching
			 */
			case MAT_ERR:
				printf("key incorrect; %s ignored\n",
					argv[optindex]);
				break;
			default:
				bad("_dofile return value unknown");
				break;
		}
	}
} /* main */

void bad(message)

char *message;
{
	puts(message);
	exit(1);
}
