GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/uuencode/uuencode.c Lines: 0 83 0.0 %
Date: 2017-11-07 Branches: 0 79 0.0 %

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