/*
 *	Simple converter  KOI <-> WIN <-> DOS
 *		created by Xor
 */
#include <stdio.h>
#include <sys/errno.h>

#define QUANTITY 3
#define BUFFER_L 4096
#define ALPH_LENGTH 66

typedef struct data_t {
	const char * name;
	const char shortname;
	const char alphabet[ALPH_LENGTH];
} data_t;

data_t data[QUANTITY] =
{
	{ "UNIX-KOI", 'u',
	  "ţ" },
	{ "WIN", 'w',
	  "Ũ" },
	{ "DOS", 'd',
	  "񦧨" }
};

static void print_syntax(const char *progname)
{
	printf(	"Syntax:  %s -{uw|ud|wu|wd|du|dw} <filename>\n", progname);
	printf(	"         u - KOI8-R (Unix OS)\n"
		"         w - CP1251 (Must Die XX OS ?!)\n"
		"         d - CP866 (DOS, non comments)\n"
		"Example: %s -wk test.txt\n"
		"         convert WIN into KOI 'test.txt'\n", progname);
	printf(	"Converter created by Xor in 2001 [ver 1.04]\n");
}

int getalphabet(char letter)
{
	int i;
	
	for(i = 0; i < QUANTITY; i++)
		if (letter == data[i].shortname)
			return i;
	return -1;
}

void convert_text(char *buffer, int read_count, int out, int in)
{
	int i;

	while (read_count--)
	{
		for(i = 0; i < ALPH_LENGTH; i++)
			if (*buffer == data[out].alphabet[i])
			{
				*buffer = data[in].alphabet[i];
				break;
			}
		buffer++;
	}
}

int main(int argc, char * argv[])
{
	int out;
	int in;
	FILE *file;
	long posfile;
	long read_count;
	char buffer[BUFFER_L];

	if (argc < 3
	|| argv[1][0] != '-')
	{
		print_syntax(argv[0]);
		return -1;
	}
	out = in = -1;
	
	out = getalphabet(argv[1][1]);
	in = getalphabet(argv[1][2]);
	
	if (out == -1
	||  in == -1
	||  out == in)
	{
		print_syntax(argv[0]);
		return -1;
	}
	
	if ((file = fopen(argv[2], "r+")) == NULL)
	{
		printf("Cann't open '%s'. %s.\n",
			argv[2], strerror(errno));
		return -2;
	}
	
	printf("Begin convert '%s' [ %s -> %s ]... ",
		argv[2], data[out].name, data[in].name);

	for(;;) {
		posfile = ftell(file);
		read_count = fread(buffer, 1, BUFFER_L, file);
		
		convert_text(buffer, read_count, out, in);
		
		fseek(file, posfile, SEEK_SET);
		fwrite(buffer, 1, read_count, file);	/* Warning. This place
							 * without checking errors.
							 */
		if (read_count != BUFFER_L)
			break;
	}

	fclose(file);
	printf("Convert has finished.\n");
	return 0;
}
