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