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