/* crypto/des/des.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#ifndef VMS
#include <unistd.h>
#else /* VMS */
#ifdef __DECC
#include <unistd.h>
#if __CRTL_VER < 70000000
#define RAND
#endif
#else /* not __DECC */
#include <math.h>
#define RAND
#endif /* __DECC */
#endif /* VMS */
#else
#include <io.h>
#define RAND
#endif

#include <time.h>
#include "des_ver.h"

#ifdef VMS
#include <types.h>
#include <stat.h>
#else
#ifndef _IRIX
#include <sys/types.h>
#endif
#include <sys/stat.h>
#endif
#include <openssl/des.h>

#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
#include <string.h>
#endif

#ifdef RAND
#define random rand
#define srandom(s) srand(s)
#endif

void usage(void);
void doencryption(void);
int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
void uufwriteEnd(FILE *fp);
int uufread(unsigned char *out,int size,unsigned int num,FILE *fp);
int uuencode(unsigned char *in,int num,unsigned char *out);
int uudecode(unsigned char *in,int num,unsigned char *out);
void des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
	des_key_schedule sk1,des_key_schedule sk2,
	des_cblock *ivec1,des_cblock *ivec2,int enc);
#ifdef VMS
#define EXIT(a) exit(a&0x10000000L)
#else
#define EXIT(a) exit(a)
#endif

#define BUFSIZE (8*1024)
#define VERIFY  1
#define KEYSIZ	8
#define KEYSIZB 1024 /* should hit tty line limit first :-) */
char key[KEYSIZB+1];
int do_encrypt,longk=0;
FILE *DES_IN,*DES_OUT,*CKSUM_OUT;
char uuname[200];
unsigned char uubuf[50];
int uubufnum=0;
#define INUUBUFN	(45*100)
#define OUTUUBUF	(65*100)
unsigned char b[OUTUUBUF];
unsigned char bb[300];
des_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
char cksumname[200]="";

int vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;

int main(int argc, char **argv)
	{
	int i;
	struct stat ins,outs;
	char *p;
	char *in=NULL,*out=NULL;

	vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0;
	error=0;
	memset(key,0,sizeof(key));

	for (i=1; i<argc; i++)
		{
		p=argv[i];
		if ((p[0] == '-') && (p[1] != '\0'))
			{
			p++;
			while (*p)
				{
				switch (*(p++))
					{
				case '3':
					flag3=1;
					longk=1;
					break;
				case 'c':
					cflag=1;
					strncpy(cksumname,p,200);
					p+=strlen(cksumname);
					break;
				case 'C':
					cflag=1;
					longk=1;
					strncpy(cksumname,p,200);
					p+=strlen(cksumname);
					break;
				case 'e':
					eflag=1;
					break;
				case 'v':
					vflag=1;
					break;
				case 'E':
					eflag=1;
					longk=1;
					break;
				case 'd':
					dflag=1;
					break;
				case 'D':
					dflag=1;
					longk=1;
					break;
				case 'b':
					bflag=1;
					break;
				case 'f':
					fflag=1;
					break;
				case 's':
					sflag=1;
					break;
				case 'u':
					uflag=1;
					strncpy(uuname,p,200);
					p+=strlen(uuname);
					break;
				case 'h':
					hflag=1;
					break;
				case 'k':
					kflag=1;
					if ((i+1) == argc)
						{
						fputs("must have a key with the -k option\n",stderr);
						error=1;
						}
					else
						{
						int j;

						i++;
						strncpy(key,argv[i],KEYSIZB);
						for (j=strlen(argv[i])-1; j>=0; j--)
							argv[i][j]='\0';
						}
					break;
				default:
					fprintf(stderr,"'%c' unknown flag\n",p[-1]);
					error=1;
					break;
					}
				}
			}
		else
			{
			if (in == NULL)
				in=argv[i];
			else if (out == NULL)
				out=argv[i];
			else
				error=1;
			}
		}
	if (error) usage();
	/* We either
	 * do checksum or
	 * do encrypt or
	 * do decrypt or
	 * do decrypt then ckecksum or
	 * do checksum then encrypt
	 */
	if (((eflag+dflag) == 1) || cflag)
		{
		if (eflag) do_encrypt=DES_ENCRYPT;
		if (dflag) do_encrypt=DES_DECRYPT;
		}
	else
		{
		if (vflag) 
			{
#ifndef _Windows			
			fprintf(stderr,"des(1) built with %s\n",libdes_version);
#endif			
			EXIT(1);
			}
		else usage();
		}

#ifndef _Windows			
	if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version);
