/*
 *  GPLv2
 *  Copyright 2003, Glenn McGrath <bug1@iinet.net.au>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation; either version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *  Based on specification from
 *  http://www.opengroup.org/onlinepubs/007904975/utilities/uuencode.html
 *
 *  Bugs: the spec doesnt mention anything about "`\n`\n" prior to the "end" line
 */


#include <stdio.h>
#include <errno.h>
#include <getopt.h> /* optind */
#include <string.h>
#include <stdlib.h>
#include "busybox.h"

static int read_stduu(FILE *src_stream, FILE *dst_stream)
{
	char *line;

	while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) {
		int length;
		char *line_ptr = line;

		if (strcmp(line, "end") == 0) {
			return(EXIT_SUCCESS);
		}
		length = ((*line_ptr - 0x20) & 0x3f)* 4 / 3;

		if (length <= 0) {
			/* Ignore the "`\n" line, why is it even in the encode file ? */
			continue;
		}
		if (length > 60) {
			bb_error_msg_and_die("Line too long");
		}

		line_ptr++;
		/* Tolerate an overly long line to acomadate a possible exta '`' */
		if (strlen(line_ptr) < (size_t)length) {
			bb_error_msg_and_die("Short file");
		}

		while (length > 0) {
			/* Merge four 6 bit chars to three 8 bit chars */
			fputc(((line_ptr[0] - 0x20) & 077) << 2 | ((line_ptr[1] - 0x20) & 077) >> 4, dst_stream);
			line_ptr++;
			length--;
			if (length == 0) {
				break;
			}

			fputc(((line_ptr[0] - 0x20) & 077) << 4 | ((line_ptr[1] - 0x20) & 077) >> 2, dst_stream);
			line_ptr++;
			length--;
			if (length == 0) {
				break;
			}

			fputc(((line_ptr[0] - 0x20) & 077) << 6 | ((line_ptr[1] - 0x20) & 077), dst_stream);
			line_ptr += 2;
			length -= 2;
		}
		free(line);
	}
	bb_error_msg_and_die("Short file");
}

static int read_base64(FILE *src_stream, FILE *dst_stream)
{
	static const char base64_table[] =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
	char term_count = 0;

	while (1) {
		char translated[4];
		int count = 0;

		while (count < 4) {
			char *table_ptr;
			int ch;

			/* Get next _valid_ character */
			do {
				ch = fgetc(src_stream);
				if (ch == EOF) {
					bb_error_msg_and_die("Short file");
				}
			} while ((table_ptr = strchr(base64_table, ch)) == NULL);

			/* Convert encoded charcter to decimal */
			ch = table_ptr - base64_table;

			if (*table_ptr == '=') {
				if (term_count == 0) {
					translated[count] = 0;
					break;
				}
				term_count++;
			}
			else if (*table_ptr == '\n') {
				/* Check for terminating line */
				if (term_count == 5) {
					return(EXIT_SUCCESS);
				}
				term_count = 1;
				continue;
			} else {
				translated[count] = ch;
				count++;
				term_count = 0;
			}
		}

		/* Merge 6 bit chars to 8 bit */
	    fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
		if (count > 2) {
			fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
		}
		if (count > 3) {
			fputc(translated[2] << 6 | translated[3], dst_stream);
		}
	}
}

int uudecode_main(int argc, char **argv)
{
	int (*decode_fn_ptr) (FILE * src, FILE * dst);
	FILE *src_stream;
	char *outname = NULL;
	char *line;
	int opt;

	opt = bb_getopt_ulflags(argc, argv, "o:", &outname);

	if (optind == argc) {
		src_stream = stdin;
	} else if (optind + 1 == argc) {
		src_stream = bb_xfopen(argv[optind], "r");
	} else {
		bb_show_usage();
	}

	/* Search for the start of the encoding */
	while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) {
		char *line_ptr = NULL;

		if (line == NULL) {
			break;
		} else if (strncmp(line, "begin-base64 ", 13) == 0) {
			line_ptr = line + 13;
			decode_fn_ptr = read_base64;
		} else if (strncmp(line, "begin ", 6) == 0) {
			line_ptr = line + 6;
			decode_fn_ptr = read_stduu;
		}

		if (line_ptr) {
			FILE *dst_stream;
			int mode;
			int ret;

			mode = strtoul(line_ptr, NULL, 8);
			if (outname == NULL) {
				outname = strchr(line_ptr, ' ');
				if ((outname == NULL) || (*outname == '\0')) {
					break;
				}
				outname++;
			}
			if (strcmp(outname, "-") == 0) {
				dst_stream = stdout;
			} else {
				dst_stream = bb_xfopen(outname, "w");
				chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO));
			}
			free(line);
			ret = decode_fn_ptr(src_stream, dst_stream);
			bb_fclose_nonstdin(src_stream);
			return(ret);
		}
		free(line);
	}
	bb_error_msg_and_die("No `begin' line");
}
