uuencode.c revision 96943
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 96943 2002-05-19 11:22:54Z 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 8696942Sjmallett if (strcmp(argv[0], "b64encode") == 0) 8796942Sjmallett base64 = 1; 8896942Sjmallett 8991661Sjmallett while ((ch = getopt(argc, argv, "mo:")) != -1) { 9091661Sjmallett switch (ch) { 9191661Sjmallett case 'm': 9291661Sjmallett base64 = 1; 9391661Sjmallett break; 9491661Sjmallett case 'o': 9591661Sjmallett outfile = optarg; 9691661Sjmallett 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 */ 14528564Scharniervoid 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 15991661Sjmallett fprintf(output, "begin-base64 %o %s\n", mode, *av); 16091661Sjmallett while ((n = fread(buf, 1, sizeof(buf), stdin))) { 16191661Sjmallett ++sequence; 16291661Sjmallett rv = b64_ntop(buf, n, buf2, (sizeof(buf2) / sizeof(buf2[0]))); 16391661Sjmallett if (rv == -1) 16491661Sjmallett errx(1, "b64_ntop: error encoding base64"); 16591661Sjmallett fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n"); 16691661Sjmallett } 16791661Sjmallett if (sequence % GROUPS) 16891661Sjmallett fprintf(output, "\n"); 16991661Sjmallett fprintf(output, "====\n"); 17091661Sjmallett} 17191661Sjmallett 17291661Sjmallett/* 17391661Sjmallett * Copy from in to out, encoding as you go along. 17491661Sjmallett */ 17591661Sjmallettvoid 17696438Smikeencode(void) 1771590Srgrimes{ 1781590Srgrimes register int ch, n; 1791590Srgrimes register char *p; 1801590Srgrimes char buf[80]; 1811590Srgrimes 18291661Sjmallett (void)fprintf(output, "begin %o %s\n", mode, *av); 18328564Scharnier while ((n = fread(buf, 1, 45, stdin))) { 1841590Srgrimes ch = ENC(n); 18591661Sjmallett if (fputc(ch, output) == EOF) 1861590Srgrimes break; 1871590Srgrimes for (p = buf; n > 0; n -= 3, p += 3) { 18884715Sru /* Pad with nulls if not a multiple of 3. */ 18984715Sru if (n < 3) { 19084715Sru p[2] = '\0'; 19184715Sru if (n < 2) 19284715Sru p[1] = '\0'; 19384715Sru } 1941590Srgrimes ch = *p >> 2; 1951590Srgrimes ch = ENC(ch); 19691661Sjmallett if (fputc(ch, output) == EOF) 1971590Srgrimes break; 19878387Sdd ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017); 1991590Srgrimes ch = ENC(ch); 20091661Sjmallett if (fputc(ch, output) == EOF) 2011590Srgrimes break; 20278387Sdd ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); 2031590Srgrimes ch = ENC(ch); 20491661Sjmallett if (fputc(ch, output) == EOF) 2051590Srgrimes break; 2061590Srgrimes ch = p[2] & 077; 2071590Srgrimes ch = ENC(ch); 20891661Sjmallett if (fputc(ch, output) == EOF) 2091590Srgrimes break; 2101590Srgrimes } 21191661Sjmallett if (fputc('\n', output) == EOF) 2121590Srgrimes break; 2131590Srgrimes } 21428564Scharnier if (ferror(stdin)) 21528564Scharnier errx(1, "read error"); 21691661Sjmallett (void)fprintf(output, "%c\nend\n", ENC('\0')); 2171590Srgrimes} 2181590Srgrimes 21928564Scharnierstatic void 22096438Smikeusage(void) 2211590Srgrimes{ 22296943Sjmallett (void)fprintf(stderr, 22396943Sjmallett"usage: uuencode [-m] [-o outfile] [infile] remotefile\n" 22496943Sjmallett" b64encode [-o outfile] [infile] remotefile\n"); 2251590Srgrimes exit(1); 2261590Srgrimes} 227