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