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