|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)uudecode.c 5.10 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * uudecode [file ...]
26: *
27: * create the specified file, decoding as you go.
28: * used with uuencode.
29: */
30: #include <sys/param.h>
31: #include <sys/stat.h>
32: #include <pwd.h>
33: #include <stdio.h>
34: #include <string.h>
35:
36: char *filename;
37:
38: /* ARGSUSED */
39: main(argc, argv)
40: int argc;
41: char **argv;
42: {
43: extern int errno;
44: int rval;
45:
46: if (*++argv) {
47: rval = 0;
48: do {
49: if (!freopen(filename = *argv, "r", stdin)) {
50: (void)fprintf(stderr, "uudecode: %s: %s\n",
51: *argv, strerror(errno));
52: rval = 1;
53: continue;
54: }
55: rval |= decode();
56: } while (*++argv);
57: } else {
58: filename = "stdin";
59: rval = decode();
60: }
61: exit(rval);
62: }
63:
64: decode()
65: {
66: extern int errno;
67: struct passwd *pw;
68: register int n;
69: register char ch, *p;
70: int mode, n1;
71: char buf[MAXPATHLEN];
72:
73: /* search for header line */
74: do {
75: if (!fgets(buf, sizeof(buf), stdin)) {
76: (void)fprintf(stderr,
77: "uudecode: %s: no \"begin\" line\n", filename);
78: return(1);
79: }
80: } while (strncmp(buf, "begin ", 6));
81: (void)sscanf(buf, "begin %o %s", &mode, buf);
82:
83: /* handle ~user/file format */
84: if (buf[0] == '~') {
85: if (!(p = index(buf, '/'))) {
86: (void)fprintf(stderr, "uudecode: %s: illegal ~user.\n",
87: filename);
88: return(1);
89: }
90: *p++ = NULL;
91: if (!(pw = getpwnam(buf + 1))) {
92: (void)fprintf(stderr, "uudecode: %s: no user %s.\n",
93: filename, buf);
94: return(1);
95: }
96: n = strlen(pw->pw_dir);
97: n1 = strlen(p);
98: if (n + n1 + 2 > MAXPATHLEN) {
99: (void)fprintf(stderr, "uudecode: %s: path too long.\n",
100: filename);
101: return(1);
102: }
103: bcopy(p, buf + n + 1, n1 + 1);
104: bcopy(pw->pw_dir, buf, n);
105: buf[n] = '/';
106: }
107:
108: /* create output file, set mode */
109: if (!freopen(buf, "w", stdout) ||
110: fchmod(fileno(stdout), mode&0666)) {
111: (void)fprintf(stderr, "uudecode: %s: %s: %s\n", buf,
112: filename, strerror(errno));
113: return(1);
114: }
115:
116: /* for each input line */
117: for (;;) {
118: if (!fgets(p = buf, sizeof(buf), stdin)) {
119: (void)fprintf(stderr, "uudecode: %s: short file.\n",
120: filename);
121: return(1);
122: }
123: #define DEC(c) (((c) - ' ') & 077) /* single character decode */
124: /*
125: * `n' is used to avoid writing out all the characters
126: * at the end of the file.
127: */
128: if ((n = DEC(*p)) <= 0)
129: break;
130: for (++p; n > 0; p += 4, n -= 3)
131: if (n >= 3) {
132: ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
133: putchar(ch);
134: ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
135: putchar(ch);
136: ch = DEC(p[2]) << 6 | DEC(p[3]);
137: putchar(ch);
138: }
139: else {
140: if (n >= 1) {
141: ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
142: putchar(ch);
143: }
144: if (n >= 2) {
145: ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
146: putchar(ch);
147: }
148: if (n >= 3) {
149: ch = DEC(p[2]) << 6 | DEC(p[3]);
150: putchar(ch);
151: }
152: }
153: }
154: if (!fgets(buf, sizeof(buf), stdin) || strcmp(buf, "end\n")) {
155: (void)fprintf(stderr, "uudecode: %s: no \"end\" line.\n",
156: filename);
157: return(1);
158: }
159: return(0);
160: }
161:
162: usage()
163: {
164: (void)fprintf(stderr, "usage: uudecode [file ...]\n");
165: exit(1);
166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.