4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 1984, 2010, Oracle and/or its affiliates. All rights reserved.
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
29 * Portions of this source code were derived from Berkeley 4.3 BSD
30 * under license from the Regents of the University of California.
34 * uuencode [-m] [input] decode_pathname
36 * Encode a file so it can be mailed to a remote system.
44 #include <sys/types.h>
51 * (Size of TABLE_SIZE octal is large enough to convert a basic 6-bit
54 #define TABLE_SIZE 0x40
57 static unsigned char base64_table_initializer
[] =
58 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
59 "abcdefghijklmnopqrstuvwxyz0123456789+/";
61 static unsigned char encode_table
[TABLE_SIZE
];
63 /* ENC is the basic 1 character encoding function to make a char printing */
64 #define ENC(c) encode_table[(c) & 077]
66 static void encode(FILE *, FILE *, int);
70 main(int argc
, char **argv
)
78 char oline
[PATH_MAX
+ 20];
81 (void) signal(SIGPIPE
, SIG_DFL
);
83 /* Set locale environment variables local definitions */
84 (void) setlocale(LC_ALL
, "");
85 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
86 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
88 (void) textdomain(TEXT_DOMAIN
);
90 while ((c
= getopt(argc
, argv
, "m")) != EOF
)
101 argv
= &argv
[optind
];
103 /* optional 1st argument */
105 if ((in
= fopen(*argv
, "r")) == NULL
) {
115 if ((argc
!= 1) || errflag
) {
116 (void) fprintf(stderr
,
117 gettext("Usage: %s [-m] [infile] remotefile\n"), prog
);
121 /* figure out the input file mode */
123 if (fstat(fileno(in
), &sbuf
) < 0 || !S_ISREG(sbuf
.st_mode
)) {
124 mode
= 0666 & ~umask(0666);
126 mode
= sbuf
.st_mode
& 0777;
130 * encoding varies depending on whether we are
131 * using base64 encoding or the historical algorithm
134 (void) memcpy(encode_table
, base64_table_initializer
,
135 sizeof (encode_table
));
137 for (i
= 0; i
< TABLE_SIZE
; i
++)
138 encode_table
[i
] = (unsigned char)i
+ 0x20;
142 * here's the meat of the whole thing
145 (void) snprintf(oline
, sizeof (oline
), "begin-base64 %lo %s\n",
148 (void) snprintf(oline
, sizeof (oline
), "begin %lo %s\n",
151 if (printf("%s", oline
) < 0) {
156 encode(in
, stdout
, base64flag
);
159 (void) snprintf(oline
, sizeof (oline
), "====\n");
161 (void) snprintf(oline
, sizeof (oline
), "end\n");
163 if (printf("%s", oline
) < 0) {
168 if (ferror(stdout
) != 0 || fclose(stdout
) != 0) {
177 * copy from in to out, encoding as you go along.
180 encode(FILE *in
, FILE *out
, int base64
)
182 unsigned char in_buf
[80];
183 unsigned char out_buf
[112];
184 unsigned char *iptr
, *optr
;
189 /* historical algorithm */
195 /* 1 (up to) 45 character line */
196 n
= fread(iptr
, 1, 45, in
);
200 for (i
= 0; i
< n
; i
+= 3) {
201 *(optr
++) = ENC(*iptr
>> 2);
202 *(optr
++) = ENC((*iptr
<< 4) & 060 |
203 (*(iptr
+ 1) >> 4) & 017);
204 *(optr
++) = ENC((*(iptr
+ 1) << 2) & 074 |
205 (*(iptr
+ 2) >> 6) & 03);
206 *(optr
++) = ENC(*(iptr
+ 2) & 077);
213 (void) fwrite(out_buf
, 1, (size_t)(optr
- out_buf
),
225 /* base64 algorithm */
229 * read must be a multiple of 3 bytes for
230 * this algorithm to work, and also must
231 * be small enough that read_size * (4/3)
232 * will always be 76 bytes or less, since
233 * base64 lines can be no longer than that
235 while ((n
= fread(in_buf
, 1, 51, in
)) > 0) {
238 for (i
= 0; i
< n
/ 3; i
++) {
239 *(optr
++) = ENC(*iptr
>> 2);
240 *(optr
++) = ENC((*iptr
<< 4) & 060 |
241 (*(iptr
+ 1) >> 4) & 017);
242 *(optr
++) = ENC((*(iptr
+ 1) << 2)
243 & 074 | (*(iptr
+ 2) >> 6) & 03);
244 *(optr
++) = ENC(*(iptr
+ 2) & 077);
248 /* need output padding ? */
252 (void) fwrite(out_buf
, 1,
254 (size_t)(optr
- out_buf
), out
);
264 * Take care of any output padding that is
267 assert(n
- opos
< 3);
270 /* no-op - 24 bits of data encoded */
274 /* 8 bits encoded - pad with 2 '=' */
275 *(optr
++) = ENC((*iptr
& 0xFC) >> 2);
276 *(optr
++) = ENC((*iptr
& 0x03) << 4);
282 /* 16 bits encoded - pad with 1 '=' */
283 *(optr
++) = ENC((*iptr
& 0xFC) >> 2);
284 *(optr
++) = ENC(((*iptr
& 0x03) << 4) |
285 ((*(iptr
+ 1) & 0xF0) >> 4));
286 *(optr
++) = ENC((*(iptr
+ 1) & 0x0F)
295 (void) fwrite(out_buf
, 1,
297 (size_t)(optr
- out_buf
), out
);