xref: /csrg-svn/usr.bin/uudecode/uudecode.c (revision 18625)
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