[comp.mail.mush] Announcing: Mush 7.0

schaefer@CSE.OGI.EDU (Barton E. Schaefer) (12/12/89)

It's Official!  Mush 7.0 has arrived!

Since I'm sure you've all seen the hype and discussion of new features
on this group at one time or another, I'll limit the advertising to the
summary of tool mode changes taken from the README-7.0 file:

    * The message display window is a textsw, with scrollbars.
    * The composition window is also a textsw, and opens in a separate
      frame, so you can read messages in the main frame while composing.
      You can still invoke an editor, and the default window size is
      such that vi no longer gets confused (as far as we can tell).
    * There are variables to control the sizes of most subwindows.
    * Header-editing works in tool mode (in fact, you MUST use it).
    * Help, options, and alias settings also pop up in their own frames.
      The help descriptions have been improved (we believe).
    * Interactive function-key binding is no longer supported; the clash
      of mush function keys with SunView functions has been eliminated.
    * The list of folders in your folder directory is made into a
      walking menu.  (Handling of this may improve in future patches.)

Mush 7.0 can be picked up via anonymous ftp from

	ucbvax.berkeley.edu:pub/mailers/mush-7.0.tar.Z

This version of mush is NOT being posted to comp.sources.unix (at least
not immediately; perhaps when Dan gets back from his European vacation).
So, to help out those of you that do not have ftp access, I've set up an
automated mail-server for mush sources.

Send mail to me:
	<schaefer@cse.ogi.edu>
    or
	{harvard,rutgers,garp,ucsd}!ogicse!schaefer

(you may have to use "ogccse" instead of "ogicse", I don't know how up-
to-date our uucp neighbors are).  The message should contain the line

@MUSH path-from-ogicse-to-you