#endif			
	if (	(in != NULL) &&
		(out != NULL) &&
#ifndef MSDOS
		(stat(in,&ins) != -1) &&
		(stat(out,&outs) != -1) &&
		(ins.st_dev == outs.st_dev) &&
		(ins.st_ino == outs.st_ino))
#else /* MSDOS */
		(strcmp(in,out) == 0))
#endif
			{
			fputs("input and output file are the same\n",stderr);
			EXIT(3);
			}

	if (!kflag)
		if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0))
			{
			fputs("password error\n",stderr);
			EXIT(2);
			}

	if (in == NULL)
		DES_IN=stdin;
	else if ((DES_IN=fopen(in,"r")) == NULL)
		{
		perror("opening input file");
		EXIT(4);
		}

	CKSUM_OUT=stdout;
	if (out == NULL)
		{
		DES_OUT=stdout;
		CKSUM_OUT=stderr;
		}
	else if ((DES_OUT=fopen(out,"w")) == NULL)
		{
		perror("opening output file");
		EXIT(5);
		}

#ifdef MSDOS
	/* This should set the file to binary mode. */
	{
#include <fcntl.h>
	if (!(uflag && dflag))
		setmode(fileno(DES_IN),O_BINARY);
	if (!(uflag && eflag))
		setmode(fileno(DES_OUT),O_BINARY);
	}
#endif

	doencryption();
	fclose(DES_IN);
	fclose(DES_OUT);
	EXIT(0);
	}

void usage(void)
	{
	char **u;
	static const char *Usage[]={
"des <options> [input-file [output-file]]",
"options:",
"-v         : des(1) version number",
"-e         : encrypt using sunOS compatible user key to DES key conversion.",
"-E         : encrypt ",
"-d         : decrypt using sunOS compatible user key to DES key conversion.",
"-D         : decrypt ",
"-c[ckname] : generate a cbc_cksum using sunOS compatible user key to",
"             DES key conversion and output to ckname (stdout default,",
"             stderr if data being output on stdout).  The checksum is",
"             generated before encryption and after decryption if used",
"             in conjunction with -[eEdD].",
"-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
"-k key     : use key 'key'",
"-h         : the key that is entered will be a hexidecimal number",
"             that is used directly as the des key",
"-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
"             (uuname is the filename to put in the uuencode header).",
"-b         : encrypt using DES in ecb encryption mode, the defaut is cbc mode.",
"-3         : encrypt using tripple DES encryption.  This uses 2 keys",
"             generated from the input key.  If the input key is less",
"             than 8 characters long, this is equivelent to normal",
"             encryption.  Default is triple cbc, -b makes it triple ecb.",
NULL
};
	for (u=(char **)Usage; *u; u++)
		{
		fputs(*u,stderr);
		fputc('\n',stderr);
		}

	EXIT(1);
	}

void doencryption(void)
	{
#ifdef _LIBC
	extern int srandom();
	extern int random();
	extern unsigned long time();
#endif

	register int i;
	des_key_schedule ks,ks2;
	unsigned char iv[8],iv2[8];
	char *p;
	int num=0,j,k,l,rem,ll,len,last,ex=0;
	des_cblock kk,k2;
	FILE *O;
	int Exit=0;
#ifndef MSDOS
	static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8];
#else
	static unsigned char *buf=NULL,*obuf=NULL;

	if (buf == NULL)
		{
		if (    (( buf=(unsigned char *)Malloc(BUFSIZE+8)) == NULL) ||
			((obuf=(unsigned char *)Malloc(BUFSIZE+8)) == NULL))
			{
			fputs("Not enough memory\n",stderr);
			Exit=10;
			goto problems;
			}
		}
