uuencode.c revision 91661
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 401590Srgrimes#ifndef lint 4128564Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)uuencode.c 8.2 (Berkeley) 4/2/94"; 4328564Scharnier#endif 4428564Scharnierstatic const char rcsid[] = 4550477Speter "$FreeBSD: head/usr.bin/uuencode/uuencode.c 91661 2002-03-05 03:27:47Z jmallett $"; 461590Srgrimes#endif /* not lint */ 471590Srgrimes 481590Srgrimes/* 491590Srgrimes * uuencode [input] output 501590Srgrimes * 511590Srgrimes * Encode a file so it can be mailed to a remote system. 521590Srgrimes */ 5391661Sjmallett#include <sys/param.h> 5491661Sjmallett#include <sys/socket.h> 551590Srgrimes#include <sys/stat.h> 561590Srgrimes 5791661Sjmallett#include <netinet/in.h> 5891661Sjmallett 5928564Scharnier#include <err.h> 6091661Sjmallett#include <resolv.h> 611590Srgrimes#include <stdio.h> 6278718Sdd#include <stdlib.h> 6391661Sjmallett#include <string.h> 6428564Scharnier#include <unistd.h> 651590Srgrimes 6628564Scharniervoid encode __P((void)); 6791661Sjmallettvoid base64_encode __P((void)); 6828564Scharnierstatic void usage __P((void)); 6928564Scharnier 7091661SjmallettFILE *output = stdout; 7191661Sjmallettint mode; 7291661Sjmallettchar **av; 7391661Sjmallett 741590Srgrimesint 751590Srgrimesmain(argc, argv) 761590Srgrimes int argc; 771590Srgrimes char *argv[]; 781590Srgrimes{ 791590Srgrimes struct stat sb; 8091661Sjmallett int base64; 8191661Sjmallett char ch; 8291661Sjmallett char *outfile; 831590Srgrimes 8491661Sjmallett base64 = 0; 8591661Sjmallett outfile = NULL; 8691661Sjmallett 8791661Sjmallett while ((ch = getopt(argc, argv, "mo:")) != -1) { 8891661Sjmallett switch (ch) { 8991661Sjmallett case 'm': 9091661Sjmallett base64 = 1; 9191661Sjmallett break; 9291661Sjmallett case 'o': 9391661Sjmallett outfile = optarg; 9491661Sjmallett break; 9591661Sjmallett case '?': 9691661Sjmallett default: 9791661Sjmallett usage(); 9891661Sjmallett } 9991661Sjmallett } 1001590Srgrimes argv += optind; 1011590Srgrimes argc -= optind; 1021590Srgrimes 1031590Srgrimes switch(argc) { 1041590Srgrimes case 2: /* optional first argument is input file */ 10528564Scharnier if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb)) 10628564Scharnier err(1, "%s", *argv); 1071590Srgrimes#define RWX (S_IRWXU|S_IRWXG|S_IRWXO) 1081590Srgrimes mode = sb.st_mode & RWX; 1091590Srgrimes ++argv; 1101590Srgrimes break; 1111590Srgrimes case 1: 1121590Srgrimes#define RW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 1131590Srgrimes mode = RW & ~umask(RW); 1141590Srgrimes break; 1151590Srgrimes case 0: 1161590Srgrimes default: 1171590Srgrimes usage(); 1181590Srgrimes } 1191590Srgrimes 12091661Sjmallett av = argv; 12191661Sjmallett 12291661Sjmallett if (outfile != NULL) { 12391661Sjmallett output = fopen(outfile, "w+"); 12491661Sjmallett if (output == NULL) 12591661Sjmallett err(1, "unable to open %s for output", outfile); 12691661Sjmallett } 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 14391661Sjmallettbase64_encode() 14491661Sjmallett{ 14591661Sjmallett#define GROUPS 8 /* Group output chunks */ 14691661Sjmallett unsigned char buf[6]; 14791661Sjmallett char buf2[16]; 14891661Sjmallett size_t n; 14991661Sjmallett int rv, sequence; 15091661Sjmallett 15191661Sjmallett sequence = 0; 15291661Sjmallett 15391661Sjmallett fprintf(output, "begin-base64 %o %s\n", mode, *av); 15491661Sjmallett while ((n = fread(buf, 1, sizeof(buf), stdin))) { 15591661Sjmallett ++sequence; 15691661Sjmallett rv = b64_ntop(buf, n, buf2, (sizeof(buf2) / sizeof(buf2[0]))); 15791661Sjmallett if (rv == -1) 15891661Sjmallett errx(1, "b64_ntop: error encoding base64"); 15991661Sjmallett fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n"); 16091661Sjmallett } 16191661Sjmallett if (sequence % GROUPS) 16291661Sjmallett fprintf(output, "\n"); 16391661Sjmallett fprintf(output, "====\n"); 16491661Sjmallett} 16591661Sjmallett 16691661Sjmallett/* 16791661Sjmallett * Copy from in to out, encoding as you go along. 16891661Sjmallett */ 16991661Sjmallettvoid 1701590Srgrimesencode() 1711590Srgrimes{ 1721590Srgrimes register int ch, n; 1731590Srgrimes register char *p; 1741590Srgrimes char buf[80]; 1751590Srgrimes 17691661Sjmallett (void)fprintf(output, "begin %o %s\n", mode, *av); 17728564Scharnier while ((n = fread(buf, 1, 45, stdin))) { 1781590Srgrimes ch = ENC(n); 17991661Sjmallett if (fputc(ch, output) == EOF) 1801590Srgrimes break; 1811590Srgrimes for (p = buf; n > 0; n -= 3, p += 3) { 18284715Sru /* Pad with nulls if not a multiple of 3. */ 18384715Sru if (n < 3) { 18484715Sru p[2] = '\0'; 18584715Sru if (n < 2) 18684715Sru p[1] = '\0'; 18784715Sru } 1881590Srgrimes ch = *p >> 2; 1891590Srgrimes ch = ENC(ch); 19091661Sjmallett if (fputc(ch, output) == EOF) 1911590Srgrimes break; 19278387Sdd ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017); 1931590Srgrimes ch = ENC(ch); 19491661Sjmallett if (fputc(ch, output) == EOF) 1951590Srgrimes break; 19678387Sdd ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); 1971590Srgrimes ch = ENC(ch); 19891661Sjmallett if (fputc(ch, output) == EOF) 1991590Srgrimes break; 2001590Srgrimes ch = p[2] & 077; 2011590Srgrimes ch = ENC(ch); 20291661Sjmallett if (fputc(ch, output) == EOF) 2031590Srgrimes break; 2041590Srgrimes } 20591661Sjmallett if (fputc('\n', output) == EOF) 2061590Srgrimes break; 2071590Srgrimes } 20828564Scharnier if (ferror(stdin)) 20928564Scharnier errx(1, "read error"); 21091661Sjmallett (void)fprintf(output, "%c\nend\n", ENC('\0')); 2111590Srgrimes} 2121590Srgrimes 21328564Scharnierstatic void 2141590Srgrimesusage() 2151590Srgrimes{ 21691661Sjmallett (void)fprintf(stderr,"usage: uuencode [-m] [-o outfile] [infile] remotefile\n"); 2171590Srgrimes exit(1); 2181590Srgrimes} 219