1*13681Ssam #ifndef lint 2*13681Ssam static char sccsid[] = "@(#)uudecode.c 5.1 (Berkeley) 07/02/83"; 3*13681Ssam #endif 4*13681Ssam 5*13681Ssam /* 6*13681Ssam * uudecode [input] 7*13681Ssam * 8*13681Ssam * create the specified file, decoding as you go. 9*13681Ssam * used with uuencode. 10*13681Ssam */ 11*13681Ssam #include <stdio.h> 12*13681Ssam #include <pwd.h> 13*13681Ssam #include <sys/types.h> 14*13681Ssam #include <sys/stat.h> 15*13681Ssam 16*13681Ssam /* single character decode */ 17*13681Ssam #define DEC(c) (((c) - ' ') & 077) 18*13681Ssam 19*13681Ssam main(argc, argv) 20*13681Ssam char **argv; 21*13681Ssam { 22*13681Ssam FILE *in, *out; 23*13681Ssam struct stat sbuf; 24*13681Ssam int mode; 25*13681Ssam char dest[128]; 26*13681Ssam char buf[80]; 27*13681Ssam 28*13681Ssam /* optional input arg */ 29*13681Ssam if (argc > 1) { 30*13681Ssam if ((in = fopen(argv[1], "r")) == NULL) { 31*13681Ssam perror(argv[1]); 32*13681Ssam exit(1); 33*13681Ssam } 34*13681Ssam argv++; argc--; 35*13681Ssam } else 36*13681Ssam in = stdin; 37*13681Ssam 38*13681Ssam if (argc != 1) { 39*13681Ssam printf("Usage: uudecode [infile]\n"); 40*13681Ssam exit(2); 41*13681Ssam } 42*13681Ssam 43*13681Ssam /* search for header line */ 44*13681Ssam for (;;) { 45*13681Ssam if (fgets(buf, sizeof buf, in) == NULL) { 46*13681Ssam fprintf(stderr, "No begin line\n"); 47*13681Ssam exit(3); 48*13681Ssam } 49*13681Ssam if (strncmp(buf, "begin ", 6) == 0) 50*13681Ssam break; 51*13681Ssam } 52*13681Ssam sscanf(buf, "begin %o %s", &mode, dest); 53*13681Ssam 54*13681Ssam /* handle ~user/file format */ 55*13681Ssam if (dest[0] == '~') { 56*13681Ssam char *sl; 57*13681Ssam struct passwd *getpwnam(); 58*13681Ssam char *index(); 59*13681Ssam struct passwd *user; 60*13681Ssam char dnbuf[100]; 61*13681Ssam 62*13681Ssam sl = index(dest, '/'); 63*13681Ssam if (sl == NULL) { 64*13681Ssam fprintf(stderr, "Illegal ~user\n"); 65*13681Ssam exit(3); 66*13681Ssam } 67*13681Ssam *sl++ = 0; 68*13681Ssam user = getpwnam(dest+1); 69*13681Ssam if (user == NULL) { 70*13681Ssam fprintf(stderr, "No such user as %s\n", dest); 71*13681Ssam exit(4); 72*13681Ssam } 73*13681Ssam strcpy(dnbuf, user->pw_dir); 74*13681Ssam strcat(dnbuf, "/"); 75*13681Ssam strcat(dnbuf, sl); 76*13681Ssam strcpy(dest, dnbuf); 77*13681Ssam } 78*13681Ssam 79*13681Ssam /* create output file */ 80*13681Ssam out = fopen(dest, "w"); 81*13681Ssam if (out == NULL) { 82*13681Ssam perror(dest); 83*13681Ssam exit(4); 84*13681Ssam } 85*13681Ssam chmod(dest, mode); 86*13681Ssam 87*13681Ssam decode(in, out); 88*13681Ssam 89*13681Ssam if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) { 90*13681Ssam fprintf(stderr, "No end line\n"); 91*13681Ssam exit(5); 92*13681Ssam } 93*13681Ssam exit(0); 94*13681Ssam } 95*13681Ssam 96*13681Ssam /* 97*13681Ssam * copy from in to out, decoding as you go along. 98*13681Ssam */ 99*13681Ssam decode(in, out) 100*13681Ssam FILE *in; 101*13681Ssam FILE *out; 102*13681Ssam { 103*13681Ssam char buf[80]; 104*13681Ssam char *bp; 105*13681Ssam int n; 106*13681Ssam 107*13681Ssam for (;;) { 108*13681Ssam /* for each input line */ 109*13681Ssam if (fgets(buf, sizeof buf, in) == NULL) { 110*13681Ssam printf("Short file\n"); 111*13681Ssam exit(10); 112*13681Ssam } 113*13681Ssam n = DEC(buf[0]); 114*13681Ssam if (n <= 0) 115*13681Ssam break; 116*13681Ssam 117*13681Ssam bp = &buf[1]; 118*13681Ssam while (n > 0) { 119*13681Ssam outdec(bp, out, n); 120*13681Ssam bp += 4; 121*13681Ssam n -= 3; 122*13681Ssam } 123*13681Ssam } 124*13681Ssam } 125*13681Ssam 126*13681Ssam /* 127*13681Ssam * output a group of 3 bytes (4 input characters). 128*13681Ssam * the input chars are pointed to by p, they are to 129*13681Ssam * be output to file f. n is used to tell us not to 130*13681Ssam * output all of them at the end of the file. 131*13681Ssam */ 132*13681Ssam outdec(p, f, n) 133*13681Ssam char *p; 134*13681Ssam FILE *f; 135*13681Ssam { 136*13681Ssam int c1, c2, c3; 137*13681Ssam 138*13681Ssam c1 = DEC(*p) << 2 | DEC(p[1]) >> 4; 139*13681Ssam c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2; 140*13681Ssam c3 = DEC(p[2]) << 6 | DEC(p[3]); 141*13681Ssam if (n >= 1) 142*13681Ssam putc(c1, f); 143*13681Ssam if (n >= 2) 144*13681Ssam putc(c2, f); 145*13681Ssam if (n >= 3) 146*13681Ssam putc(c3, f); 147*13681Ssam } 148*13681Ssam 149*13681Ssam 150*13681Ssam /* fr: like read but stdio */ 151*13681Ssam int 152*13681Ssam fr(fd, buf, cnt) 153*13681Ssam FILE *fd; 154*13681Ssam char *buf; 155*13681Ssam int cnt; 156*13681Ssam { 157*13681Ssam int c, i; 158*13681Ssam 159*13681Ssam for (i=0; i<cnt; i++) { 160*13681Ssam c = getc(fd); 161*13681Ssam if (c == EOF) 162*13681Ssam return(i); 163*13681Ssam buf[i] = c; 164*13681Ssam } 165*13681Ssam return (cnt); 166*13681Ssam } 167*13681Ssam 168*13681Ssam /* 169*13681Ssam * Return the ptr in sp at which the character c appears; 170*13681Ssam * NULL if not found 171*13681Ssam */ 172*13681Ssam 173*13681Ssam #define NULL 0 174*13681Ssam 175*13681Ssam char * 176*13681Ssam index(sp, c) 177*13681Ssam register char *sp, c; 178*13681Ssam { 179*13681Ssam do { 180*13681Ssam if (*sp == c) 181*13681Ssam return(sp); 182*13681Ssam } while (*sp++); 183*13681Ssam return(NULL); 184*13681Ssam } 185