1 #ifndef lint 2 static char sccsid[] = "@(#)uudecode.c 5.1 (Berkeley) 07/02/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 } 185