11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1983, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 30114594Sobrien#if 0 311590Srgrimes#ifndef lint 3228564Scharnierstatic const char copyright[] = 331590Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 341590Srgrimes The Regents of the University of California. All rights reserved.\n"; 351590Srgrimes#endif /* not lint */ 361590Srgrimes 371590Srgrimes#ifndef lint 381590Srgrimesstatic char sccsid[] = "@(#)uuencode.c 8.2 (Berkeley) 4/2/94"; 3996438Smike#endif /* not lint */ 4028564Scharnier#endif 4196438Smike#include <sys/cdefs.h> 4296438Smike__FBSDID("$FreeBSD: stable/11/usr.bin/uuencode/uuencode.c 317062 2017-04-17 18:55:54Z araujo $"); 4396438Smike 441590Srgrimes/* 451590Srgrimes * uuencode [input] output 461590Srgrimes * 471590Srgrimes * Encode a file so it can be mailed to a remote system. 481590Srgrimes */ 4991661Sjmallett#include <sys/param.h> 5091661Sjmallett#include <sys/socket.h> 511590Srgrimes#include <sys/stat.h> 521590Srgrimes 5391661Sjmallett#include <netinet/in.h> 5491661Sjmallett 5528564Scharnier#include <err.h> 56105519Sfanf#include <libgen.h> 5791661Sjmallett#include <resolv.h> 581590Srgrimes#include <stdio.h> 5978718Sdd#include <stdlib.h> 6091661Sjmallett#include <string.h> 6128564Scharnier#include <unistd.h> 621590Srgrimes 63227197Sedstatic void encode(void); 64227197Sedstatic void base64_encode(void); 6592922Simpstatic void usage(void); 6628564Scharnier 67227197Sedstatic FILE *output; 68227197Sedstatic int mode; 69297678Sgahrstatic char raw = 0; 70227197Sedstatic char **av; 7191661Sjmallett 721590Srgrimesint 7396386Salfredmain(int argc, char *argv[]) 741590Srgrimes{ 751590Srgrimes struct stat sb; 7691661Sjmallett int base64; 77124830Sgrehan int ch; 7891661Sjmallett char *outfile; 791590Srgrimes 8091661Sjmallett base64 = 0; 8191661Sjmallett outfile = NULL; 8291661Sjmallett 83105519Sfanf if (strcmp(basename(argv[0]), "b64encode") == 0) 8496942Sjmallett base64 = 1; 8596942Sjmallett 86297678Sgahr while ((ch = getopt(argc, argv, "mo:r")) != -1) { 8791661Sjmallett switch (ch) { 8891661Sjmallett case 'm': 8991661Sjmallett base64 = 1; 9091661Sjmallett break; 9191661Sjmallett case 'o': 9291661Sjmallett outfile = optarg; 9391661Sjmallett break; 94297678Sgahr case 'r': 95297678Sgahr raw = 1; 96297678Sgahr break; 9791661Sjmallett case '?': 9891661Sjmallett default: 9991661Sjmallett usage(); 10091661Sjmallett } 10191661Sjmallett } 1021590Srgrimes argv += optind; 1031590Srgrimes argc -= optind; 1041590Srgrimes 1051590Srgrimes switch(argc) { 1061590Srgrimes case 2: /* optional first argument is input file */ 10728564Scharnier if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb)) 10828564Scharnier err(1, "%s", *argv); 1091590Srgrimes#define RWX (S_IRWXU|S_IRWXG|S_IRWXO) 1101590Srgrimes mode = sb.st_mode & RWX; 1111590Srgrimes ++argv; 1121590Srgrimes break; 1131590Srgrimes case 1: 1141590Srgrimes#define RW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 1151590Srgrimes mode = RW & ~umask(RW); 1161590Srgrimes break; 1171590Srgrimes case 0: 1181590Srgrimes default: 1191590Srgrimes usage(); 1201590Srgrimes } 1211590Srgrimes 12291661Sjmallett av = argv; 12391661Sjmallett 12491661Sjmallett if (outfile != NULL) { 12591661Sjmallett output = fopen(outfile, "w+"); 12691661Sjmallett if (output == NULL) 12791661Sjmallett err(1, "unable to open %s for output", outfile); 12891676Smike } else 12991676Smike output = stdout; 13091661Sjmallett if (base64) 13191661Sjmallett base64_encode(); 13291661Sjmallett else 13391661Sjmallett encode(); 13491661Sjmallett if (ferror(output)) 13528564Scharnier errx(1, "write error"); 1361590Srgrimes exit(0); 1371590Srgrimes} 1381590Srgrimes 1391590Srgrimes/* ENC is the basic 1 character encoding function to make a char printing */ 1401590Srgrimes#define ENC(c) ((c) ? ((c) & 077) + ' ': '`') 1411590Srgrimes 1421590Srgrimes/* 14391661Sjmallett * Copy from in to out, encoding in base64 as you go along. 1441590Srgrimes */ 145227197Sedstatic void 14696438Smikebase64_encode(void) 14791661Sjmallett{ 14896810Sjmallett /* 14996810Sjmallett * Output must fit into 80 columns, chunks come in 4, leave 1. 15096810Sjmallett */ 15196810Sjmallett#define GROUPS ((80 / 4) - 1) 15296810Sjmallett unsigned char buf[3]; 15396810Sjmallett char buf2[sizeof(buf) * 2 + 1]; 15491661Sjmallett size_t n; 15591661Sjmallett int rv, sequence; 15691661Sjmallett 15791661Sjmallett sequence = 0; 15891661Sjmallett 159297678Sgahr if (!raw) 160297678Sgahr fprintf(output, "begin-base64 %o %s\n", mode, *av); 16191661Sjmallett while ((n = fread(buf, 1, sizeof(buf), stdin))) { 16291661Sjmallett ++sequence; 163317062Saraujo rv = b64_ntop(buf, n, buf2, nitems(buf2)); 16491661Sjmallett if (rv == -1) 16591661Sjmallett errx(1, "b64_ntop: error encoding base64"); 16691661Sjmallett fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n"); 16791661Sjmallett } 16891661Sjmallett if (sequence % GROUPS) 16991661Sjmallett fprintf(output, "\n"); 170297678Sgahr if (!raw) 171297678Sgahr fprintf(output, "====\n"); 17291661Sjmallett} 17391661Sjmallett 17491661Sjmallett/* 17591661Sjmallett * Copy from in to out, encoding as you go along. 17691661Sjmallett */ 177227197Sedstatic void 17896438Smikeencode(void) 1791590Srgrimes{ 1801590Srgrimes register int ch, n; 1811590Srgrimes register char *p; 1821590Srgrimes char buf[80]; 1831590Srgrimes 184297678Sgahr if (!raw) 185297678Sgahr (void)fprintf(output, "begin %o %s\n", mode, *av); 18628564Scharnier while ((n = fread(buf, 1, 45, stdin))) { 1871590Srgrimes ch = ENC(n); 18891661Sjmallett if (fputc(ch, output) == EOF) 1891590Srgrimes break; 1901590Srgrimes for (p = buf; n > 0; n -= 3, p += 3) { 19184715Sru /* Pad with nulls if not a multiple of 3. */ 19284715Sru if (n < 3) { 19384715Sru p[2] = '\0'; 19484715Sru if (n < 2) 19584715Sru p[1] = '\0'; 19684715Sru } 1971590Srgrimes ch = *p >> 2; 1981590Srgrimes ch = ENC(ch); 19991661Sjmallett if (fputc(ch, output) == EOF) 2001590Srgrimes break; 20178387Sdd ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017); 2021590Srgrimes ch = ENC(ch); 20391661Sjmallett if (fputc(ch, output) == EOF) 2041590Srgrimes break; 20578387Sdd ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); 2061590Srgrimes ch = ENC(ch); 20791661Sjmallett if (fputc(ch, output) == EOF) 2081590Srgrimes break; 2091590Srgrimes ch = p[2] & 077; 2101590Srgrimes ch = ENC(ch); 21191661Sjmallett if (fputc(ch, output) == EOF) 2121590Srgrimes break; 2131590Srgrimes } 21491661Sjmallett if (fputc('\n', output) == EOF) 2151590Srgrimes break; 2161590Srgrimes } 21728564Scharnier if (ferror(stdin)) 21828564Scharnier errx(1, "read error"); 219297678Sgahr if (!raw) 220297678Sgahr (void)fprintf(output, "%c\nend\n", ENC('\0')); 2211590Srgrimes} 2221590Srgrimes 22328564Scharnierstatic void 22496438Smikeusage(void) 2251590Srgrimes{ 22696943Sjmallett (void)fprintf(stderr, 22796943Sjmallett"usage: uuencode [-m] [-o outfile] [infile] remotefile\n" 22896943Sjmallett" b64encode [-o outfile] [infile] remotefile\n"); 2291590Srgrimes exit(1); 2301590Srgrimes} 231