home *** CD-ROM | disk | FTP | other *** search
- From decwrl!purdue!mailrus!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery Sun Jan 22 15:42:20 PST 1989
- Article 776 of comp.sources.misc:
- Path: granite!decwrl!purdue!mailrus!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
-
-
-