1*34953Sbostic /* 2*34953Sbostic * Copyright (c) 1983 Regents of the University of California. 3*34953Sbostic * All rights reserved. 4*34953Sbostic * 5*34953Sbostic * Redistribution and use in source and binary forms are permitted 6*34953Sbostic * provided that the above copyright notice and this paragraph are 7*34953Sbostic * duplicated in all such forms and that any documentation, 8*34953Sbostic * advertising materials, and other materials related to such 9*34953Sbostic * distribution and use acknowledge that the software was developed 10*34953Sbostic * by the University of California, Berkeley. The name of the 11*34953Sbostic * University may not be used to endorse or promote products derived 12*34953Sbostic * from this software without specific prior written permission. 13*34953Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34953Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34953Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16*34953Sbostic */ 17*34953Sbostic 1813681Ssam #ifndef lint 19*34953Sbostic static char sccsid[] = "@(#)uudecode.c 5.4 (Berkeley) 07/06/88"; 20*34953Sbostic #endif /* not lint */ 2113681Ssam 2213681Ssam /* 2313681Ssam * uudecode [input] 2413681Ssam * 2513681Ssam * create the specified file, decoding as you go. 2613681Ssam * used with uuencode. 2713681Ssam */ 2813681Ssam #include <stdio.h> 2913681Ssam #include <pwd.h> 3013681Ssam #include <sys/types.h> 3113681Ssam #include <sys/stat.h> 3213681Ssam 3313681Ssam /* single character decode */ 3413681Ssam #define DEC(c) (((c) - ' ') & 077) 3513681Ssam 3613681Ssam main(argc, argv) 3713681Ssam char **argv; 3813681Ssam { 3913681Ssam FILE *in, *out; 4013681Ssam int mode; 4113681Ssam char dest[128]; 4213681Ssam char buf[80]; 4313681Ssam 4413681Ssam /* optional input arg */ 4513681Ssam if (argc > 1) { 4613681Ssam if ((in = fopen(argv[1], "r")) == NULL) { 4713681Ssam perror(argv[1]); 4813681Ssam exit(1); 4913681Ssam } 5013681Ssam argv++; argc--; 5113681Ssam } else 5213681Ssam in = stdin; 5313681Ssam 5413681Ssam if (argc != 1) { 5513681Ssam printf("Usage: uudecode [infile]\n"); 5613681Ssam exit(2); 5713681Ssam } 5813681Ssam 5913681Ssam /* search for header line */ 6013681Ssam for (;;) { 6113681Ssam if (fgets(buf, sizeof buf, in) == NULL) { 6213681Ssam fprintf(stderr, "No begin line\n"); 6313681Ssam exit(3); 6413681Ssam } 6513681Ssam if (strncmp(buf, "begin ", 6) == 0) 6613681Ssam break; 6713681Ssam } 6813681Ssam sscanf(buf, "begin %o %s", &mode, dest); 6913681Ssam 7013681Ssam /* handle ~user/file format */ 7113681Ssam if (dest[0] == '~') { 7213681Ssam char *sl; 7313681Ssam struct passwd *getpwnam(); 7413681Ssam char *index(); 7513681Ssam struct passwd *user; 7613681Ssam char dnbuf[100]; 7713681Ssam 7813681Ssam sl = index(dest, '/'); 7913681Ssam if (sl == NULL) { 8013681Ssam fprintf(stderr, "Illegal ~user\n"); 8113681Ssam exit(3); 8213681Ssam } 8313681Ssam *sl++ = 0; 8413681Ssam user = getpwnam(dest+1); 8513681Ssam if (user == NULL) { 8613681Ssam fprintf(stderr, "No such user as %s\n", dest); 8713681Ssam exit(4); 8813681Ssam } 8913681Ssam strcpy(dnbuf, user->pw_dir); 9013681Ssam strcat(dnbuf, "/"); 9113681Ssam strcat(dnbuf, sl); 9213681Ssam strcpy(dest, dnbuf); 9313681Ssam } 9413681Ssam 9513681Ssam /* create output file */ 9613681Ssam out = fopen(dest, "w"); 9713681Ssam if (out == NULL) { 9813681Ssam perror(dest); 9913681Ssam exit(4); 10013681Ssam } 10113681Ssam chmod(dest, mode); 10213681Ssam 10313681Ssam decode(in, out); 10413681Ssam 10513681Ssam if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) { 10613681Ssam fprintf(stderr, "No end line\n"); 10713681Ssam exit(5); 10813681Ssam } 10913681Ssam exit(0); 11013681Ssam } 11113681Ssam 11213681Ssam /* 11313681Ssam * copy from in to out, decoding as you go along. 11413681Ssam */ 11513681Ssam decode(in, out) 11613681Ssam FILE *in; 11713681Ssam FILE *out; 11813681Ssam { 11913681Ssam char buf[80]; 12013681Ssam char *bp; 12113681Ssam int n; 12213681Ssam 12313681Ssam for (;;) { 12413681Ssam /* for each input line */ 12513681Ssam if (fgets(buf, sizeof buf, in) == NULL) { 12613681Ssam printf("Short file\n"); 12713681Ssam exit(10); 12813681Ssam } 12913681Ssam n = DEC(buf[0]); 13013681Ssam if (n <= 0) 13113681Ssam break; 13213681Ssam 13313681Ssam bp = &buf[1]; 13413681Ssam while (n > 0) { 13513681Ssam outdec(bp, out, n); 13613681Ssam bp += 4; 13713681Ssam n -= 3; 13813681Ssam } 13913681Ssam } 14013681Ssam } 14113681Ssam 14213681Ssam /* 14313681Ssam * output a group of 3 bytes (4 input characters). 14413681Ssam * the input chars are pointed to by p, they are to 14513681Ssam * be output to file f. n is used to tell us not to 14613681Ssam * output all of them at the end of the file. 14713681Ssam */ 14813681Ssam outdec(p, f, n) 14913681Ssam char *p; 15013681Ssam FILE *f; 15113681Ssam { 15213681Ssam int c1, c2, c3; 15313681Ssam 15413681Ssam c1 = DEC(*p) << 2 | DEC(p[1]) >> 4; 15513681Ssam c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2; 15613681Ssam c3 = DEC(p[2]) << 6 | DEC(p[3]); 15713681Ssam if (n >= 1) 15813681Ssam putc(c1, f); 15913681Ssam if (n >= 2) 16013681Ssam putc(c2, f); 16113681Ssam if (n >= 3) 16213681Ssam putc(c3, f); 16313681Ssam } 16413681Ssam 16513681Ssam 16613681Ssam /* fr: like read but stdio */ 16713681Ssam int 16813681Ssam fr(fd, buf, cnt) 16913681Ssam FILE *fd; 17013681Ssam char *buf; 17113681Ssam int cnt; 17213681Ssam { 17313681Ssam int c, i; 17413681Ssam 17513681Ssam for (i=0; i<cnt; i++) { 17613681Ssam c = getc(fd); 17713681Ssam if (c == EOF) 17813681Ssam return(i); 17913681Ssam buf[i] = c; 18013681Ssam } 18113681Ssam return (cnt); 18213681Ssam } 18313681Ssam 18413681Ssam /* 18513681Ssam * Return the ptr in sp at which the character c appears; 18613681Ssam * NULL if not found 18713681Ssam */ 18813681Ssam 18913681Ssam #define NULL 0 19013681Ssam 19113681Ssam char * 19213681Ssam index(sp, c) 19313681Ssam register char *sp, c; 19413681Ssam { 19513681Ssam do { 19613681Ssam if (*sp == c) 19713681Ssam return(sp); 19813681Ssam } while (*sp++); 19913681Ssam return(NULL); 20013681Ssam } 201