#endif

	if (hflag)
		{
		j=(flag3?16:8);
		p=key;
		for (i=0; i<j; i++)
			{
			k=0;
			if ((*p <= '9') && (*p >= '0'))
				k=(*p-'0')<<4;
			else if ((*p <= 'f') && (*p >= 'a'))
				k=(*p-'a'+10)<<4;
			else if ((*p <= 'F') && (*p >= 'A'))
				k=(*p-'A'+10)<<4;
			else
				{
				fputs("Bad hex key\n",stderr);
				Exit=9;
				goto problems;
				}
			p++;
			if ((*p <= '9') && (*p >= '0'))
				k|=(*p-'0');
			else if ((*p <= 'f') && (*p >= 'a'))
				k|=(*p-'a'+10);
			else if ((*p <= 'F') && (*p >= 'A'))
				k|=(*p-'A'+10);
			else
				{
				fputs("Bad hex key\n",stderr);
				Exit=9;
				goto problems;
				}
			p++;
			if (i < 8)
				kk[i]=k;
			else
				k2[i-8]=k;
			}
		des_set_key((C_Block *)k2,ks2);
		memset(k2,0,sizeof(k2));
		}
	else if (longk || flag3)
		{
		if (flag3)
			{
			des_string_to_2keys(key,(C_Block *)kk,(C_Block *)k2);
			des_set_key((C_Block *)k2,ks2);
			memset(k2,0,sizeof(k2));
			}
		else
			des_string_to_key(key,(C_Block *)kk);
		}
	else
		for (i=0; i<KEYSIZ; i++)
			{
			l=0;
			k=key[i];
			for (j=0; j<8; j++)
				{
				if (k&1) l++;
				k>>=1;
				}
			if (l & 1)
				kk[i]=key[i]&0x7f;
			else
				kk[i]=key[i]|0x80;
			}

	des_set_key((C_Block *)kk,ks);
	memset(key,0,sizeof(key));
	memset(kk,0,sizeof(kk));
	/* woops - A bug that does not showup under unix :-( */
	memset(iv,0,sizeof(iv));
	memset(iv2,0,sizeof(iv2));

	l=1;
	rem=0;
	/* first read */
	if (eflag || (!dflag && cflag))
		{
		for (;;)
			{
			num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
			l+=rem;
			num+=rem;
			if (l < 0)
				{
				perror("read error");
				Exit=6;
				goto problems;
				}

			rem=l%8;
			len=l-rem;
			if (feof(DES_IN))
				{
				srandom((unsigned int)time(NULL));
				for (i=7-rem; i>0; i--)
					buf[l++]=random()&0xff;
				buf[l++]=rem;
				ex=1;
				len+=rem;
				}
			else
				l-=rem;

			if (cflag)
				{
				des_cbc_cksum((C_Block *)buf,(C_Block *)cksum,
					(long)len,ks,(C_Block *)cksum);
				if (!eflag)
					{
					if (feof(DES_IN)) break;
					else continue;
					}
				}

			if (bflag && !flag3)
				for (i=0; i<l; i+=8)
					des_ecb_encrypt(
						(des_cblock *)&(buf[i]),
						(des_cblock *)&(obuf[i]),
						ks,do_encrypt);
			else if (flag3 && bflag)
				for (i=0; i<l; i+=8)
					des_ecb2_encrypt(
						(des_cblock *)&(buf[i]),
						(des_cblock *)&(obuf[i]),
						ks,ks2,do_encrypt);
			else if (flag3 && !bflag)
				{
				char tmpbuf[8];

				if (rem) memcpy(tmpbuf,&(buf[l]),
					(unsigned int)rem);
				des_3cbc_encrypt(
					(des_cblock *)buf,(des_cblock *)obuf,
					(long)l,ks,ks2,(des_cblock *)iv,
					(des_cblock *)iv2,do_encrypt);
				if (rem) memcpy(&(buf[l]),tmpbuf,
					(unsigned int)rem);
				}
			else
				{
				des_cbc_encrypt(
					(des_cblock *)buf,(des_cblock *)obuf,
					(long)l,ks,(des_cblock *)iv,do_encrypt);
				if (l >= 8) memcpy(iv,&(obuf[l-8]),8);
				}
			if (rem) memcpy(buf,&(buf[l]),(unsigned int)rem);

			i=0;
			while (i < l)
				{
				if (uflag)
					j=uufwrite(obuf,1,(unsigned int)l-i,
						DES_OUT);
				else
					j=fwrite(obuf,1,(unsigned int)l-i,
						DES_OUT);
				if (j == -1)
					{
					perror("Write error");
					Exit=7;
					goto problems;
					}
				i+=j;
				}
			if (feof(DES_IN))
				{
				if (uflag) uufwriteEnd(DES_OUT);
				break;
				}
			}
		}
	else /* decrypt */
		{
		ex=1;
		for (;;)
			{
			if (ex) {
				if (uflag)
					l=uufread(buf,1,BUFSIZE,DES_IN);
				else
					l=fread(buf,1,BUFSIZE,DES_IN);
				ex=0;
				rem=l%8;
				l-=rem;
				}
			if (l < 0)
				{
				perror("read error");
				Exit=6;
				goto problems;
				}

			if (bflag && !flag3)
				for (i=0; i<l; i+=8)
					des_ecb_encrypt(
						(des_cblock *)&(buf[i]),
						(des_cblock *)&(obuf[i]),
						ks,do_encrypt);
			else if (flag3 && bflag)
				for (i=0; i<l; i+=8)
					des_ecb2_encrypt(
						(des_cblock *)&(buf[i]),
						(des_cblock *)&(obuf[i]),
						ks,ks2,do_encrypt);
			else if (flag3 && !bflag)
				{
				des_3cbc_encrypt(
					(des_cblock *)buf,(des_cblock *)obuf,
					(long)l,ks,ks2,(des_cblock *)iv,
					(des_cblock *)iv2,do_encrypt);
				}
			else
				{
				des_cbc_encrypt(
					(des_cblock *)buf,(des_cblock *)obuf,
				 	(long)l,ks,(des_cblock *)iv,do_encrypt);
				if (l >= 8) memcpy(iv,&(buf[l-8]),8);
				}

			if (uflag)
				ll=uufread(&(buf[rem]),1,BUFSIZE,DES_IN);
			else
				ll=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
			ll+=rem;
			rem=ll%8;
			ll-=rem;
			if (feof(DES_IN) && (ll == 0))
				{
				last=obuf[l-1];

				if ((last > 7) || (last < 0))
					{
					fputs("The file was not decrypted correctly.\n",
						stderr);
					Exit=8;
					last=0;
					}
				l=l-8+last;
				}
			i=0;
			if (cflag) des_cbc_cksum((C_Block *)obuf,
				(C_Block *)cksum,(long)l/8*8,ks,
				(C_Block *)cksum);
			while (i != l)
				{
				j=fwrite(obuf,1,(unsigned int)l-i,DES_OUT);
				if (j == -1)
					{
					perror("Write error");
					Exit=7;
					goto problems;
					}
				i+=j;
				}
			l=ll;
			if ((l == 0) && feof(DES_IN)) break;
			}
		}
	if (cflag)
		{
		l=0;
		if (cksumname[0] != '\0')
			{
			if ((O=fopen(cksumname,"w")) != NULL)
				{
				CKSUM_OUT=O;
				l=1;
				}
			}
		for (i=0; i<8; i++)
			fprintf(CKSUM_OUT,"%02X",cksum[i]);
		fprintf(CKSUM_OUT,"\n");
		if (l) fclose(CKSUM_OUT);
		}
