uuencode.c revision 96810
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 * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3528564Scharnierstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 4096438Smike#if 0 411590Srgrimes#ifndef lint 421590Srgrimesstatic char sccsid[] = "@(#)uuencode.c 8.2 (Berkeley) 4/2/94"; 4396438Smike#endif /* not lint */ 4428564Scharnier#endif 451590Srgrimes 4696438Smike#include <sys/cdefs.h> 4796438Smike__FBSDID("$FreeBSD: head/usr.bin/uuencode/uuencode.c 96810 2002-05-17 12:27:02Z jmallett $"); 4896438Smike 491590Srgrimes/* 501590Srgrimes * uuencode [input] output 511590Srgrimes * 521590Srgrimes * Encode a file so it can be mailed to a remote system. 531590Srgrimes */ 5491661Sjmallett#include <sys/param.h> 5591661Sjmallett#include <sys/socket.h> 561590Srgrimes#include <sys/stat.h> 571590Srgrimes 5891661Sjmallett#include <netinet/in.h> 5991661Sjmallett 6028564Scharnier#include <err.h> 6191661Sjmallett#include <resolv.h> 621590Srgrimes#include <stdio.h> 6378718Sdd#include <stdlib.h> 6491661Sjmallett#include <string.h> 6528564Scharnier#include <unistd.h> 661590Srgrimes 6792922Simpvoid encode(void); 6892922Simpvoid base64_encode(void); 6992922Simpstatic void usage(void); 7028564Scharnier 7191676SmikeFILE *output; 7291661Sjmallettint mode; 7391661Sjmallettchar **av; 7491661Sjmallett 751590Srgrimesint 7696386Salfredmain(int argc, char *argv[]) 771590Srgrimes{ 781590Srgrimes struct stat sb; 7991661Sjmallett int base64; 8091661Sjmallett char ch; 8191661Sjmallett char *outfile; 821590Srgrimes 8391661Sjmallett base64 = 0; 8491661Sjmallett outfile = NULL; 8591661Sjmallett 8691661Sjmallett while ((ch = getopt(argc, argv, "mo:")) != -1) { 8791661Sjmallett switch (ch) { 8891661Sjmallett case 'm': 8991661Sjmallett base64 = 1; 9091661Sjmallett break; 9191661Sjmallett case 'o': 9291661Sjmallett outfile = optarg; 9391661Sjmallett break; 9491661Sjmallett case '?': 9591661Sjmallett default: 9691661Sjmallett usage(); 9791661Sjmallett } 9891661Sjmallett } 991590Srgrimes argv += optind; 1001590Srgrimes argc -= optind; 1011590Srgrimes 1021590Srgrimes switch(argc) { 1031590Srgrimes case 2: /* optional first argument is input file */ 10428564Scharnier if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb)) 10528564Scharnier err(1, "%s", *argv); 1061590Srgrimes#define RWX (S_IRWXU|S_IRWXG|S_IRWXO) 1071590Srgrimes mode = sb.st_mode & RWX; 1081590Srgrimes ++argv; 1091590Srgrimes break; 1101590Srgrimes case 1: 1111590Srgrimes#define RW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 1121590Srgrimes mode = RW & ~umask(RW); 1131590Srgrimes break; 1141590Srgrimes case 0: 1151590Srgrimes default: 1161590Srgrimes usage(); 1171590Srgrimes } 1181590Srgrimes 11991661Sjmallett av = argv; 12091661Sjmallett 12191661Sjmallett if (outfile != NULL) { 12291661Sjmallett output = fopen(outfile, "w+"); 12391661Sjmallett if (output == NULL) 12491661Sjmallett err(1, "unable to open %s for output", outfile); 12591676Smike } else 12691676Smike output = stdout; 12791661Sjmallett if (base64) 12891661Sjmallett base64_encode(); 12991661Sjmallett else 13091661Sjmallett encode(); 13191661Sjmallett if (ferror(output)) 13228564Scharnier errx(1, "write error"); 1331590Srgrimes exit(0); 1341590Srgrimes} 1351590Srgrimes 1361590Srgrimes/* ENC is the basic 1 character encoding function to make a char printing */ 1371590Srgrimes#define ENC(c) ((c) ? ((c) & 077) + ' ': '`') 1381590Srgrimes 1391590Srgrimes/* 14091661Sjmallett * Copy from in to out, encoding in base64 as you go along. 1411590Srgrimes */ 14228564Scharniervoid 14396438Smikebase64_encode(void) 14491661Sjmallett{ 14596810Sjmallett /* 14696810Sjmallett * Output must fit into 80 columns, chunks come in 4, leave 1. 14796810Sjmallett */ 14896810Sjmallett#define GROUPS ((80 / 4) - 1) 14996810Sjmallett unsigned char buf[3]; 15096810Sjmallett char buf2[sizeof(buf) * 2 + 1]; 15191661Sjmallett size_t n; 15291661Sjmallett int rv, sequence; 15391661Sjmallett 15491661Sjmallett sequence = 0; 15591661Sjmallett 15691661Sjmallett fprintf(output, "begin-base64 %o %s\n", mode, *av); 15791661Sjmallett while ((n = fread(buf, 1, sizeof(buf), stdin))) { 15891661Sjmallett ++sequence; 15991661Sjmallett rv = b64_ntop(buf, n, buf2, (sizeof(buf2) / sizeof(buf2[0]))); 16091661Sjmallett if (rv == -1) 16191661Sjmallett errx(1, "b64_ntop: error encoding base64"); 16291661Sjmallett fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n"); 16391661Sjmallett } 16491661Sjmallett if (sequence % GROUPS) 16591661Sjmallett fprintf(output, "\n"); 16691661Sjmallett fprintf(output, "====\n"); 16791661Sjmallett} 16891661Sjmallett 16991661Sjmallett/* 17091661Sjmallett * Copy from in to out, encoding as you go along. 17191661Sjmallett */ 17291661Sjmallettvoid 17396438Smikeencode(void) 1741590Srgrimes{ 1751590Srgrimes register int ch, n; 1761590Srgrimes register char *p; 1771590Srgrimes char buf[80]; 1781590Srgrimes 17991661Sjmallett (void)fprintf(output, "begin %o %s\n", mode, *av); 18028564Scharnier while ((n = fread(buf, 1, 45, stdin))) { 1811590Srgrimes ch = ENC(n); 18291661Sjmallett if (fputc(ch, output) == EOF) 1831590Srgrimes break; 1841590Srgrimes for (p = buf; n > 0; n -= 3, p += 3) { 18584715Sru /* Pad with nulls if not a multiple of 3. */ 18684715Sru if (n < 3) { 18784715Sru p[2] = '\0'; 18884715Sru if (n < 2) 18984715Sru p[1] = '\0'; 19084715Sru } 1911590Srgrimes ch = *p >> 2; 1921590Srgrimes ch = ENC(ch); 19391661Sjmallett if (fputc(ch, output) == EOF) 1941590Srgrimes break; 19578387Sdd ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017); 1961590Srgrimes ch = ENC(ch); 19791661Sjmallett if (fputc(ch, output) == EOF) 1981590Srgrimes break; 19978387Sdd ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); 2001590Srgrimes ch = ENC(ch); 20191661Sjmallett if (fputc(ch, output) == EOF) 2021590Srgrimes break; 2031590Srgrimes ch = p[2] & 077; 2041590Srgrimes ch = ENC(ch); 20591661Sjmallett if (fputc(ch, output) == EOF) 2061590Srgrimes break; 2071590Srgrimes } 20891661Sjmallett if (fputc('\n', output) == EOF) 2091590Srgrimes break; 2101590Srgrimes } 21128564Scharnier if (ferror(stdin)) 21228564Scharnier errx(1, "read error"); 21391661Sjmallett (void)fprintf(output, "%c\nend\n", ENC('\0')); 2141590Srgrimes} 2151590Srgrimes 21628564Scharnierstatic void 21796438Smikeusage(void) 2181590Srgrimes{ 21991661Sjmallett (void)fprintf(stderr,"usage: uuencode [-m] [-o outfile] [infile] remotefile\n"); 2201590Srgrimes exit(1); 2211590Srgrimes} 222