home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume6
/
btoa
< prev
next >
Wrap
Text File
|
1989-02-03
|
10KB
|
431 lines
Path: lll-winken!ncis.llnl.gov!helios.ee.lbl.gov!pasteur!agate!bionet!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Newsgroups: comp.sources.misc
Subject: v06i001: btoa, tarmail
Message-ID: <46897@uunet.UU.NET>
Date: 21 Jan 89 20:19:33 GMT
Sender: allbery@uunet.UU.NET
Reply-To: per@philabs.Philips.Com (Paul E. Rutter)
Lines: 419
Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Posting-number: Volume 6, Issue 1
Submitted-by: per@philabs.Philips.Com (Paul E. Rutter)
Archive-name: btoa
[I thought this came with Usenet news sources?! ++bsa]
As I have seen a number of requests for btoa lately in comp.sources.wanted,
and received a number of requests personally through round about email, it
seems like it is time to repost sources to btoa/atob and tarmail/untarmail.
A man page is included in the following shar file. I am the original author
of btoa.
Paul Rutter
per@philabs.philips.com
#! /bin/sh
# The rest of this file is a shell script which will extract:
# Makefile atob.c btoa.c btoa.man tarmail untarmail
# Suggested restore procedure:
# Edit off anything above these comment lines,
# save this file in an empty directory,
# then say: sh < file
echo x - Makefile
cat >Makefile <<'!Funky!Stuff!'
CC=cc -O -s
BIN=/usr/local/bin
MAN=/usr/man/manl
L=l
install: atob btoa tarmail untarmail
rm -f $(BIN)/atob $(BIN)/btoa $(BIN)/tarmail $(BIN)/untarmail
cp atob btoa $(BIN)
cp tarmail untarmail $(BIN)
make man clean
man: btoa.man
rm -f $(MAN)/btoa.$(L) $(MAN)/tarmail.$(L)
cp btoa.man $(MAN)/btoa.$(L)
cp btoa.man $(MAN)/tarmail.$(L)
atob: atob.c
$(CC) atob.c -o atob
btoa: btoa.c
$(CC) btoa.c -o btoa
clean:
rm -f *.o atob btoa
!Funky!Stuff!
echo x - atob.c
cat >atob.c <<'!Funky!Stuff!'
/* atob
* stream filter to change printable ascii from "btoa" back into 8 bit bytes
* if bad chars, or Csums do not match: exit(1) [and NO output]
*
* Paul Rutter Joe Orost
*/
#include <stdio.h>
#define reg register
#define streq(s0, s1) strcmp(s0, s1) == 0
#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)
long int Ceor = 0;
long int Csum = 0;
long int Crot = 0;
long int word = 0;
long int bcount = 0;
fatal() {
fprintf(stderr, "bad format or Csum to atob\n");
exit(1);
}
#define DE(c) ((c) - '!')
decode(c) reg c;
{
if (c == 'z') {
if (bcount != 0) {
fatal();
}
else {
byteout(0);
byteout(0);
byteout(0);
byteout(0);
}
}
else if ((c >= '!') && (c < ('!' + 85))) {
if (bcount == 0) {
word = DE(c);
++bcount;
}
else if (bcount < 4) {
word = times85(word);
word += DE(c);
++bcount;
}
else {
word = times85(word) + DE(c);
byteout((int)((word >> 24) & 255));
byteout((int)((word >> 16) & 255));
byteout((int)((word >> 8) & 255));
byteout((int)(word & 255));
word = 0;
bcount = 0;
}
}
else {
fatal();
}
}
FILE *tmp_file;
byteout(c) reg c;
{
Ceor ^= c;
Csum += c;
Csum += 1;
if ((Crot & 0x80000000)) {
Crot <<= 1;
Crot += 1;
}
else {
Crot <<= 1;
}
Crot += c;
putc(c, tmp_file);
}
main(argc, argv) char **argv;
{
reg c;
reg long int i;
char tmp_name[100];
char buf[100];
long int n1, n2, oeor, osum, orot;
if (argc != 1) {
fprintf(stderr,"bad args to %s\n", argv[0]);
exit(2);
}
sprintf(tmp_name, "/usr/tmp/atob.%x", getpid());
tmp_file = fopen(tmp_name, "w+");
if (tmp_file == NULL) {
fatal();
}
unlink(tmp_name); /* Make file disappear */
/*search for header line*/
for (;;) {
if (fgets(buf, sizeof buf, stdin) == NULL) {
fatal();
}
if (streq(buf, "xbtoa Begin\n")) {
break;
}
}
while ((c = getchar()) != EOF) {
if (c == '\n') {
continue;
}
else if (c == 'x') {
break;
}
else {
decode(c);
}
}
if (scanf("btoa End N %ld %lx E %lx S %lx R %lx\n", &n1, &n2, &oeor, &osum, &
orot) != 5) {
fatal();
}
if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
fatal();
}
else {
/* Now that we know everything is OK, copy tmp file to stdout */
fseek(tmp_file, 0L, 0);
for (i = n1; --i >= 0;) {
putchar(getc(tmp_file));
}
}
exit(0);
}
!Funky!Stuff!
echo x - btoa.c
cat >btoa.c <<'!Funky!Stuff!'
/* btoa: version 4.0
* stream filter to change 8 bit bytes into printable ascii
* computes the number of bytes, and three kinds of simple checksums
* incoming bytes are collected into 32-bit words, then printed in base 85
* exp(85,5) > exp(2,32)
* the ASCII characters used are between '!' and 'u'
* 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
*
* Paul Rutter Joe Orost
*/
#include <stdio.h>
#define reg register
#define MAXPERLINE 78
long int Ceor = 0;
long int Csum = 0;
long int Crot = 0;
long int ccount = 0;
long int bcount = 0;
long int word;
#define EN(c) (int) ((c) + '!')
encode(c) reg c;
{
Ceor ^= c;
Csum += c;
Csum += 1;
if ((Crot & 0x80000000)) {
Crot <<= 1;
Crot += 1;
}
else {
Crot <<= 1;
}
Crot += c;
word <<= 8;
word |= c;
if (bcount == 3) {
wordout(word);
bcount = 0;
}
else {
bcount += 1;
}
}
wordout(word) reg long int word;
{
if (word == 0) {
charout('z');
}
else {
reg int tmp = 0;
if (word < 0)
{ /* Because some don't support unsigned long */
tmp = 32;
word = word - (long)(85L * 85 * 85 * 85 * 32);
}
if (word < 0) {
tmp = 64;
word = word - (long)(85L * 85 * 85 * 85 * 32);
}
charout(EN((word / (long)(85L * 85 * 85 * 85)) + tmp));
word %= (long)(85L * 85 * 85 * 85);
charout(EN(word / (85L * 85 * 85)));
word %= (85L * 85 * 85);
charout(EN(word / (85L * 85)));
word %= (85L * 85);
charout(EN(word / 85));
word %= 85;
charout(EN(word));
}
}
charout(c) {
putchar(c);
ccount += 1;
if (ccount == MAXPERLINE) {
putchar('\n');
ccount = 0;
}
}
main(argc,argv)
char **argv;
{
reg c;
reg long int n;
if (argc != 1) {
fprintf(stderr,"bad args to %s\n", argv[0]);
exit(2);
}
printf("xbtoa Begin\n");
n = 0;
while ((c = getchar()) != EOF) {
encode(c);
n += 1;
}
while (bcount != 0) {
encode(0);
}
/* n is written twice as crude cross check*/
if (ccount == 0) /* ccount == 0 means '\n' just written in charout() */
; /* this avoids bug in BITNET, which changes blank line to spaces */
else
putchar('\n');
printf("xbtoa End N %ld %lx E %lx S %lx R %lx\n", n, n, Ceor, Csum, Crot);
exit(0);
}
!Funky!Stuff!
echo x - btoa.man
cat >btoa.man <<'!Funky!Stuff!'
.TH BTOA 1 local
.SH NAME
btoa, atob, tarmail, untarmail \- encode/decode binary to printable ASCII
.SH SYNOPSIS
.B btoa
.br
.B atob
.br
.B tarmail
who files ...
.br
.B untarmail
[ file ]
.SH DESCRIPTION
.I Btoa
is a filter that reads anything from the standard input, and encodes it into
printable ASCII on the standard output. It also attaches a header and checksum
information used by the reverse filter
.I atob
to find the start of the data and to check integrity.
.PP
.I Atob
reads an encoded file, strips off any leading and trailing lines added by
mailers, and recreates a copy of the original file on the standard output.
.I Atob
gives NO output (and exits with an error message) if its input is garbage or
the checksums do not check. (The checksum is at the end; giving no output on
checksum error guarantees that no "partial things" will be created if there
was an error in transit).
.PP
.I Tarmail
is a shell script that tar's up all the given files, pipes them
through
.IR compress ","
.IR btoa ","
and mails them to the given person. For
example:
.PP
.in 1i
tarmail ralph foo.c a.out
.in -1i
.PP
Will package up files "foo.c" and "a.out" and mail them to "ralph".
.PP
.I Tarmail
with no args will print a short message reminding you what the required args
are. When the mail is received at the other end, that person should use
mail to save the message in some temporary file name (say "xx").
Then saying "untarmail xx"
will decode the message and untar it.
.I Untarmail
can also be used as a filter. By using
.IR tarmail ","
binary files and
entire directory structures can be easily transmitted between machines.
Naturally, you should understand what tar itself does before you use
.IR tarmail "."
.PP
Other uses:
.PP
compress < secrets | crypt | btoa | mail ralph
.PP
will mail the encrypted contents of the file "secrets" to ralph. If ralph
knows the encryption key, he can decode it by saving the mail (say in "xx"),
and then running:
.PP
atob < xx | crypt | uncompress
.PP
(crypt requests the key from the terminal,
and the "secrets" come out on the terminal).
.SH AUTHOR
Paul Rutter
.SH FEATURES
.I Btoa
uses a compact base-85 encoding so that
4 bytes are encoded into 5 characters (file is expanded by 25%).
As a special case, 32-bit zero is encoded as one character. This encoding
produces less output than
.IR uuencode "(1)."
.SH "SEE ALSO"
compress(1), crypt(1), uuencode(1), mail(1)
!Funky!Stuff!
echo x - tarmail
cat >tarmail <<'!Funky!Stuff!'
if test $# -lt 2; then
echo "Usage: tarmail mailpath directory-or-file(s)"
exit
else
mailpath=$1
echo "mailpath = $mailpath"
shift
echo files = $*
tar cvf - $* | compress | btoa | mail $mailpath
fi
!Funky!Stuff!
echo x - untarmail
cat >untarmail <<'!Funky!Stuff!'
if test $# -ge 1; then
atob < $1 | uncompress | tar xvpf -
mv $1 /tmp/$1.$$
echo tarmail file moved to: /usr/tmp/$1.$$
else
atob | uncompress | tar xvpf -
fi
!Funky!Stuff!
exit 0