/* 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 <openssl/opensslconf.h>
#include OPENSSL_UNISTD
#else /* VMS */
#ifdef __DECC
#include <unistd.h>
#else /* not __DECC */
#include <math.h>
#endif /* __DECC */
#endif /* VMS */
#else
#include <io.h>
#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>
#include <openssl/rand.h>

#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
#include <string.h>
#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 hexadecimal 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 unsigned long time();
#endif

	register int i;
	des_key_schedule ks,ks2;
	des_cblock iv,iv2;
	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=Malloc(BUFSIZE+8)) == NULL) ||
			((obuf=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(&k2,ks2);
		memset(k2,0,sizeof(k2));
		}
	else if (longk || flag3)
		{
		if (flag3)
			{
			des_string_to_2keys(key,&kk,&k2);
			des_set_key(&k2,ks2);
			memset(k2,0,sizeof(k2));
			}
		else
			des_string_to_key(key,&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(&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))
				{
				for (i=7-rem; i>0; i--)
					RAND_bytes(buf + l++, 1);
				buf[l++]=rem;
				ex=1;
				len+=rem;
				}
			else
				l-=rem;

			if (cflag)
				{
				des_cbc_cksum(buf,&cksum,
					(long)len,ks,&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,&iv,
					&iv2,do_encrypt);
				if (rem) memcpy(&(buf[l]),tmpbuf,
					(unsigned int)rem);
				}
			else
				{
				des_cbc_encrypt(
					buf,obuf,
					(long)l,ks,&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,&iv,
					&iv2,do_encrypt);
				}
			else
				{
				des_cbc_encrypt(
					buf,obuf,
				 	(long)l,ks,&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(obuf,
				(des_cblock *)cksum,(long)l/8*8,ks,
				(des_cblock *)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);
	}
