-x flag
[unix-history] / usr / src / usr.bin / uudecode / uudecode.c
CommitLineData
4c7e459f
SL
1#ifndef lint
2static char sccsid[] = "@(#)uudecode.c 5.1 (Berkeley) %G%";
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
19main(argc, argv)
20char **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 */
99decode(in, out)
100FILE *in;
101FILE *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 */
132outdec(p, f, n)
133char *p;
134FILE *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 */
151int
152fr(fd, buf, cnt)
153FILE *fd;
154char *buf;
155int 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
175char *
176index(sp, c)
177register char *sp, c;
178{
179 do {
180 if (*sp == c)
181 return(sp);
182 } while (*sp++);
183 return(NULL);
184}