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