sl@0: /* crypto/des/des.c */ sl@0: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) sl@0: * All rights reserved. sl@0: * sl@0: * This package is an SSL implementation written sl@0: * by Eric Young (eay@cryptsoft.com). sl@0: * The implementation was written so as to conform with Netscapes SSL. sl@0: * sl@0: * This library is free for commercial and non-commercial use as long as sl@0: * the following conditions are aheared to. The following conditions sl@0: * apply to all code found in this distribution, be it the RC4, RSA, sl@0: * lhash, DES, etc., code; not just the SSL code. The SSL documentation sl@0: * included with this distribution is covered by the same copyright terms sl@0: * except that the holder is Tim Hudson (tjh@cryptsoft.com). sl@0: * sl@0: * Copyright remains Eric Young's, and as such any Copyright notices in sl@0: * the code are not to be removed. sl@0: * If this package is used in a product, Eric Young should be given attribution sl@0: * as the author of the parts of the library used. sl@0: * This can be in the form of a textual message at program startup or sl@0: * in documentation (online or textual) provided with the package. sl@0: * sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * 3. All advertising materials mentioning features or use of this software sl@0: * must display the following acknowledgement: sl@0: * "This product includes cryptographic software written by sl@0: * Eric Young (eay@cryptsoft.com)" sl@0: * The word 'cryptographic' can be left out if the rouines from the library sl@0: * being used are not cryptographic related :-). sl@0: * 4. If you include any Windows specific code (or a derivative thereof) from sl@0: * the apps directory (application code) you must include an acknowledgement: sl@0: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND sl@0: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE sl@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE sl@0: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL sl@0: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS sl@0: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT sl@0: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY sl@0: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF sl@0: * SUCH DAMAGE. sl@0: * sl@0: * The licence and distribution terms for any publically available version or sl@0: * derivative of this code cannot be changed. i.e. this code cannot simply be sl@0: * copied and put under another distribution licence sl@0: * [including the GNU Public Licence.] sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #ifndef OPENSSL_SYS_MSDOS sl@0: #ifndef OPENSSL_SYS_VMS sl@0: #include OPENSSL_UNISTD sl@0: #else /* OPENSSL_SYS_VMS */ sl@0: #ifdef __DECC sl@0: #include sl@0: #else /* not __DECC */ sl@0: #include sl@0: #endif /* __DECC */ sl@0: #endif /* OPENSSL_SYS_VMS */ sl@0: #else /* OPENSSL_SYS_MSDOS */ sl@0: #include sl@0: #endif sl@0: sl@0: #include sl@0: #include "des_ver.h" sl@0: sl@0: #ifdef OPENSSL_SYS_VMS sl@0: #include sl@0: #include sl@0: #else sl@0: #ifndef _IRIX sl@0: #include sl@0: #endif sl@0: #include sl@0: #endif sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: void usage(void); sl@0: void doencryption(void); sl@0: int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp); sl@0: void uufwriteEnd(FILE *fp); sl@0: int uufread(unsigned char *out,int size,unsigned int num,FILE *fp); sl@0: int uuencode(unsigned char *in,int num,unsigned char *out); sl@0: int uudecode(unsigned char *in,int num,unsigned char *out); sl@0: void DES_3cbc_encrypt(DES_cblock *input,DES_cblock *output,long length, sl@0: DES_key_schedule sk1,DES_key_schedule sk2, sl@0: DES_cblock *ivec1,DES_cblock *ivec2,int enc); sl@0: #ifdef OPENSSL_SYS_VMS sl@0: #define EXIT(a) exit(a&0x10000000L) sl@0: #else sl@0: #define EXIT(a) exit(a) sl@0: #endif sl@0: sl@0: #define BUFSIZE (8*1024) sl@0: #define VERIFY 1 sl@0: #define KEYSIZ 8 sl@0: #define KEYSIZB 1024 /* should hit tty line limit first :-) */ sl@0: char key[KEYSIZB+1]; sl@0: int do_encrypt,longk=0; sl@0: FILE *DES_IN,*DES_OUT,*CKSUM_OUT; sl@0: char uuname[200]; sl@0: unsigned char uubuf[50]; sl@0: int uubufnum=0; sl@0: #define INUUBUFN (45*100) sl@0: #define OUTUUBUF (65*100) sl@0: unsigned char b[OUTUUBUF]; sl@0: unsigned char bb[300]; sl@0: DES_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; sl@0: char cksumname[200]=""; sl@0: sl@0: int vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error; sl@0: sl@0: int main(int argc, char **argv) sl@0: { sl@0: int i; sl@0: struct stat ins,outs; sl@0: char *p; sl@0: char *in=NULL,*out=NULL; sl@0: sl@0: vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0; sl@0: error=0; sl@0: memset(key,0,sizeof(key)); sl@0: sl@0: for (i=1; i=0; j--) sl@0: argv[i][j]='\0'; sl@0: } sl@0: break; sl@0: default: sl@0: fprintf(stderr,"'%c' unknown flag\n",p[-1]); sl@0: error=1; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (in == NULL) sl@0: in=argv[i]; sl@0: else if (out == NULL) sl@0: out=argv[i]; sl@0: else sl@0: error=1; sl@0: } sl@0: } sl@0: if (error) usage(); sl@0: /* We either sl@0: * do checksum or sl@0: * do encrypt or sl@0: * do decrypt or sl@0: * do decrypt then ckecksum or sl@0: * do checksum then encrypt sl@0: */ sl@0: if (((eflag+dflag) == 1) || cflag) sl@0: { sl@0: if (eflag) do_encrypt=DES_ENCRYPT; sl@0: if (dflag) do_encrypt=DES_DECRYPT; sl@0: } sl@0: else sl@0: { sl@0: if (vflag) sl@0: { sl@0: #ifndef _Windows sl@0: fprintf(stderr,"des(1) built with %s\n",libdes_version); sl@0: #endif sl@0: EXIT(1); sl@0: } sl@0: else usage(); sl@0: } sl@0: sl@0: #ifndef _Windows sl@0: if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version); sl@0: #endif sl@0: if ( (in != NULL) && sl@0: (out != NULL) && sl@0: #ifndef OPENSSL_SYS_MSDOS sl@0: (stat(in,&ins) != -1) && sl@0: (stat(out,&outs) != -1) && sl@0: (ins.st_dev == outs.st_dev) && sl@0: (ins.st_ino == outs.st_ino)) sl@0: #else /* OPENSSL_SYS_MSDOS */ sl@0: (strcmp(in,out) == 0)) sl@0: #endif sl@0: { sl@0: fputs("input and output file are the same\n",stderr); sl@0: EXIT(3); sl@0: } sl@0: sl@0: if (!kflag) sl@0: if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0)) sl@0: { sl@0: fputs("password error\n",stderr); sl@0: EXIT(2); sl@0: } sl@0: sl@0: if (in == NULL) sl@0: DES_IN=stdin; sl@0: else if ((DES_IN=fopen(in,"r")) == NULL) sl@0: { sl@0: perror("opening input file"); sl@0: EXIT(4); sl@0: } sl@0: sl@0: CKSUM_OUT=stdout; sl@0: if (out == NULL) sl@0: { sl@0: DES_OUT=stdout; sl@0: CKSUM_OUT=stderr; sl@0: } sl@0: else if ((DES_OUT=fopen(out,"w")) == NULL) sl@0: { sl@0: perror("opening output file"); sl@0: EXIT(5); sl@0: } sl@0: sl@0: #ifdef OPENSSL_SYS_MSDOS sl@0: /* This should set the file to binary mode. */ sl@0: { sl@0: #include sl@0: if (!(uflag && dflag)) sl@0: setmode(fileno(DES_IN),O_BINARY); sl@0: if (!(uflag && eflag)) sl@0: setmode(fileno(DES_OUT),O_BINARY); sl@0: } sl@0: #endif sl@0: sl@0: doencryption(); sl@0: fclose(DES_IN); sl@0: fclose(DES_OUT); sl@0: EXIT(0); sl@0: } sl@0: sl@0: void usage(void) sl@0: { sl@0: char **u; sl@0: static const char *Usage[]={ sl@0: "des [input-file [output-file]]", sl@0: "options:", sl@0: "-v : des(1) version number", sl@0: "-e : encrypt using SunOS compatible user key to DES key conversion.", sl@0: "-E : encrypt ", sl@0: "-d : decrypt using SunOS compatible user key to DES key conversion.", sl@0: "-D : decrypt ", sl@0: "-c[ckname] : generate a cbc_cksum using SunOS compatible user key to", sl@0: " DES key conversion and output to ckname (stdout default,", sl@0: " stderr if data being output on stdout). The checksum is", sl@0: " generated before encryption and after decryption if used", sl@0: " in conjunction with -[eEdD].", sl@0: "-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].", sl@0: "-k key : use key 'key'", sl@0: "-h : the key that is entered will be a hexadecimal number", sl@0: " that is used directly as the des key", sl@0: "-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]", sl@0: " (uuname is the filename to put in the uuencode header).", sl@0: "-b : encrypt using DES in ecb encryption mode, the default is cbc mode.", sl@0: "-3 : encrypt using triple DES encryption. This uses 2 keys", sl@0: " generated from the input key. If the input key is less", sl@0: " than 8 characters long, this is equivalent to normal", sl@0: " encryption. Default is triple cbc, -b makes it triple ecb.", sl@0: NULL sl@0: }; sl@0: for (u=(char **)Usage; *u; u++) sl@0: { sl@0: fputs(*u,stderr); sl@0: fputc('\n',stderr); sl@0: } sl@0: sl@0: EXIT(1); sl@0: } sl@0: sl@0: void doencryption(void) sl@0: { sl@0: #ifdef _LIBC sl@0: extern unsigned long time(); sl@0: #endif sl@0: sl@0: register int i; sl@0: DES_key_schedule ks,ks2; sl@0: DES_cblock iv,iv2; sl@0: char *p; sl@0: int num=0,j,k,l,rem,ll,len,last,ex=0; sl@0: DES_cblock kk,k2; sl@0: FILE *O; sl@0: int Exit=0; sl@0: #ifndef OPENSSL_SYS_MSDOS sl@0: static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8]; sl@0: #else sl@0: static unsigned char *buf=NULL,*obuf=NULL; sl@0: sl@0: if (buf == NULL) sl@0: { sl@0: if ( (( buf=OPENSSL_malloc(BUFSIZE+8)) == NULL) || sl@0: ((obuf=OPENSSL_malloc(BUFSIZE+8)) == NULL)) sl@0: { sl@0: fputs("Not enough memory\n",stderr); sl@0: Exit=10; sl@0: goto problems; sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: if (hflag) sl@0: { sl@0: j=(flag3?16:8); sl@0: p=key; sl@0: for (i=0; i= '0')) sl@0: k=(*p-'0')<<4; sl@0: else if ((*p <= 'f') && (*p >= 'a')) sl@0: k=(*p-'a'+10)<<4; sl@0: else if ((*p <= 'F') && (*p >= 'A')) sl@0: k=(*p-'A'+10)<<4; sl@0: else sl@0: { sl@0: fputs("Bad hex key\n",stderr); sl@0: Exit=9; sl@0: goto problems; sl@0: } sl@0: p++; sl@0: if ((*p <= '9') && (*p >= '0')) sl@0: k|=(*p-'0'); sl@0: else if ((*p <= 'f') && (*p >= 'a')) sl@0: k|=(*p-'a'+10); sl@0: else if ((*p <= 'F') && (*p >= 'A')) sl@0: k|=(*p-'A'+10); sl@0: else sl@0: { sl@0: fputs("Bad hex key\n",stderr); sl@0: Exit=9; sl@0: goto problems; sl@0: } sl@0: p++; sl@0: if (i < 8) sl@0: kk[i]=k; sl@0: else sl@0: k2[i-8]=k; sl@0: } sl@0: DES_set_key_unchecked(&k2,&ks2); sl@0: OPENSSL_cleanse(k2,sizeof(k2)); sl@0: } sl@0: else if (longk || flag3) sl@0: { sl@0: if (flag3) sl@0: { sl@0: DES_string_to_2keys(key,&kk,&k2); sl@0: DES_set_key_unchecked(&k2,&ks2); sl@0: OPENSSL_cleanse(k2,sizeof(k2)); sl@0: } sl@0: else sl@0: DES_string_to_key(key,&kk); sl@0: } sl@0: else sl@0: for (i=0; i>=1; sl@0: } sl@0: if (l & 1) sl@0: kk[i]=key[i]&0x7f; sl@0: else sl@0: kk[i]=key[i]|0x80; sl@0: } sl@0: sl@0: DES_set_key_unchecked(&kk,&ks); sl@0: OPENSSL_cleanse(key,sizeof(key)); sl@0: OPENSSL_cleanse(kk,sizeof(kk)); sl@0: /* woops - A bug that does not showup under unix :-( */ sl@0: memset(iv,0,sizeof(iv)); sl@0: memset(iv2,0,sizeof(iv2)); sl@0: sl@0: l=1; sl@0: rem=0; sl@0: /* first read */ sl@0: if (eflag || (!dflag && cflag)) sl@0: { sl@0: for (;;) sl@0: { sl@0: num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN); sl@0: l+=rem; sl@0: num+=rem; sl@0: if (l < 0) sl@0: { sl@0: perror("read error"); sl@0: Exit=6; sl@0: goto problems; sl@0: } sl@0: sl@0: rem=l%8; sl@0: len=l-rem; sl@0: if (feof(DES_IN)) sl@0: { sl@0: for (i=7-rem; i>0; i--) sl@0: RAND_pseudo_bytes(buf + l++, 1); sl@0: buf[l++]=rem; sl@0: ex=1; sl@0: len+=rem; sl@0: } sl@0: else sl@0: l-=rem; sl@0: sl@0: if (cflag) sl@0: { sl@0: DES_cbc_cksum(buf,&cksum, sl@0: (long)len,&ks,&cksum); sl@0: if (!eflag) sl@0: { sl@0: if (feof(DES_IN)) break; sl@0: else continue; sl@0: } sl@0: } sl@0: sl@0: if (bflag && !flag3) sl@0: for (i=0; i= 8) memcpy(iv,&(obuf[l-8]),8); sl@0: } sl@0: if (rem) memcpy(buf,&(buf[l]),(unsigned int)rem); sl@0: sl@0: i=0; sl@0: while (i < l) sl@0: { sl@0: if (uflag) sl@0: j=uufwrite(obuf,1,(unsigned int)l-i, sl@0: DES_OUT); sl@0: else sl@0: j=fwrite(obuf,1,(unsigned int)l-i, sl@0: DES_OUT); sl@0: if (j == -1) sl@0: { sl@0: perror("Write error"); sl@0: Exit=7; sl@0: goto problems; sl@0: } sl@0: i+=j; sl@0: } sl@0: if (feof(DES_IN)) sl@0: { sl@0: if (uflag) uufwriteEnd(DES_OUT); sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: else /* decrypt */ sl@0: { sl@0: ex=1; sl@0: for (;;) sl@0: { sl@0: if (ex) { sl@0: if (uflag) sl@0: l=uufread(buf,1,BUFSIZE,DES_IN); sl@0: else sl@0: l=fread(buf,1,BUFSIZE,DES_IN); sl@0: ex=0; sl@0: rem=l%8; sl@0: l-=rem; sl@0: } sl@0: if (l < 0) sl@0: { sl@0: perror("read error"); sl@0: Exit=6; sl@0: goto problems; sl@0: } sl@0: sl@0: if (bflag && !flag3) sl@0: for (i=0; i= 8) memcpy(iv,&(buf[l-8]),8); sl@0: } sl@0: sl@0: if (uflag) sl@0: ll=uufread(&(buf[rem]),1,BUFSIZE,DES_IN); sl@0: else sl@0: ll=fread(&(buf[rem]),1,BUFSIZE,DES_IN); sl@0: ll+=rem; sl@0: rem=ll%8; sl@0: ll-=rem; sl@0: if (feof(DES_IN) && (ll == 0)) sl@0: { sl@0: last=obuf[l-1]; sl@0: sl@0: if ((last > 7) || (last < 0)) sl@0: { sl@0: fputs("The file was not decrypted correctly.\n", sl@0: stderr); sl@0: Exit=8; sl@0: last=0; sl@0: } sl@0: l=l-8+last; sl@0: } sl@0: i=0; sl@0: if (cflag) DES_cbc_cksum(obuf, sl@0: (DES_cblock *)cksum,(long)l/8*8,&ks, sl@0: (DES_cblock *)cksum); sl@0: while (i != l) sl@0: { sl@0: j=fwrite(obuf,1,(unsigned int)l-i,DES_OUT); sl@0: if (j == -1) sl@0: { sl@0: perror("Write error"); sl@0: Exit=7; sl@0: goto problems; sl@0: } sl@0: i+=j; sl@0: } sl@0: l=ll; sl@0: if ((l == 0) && feof(DES_IN)) break; sl@0: } sl@0: } sl@0: if (cflag) sl@0: { sl@0: l=0; sl@0: if (cksumname[0] != '\0') sl@0: { sl@0: if ((O=fopen(cksumname,"w")) != NULL) sl@0: { sl@0: CKSUM_OUT=O; sl@0: l=1; sl@0: } sl@0: } sl@0: for (i=0; i<8; i++) sl@0: fprintf(CKSUM_OUT,"%02X",cksum[i]); sl@0: fprintf(CKSUM_OUT,"\n"); sl@0: if (l) fclose(CKSUM_OUT); sl@0: } sl@0: problems: sl@0: OPENSSL_cleanse(buf,sizeof(buf)); sl@0: OPENSSL_cleanse(obuf,sizeof(obuf)); sl@0: OPENSSL_cleanse(&ks,sizeof(ks)); sl@0: OPENSSL_cleanse(&ks2,sizeof(ks2)); sl@0: OPENSSL_cleanse(iv,sizeof(iv)); sl@0: OPENSSL_cleanse(iv2,sizeof(iv2)); sl@0: OPENSSL_cleanse(kk,sizeof(kk)); sl@0: OPENSSL_cleanse(k2,sizeof(k2)); sl@0: OPENSSL_cleanse(uubuf,sizeof(uubuf)); sl@0: OPENSSL_cleanse(b,sizeof(b)); sl@0: OPENSSL_cleanse(bb,sizeof(bb)); sl@0: OPENSSL_cleanse(cksum,sizeof(cksum)); sl@0: if (Exit) EXIT(Exit); sl@0: } sl@0: sl@0: /* We ignore this parameter but it should be > ~50 I believe */ sl@0: int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp) sl@0: { sl@0: int i,j,left,rem,ret=num; sl@0: static int start=1; sl@0: sl@0: if (start) sl@0: { sl@0: fprintf(fp,"begin 600 %s\n", sl@0: (uuname[0] == '\0')?"text.d":uuname); sl@0: start=0; sl@0: } sl@0: sl@0: if (uubufnum) sl@0: { sl@0: if (uubufnum+num < 45) sl@0: { sl@0: memcpy(&(uubuf[uubufnum]),data,(unsigned int)num); sl@0: uubufnum+=num; sl@0: return(num); sl@0: } sl@0: else sl@0: { sl@0: i=45-uubufnum; sl@0: memcpy(&(uubuf[uubufnum]),data,(unsigned int)i); sl@0: j=uuencode((unsigned char *)uubuf,45,b); sl@0: fwrite(b,1,(unsigned int)j,fp); sl@0: uubufnum=0; sl@0: data+=i; sl@0: num-=i; sl@0: } sl@0: } sl@0: sl@0: for (i=0; i<(((int)num)-INUUBUFN); i+=INUUBUFN) sl@0: { sl@0: j=uuencode(&(data[i]),INUUBUFN,b); sl@0: fwrite(b,1,(unsigned int)j,fp); sl@0: } sl@0: rem=(num-i)%45; sl@0: left=(num-i-rem); sl@0: if (left) sl@0: { sl@0: j=uuencode(&(data[i]),left,b); sl@0: fwrite(b,1,(unsigned int)j,fp); sl@0: i+=left; sl@0: } sl@0: if (i != num) sl@0: { sl@0: memcpy(uubuf,&(data[i]),(unsigned int)rem); sl@0: uubufnum=rem; sl@0: } sl@0: return(ret); sl@0: } sl@0: sl@0: void uufwriteEnd(FILE *fp) sl@0: { sl@0: int j; sl@0: static const char *end=" \nend\n"; sl@0: sl@0: if (uubufnum != 0) sl@0: { sl@0: uubuf[uubufnum]='\0'; sl@0: uubuf[uubufnum+1]='\0'; sl@0: uubuf[uubufnum+2]='\0'; sl@0: j=uuencode(uubuf,uubufnum,b); sl@0: fwrite(b,1,(unsigned int)j,fp); sl@0: } sl@0: fwrite(end,1,strlen(end),fp); sl@0: } sl@0: sl@0: /* int size: should always be > ~ 60; I actually ignore this parameter :-) */ sl@0: int uufread(unsigned char *out, int size, unsigned int num, FILE *fp) sl@0: { sl@0: int i,j,tot; sl@0: static int done=0; sl@0: static int valid=0; sl@0: static int start=1; sl@0: sl@0: if (start) sl@0: { sl@0: for (;;) sl@0: { sl@0: b[0]='\0'; sl@0: fgets((char *)b,300,fp); sl@0: if (b[0] == '\0') sl@0: { sl@0: fprintf(stderr,"no 'begin' found in uuencoded input\n"); sl@0: return(-1); sl@0: } sl@0: if (strncmp((char *)b,"begin ",6) == 0) break; sl@0: } sl@0: start=0; sl@0: } sl@0: if (done) return(0); sl@0: tot=0; sl@0: if (valid) sl@0: { sl@0: memcpy(out,bb,(unsigned int)valid); sl@0: tot=valid; sl@0: valid=0; sl@0: } sl@0: for (;;) sl@0: { sl@0: b[0]='\0'; sl@0: fgets((char *)b,300,fp); sl@0: if (b[0] == '\0') break; sl@0: i=strlen((char *)b); sl@0: if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd')) sl@0: { sl@0: done=1; sl@0: while (!feof(fp)) sl@0: { sl@0: fgets((char *)b,300,fp); sl@0: } sl@0: break; sl@0: } sl@0: i=uudecode(b,i,bb); sl@0: if (i < 0) break; sl@0: if ((i+tot+8) > num) sl@0: { sl@0: /* num to copy to make it a multiple of 8 */ sl@0: j=(num/8*8)-tot-8; sl@0: memcpy(&(out[tot]),bb,(unsigned int)j); sl@0: tot+=j; sl@0: memcpy(bb,&(bb[j]),(unsigned int)i-j); sl@0: valid=i-j; sl@0: break; sl@0: } sl@0: memcpy(&(out[tot]),bb,(unsigned int)i); sl@0: tot+=i; sl@0: } sl@0: return(tot); sl@0: } sl@0: sl@0: #define ccc2l(c,l) (l =((DES_LONG)(*((c)++)))<<16, \ sl@0: l|=((DES_LONG)(*((c)++)))<< 8, \ sl@0: l|=((DES_LONG)(*((c)++)))) sl@0: sl@0: #define l2ccc(l,c) (*((c)++)=(unsigned char)(((l)>>16)&0xff), \ sl@0: *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ sl@0: *((c)++)=(unsigned char)(((l) )&0xff)) sl@0: sl@0: sl@0: int uuencode(unsigned char *in, int num, unsigned char *out) sl@0: { sl@0: int j,i,n,tot=0; sl@0: DES_LONG l; sl@0: register unsigned char *p; sl@0: p=out; sl@0: sl@0: for (j=0; j num) sl@0: i=(num-j); sl@0: else i=45; sl@0: *(p++)=i+' '; sl@0: for (n=0; n>18)&0x3f)+' '; sl@0: *(p++)=((l>>12)&0x3f)+' '; sl@0: *(p++)=((l>> 6)&0x3f)+' '; sl@0: *(p++)=((l )&0x3f)+' '; sl@0: tot+=4; sl@0: } sl@0: *(p++)='\n'; sl@0: tot+=2; sl@0: } sl@0: *p='\0'; sl@0: l=0; sl@0: return(tot); sl@0: } sl@0: sl@0: int uudecode(unsigned char *in, int num, unsigned char *out) sl@0: { sl@0: int j,i,k; sl@0: unsigned int n=0,space=0; sl@0: DES_LONG l; sl@0: DES_LONG w,x,y,z; sl@0: unsigned int blank=(unsigned int)'\n'-' '; sl@0: sl@0: for (j=0; j 60) sl@0: { sl@0: fprintf(stderr,"uuencoded line length too long\n"); sl@0: return(-1); sl@0: } sl@0: j++; sl@0: sl@0: for (i=0; i 63) || (x > 63) || (y > 63) || (z > 63)) sl@0: { sl@0: k=0; sl@0: if (w == blank) k=1; sl@0: if (x == blank) k=2; sl@0: if (y == blank) k=3; sl@0: if (z == blank) k=4; sl@0: space=1; sl@0: switch (k) { sl@0: case 1: w=0; in--; sl@0: case 2: x=0; in--; sl@0: case 3: y=0; in--; sl@0: case 4: z=0; in--; sl@0: break; sl@0: case 0: sl@0: space=0; sl@0: fprintf(stderr,"bad uuencoded data values\n"); sl@0: w=x=y=z=0; sl@0: return(-1); sl@0: break; sl@0: } sl@0: } sl@0: l=(w<<18)|(x<<12)|(y<< 6)|(z ); sl@0: l2ccc(l,out); sl@0: } sl@0: if (*(in++) != '\n') sl@0: { sl@0: fprintf(stderr,"missing nl in uuencoded line\n"); sl@0: w=x=y=z=0; sl@0: return(-1); sl@0: } sl@0: j++; sl@0: } sl@0: *out='\0'; sl@0: w=x=y=z=0; sl@0: return(n); sl@0: }