diff options
author | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
---|---|---|
committer | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /basic_cmds/uuencode | |
download | apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip |
Import macOS userland
adv_cmds-176
basic_cmds-55
bootstrap_cmds-116.100.1
developer_cmds-66
diskdev_cmds-667.40.1
doc_cmds-53.60.1
file_cmds-321.40.3
mail_cmds-35
misc_cmds-34
network_cmds-606.40.1
patch_cmds-17
remote_cmds-63
shell_cmds-216.60.1
system_cmds-880.60.2
text_cmds-106
Diffstat (limited to 'basic_cmds/uuencode')
-rw-r--r-- | basic_cmds/uuencode/base64.c | 317 | ||||
-rw-r--r-- | basic_cmds/uuencode/uuencode.1 | 192 | ||||
-rw-r--r-- | basic_cmds/uuencode/uuencode.5 | 100 | ||||
-rw-r--r-- | basic_cmds/uuencode/uuencode.c | 226 |
4 files changed, 835 insertions, 0 deletions
diff --git a/basic_cmds/uuencode/base64.c b/basic_cmds/uuencode/base64.c new file mode 100644 index 0000000..b537171 --- /dev/null +++ b/basic_cmds/uuencode/base64.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 1996, 1998 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#if !defined(LINT) && !defined(CODECENTER) +#include <sys/cdefs.h> +__unused static char rcsid[] = "$FreeBSD: src/lib/libc/net/base64.c,v 1.4 1999/11/04 04:30:43 ache Exp $"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> + +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <ctype.h> +#include <resolv.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) { + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + size_t i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(src, target, targsize) + char const *src; + u_char *target; + size_t targsize; +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace((unsigned char)ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace((unsigned char)ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/basic_cmds/uuencode/uuencode.1 b/basic_cmds/uuencode/uuencode.1 new file mode 100644 index 0000000..20a8bf4 --- /dev/null +++ b/basic_cmds/uuencode/uuencode.1 @@ -0,0 +1,192 @@ +.\" Copyright (c) 1980, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)uuencode.1 8.1 (Berkeley) 6/6/93 +.\" $FreeBSD: src/usr.bin/uuencode/uuencode.1,v 1.9.2.6 2002/04/27 01:55:11 jmallett Exp $ +.\" +.Dd January 27, 2002 +.Dt UUENCODE 1 +.Os +.Sh NAME +.Nm uudecode , +.Nm uuencode +.Nd encode/decode a binary file +.Sh SYNOPSIS +.Nm uuencode +.Op Fl m +.Op Fl o Ar output_file +.Op Ar file +.Ar name +.Nm uudecode +.Op Fl cips +.Op Ar +.Nm uudecode +.Op Fl i +.Fl o Ar output_file +.Op Ar file +.Sh DESCRIPTION +The +.Nm uuencode +and +.Nm uudecode +utilities are used to transmit binary files over transmission mediums +that do not support other than simple +.Tn ASCII +data. +.Pp +The +.Nm uuencode +utility reads +.Ar file +(or by default the standard input) and writes an encoded version +to the standard output, or +.Ar output_file +if one has been specified. +The encoding uses only printing +.Tn ASCII +characters and includes the +mode of the file and the operand +.Ar name +for use by +.Nm uudecode . +.Pp +The +.Nm uudecode +utility transforms +.Em uuencoded +files (or by default, the standard input) into the original form. +The resulting file is named either +.Ar name +or (depending on options passed to +.Nm uudecode ) +.Ar output_file +and will have the mode of the original file except that setuid +and execute bits are not retained. +The +.Nm uudecode +utility ignores any leading and trailing lines. +.Pp +The following options are available for +.Nm uuencode : +.Bl -tag -width ident +.It Fl m +Use the Base64 method of encoding, rather than the traditional +.Nm uuencode +algorithm. +.It Fl o Ar output_file +Output to +.Ar output_file +instead of standard output. +.El +.Pp +The following options are available for +.Nm uudecode : +.Bl -tag -width ident +.It Fl c +Decode more than one uuencode'd file from +.Ar file +if possible. +.It Fl i +Do not overwrite files. +.It Fl o Ar output_file +Output to +.Ar output_file +instead of any pathname contained in the input data. +.It Fl p +Decode +.Ar file +and write output to standard output. +.It Fl s +Do not strip output pathname to base filename. +By default +.Nm uudecode +deletes any prefix ending with the last slash '/' for security +purpose. +.El +.Sh EXAMPLES +The following example packages up a source tree, compresses it, +uuencodes it and mails it to a user on another system. +When +.Nm uudecode +is run on the target system, the file ``src_tree.tar.Z'' will be +created which may then be uncompressed and extracted into the original +tree. +.Pp +.Bd -literal -offset indent -compact +tar cf \- src_tree \&| compress \&| +uuencode src_tree.tar.Z \&| mail sys1!sys2!user +.Ed +.Pp +The following example unpack all uuencode'd +files from your mailbox into your current working directory. +.Pp +.Bd -literal -offset indent -compact +uudecode -c < $MAIL +.Ed +.Pp +The following example extract a compress'ed tar +archive from your mailbox +.Pp +.Bd -literal -offset indent -compact +uudecode -o /dev/stdout < $MAIL | zcat | tar xfv - +.Ed +.Sh LEGACY DESCRIPTION +In legacy operation, +.Nm uudecode +masks file modes with 0666, +preventing the creation of executable files. +.Pp +.Nm uudecode +cannot change the mode of a created file +which is not owned by the current user (unless that user is root). +In legacy operation, +.Xr fchmod 2 +allows the mode to be changed. +.Pp +For more information about legacy mode, see +.Xr compat 5 . +.Sh SEE ALSO +.Xr basename 1 , +.Xr compress 1 , +.Xr mail 1 , +.Xr uucp 1 , +.Xr fchmod 2 , +.Xr uuencode 5 +.Sh BUGS +Files encoded using the traditional algorithm are expanded by 35% +(3 bytes become 4, plus control information). +.Sh HISTORY +The +.Nm uudecode +and +.Nm uuencode +utilities appeared in +.Bx 4.0 . diff --git a/basic_cmds/uuencode/uuencode.5 b/basic_cmds/uuencode/uuencode.5 new file mode 100644 index 0000000..3914dad --- /dev/null +++ b/basic_cmds/uuencode/uuencode.5 @@ -0,0 +1,100 @@ +.TH uuencode 5 "May, 2001" "Apple Computer, Inc." +.SH NAME +uuencode file format +.NM uuencode +.ND description of the uuencode file format +.SH DESCRIPTION + +The +.XR uuencode 1 +command generates files in a format that allows them to be successfully +transferred by systems which strip the high bit from an 8-bit byte. +.XR uudecode 1 +decodes uuencoded files. + +.PP +The uuencode file format consists of three sections: header, body, and trailer. +The header is a line is of the form: + +.PP +begin 644 "filename.ext" + +.PP +where "644" is a +.XR chmod 1 +-format permissions byte for the file and "filename.ext" is the name of +the encoded file. + +.PP +The body section is the encoded representation of the source file. Three +bytes of input file data are encoded into four bytes of output data. +.PP +The 24 input bits are divided up into four pieces of six bits +each. The integer value 32 (the ASCII value for the space character) is +added to each of these pieces to move them outside of the range of control +characters. To avoid using the space character in the encoding, pieces with +value zero are encoded using backquote (ASCII value 96) instead of zero. The +resulting character is one of the this set (ASCII values 96,33-95): + +.DQ `!"#$%&'()*+,-./012356789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ + +.PP +A line itself contains three segments: a length character (encoded using +the "add a space" algorithm described above), the body of the line, +typically (although not required to be) 60 output characters long, +representing 45 input bytes, and (of course) a linefeed. The length +character specifies the number of valid input bytes on the line (so, for +a line which is 60 encoded bytes, the length value would be 45). +Decoding programs should decode no further than the specified length on +a single line. + +.PP +The trailer, which must exist, consists of a single backquote +("`", ASCII 96) character on a line by itself, directly followed by +.DQ end +on a line by itself. + +.PP +.DQ .uue +is the canonical filename extension for uuencoded files. + +.SH BUGS +uudecode does not read all permutations of the file format described in +this man page. + +.PP +Ancient versions of uuencode used a space character (ASCII 32) in the +encoding to represent zero. Many (arguably broken) mailers and transport +agents stripped, rewrapped, or otherwise mangled this format, so the space +was later changed to the backquote, ASCII 96. Decoders may attempt to +read the older format if they wish, though it's unlikely to be encountered +in practice at this point in time. + +.PP +The uuencode encoding method is highly ASCII-centric. In particular, the +character set used doesn't work well on EBCDIC-based systems. (EBCDIC, +generally used by IBM mainframes, is an old alternative character encoding; +most computers use ASCII instead). + +.PP +Many variants of uuencode on various platforms generate different forms +of line checksums, using to represent the checksum one or more encoded +characters after the last counted character in a line. Because these +formats are different and impossible to distinguish (with certainty), +such characters should be ignored by decoding implementations. + +.PP +The uuencode encoding format has no provisions for segmented files. +Writers of segmenting utilities should be careful to avoid using +character sequences that may naturally occur in the encoding (such +as sequences of dashes ("---")) to divide sections. + +.SH SEE ALSO +The MIME Base64 encoding (documented in RFC 2045) is a consistent, +cross-platform-savvy message encoding which should be used in place of +UUEncode wherever possible. + +.PP +The Unix-Hater's Handbook (IDG, 1994) identifies the folly of the +older zero-encoded-as-space versions of uuencode. + diff --git a/basic_cmds/uuencode/uuencode.c b/basic_cmds/uuencode/uuencode.c new file mode 100644 index 0000000..bb528a6 --- /dev/null +++ b/basic_cmds/uuencode/uuencode.c @@ -0,0 +1,226 @@ +/*- + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +#include <sys/cdefs.h> +__unused static const char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)uuencode.c 8.2 (Berkeley) 4/2/94"; +#endif +__unused static const char rcsid[] = + "$FreeBSD: src/usr.bin/uuencode/uuencode.c,v 1.4.2.4 2002/06/17 05:01:46 jmallett Exp $"; +#endif /* not lint */ + +/* + * uuencode [input] output + * + * Encode a file so it can be mailed to a remote system. + */ +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/stat.h> + +#include <netinet/in.h> + +#include <err.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int b64_ntop __P((u_char const *, size_t, char *, size_t)); +int b64_pton __P((char const *, u_char *, size_t)); +void encode(void); +void base64_encode(void); +static void usage(void); + +FILE *output; +int mode; +char **av; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + struct stat sb; + int base64; + char ch; + char *outfile; + + base64 = 0; + outfile = NULL; + + while ((ch = getopt(argc, argv, "mo:")) != -1) { + switch (ch) { + case 'm': + base64 = 1; + break; + case 'o': + outfile = optarg; + break; + case '?': + default: + usage(); + } + } + argv += optind; + argc -= optind; + + switch(argc) { + case 2: /* optional first argument is input file */ + if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb)) + err(1, "%s", *argv); +#define RWX (S_IRWXU|S_IRWXG|S_IRWXO) + mode = sb.st_mode & RWX; + ++argv; + break; + case 1: +#define RW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) + mode = RW & ~umask(RW); + break; + case 0: + default: + usage(); + } + + av = argv; + + if (outfile != NULL) { + output = fopen(outfile, "w+"); + if (output == NULL) + err(1, "unable to open %s for output", outfile); + } else + output = stdout; + if (base64) + base64_encode(); + else + encode(); + if (ferror(output)) + errx(1, "write error"); + exit(0); +} + +/* ENC is the basic 1 character encoding function to make a char printing */ +#define ENC(c) ((c) ? ((c) & 077) + ' ': '`') + +/* + * Copy from in to out, encoding in base64 as you go along. + */ +void +base64_encode() +{ + /* + * Output must fit into 80 columns, chunks come in 4, leave 1. + */ +#define GROUPS ((80 / 4) - 1) + unsigned char buf[3]; + char buf2[sizeof(buf) * 2 + 1]; + size_t n; + int rv, sequence; + + sequence = 0; + + fprintf(output, "begin-base64 %o %s\n", mode, *av); + while ((n = fread(buf, 1, sizeof(buf), stdin))) { + ++sequence; + rv = b64_ntop(buf, n, buf2, (sizeof(buf2) / sizeof(buf2[0]))); + if (rv == -1) + errx(1, "b64_ntop: error encoding base64"); + fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n"); + } + if (sequence % GROUPS) + fprintf(output, "\n"); + fprintf(output, "====\n"); +} + +/* + * Copy from in to out, encoding as you go along. + */ +void +encode() +{ + register int ch, n; + register char *p; + char buf[80]; + + (void)fprintf(output, "begin %o %s\n", mode, *av); + while ((n = fread(buf, 1, 45, stdin))) { + ch = ENC(n); + if (fputc(ch, output) == EOF) + break; + for (p = buf; n > 0; n -= 3, p += 3) { + /* Pad with nulls if not a multiple of 3. */ + if (n < 3) { + p[2] = '\0'; + if (n < 2) + p[1] = '\0'; + } + ch = *p >> 2; + ch = ENC(ch); + if (fputc(ch, output) == EOF) + break; + ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017); + ch = ENC(ch); + if (fputc(ch, output) == EOF) + break; + ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); + ch = ENC(ch); + if (fputc(ch, output) == EOF) + break; + ch = p[2] & 077; + ch = ENC(ch); + if (fputc(ch, output) == EOF) + break; + } + if (fputc('\n', output) == EOF) + break; + } + if (ferror(stdin)) + errx(1, "read error"); + (void)fprintf(output, "%c\nend\n", ENC('\0')); +} + +static void +usage() +{ + (void)fprintf(stderr,"usage: uuencode [-m] [-o outfile] [infile] remotefile\n"); + exit(1); +} |