where "path-from-ogicse-to-you" is pretty self-explanatory -- it will
be the reverse of the path you use to send me the message, including
your login name (just yourname@yourhost will work if you are on the
Internet, but ogicse's mailer does not consult the UUCP maps).  If you
omit this path, the server will still try to figure out where to send
the sources, but it'll probably mess up in many cases, and I'd rather
not get all 500K of the sources bounced back to me very often.  So try
to include a valid path.  Also note that the `@' character must be in
the first column of the line.

The sources are shipped as a "chunky tarmail" -- that is, a "tar" file,
"compress"ed, encoded with "btoa", and "split" into approximately 60Kb
chunks for uucp mailing.  There are presently nine parts.  If you're
lucky, you'll get a summary of the server conversation showing the
shipping size of each part.  (If you aren't lucky, the server will drop
the conversation transcript on the floor, but you should still get the
9 parts if you put a valid path on the @MUSH line.)  If you don't have
compress/uncompress, you're on your own, but I've appended the sources
for btoa/atob and the chunky (un)tarmail below -- it's very short, and
Dan and I ship almost everything packaged this way, so it's worth
posting it here.

As for bug reports:  as I mentioned, Dan is out of the country until
the second week of January (shades of LarryWallism -- make a release
and vanish), so you're probably better off mailing me.  I, however,
am trying desperately to finish a PhD thesis by sometime soon after
Christmas, so you may be even better off just waiting until January
and sending mail to Dan.  His addresses are in the README as usual.

That's about it.  Try not to flood ogicse with too much mail in the
next couple of days.  And, Enjoy!

-- 
Bart Schaefer   "I seem to have run into a novel problem with the electronic
                       mail.  My computer's demanding an electronic female."
schaefer@cse.ogi.edu
(used to be cse.ogc.edu)                              "Preferably brunette."

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

From: per@parrot.Philips.Com (Paul E. Rutter)
Newsgroups: comp.sources.d,alt.sources
Subject: "btoa Classic", "tarmailchunky"
Keywords: binary-to-ASCII, tarmail, tarmailchunky
Message-ID: <55590@philabs.Philips.Com>
Date: 13 Jun 89 21:05:51 GMT
Article-I.D.: philabs.55590
Posted: Tue Jun 13 14:05:51 1989
Sender: news@philabs.Philips.Com
Lines: 651

[ Note: This message has been edited.  Only the shar of sources remains. ]

# The rest of this file is a shell script which will extract:
# Makefile btoa.c atob.c tarmail untarmail tarmailchunky untarmailchunky btoa.man
# 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!'
# makefile for  btoa/atob/tarmail
# Paul E. Rutter
# per@philabs.philips.com
#
# do whatever you want with these programs, but please do not make any
# changes and distribute "new" versions under the same program names.
#
# You need to make BINDIR, SHELLDIR, and MANDIR correct for your situation

BINDIR   = /usr/local/bin
SHELLDIR = /usr/local/bin
MANDIR   = /usr/man/manl

CC       = cc -O

BINS   = btoa atob
SHELLS = tarmail untarmail tarmailchunky untarmailchunky
MANS   = btoa.man


install:	clean man all
		strip $(BINS)
		chmod 755 $(BINS) $(SHELLS)
		cp -p $(BINS)   $(BINDIR)
		cp -p $(SHELLS) $(SHELLDIR)
		make clean

all:		$(BINS) $(SHELLS)

man:		$(MANS)
		chmod 644 $(MANS)
		cp -p btoa.man $(MANDIR)/btoa.l
		cp -p btoa.man $(MANDIR)/tarmail.l

btoa:		btoa.c
		$(CC) -o btoa btoa.c

atob:		atob.c
		$(CC) -o atob atob.c


shar:		Makefile btoa.c atob.c $(SHELLS) $(MANS)
		shar btoa.shar Makefile btoa.c atob.c $(SHELLS) $(MANS)

clean:		
		rm -f $(BINS) btoa.shar
!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.
 *
 * do whatever you want with these programs, but PLEASE do not make any
 * changes and distribute "new" versions under the same program names.
 *
 * 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 - 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]
 *
 * do whatever you want with these programs, but PLEASE do not make any
 * changes and distribute "new" versions under the same program names.
 *
 * 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();
  }
  /* Make file disappear */
  if (unlink(tmp_name) == -1) {
    fatal();
  }
  /*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 */
    if (fseek(tmp_file, 0L, 0) == -1) {
      fatal();
    }
    for (i = n1; --i >= 0;) {
      putchar(getc(tmp_file));
    }
  }
  exit(0);
}
!Funky!Stuff!
echo x - tarmail
cat >tarmail <<'!Funky!Stuff!'
#!/bin/sh
if test $# -lt 3; then
  echo "Usage:  tarmail mailpath \"subject-string\" directory-or-file(s)"
  exit
else
  mailpath=$1
  echo "mailpath = $mailpath"
  shift
  subject="$1"
  echo "subject-string = $subject"
  shift
  echo files = $*
  tar cvf - $* | compress | btoa | Mail -s "$subject" $mailpath
fi
!Funky!Stuff!
echo x - untarmail
cat >untarmail <<'!Funky!Stuff!'
#!/bin/sh
if test $# -ge 1; then
   atob < $1 | uncompress | tar xvpf -
   mv $1 /tmp/$1.$$
   echo tarmail file moved to: /tmp/$1.$$
else
   atob | uncompress | tar xvpf -
fi
!Funky!Stuff!
echo x - tarmailchunky
cat >tarmailchunky <<'!Funky!Stuff!'
#!/bin/sh
# "tarmailchunky" takes a file or list of files and creates a "tar file" it
# then compresses this data (using compress) and converts it to an ascii
# form (using btoa). If it is "too large" to fit into typical mail
# transport systems (some uucp sites break at 64K bytes), it will split
# the image into multiple parts and send them using the standard "mail"
# command.
if test $# -lt 3; then
  echo "Usage:  tarmailchunky mailpath \"subject-string\" directory-or-file(s)"
  echo
  echo "tarmailchunky is a shell script that uses tar, compress, btoa, and split"
  echo "to send arbitrary hierarchies by mail.  It sends things as one or"
  echo "more < 64K pieces.  (see shell script to change this size)."
  exit
else
  mailpath=$1
  echo "mailpath = $mailpath"
  shift
  subject="$1"
  echo "subject-string = $subject"
  shift
  echo files = $*
  tar cvf - $* | compress | btoa | split -750 - /tmp/tm$$
  n=1
  set /tmp/tm$$*
  for f do
    {
	echo '---start beef'
	cat $f
	echo '---end beef'
    } | Mail -s "$subject - part $n of $#" $mailpath
    echo "part $n of $# sent (" `wc -c < $f` "bytes)"
    n=`expr $n + 1`
  done
  rm /tmp/tm$$*
fi
!Funky!Stuff!
echo x - untarmailchunky
cat >untarmailchunky <<'!Funky!Stuff!'
#!/bin/sh
# "untarmailchunky" takes a an ordered list of mail messages (if they were in
# multiple parts, the must be fed to untarmail in order) and recreates
# the data stored by the original "tarmail" reversing each step along
# the way.
if test $# -ge 1; then
   sed '/^---end beef/,/^---start beef/d' $* | atob | uncompress | tar xvpf -
   echo remember to remove the tarmail files: $*
else
   sed '/^---end beef/,/^---start beef/d' | atob | uncompress | tar xvpf -
fi
!Funky!Stuff!
echo x - btoa.man
cat >btoa.man <<'!Funky!Stuff!'
.TH BTOA 1 local
.SH NAME
btoa, atob, tarmail, untarmail, tarmailchunky, untarmailchunky \- encode/decode binary to printable ASCII
.SH SYNOPSIS
.B btoa < anything > ASCII
.br
.B atob < btoafile > anything
.br
.B tarmail
subject-string who files ...
.br
.B untarmail
[ file ]
.br
.B tarmailchunky
subject-string who files ...
.br
.B untarmailchunky
[ 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 by pipe
scripts like untarmail 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 "two files for you"  foo.c a.out
.in -1i
.PP
Will package up files "foo.c" and "a.out" and mail them to "ralph", with a mail
subject line of "two files for you".
.PP
.I tarmail
with no arguments 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,
executing
.PP
.in 1i
untarmail xx
.in -1i
.PP
will decode the message and untar it.  (In general, you will want to be in an
empty directory, or the "right" directory when you execute this, since the
"untar" will be creating new files).
.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
.I tarmailchunky
is a shell script similar to tarmail, but it uses split to break the message
into one or more pieces, each less than 64 Kbytes long.  Use it when faced
with mail size limits.  On the receiving end, save the pieces as "xx.01",
"xx.02", ... as they come in (they are numbered for you in the subject line
by tarmailchunky).  Then, use
.PP
.in 1i
untarmailchunky xx.??
.in -1i
.PP
to decode the message and untar it.  untarmailchunky uses sed to strip off
mail headers and trailers on the pieces, so you do not have to do that
manually.  You DO have to give it the files in numerical order.
.PP
Other uses for btoa:
.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 (with thanks to Joe Orost and Mark Baushke)
.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 NOTE
The source for btoa is freely available.  Use it any way you want, but please
do not distribute changed versions under these program names.
.SH "SEE ALSO"
compress(1), crypt(1), uuencode(1), mail(1), split(1), sed(1)
!Funky!Stuff!
Paul Rutter    Philips Labs     per@philabs.philips.com    uunet!philabs!per


-- 

lj@spdcc.COM (Len Jacobs) (12/13/89)

Glad to see a release of Mush 7.0.  Unfortunately, under OS 3.5 on a Sun,
the TEXTSW_FILE_CONTENTS and TEXTSW_WRAP_AT_WORD functions
are not included in the stadard libraries.

What is the suitable replacement?  When I tried TEXTSW_FILE
and TEXTSW_WRAP_AT_CHAR, my results were not suitable.

Thanks.
-- 
Len Jacobs
lj@ursa-major.SPDCC.COM

crehta@tasu74.UUCP (Ran Ever-Hadani) (12/14/89)

In article <851@ursa-major.SPDCC.COM> lj@ursa-major.spdcc.COM (Len Jacobs) writes:
>Glad to see a release of Mush 7.0.  Unfortunately, under OS 3.5 on a Sun,
>the TEXTSW_FILE_CONTENTS and TEXTSW_WRAP_AT_WORD functions
>are not included in the stadard libraries.
>
>What is the suitable replacement?  When I tried TEXTSW_FILE
>and TEXTSW_WRAP_AT_CHAR, my results were not suitable.
>
>Thanks.
>-- 
>Len Jacobs
>lj@ursa-major.SPDCC.COM

Me too!
------------
cc -O -DSUNTOOL -DCURSES -DBSD -c doproc.c
"doproc.c", line 415: TEXTSW_FILE_CONTENTS undefined
"doproc.c", line 489: TEXTSW_FILE_CONTENTS undefined
*** Error code 1
cc -O -DSUNTOOL -DCURSES -DBSD -c execute.c
"execute.c", line 47: TEXTSW_FILE_CONTENTS undefined
*** Error code 1
cc -O -DSUNTOOL -DCURSES -DBSD -c misc_frame.c
"misc_frame.c", line 259: TEXTSW_WRAP_AT_WORD undefined
*** Error code 1
`mush' not remade because of errors
-----------------------------------------------
Reply-To: crehta@taux01.nsc.com (Ran Ever-Hadani)
Disclaimer: The above is to be attributed to me only, not to any organization.
Apology: Bad English.  E-mailed spelling and style corrections are welcome.