xref: /original-bsd/usr.bin/uuencode/uuencode.c (revision b4971bb3)
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 static char sccsid[] = "@(#)uuencode.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 /*
13  * uuencode [input] output
14  *
15  * Encode a file so it can be mailed to a remote system.
16  */
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <stdio.h>
20 
21 main(argc, argv)
22 	int argc;
23 	char **argv;
24 {
25 	extern int optind;
26 	extern int errno;
27 	struct stat sb;
28 	int mode;
29 	char *strerror();
30 
31 	while (getopt(argc, argv, "") != EOF)
32 		usage();
33 	argv += optind;
34 	argc -= optind;
35 
36 	switch(argc) {
37 	case 2:			/* optional first argument is input file */
38 		if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb)) {
39 			(void)fprintf(stderr, "uuencode: %s: %s.\n",
40 			    *argv, strerror(errno));
41 			exit(1);
42 		}
43 #define	RWX	(S_IRWXU|S_IRWXG|S_IRWXO)
44 		mode = sb.st_mode & RWX;
45 		++argv;
46 		break;
47 	case 1:
48 #define	RW	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
49 		mode = RW & ~umask(RW);
50 		break;
51 	case 0:
52 	default:
53 		usage();
54 	}
55 
56 	(void)printf("begin %o %s\n", mode, *argv);
57 	encode();
58 	(void)printf("end\n");
59 	if (ferror(stdout)) {
60 		(void)fprintf(stderr, "uuencode: write error.\n");
61 		exit(1);
62 	}
63 	exit(0);
64 }
65 
66 /* ENC is the basic 1 character encoding function to make a char printing */
67 #define	ENC(c) ((c) ? ((c) & 077) + ' ': '`')
68 
69 /*
70  * copy from in to out, encoding as you go along.
71  */
72 encode()
73 {
74 	register int ch, n;
75 	register char *p;
76 	char buf[80];
77 
78 	while (n = fread(buf, 1, 45, stdin)) {
79 		ch = ENC(n);
80 		if (putchar(ch) == EOF)
81 			break;
82 		for (p = buf; n > 0; n -= 3, p += 3) {
83 			ch = *p >> 2;
84 			ch = ENC(ch);
85 			if (putchar(ch) == EOF)
86 				break;
87 			ch = (*p << 4) & 060 | (p[1] >> 4) & 017;
88 			ch = ENC(ch);
89 			if (putchar(ch) == EOF)
90 				break;
91 			ch = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
92 			ch = ENC(ch);
93 			if (putchar(ch) == EOF)
94 				break;
95 			ch = p[2] & 077;
96 			ch = ENC(ch);
97 			if (putchar(ch) == EOF)
98 				break;
99 		}
100 		if (putchar('\n') == EOF)
101 			break;
102 	}
103 	if (ferror(stdin)) {
104 		(void)fprintf(stderr, "uuencode: read error.\n");
105 		exit(1);
106 	}
107 	ch = ENC('\0');
108 	(void)putchar(ch);
109 	(void)putchar('\n');
110 }
111 
112 usage()
113 {
114 	(void)fprintf(stderr,"usage: uuencode [infile] remotefile\n");
115 	exit(1);
116 }
117