1*2fde3a48SSky Liu /* $NetBSD: uuencode.c,v 1.16 2014/09/06 18:58:35 dholland Exp $ */
2*2fde3a48SSky Liu
3*2fde3a48SSky Liu /*-
4*2fde3a48SSky Liu * Copyright (c) 1983, 1993
5*2fde3a48SSky Liu * The Regents of the University of California. All rights reserved.
6*2fde3a48SSky Liu *
7*2fde3a48SSky Liu * Redistribution and use in source and binary forms, with or without
8*2fde3a48SSky Liu * modification, are permitted provided that the following conditions
9*2fde3a48SSky Liu * are met:
10*2fde3a48SSky Liu * 1. Redistributions of source code must retain the above copyright
11*2fde3a48SSky Liu * notice, this list of conditions and the following disclaimer.
12*2fde3a48SSky Liu * 2. Redistributions in binary form must reproduce the above copyright
13*2fde3a48SSky Liu * notice, this list of conditions and the following disclaimer in the
14*2fde3a48SSky Liu * documentation and/or other materials provided with the distribution.
15*2fde3a48SSky Liu * 3. Neither the name of the University nor the names of its contributors
16*2fde3a48SSky Liu * may be used to endorse or promote products derived from this software
17*2fde3a48SSky Liu * without specific prior written permission.
18*2fde3a48SSky Liu *
19*2fde3a48SSky Liu * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*2fde3a48SSky Liu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*2fde3a48SSky Liu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*2fde3a48SSky Liu * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*2fde3a48SSky Liu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*2fde3a48SSky Liu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*2fde3a48SSky Liu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*2fde3a48SSky Liu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*2fde3a48SSky Liu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*2fde3a48SSky Liu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*2fde3a48SSky Liu * SUCH DAMAGE.
30*2fde3a48SSky Liu */
31*2fde3a48SSky Liu
32*2fde3a48SSky Liu #include <sys/cdefs.h>
33*2fde3a48SSky Liu #ifndef lint
34*2fde3a48SSky Liu __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
35*2fde3a48SSky Liu The Regents of the University of California. All rights reserved.");
36*2fde3a48SSky Liu #endif /* not lint */
37*2fde3a48SSky Liu
38*2fde3a48SSky Liu #ifndef lint
39*2fde3a48SSky Liu #if 0
40*2fde3a48SSky Liu static char sccsid[] = "@(#)uuencode.c 8.2 (Berkeley) 4/2/94";
41*2fde3a48SSky Liu #else
42*2fde3a48SSky Liu __RCSID("$NetBSD: uuencode.c,v 1.16 2014/09/06 18:58:35 dholland Exp $");
43*2fde3a48SSky Liu #endif
44*2fde3a48SSky Liu #endif /* not lint */
45*2fde3a48SSky Liu
46*2fde3a48SSky Liu /*
47*2fde3a48SSky Liu * uuencode [input] output
48*2fde3a48SSky Liu *
49*2fde3a48SSky Liu * Encode a file so it can be mailed to a remote system.
50*2fde3a48SSky Liu */
51*2fde3a48SSky Liu #include <sys/types.h>
52*2fde3a48SSky Liu #include <sys/stat.h>
53*2fde3a48SSky Liu #include <netinet/in.h>
54*2fde3a48SSky Liu #include <err.h>
55*2fde3a48SSky Liu #include <errno.h>
56*2fde3a48SSky Liu #include <locale.h>
57*2fde3a48SSky Liu #include <resolv.h>
58*2fde3a48SSky Liu #include <stdio.h>
59*2fde3a48SSky Liu #include <stdlib.h>
60*2fde3a48SSky Liu #include <string.h>
61*2fde3a48SSky Liu #include <unistd.h>
62*2fde3a48SSky Liu
63*2fde3a48SSky Liu static void encode(void);
64*2fde3a48SSky Liu static void base64_encode(void);
65*2fde3a48SSky Liu __dead static void usage(void);
66*2fde3a48SSky Liu
67*2fde3a48SSky Liu int
main(int argc,char * argv[])68*2fde3a48SSky Liu main(int argc, char *argv[])
69*2fde3a48SSky Liu {
70*2fde3a48SSky Liu struct stat sb;
71*2fde3a48SSky Liu int base64, ch, mode;
72*2fde3a48SSky Liu
73*2fde3a48SSky Liu mode = 0;
74*2fde3a48SSky Liu base64 = 0;
75*2fde3a48SSky Liu setlocale(LC_ALL, "");
76*2fde3a48SSky Liu setprogname(argv[0]);
77*2fde3a48SSky Liu
78*2fde3a48SSky Liu while ((ch = getopt(argc, argv, "m")) != -1) {
79*2fde3a48SSky Liu switch(ch) {
80*2fde3a48SSky Liu case 'm':
81*2fde3a48SSky Liu base64 = 1;
82*2fde3a48SSky Liu break;
83*2fde3a48SSky Liu default:
84*2fde3a48SSky Liu usage();
85*2fde3a48SSky Liu }
86*2fde3a48SSky Liu }
87*2fde3a48SSky Liu argv += optind;
88*2fde3a48SSky Liu argc -= optind;
89*2fde3a48SSky Liu
90*2fde3a48SSky Liu switch(argc) {
91*2fde3a48SSky Liu case 2: /* optional first argument is input file */
92*2fde3a48SSky Liu if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb))
93*2fde3a48SSky Liu err(1, "%s", *argv);
94*2fde3a48SSky Liu #define RWX (S_IRWXU|S_IRWXG|S_IRWXO)
95*2fde3a48SSky Liu mode = sb.st_mode & RWX;
96*2fde3a48SSky Liu ++argv;
97*2fde3a48SSky Liu break;
98*2fde3a48SSky Liu case 1:
99*2fde3a48SSky Liu #define RW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
100*2fde3a48SSky Liu mode = RW & ~umask(RW);
101*2fde3a48SSky Liu break;
102*2fde3a48SSky Liu case 0:
103*2fde3a48SSky Liu default:
104*2fde3a48SSky Liu usage();
105*2fde3a48SSky Liu }
106*2fde3a48SSky Liu
107*2fde3a48SSky Liu if (base64) {
108*2fde3a48SSky Liu (void)printf("begin-base64 %o %s\n", mode, *argv);
109*2fde3a48SSky Liu base64_encode();
110*2fde3a48SSky Liu (void)printf("====\n");
111*2fde3a48SSky Liu } else {
112*2fde3a48SSky Liu (void)printf("begin %o %s\n", mode, *argv);
113*2fde3a48SSky Liu encode();
114*2fde3a48SSky Liu (void)printf("end\n");
115*2fde3a48SSky Liu }
116*2fde3a48SSky Liu
117*2fde3a48SSky Liu if (ferror(stdout))
118*2fde3a48SSky Liu err(1, "write error");
119*2fde3a48SSky Liu exit(0);
120*2fde3a48SSky Liu }
121*2fde3a48SSky Liu
122*2fde3a48SSky Liu /* ENC is the basic 1 character encoding function to make a char printing */
123*2fde3a48SSky Liu #define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
124*2fde3a48SSky Liu
125*2fde3a48SSky Liu /*
126*2fde3a48SSky Liu * copy from in to out, encoding in base64 as you go along.
127*2fde3a48SSky Liu */
128*2fde3a48SSky Liu static void
base64_encode(void)129*2fde3a48SSky Liu base64_encode(void)
130*2fde3a48SSky Liu {
131*2fde3a48SSky Liu /*
132*2fde3a48SSky Liu * Output must fit into 80 columns, chunks come in 4, leave 1.
133*2fde3a48SSky Liu */
134*2fde3a48SSky Liu #define GROUPS ((70 / 4) - 1)
135*2fde3a48SSky Liu unsigned char buf[3];
136*2fde3a48SSky Liu char buf2[sizeof(buf) * 2 + 1];
137*2fde3a48SSky Liu size_t n;
138*2fde3a48SSky Liu int rv, sequence;
139*2fde3a48SSky Liu
140*2fde3a48SSky Liu sequence = 0;
141*2fde3a48SSky Liu
142*2fde3a48SSky Liu while ((n = fread(buf, 1, sizeof(buf), stdin))) {
143*2fde3a48SSky Liu ++sequence;
144*2fde3a48SSky Liu rv = b64_ntop(buf, n, buf2, (sizeof(buf2) / sizeof(buf2[0])));
145*2fde3a48SSky Liu if (rv == -1)
146*2fde3a48SSky Liu errx(1, "b64_ntop: error encoding base64");
147*2fde3a48SSky Liu printf("%s%s", buf2, (sequence % GROUPS) ? "" : "\n");
148*2fde3a48SSky Liu }
149*2fde3a48SSky Liu if (sequence % GROUPS)
150*2fde3a48SSky Liu printf("\n");
151*2fde3a48SSky Liu }
152*2fde3a48SSky Liu
153*2fde3a48SSky Liu /*
154*2fde3a48SSky Liu * copy from in to out, encoding as you go along.
155*2fde3a48SSky Liu */
156*2fde3a48SSky Liu static void
encode(void)157*2fde3a48SSky Liu encode(void)
158*2fde3a48SSky Liu {
159*2fde3a48SSky Liu int ch, n;
160*2fde3a48SSky Liu char *p;
161*2fde3a48SSky Liu char buf[80];
162*2fde3a48SSky Liu
163*2fde3a48SSky Liu while ((n = fread(buf, 1, 45, stdin)) > 0) {
164*2fde3a48SSky Liu ch = ENC(n);
165*2fde3a48SSky Liu if (putchar(ch) == EOF)
166*2fde3a48SSky Liu break;
167*2fde3a48SSky Liu for (p = buf; n > 0; n -= 3, p += 3) {
168*2fde3a48SSky Liu ch = *p >> 2;
169*2fde3a48SSky Liu ch = ENC(ch);
170*2fde3a48SSky Liu if (putchar(ch) == EOF)
171*2fde3a48SSky Liu break;
172*2fde3a48SSky Liu ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017);
173*2fde3a48SSky Liu ch = ENC(ch);
174*2fde3a48SSky Liu if (putchar(ch) == EOF)
175*2fde3a48SSky Liu break;
176*2fde3a48SSky Liu ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03);
177*2fde3a48SSky Liu ch = ENC(ch);
178*2fde3a48SSky Liu if (putchar(ch) == EOF)
179*2fde3a48SSky Liu break;
180*2fde3a48SSky Liu ch = p[2] & 077;
181*2fde3a48SSky Liu ch = ENC(ch);
182*2fde3a48SSky Liu if (putchar(ch) == EOF)
183*2fde3a48SSky Liu break;
184*2fde3a48SSky Liu }
185*2fde3a48SSky Liu if (putchar('\n') == EOF)
186*2fde3a48SSky Liu break;
187*2fde3a48SSky Liu }
188*2fde3a48SSky Liu if (ferror(stdin))
189*2fde3a48SSky Liu err(1, "read error.");
190*2fde3a48SSky Liu ch = ENC('\0');
191*2fde3a48SSky Liu (void)putchar(ch);
192*2fde3a48SSky Liu (void)putchar('\n');
193*2fde3a48SSky Liu }
194*2fde3a48SSky Liu
195*2fde3a48SSky Liu static void
usage(void)196*2fde3a48SSky Liu usage(void)
197*2fde3a48SSky Liu {
198*2fde3a48SSky Liu (void)fprintf(stderr,
199*2fde3a48SSky Liu "usage: %s [-m] [inputfile] headername > encodedfile\n",
200*2fde3a48SSky Liu getprogname());
201*2fde3a48SSky Liu exit(1);
202*2fde3a48SSky Liu }
203