problems:
	memset(buf,0,sizeof(buf));
	memset(obuf,0,sizeof(obuf));
	memset(ks,0,sizeof(ks));
	memset(ks2,0,sizeof(ks2));
	memset(iv,0,sizeof(iv));
	memset(iv2,0,sizeof(iv2));
	memset(kk,0,sizeof(kk));
	memset(k2,0,sizeof(k2));
	memset(uubuf,0,sizeof(uubuf));
	memset(b,0,sizeof(b));
	memset(bb,0,sizeof(bb));
	memset(cksum,0,sizeof(cksum));
	if (Exit) EXIT(Exit);
	}

/*    We ignore this parameter but it should be > ~50 I believe    */
int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
	{
	int i,j,left,rem,ret=num;
	static int start=1;

	if (start)
		{
		fprintf(fp,"begin 600 %s\n",
			(uuname[0] == '\0')?"text.d":uuname);
		start=0;
		}

	if (uubufnum)
		{
		if (uubufnum+num < 45)
			{
			memcpy(&(uubuf[uubufnum]),data,(unsigned int)num);
			uubufnum+=num;
			return(num);
			}
		else
			{
			i=45-uubufnum;
			memcpy(&(uubuf[uubufnum]),data,(unsigned int)i);
			j=uuencode((unsigned char *)uubuf,45,b);
			fwrite(b,1,(unsigned int)j,fp);
			uubufnum=0;
			data+=i;
			num-=i;
			}
		}

	for (i=0; i<(((int)num)-INUUBUFN); i+=INUUBUFN)
		{
		j=uuencode(&(data[i]),INUUBUFN,b);
		fwrite(b,1,(unsigned int)j,fp);
		}
	rem=(num-i)%45;
	left=(num-i-rem);
	if (left)
		{
		j=uuencode(&(data[i]),left,b);
		fwrite(b,1,(unsigned int)j,fp);
		i+=left;
		}
	if (i != num)
		{
		memcpy(uubuf,&(data[i]),(unsigned int)rem);
		uubufnum=rem;
		}
	return(ret);
	}

void uufwriteEnd(FILE *fp)
	{
	int j;
	static const char *end=" \nend\n";

	if (uubufnum != 0)
		{
		uubuf[uubufnum]='\0';
		uubuf[uubufnum+1]='\0';
		uubuf[uubufnum+2]='\0';
		j=uuencode(uubuf,uubufnum,b);
		fwrite(b,1,(unsigned int)j,fp);
		}
	fwrite(end,1,strlen(end),fp);
	}

