uuencode.c revision 84715
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 84715 2001-10-09 11:05:27Z ru $";
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 */
531590Srgrimes#include <sys/types.h>
541590Srgrimes#include <sys/stat.h>
551590Srgrimes
5628564Scharnier#include <err.h>
571590Srgrimes#include <stdio.h>
5878718Sdd#include <stdlib.h>
5928564Scharnier#include <unistd.h>
601590Srgrimes
6128564Scharniervoid encode __P((void));
6228564Scharnierstatic void usage __P((void));
6328564Scharnier
641590Srgrimesint
651590Srgrimesmain(argc, argv)
661590Srgrimes	int argc;
671590Srgrimes	char *argv[];
681590Srgrimes{
691590Srgrimes	struct stat sb;
701590Srgrimes	int mode;
711590Srgrimes
7224360Simp	while (getopt(argc, argv, "") != -1)
731590Srgrimes		usage();
741590Srgrimes	argv += optind;
751590Srgrimes	argc -= optind;
761590Srgrimes
771590Srgrimes	switch(argc) {
781590Srgrimes	case 2:			/* optional first argument is input file */
7928564Scharnier		if (!freopen(*argv, "r", stdin) || fstat(fileno(stdin), &sb))
8028564Scharnier			err(1, "%s", *argv);
811590Srgrimes#define	RWX	(S_IRWXU|S_IRWXG|S_IRWXO)
821590Srgrimes		mode = sb.st_mode & RWX;
831590Srgrimes		++argv;
841590Srgrimes		break;
851590Srgrimes	case 1:
861590Srgrimes#define	RW	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
871590Srgrimes		mode = RW & ~umask(RW);
881590Srgrimes		break;
891590Srgrimes	case 0:
901590Srgrimes	default:
911590Srgrimes		usage();
921590Srgrimes	}
931590Srgrimes
941590Srgrimes	(void)printf("begin %o %s\n", mode, *argv);
951590Srgrimes	encode();
961590Srgrimes	(void)printf("end\n");
9728564Scharnier	if (ferror(stdout))
9828564Scharnier		errx(1, "write error");
991590Srgrimes	exit(0);
1001590Srgrimes}
1011590Srgrimes
1021590Srgrimes/* ENC is the basic 1 character encoding function to make a char printing */
1031590Srgrimes#define	ENC(c) ((c) ? ((c) & 077) + ' ': '`')
1041590Srgrimes
1051590Srgrimes/*
1061590Srgrimes * copy from in to out, encoding as you go along.
1071590Srgrimes */
10828564Scharniervoid
1091590Srgrimesencode()
1101590Srgrimes{
1111590Srgrimes	register int ch, n;
1121590Srgrimes	register char *p;
1131590Srgrimes	char buf[80];
1141590Srgrimes
11528564Scharnier	while ((n = fread(buf, 1, 45, stdin))) {
1161590Srgrimes		ch = ENC(n);
1171590Srgrimes		if (putchar(ch) == EOF)
1181590Srgrimes			break;
1191590Srgrimes		for (p = buf; n > 0; n -= 3, p += 3) {
12084715Sru			/* Pad with nulls if not a multiple of 3. */
12184715Sru			if (n < 3) {
12284715Sru				p[2] = '\0';
12384715Sru				if (n < 2)
12484715Sru					p[1] = '\0';
12584715Sru			}
1261590Srgrimes			ch = *p >> 2;
1271590Srgrimes			ch = ENC(ch);
1281590Srgrimes			if (putchar(ch) == EOF)
1291590Srgrimes				break;
13078387Sdd			ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017);
1311590Srgrimes			ch = ENC(ch);
1321590Srgrimes			if (putchar(ch) == EOF)
1331590Srgrimes				break;
13478387Sdd			ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03);
1351590Srgrimes			ch = ENC(ch);
1361590Srgrimes			if (putchar(ch) == EOF)
1371590Srgrimes				break;
1381590Srgrimes			ch = p[2] & 077;
1391590Srgrimes			ch = ENC(ch);
1401590Srgrimes			if (putchar(ch) == EOF)
1411590Srgrimes				break;
1421590Srgrimes		}
1431590Srgrimes		if (putchar('\n') == EOF)
1441590Srgrimes			break;
1451590Srgrimes	}
14628564Scharnier	if (ferror(stdin))
14728564Scharnier		errx(1, "read error");
1481590Srgrimes	ch = ENC('\0');
1491590Srgrimes	(void)putchar(ch);
1501590Srgrimes	(void)putchar('\n');
1511590Srgrimes}
1521590Srgrimes
15328564Scharnierstatic void
1541590Srgrimesusage()
1551590Srgrimes{
1561590Srgrimes	(void)fprintf(stderr,"usage: uuencode [infile] remotefile\n");
1571590Srgrimes	exit(1);
1581590Srgrimes}
159