/*
 * mozillapw.c - Recover stored passwords from Mozilla user profiles
 * 
 * Copyright (C) 2002  Jochen Eisinger <jochen@penguin-breeder.org>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * 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 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
 *
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

unsigned int c2v(unsigned char c)
{
	if ((c >= 'A') && (c <= 'Z'))
		return c - 'A';
	else if ((c >= 'a') && (c <= 'z'))
		return c - 'a' + 26;
	else if ((c >= '0') && (c <= '9'))
		return c - '0' + 52;
	else if (c == '+')
		return 62;
	else if (c == '/')
		return 63;

	return -1;
}

_4to3(char *src, char *dst)
{
	unsigned int b32 = 0, bits, i;

	for (i = 0; i < 4; i++) {
		bits = c2v(src[i]);
		b32 <<= 6;
		b32 |= bits;
	}

	dst[0] = (unsigned char) ((b32 >> 16) & 0xff);
	dst[1] = (unsigned char) ((b32 >> 8) & 0xff);
	dst[2] = (unsigned char) ((b32) & 0xff);
}

_3to2(char *src, char *dst)
{
	unsigned int b32 = 0, bits, i;

	bits = c2v(src[0]);
	b32 = bits;
	b32 <<= 6;

	bits = c2v(src[1]);
	b32 |= bits;
	b32 <<= 4;

	bits = c2v(src[2]);
	b32 |= (bits >> 2);

	dst[0] = (unsigned char) ((b32 >> 8) & 0xFF);
	dst[1] = (unsigned char) ((b32) & 0xFF);
}

_2to1(char *src, char *dst)
{
	unsigned int b32 = 0, bits, i;

	bits = c2v(src[0]);
	b32 = (bits << 2);

	bits = c2v(src[1]);
	b32 |= (bits >> 4);

	dst[0] = (unsigned char) b32;

}

decode(char *test)
{

	char src[256], *sptr, dst[256], *dptr;
	int slen;

	strcpy(src, test);
	memset(dst, 0, 256);
	dptr = dst;
	sptr = src;
	dst[0] = 0;

	while (src[strlen(src) - 1] == '=')
		src[strlen(src) - 1] = 0;

	slen = strlen(src);

	while (slen >= 4) {
		_4to3(sptr, dptr);
		sptr += 4;
		dptr += 3;
		slen -= 4;
	}

	switch (slen) {

	case 3:
		_3to2(sptr, dptr);
		break;

	case 2:
		_2to1(sptr, dptr);
		break;

	}

	puts(dst);
}

main()
{

	char in[256];

	memset(in, 256, 0);

	while (!feof(stdin)) {

		fgets(in, 255, stdin);

		if (in[0] != '~') {
			printf(in);
			continue;
		}

		if (strlen(in) == 2) {
			puts("");
			continue;
		}

		in[strlen(in) - 1] = 0;

		decode(in + 1);

	}


}
