1 /*- 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1983, 1993\n\ 11 The Regents of the University of California. All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)uudecode.c 8.2 (Berkeley) 04/02/94"; 16 #endif /* not lint */ 17 18 /* 19 * uudecode [file ...] 20 * 21 * create the specified file, decoding as you go. 22 * used with uuencode. 23 */ 24 #include <sys/param.h> 25 #include <sys/stat.h> 26 27 #include <pwd.h> 28 #include <stdio.h> 29 #include <string.h> 30 31 char *filename; 32 33 int 34 main(argc, argv) 35 int argc; 36 char *argv[]; 37 { 38 extern int errno; 39 int rval; 40 41 if (*++argv) { 42 rval = 0; 43 do { 44 if (!freopen(filename = *argv, "r", stdin)) { 45 (void)fprintf(stderr, "uudecode: %s: %s\n", 46 *argv, strerror(errno)); 47 rval = 1; 48 continue; 49 } 50 rval |= decode(); 51 } while (*++argv); 52 } else { 53 filename = "stdin"; 54 rval = decode(); 55 } 56 exit(rval); 57 } 58 59 decode() 60 { 61 extern int errno; 62 struct passwd *pw; 63 register int n; 64 register char ch, *p; 65 int mode, n1; 66 char buf[MAXPATHLEN]; 67 68 /* search for header line */ 69 do { 70 if (!fgets(buf, sizeof(buf), stdin)) { 71 (void)fprintf(stderr, 72 "uudecode: %s: no \"begin\" line\n", filename); 73 return(1); 74 } 75 } while (strncmp(buf, "begin ", 6)); 76 (void)sscanf(buf, "begin %o %s", &mode, buf); 77 78 /* handle ~user/file format */ 79 if (buf[0] == '~') { 80 if (!(p = index(buf, '/'))) { 81 (void)fprintf(stderr, "uudecode: %s: illegal ~user.\n", 82 filename); 83 return(1); 84 } 85 *p++ = NULL; 86 if (!(pw = getpwnam(buf + 1))) { 87 (void)fprintf(stderr, "uudecode: %s: no user %s.\n", 88 filename, buf); 89 return(1); 90 } 91 n = strlen(pw->pw_dir); 92 n1 = strlen(p); 93 if (n + n1 + 2 > MAXPATHLEN) { 94 (void)fprintf(stderr, "uudecode: %s: path too long.\n", 95 filename); 96 return(1); 97 } 98 bcopy(p, buf + n + 1, n1 + 1); 99 bcopy(pw->pw_dir, buf, n); 100 buf[n] = '/'; 101 } 102 103 /* create output file, set mode */ 104 if (!freopen(buf, "w", stdout) || 105 fchmod(fileno(stdout), mode&0666)) { 106 (void)fprintf(stderr, "uudecode: %s: %s: %s\n", buf, 107 filename, strerror(errno)); 108 return(1); 109 } 110 111 /* for each input line */ 112 for (;;) { 113 if (!fgets(p = buf, sizeof(buf), stdin)) { 114 (void)fprintf(stderr, "uudecode: %s: short file.\n", 115 filename); 116 return(1); 117 } 118 #define DEC(c) (((c) - ' ') & 077) /* single character decode */ 119 /* 120 * `n' is used to avoid writing out all the characters 121 * at the end of the file. 122 */ 123 if ((n = DEC(*p)) <= 0) 124 break; 125 for (++p; n > 0; p += 4, n -= 3) 126 if (n >= 3) { 127 ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; 128 putchar(ch); 129 ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; 130 putchar(ch); 131 ch = DEC(p[2]) << 6 | DEC(p[3]); 132 putchar(ch); 133 } 134 else { 135 if (n >= 1) { 136 ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; 137 putchar(ch); 138 } 139 if (n >= 2) { 140 ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; 141 putchar(ch); 142 } 143 if (n >= 3) { 144 ch = DEC(p[2]) << 6 | DEC(p[3]); 145 putchar(ch); 146 } 147 } 148 } 149 if (!fgets(buf, sizeof(buf), stdin) || strcmp(buf, "end\n")) { 150 (void)fprintf(stderr, "uudecode: %s: no \"end\" line.\n", 151 filename); 152 return(1); 153 } 154 return(0); 155 } 156 157 usage() 158 { 159 (void)fprintf(stderr, "usage: uudecode [file ...]\n"); 160 exit(1); 161 } 162