xref: /csrg-svn/usr.bin/uudecode/uudecode.c (revision 13681)
1*13681Ssam #ifndef lint
2*13681Ssam static char sccsid[] = "@(#)uudecode.c	5.1 (Berkeley) 07/02/83";
3*13681Ssam #endif
4*13681Ssam 
5*13681Ssam /*
6*13681Ssam  * uudecode [input]
7*13681Ssam  *
8*13681Ssam  * create the specified file, decoding as you go.
9*13681Ssam  * used with uuencode.
10*13681Ssam  */
11*13681Ssam #include <stdio.h>
12*13681Ssam #include <pwd.h>
13*13681Ssam #include <sys/types.h>
14*13681Ssam #include <sys/stat.h>
15*13681Ssam 
16*13681Ssam /* single character decode */
17*13681Ssam #define DEC(c)	(((c) - ' ') & 077)
18*13681Ssam 
19*13681Ssam main(argc, argv)
20*13681Ssam char **argv;
21*13681Ssam {
22*13681Ssam 	FILE *in, *out;
23*13681Ssam 	struct stat sbuf;
24*13681Ssam 	int mode;
25*13681Ssam 	char dest[128];
26*13681Ssam 	char buf[80];
27*13681Ssam 
28*13681Ssam 	/* optional input arg */
29*13681Ssam 	if (argc > 1) {
30*13681Ssam 		if ((in = fopen(argv[1], "r")) == NULL) {
31*13681Ssam 			perror(argv[1]);
32*13681Ssam 			exit(1);
33*13681Ssam 		}
34*13681Ssam 		argv++; argc--;
35*13681Ssam 	} else
36*13681Ssam 		in = stdin;
37*13681Ssam 
38*13681Ssam 	if (argc != 1) {
39*13681Ssam 		printf("Usage: uudecode [infile]\n");
40*13681Ssam 		exit(2);
41*13681Ssam 	}
42*13681Ssam 
43*13681Ssam 	/* search for header line */
44*13681Ssam 	for (;;) {
45*13681Ssam 		if (fgets(buf, sizeof buf, in) == NULL) {
46*13681Ssam 			fprintf(stderr, "No begin line\n");
47*13681Ssam 			exit(3);
48*13681Ssam 		}
49*13681Ssam 		if (strncmp(buf, "begin ", 6) == 0)
50*13681Ssam 			break;
51*13681Ssam 	}
52*13681Ssam 	sscanf(buf, "begin %o %s", &mode, dest);
53*13681Ssam 
54*13681Ssam 	/* handle ~user/file format */
55*13681Ssam 	if (dest[0] == '~') {
56*13681Ssam 		char *sl;
57*13681Ssam 		struct passwd *getpwnam();
58*13681Ssam 		char *index();
59*13681Ssam 		struct passwd *user;
60*13681Ssam 		char dnbuf[100];
61*13681Ssam 
62*13681Ssam 		sl = index(dest, '/');
63*13681Ssam 		if (sl == NULL) {
64*13681Ssam 			fprintf(stderr, "Illegal ~user\n");
65*13681Ssam 			exit(3);
66*13681Ssam 		}
67*13681Ssam 		*sl++ = 0;
68*13681Ssam 		user = getpwnam(dest+1);
69*13681Ssam 		if (user == NULL) {
70*13681Ssam 			fprintf(stderr, "No such user as %s\n", dest);
71*13681Ssam 			exit(4);
72*13681Ssam 		}
73*13681Ssam 		strcpy(dnbuf, user->pw_dir);
74*13681Ssam 		strcat(dnbuf, "/");
75*13681Ssam 		strcat(dnbuf, sl);
76*13681Ssam 		strcpy(dest, dnbuf);
77*13681Ssam 	}
78*13681Ssam 
79*13681Ssam 	/* create output file */
80*13681Ssam 	out = fopen(dest, "w");
81*13681Ssam 	if (out == NULL) {
82*13681Ssam 		perror(dest);
83*13681Ssam 		exit(4);
84*13681Ssam 	}
85*13681Ssam 	chmod(dest, mode);
86*13681Ssam 
87*13681Ssam 	decode(in, out);
88*13681Ssam 
89*13681Ssam 	if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
90*13681Ssam 		fprintf(stderr, "No end line\n");
91*13681Ssam 		exit(5);
92*13681Ssam 	}
93*13681Ssam 	exit(0);
94*13681Ssam }
95*13681Ssam 
96*13681Ssam /*
97*13681Ssam  * copy from in to out, decoding as you go along.
98*13681Ssam  */
99*13681Ssam decode(in, out)
100*13681Ssam FILE *in;
101*13681Ssam FILE *out;
102*13681Ssam {
103*13681Ssam 	char buf[80];
104*13681Ssam 	char *bp;
105*13681Ssam 	int n;
106*13681Ssam 
107*13681Ssam 	for (;;) {
108*13681Ssam 		/* for each input line */
109*13681Ssam 		if (fgets(buf, sizeof buf, in) == NULL) {
110*13681Ssam 			printf("Short file\n");
111*13681Ssam 			exit(10);
112*13681Ssam 		}
113*13681Ssam 		n = DEC(buf[0]);
114*13681Ssam 		if (n <= 0)
115*13681Ssam 			break;
116*13681Ssam 
117*13681Ssam 		bp = &buf[1];
118*13681Ssam 		while (n > 0) {
119*13681Ssam 			outdec(bp, out, n);
120*13681Ssam 			bp += 4;
121*13681Ssam 			n -= 3;
122*13681Ssam 		}
123*13681Ssam 	}
124*13681Ssam }
125*13681Ssam 
126*13681Ssam /*
127*13681Ssam  * output a group of 3 bytes (4 input characters).
128*13681Ssam  * the input chars are pointed to by p, they are to
129*13681Ssam  * be output to file f.  n is used to tell us not to
130*13681Ssam  * output all of them at the end of the file.
131*13681Ssam  */
132*13681Ssam outdec(p, f, n)
133*13681Ssam char *p;
134*13681Ssam FILE *f;
135*13681Ssam {
136*13681Ssam 	int c1, c2, c3;
137*13681Ssam 
138*13681Ssam 	c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
139*13681Ssam 	c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
140*13681Ssam 	c3 = DEC(p[2]) << 6 | DEC(p[3]);
141*13681Ssam 	if (n >= 1)
142*13681Ssam 		putc(c1, f);
143*13681Ssam 	if (n >= 2)
144*13681Ssam 		putc(c2, f);
145*13681Ssam 	if (n >= 3)
146*13681Ssam 		putc(c3, f);
147*13681Ssam }
148*13681Ssam 
149*13681Ssam 
150*13681Ssam /* fr: like read but stdio */
151*13681Ssam int
152*13681Ssam fr(fd, buf, cnt)
153*13681Ssam FILE *fd;
154*13681Ssam char *buf;
155*13681Ssam int cnt;
156*13681Ssam {
157*13681Ssam 	int c, i;
158*13681Ssam 
159*13681Ssam 	for (i=0; i<cnt; i++) {
160*13681Ssam 		c = getc(fd);
161*13681Ssam 		if (c == EOF)
162*13681Ssam 			return(i);
163*13681Ssam 		buf[i] = c;
164*13681Ssam 	}
165*13681Ssam 	return (cnt);
166*13681Ssam }
167*13681Ssam 
168*13681Ssam /*
169*13681Ssam  * Return the ptr in sp at which the character c appears;
170*13681Ssam  * NULL if not found
171*13681Ssam  */
172*13681Ssam 
173*13681Ssam #define	NULL	0
174*13681Ssam 
175*13681Ssam char *
176*13681Ssam index(sp, c)
177*13681Ssam register char *sp, c;
178*13681Ssam {
179*13681Ssam 	do {
180*13681Ssam 		if (*sp == c)
181*13681Ssam 			return(sp);
182*13681Ssam 	} while (*sp++);
183*13681Ssam 	return(NULL);
184*13681Ssam }
185