/* int size:  should always be > ~ 60; I actually ignore this parameter :-)    */
int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
	{
	int i,j,tot;
	static int done=0;
	static int valid=0;
	static int start=1;

	if (start)
		{
		for (;;)
			{
			b[0]='\0';
			fgets((char *)b,300,fp);
			if (b[0] == '\0')
				{
				fprintf(stderr,"no 'begin' found in uuencoded input\n");
				return(-1);
				}
			if (strncmp((char *)b,"begin ",6) == 0) break;
			}
		start=0;
		}
	if (done) return(0);
	tot=0;
	if (valid)
		{
		memcpy(out,bb,(unsigned int)valid);
		tot=valid;
		valid=0;
		}
	for (;;)
		{
		b[0]='\0';
		fgets((char *)b,300,fp);
		if (b[0] == '\0') break;
		i=strlen((char *)b);
		if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd'))
			{
			done=1;
			while (!feof(fp))
				{
				fgets((char *)b,300,fp);
				}
			break;
			}
		i=uudecode(b,i,bb);
		if (i < 0) break;
		if ((i+tot+8) > num)
			{
			/* num to copy to make it a multiple of 8 */
			j=(num/8*8)-tot-8;
			memcpy(&(out[tot]),bb,(unsigned int)j);
			tot+=j;
			memcpy(bb,&(bb[j]),(unsigned int)i-j);
			valid=i-j;
			break;
			}
		memcpy(&(out[tot]),bb,(unsigned int)i);
		tot+=i;
		}
	return(tot);
	}

#define ccc2l(c,l)      (l =((DES_LONG)(*((c)++)))<<16, \
			 l|=((DES_LONG)(*((c)++)))<< 8, \
		 	 l|=((DES_LONG)(*((c)++))))

#define l2ccc(l,c)      (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
                    *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                    *((c)++)=(unsigned char)(((l)    )&0xff))


int uuencode(unsigned char *in, int num, unsigned char *out)
	{
	int j,i,n,tot=0;
	DES_LONG l;
	register unsigned char *p;
	p=out;

	for (j=0; j<num; j+=45)
		{
		if (j+45 > num)
			i=(num-j);
		else	i=45;
		*(p++)=i+' ';
		for (n=0; n<i; n+=3)
			{
			ccc2l(in,l);
			*(p++)=((l>>18)&0x3f)+' ';
			*(p++)=((l>>12)&0x3f)+' ';
			*(p++)=((l>> 6)&0x3f)+' ';
			*(p++)=((l    )&0x3f)+' ';
			tot+=4;
			}
		*(p++)='\n';
		tot+=2;
		}
	*p='\0';
	l=0;
	return(tot);
	}

int uudecode(unsigned char *in, int num, unsigned char *out)
	{
	int j,i,k;
	unsigned int n=0,space=0;
	DES_LONG l;
	DES_LONG w,x,y,z;
	unsigned int blank=(unsigned int)'\n'-' ';

	for (j=0; j<num; )
		{
		n= *(in++)-' ';
		if (n == blank)
			{
			n=0;
			in--;
			}
		if (n > 60)
			{
			fprintf(stderr,"uuencoded line length too long\n");
			return(-1);
			}
		j++;

		for (i=0; i<n; j+=4,i+=3)
			{
			/* the following is for cases where spaces are
			 * removed from lines.
			 */
			if (space)
				{
				w=x=y=z=0;
				}
			else
				{
				w= *(in++)-' ';
				x= *(in++)-' ';
				y= *(in++)-' ';
				z= *(in++)-' ';
				}
			if ((w > 63) || (x > 63) || (y > 63) || (z > 63))
				{
				k=0;
				if (w == blank) k=1;
				if (x == blank) k=2;
				if (y == blank) k=3;
				if (z == blank) k=4;
				space=1;
				switch (k) {
				case 1:	w=0; in--;
				case 2: x=0; in--;
				case 3: y=0; in--;
				case 4: z=0; in--;
					break;
				case 0:
					space=0;
					fprintf(stderr,"bad uuencoded data values\n");
					w=x=y=z=0;
					return(-1);
					break;
					}
				}
			l=(w<<18)|(x<<12)|(y<< 6)|(z    );
			l2ccc(l,out);
			}
		if (*(in++) != '\n')
			{
			fprintf(stderr,"missing nl in uuencoded line\n");
			w=x=y=z=0;
			return(-1);
			}
		j++;
		}
	*out='\0';
	w=x=y=z=0;
	return(n);
	}
