[comp.sources.amiga] uutwins

ain@j.cc.purdue.edu (Patrick White) (12/06/87)

Program Name:	uuencode, uudecode, manual
Submitted By:	kim@amdahl.amdahl.com
Summary:	latest and greateds uuencode and uudecode -- has crc checking
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Tested.

NOTES:
   Kim sent these to me, but she didn't write them -- they were posted to
comp.sources.unix a while ago and modified for the Amiga (by Bryce?  It's
all in the Notes file anyway).
   I wrote the Makefile for them (for Manx 3.4a) -- not that they really
needed it, but it was easier that way.
   I also posted binaries of these to comp.binaries.amiga since I feel they
are pretty important and not everybody has a C compiler.

   Thanks go to Kim for bringing these to my attention and sending us a copy.
   Thanks also go to whoever modified them for the Amiga (I think it was
Bryce, but I only scanned the Notes and I might be wrong).

   So, now we all have the latest and greatest copy of uuen/decode just in
time for the new Christmas Users, right? :-)


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: k.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

----------------------------------------

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Makefile
#	Notes
#	uuencode.1
#	uudecode.c
#	uuencode.c
# This archive created: Sat Dec  5 15:41:55 1987
# By:	Patrick White (PUCC Land, USA)
cat << \SHAR_EOF > Makefile
#
# Makefile for Aztec C 3.4a
#
# Pat White
#   you can use different memory modes if you want, but this works as is.
#
ENOBJ=uuencode.o
DEOBJ=uudecode.o
ENSRC=uuencode.c
DEDRC=uudecode.c
CFLAGS=+CDp

all: uuencode uudecode

uuencode: $(ENOBJ)
	ln -o uuencode $(ENOBJ) -lcl32

uudecode: $(DEOBJ)
	ln -o uudecode $(DEOBJ) -lcl32

.c.o:
	cc $(CFLAGS) $*.c
SHAR_EOF
cat << \SHAR_EOF > Notes
>From ames!sdcsvax!ucbvax!ucbcad!zen!hoser.berkeley.edu!bryce Fri Sep 11 02:06:19 1987
Path: amdahl!ames!sdcsvax!ucbvax!ucbcad!zen!hoser.berkeley.edu!bryce
From: bryce@hoser.berkeley.edu (Bryce Nesbitt)
Newsgroups: comp.sources.d,comp.sys.amiga
Subject: Re: Question about uu*code
Summary: Yup!
Keywords: BITNET, uuencode, uudecode, security, checksums, BSD 4.4
Message-ID: <3687@zen.berkeley.edu>
Date: 11 Sep 87 09:06:19 GMT
References: <241@n8emr.UUCP>
Sender: news@zen.berkeley.edu
Reply-To: bryce@hoser.berkeley.edu.UUCP (Bryce Nesbitt)
Distribution: usa
Organization: Tubular Transport Devices, Ltd.
Lines: 71

In article <241@n8emr.UUCP> lwv@n8emr.UUCP (Larry W. Virden) writes:

)I noticed that we just recieved two 'new' versions of uu*code which are VERY
)similar.  The one in the Amiga group claims that it is the most compatible
)with others.  The one from comp.sources.misc (??) was almost identical...
)...Even the comment wording is VERY VERY similar.

That's because they are the same program.  Four people have worked on those
programs...  Mark, Alan, Fred and Bryce. (see the source for full names
and net addresses).  I'm Bryce, the latest.


>Is the one dated Sept 7 a 'more correct' version?...
>I dont want to generate incorrect encodings... 

Both versions produce identical encodings.  The comp.sources.misc version
has a new uudecode that handles BITNET.  This is the only difference.

These uu*codes where designed to be totally forward *and* backward compatible.
The decode can use old encoded files, and the encode will produce files that
an old decode can deal with.  Works real slick.

The new features are; checksums on each line, and a file size check
(in case an entire line got deleted, or you run AmigaDOS which cares
how large a file is).  Old uudecodes could have an error or three...
but you may never find out (until too late).

The version posted to comp.sys.amiga is old.  j.cc.purdue was down the
same day I sent the new version and Craig decided to post the old one.
(Murphy and his laws!!)
(It has been about two months since I sent the old one to him... he had
another "better" uu*code from the ST group that turned out to be vapor;
full of bugs, sloppy code and hard to convert back to an Amiga/UNIX
style interface. It also did not do checksums or filesize.)

BITNET has an incorrect ASCII<->EBCDIC table!!  I finally talked to
such a site, thus the upgrade.


>Also, I notice that an occasional encoded program has some sort of little
>printable ASCII table before the begin.  It looks like it is intended to
>be either a visual or perhaps auto-check for bad ASCII translations - 
>is this the case and does anyone know what code needs to be added...

The theory is that the table will get mangled the exact same way the file
was mangled.  It knows that the table *should* have, can compare with the
file, and can fix it up.  Only works on files encoded by it.

This is not in my uuencode/uudecode.  I do not plan to add it.  I do,
however, have code in my uudecode that checks for mangled files.  It can
even decode a damaged *old* file.
Common damage is spaces get changed to tabs, spaces get truncated at the
end of a line, BITNET hosts mangle the ASCII, etc.  The first is solved
by encoding space as "`", the rest are checks in the decode and thus
apply to any file, new or old.

The uudecode will report "Checksum error" to stderr only if the file was
encode with checksums.  It will report "file size mismatch" only if the
file has a file size encoded in it.  The space truncate and ASCII checks
are always active.  100% forward and back compatible.

My contributions to the code are free for all to use... use 'em, abuse 'em,
even put them on the BSD 4.4 tapes.  I'd like that, since I would then
have the security of receiving checksumed files, instead of just sending
them out!!!


|\ /|  . Ack! (NAK, EOT, SOH)
{O o} . 
 (")	bryce@hoser.berkeley.EDU -or- ucbvax!hoser!bryce
  U	


>From ames!aurora!labrea!rutgers!sunybcs!boulder!hao!hull Fri Sep 11 06:52:05 1987
Path: amdahl!ames!aurora!labrea!rutgers!sunybcs!boulder!hao!hull
From: hull@hao.UCAR.EDU (Howard Hull)
Newsgroups: comp.sys.amiga
Subject: Re: Question about uu*code
Summary: "A verb Senator, can we have a verb?"
Keywords: BITNET, uuencode, uudecode, security, checksums, BSD 4.4
Message-ID: <890@hao.UCAR.EDU>
Date: 11 Sep 87 13:52:05 GMT
References: <241@n8emr.UUCP> <3687@zen.berkeley.edu>
Distribution: usa
Organization: High Altitude Obs./NCAR, Boulder CO
Lines: 90

In article <3687@zen.berkeley.edu>, bryce@hoser.berkeley.edu (Bryce Nesbitt) writes:
> In article <241@n8emr.UUCP> lwv@n8emr.UUCP (Larry W. Virden) writes:
> 
> )I noticed that we just recieved two 'new' versions of uu*code which are VERY
> )similar.  The one in the Amiga group claims that it is the most compatible
                            ^^^^^
Which Amiga group, I wonder.  Is this an ARPA Abberation?

> )with others.  The one from comp.sources.misc (??) was almost identical...
> )...Even the comment wording is VERY VERY similar.
> 
> That's because they are the same program.  Four people have worked on those
> programs...  Mark, Alan, Fred and Bryce. (see the source for full names
> and net addresses).  I'm Bryce, the latest.
> 
Will the AMIGA representative please stand up?...
> 
> >Is the one dated Sept 7 a 'more correct' version?...
> >I dont want to generate incorrect encodings... 
> 
> Both versions produce identical encodings.  The comp.sources.misc version
> has a new uudecode that handles BITNET.  This is the only difference.
> 

Pardon me, sir, but will you please cut the hype and answer the man's question?

> The version posted to comp.sys.amiga is old.  j.cc.purdue was down the
> same day I sent the new version and Craig decided to post the old one.

Er, do you by any chance have an article ID number for this comp.sys.amiga
bogie?  Did you *really* mean comp.sys.amiga and not comp.sources.amiga?

> 
> BITNET has an incorrect ASCII<->EBCDIC table!!  I finally talked to
> such a site, thus the upgrade.

Let's have an article ID number for this one, too.

Now then, what I have is:

Message-ID: <905@s.cc.purdue.edu>
Date: 8 Sep 87 18:08:25 GMT
comp.sources.amiga

Message-ID: <906@s.cc.purdue.edu>
Date: 8 Sep 87 18:10:07 GMT
comp.binaries.amiga

1.) Are these sufficiently current that I should use them until you announce
a new version?
2.) If not, are you going to get bold and post a new version to comp.sys.amiga
in order to compensate for the latency of j.cc.purdue and its time-warp port,
comp.sources.amiga and comp.binaries.amiga ?  Is that a cool thing to do?

> >Also, I notice that an occasional encoded program has some sort of little
> >printable ASCII table before the begin.  It looks like it is intended to
> >be either a visual or perhaps auto-check for bad ASCII translations - 
> >is this the case and does anyone know what code needs to be added...
> 
> The theory is that the table will get mangled the exact same way the file
> was mangled.  It knows that the table *should* have, can compare with the
> file, and can fix it up.  Only works on files encoded by it.
> 
> This is not in my uuencode/uudecode.  I do not plan to add it.  I do,
> however, have code in my uudecode that checks for mangled files.  It can
> even decode a damaged *old* file.

Would you be able, by any chance, to say where the ASCII table version resides?
Would you also make some kind of comment stating that you either do or do not
appreciate this particular version, if so, why, if not, why not?

> My contributions to the code are free for all to use... use 'em, abuse 'em,
> even put them on the BSD 4.4 tapes.  I'd like that, since I would then
> have the security of receiving checksumed files, instead of just sending
> them out!!!

Thank you very, very much for your efforts on the uu* projects.  You are saving
thousands of other people many, many hours of agony.  My comments are directed
at trying to pick up another 1% of that savings, if possible.
> 
> |\ /|  . Ack! (NAK, EOT, SOH)
> {O o} . 
>  (")	bryce@hoser.berkeley.EDU -or- ucbvax!hoser!bryce
>   U	

						Best Regards,   Howard Hull
[If yet unproven concepts are outlawed in the range of discussion...
                 ...Then only the deranged will discuss yet unproven concepts]
	{ucbvax!hplabs | decvax!noao | mcvax!seismo | ihnp4!seismo} !hao!hull
	for domain mailers: hull@hao.ucar.edu


>From ames!sdcsvax!ucbvax!ucbcad!zen!hoser.berkeley.edu!bryce Fri Sep 11 08:57:04 1987
Path: amdahl!ames!sdcsvax!ucbvax!ucbcad!zen!hoser.berkeley.edu!bryce
From: bryce@hoser.berkeley.edu (Bryce Nesbitt)
Newsgroups: comp.sys.amiga
Subject: Re: Question about uu*code
Summary: "some verbs for my constituents" :-)
Keywords: BITNET, uuencode, uudecode, security, checksums
Message-ID: <3689@zen.berkeley.edu>
Date: 11 Sep 87 15:57:04 GMT
References: <241@n8emr.UUCP> <3687@zen.berkeley.edu> <890@hao.UCAR.EDU>
Sender: news@zen.berkeley.edu
Distribution: usa
Organization: Tubular Transport Devices, Ltd.
Lines: 114

In article <890@hao.UCAR.EDU> hull@hao.UCAR.EDU (Howard Hull) writes:
>In article <3687@zen.berkeley.edu>, (Bryce Nesbitt) writes:
)> In article <241@n8emr.UUCP> lwv@n8emr.UUCP (Larry W. Virden) writes:
)> 
)> The one in the Amiga group claims that it is the most compatible
)                             ^^^^^^
) Which Amiga group, I wonder.  Is this an ARPA Abberation?

Oops!  The groups that the uu*codes showed up in are comp.sources.misc,
comp.binaries.amiga and comp.sources.amiga.


>[uuencode brought to you by... Mark, Alan, Fred and Bryce...]
>Will the AMIGA representative please stand up?...

I'm standing.  Mr. Alan Roenthal, Mr. Fred Fish (and Keith Pyle) are you
also standing?  Ok, all of us disconnected nobodies that hacked on the
Amiga version are here, and god-willing, standing. 
 
What next?


>Pardon me, sir, but will you please cut the hype and answer the man's question?

I thought I had.  The versions are identical except that the one posted
to comp.sources.misc is more recent; it adds BITNET compatibility to
uudecode.  If you are not on BITNET it makes no difference.

It is unfortunate that both new and old versions got posted to different
groups the very same day.  As I said, j.cc.purdue.EDU was down.  The
source contains a date... so you can tell them apart.


>> BITNET has an incorrect ASCII<->EBCDIC table!!  I finally talked to
>> such a site, thus the upgrade.
>
>Let's have an article ID number for this one, too.

BITNET is a computer network, and does not have an article ID number,
as such.  I could probably pull up an internet gateway address...
but you don't want that.  You could call 1-800-IBM-INFO since IBM
created EBCDIC.  (EBCDIC is a character format, like ASCII, only weirder)


>[ article ID's from comp.sources.amiga comp.binaries.amiga]
>1.) Are these sufficiently current that I should use them until you announce
>a new version?

In a word -> YES!

If you are not on BITNET these versions will be just fine.  If you *are* on
BITNET you have never been able to uudecode files from USENET because
your machines are broken.  These uu*codes then, will be nothing new.


>2.) If not, are you going to get bold and post a new version to comp.sys.amiga
>in order to compensate for the latency of j.cc.purdue and its time-warp port,
>comp.sources.amiga and comp.binaries.amiga ?  Is that a cool thing to do?

In a word -> NO!

It's not cool.  This group has high enough volume as it is.  I'd like to
see the time-warp at purdue shorten, but I don't have control over that.
I also don't have a recent enough C compiler to feel good about posting
binaries.  Doc has Manx 3.4, which produces code half the size of my
Lattice 3.03. 

The new version with BITNET compatibility was sent to doc@j.cc.purdue.EDU,
it's up to the moderator what happens next.

If you are on BITNET, and need a uudecode that can deal with your machine,
just write.  I'll send you a uuencoded file. :-) :-)  (Strip the :-)'s...
I can tell you how to fix it with "ed".  They just swapped ~ and ^.)


>> >Also, I notice that an occasional encoded program has some sort of little
>> >printable ASCII table before the begin... 
>
>Would you be able, by any chance, to say where the ASCII table version resides?

I deleted my copy, too many bugs.  Craig Norberg, comp.{sources,binaries}.amiga
moderator, has one.  You could ask him.  (doc@j.cc.purdue.EDU)


>Would you also make some kind of comment stating that you either do or do not
>appreciate this particular version, if so, why, if not, why not?

The particular version aside, I feel the idea is unecessary.  It only
works for new files created by it.  An old file will still fail to decode
unless you fixed the problem directly (like my new BITNET version does).
It takes up space for little good.  That particular version also did
not do checksums or filesize, which I consider more important.

Naturally, all versions of my uudecode will decode a file even if it has
a table in front.  If you insist on a table, you can write it starting
with the current uu*codes as a base.

------------------
Now, to summarize:

The version released to comp.sources.amiga and comp.binaries.amiga is slightly
old due to a screwup.
The version released to comp.sources.misc is new.  The only substantial
difference is that the uudecode knows how to deal with files that have passed
though BITNET hosts.
-----------------

Did I use enough verbs?  :-)


|\ /|  . Ack! (NAK, EOT, SOH)
{O o} . 
 (")	bryce@hoser.berkeley.EDU -or- ucbvax!hoser!bryce
  U	


>From ames!hc!beta!cmcl2!rutgers!rochester!udel!burdvax!bpa!sjuvax!bbanerje Sun Sep 13 05:07:03 1987
Path: amdahl!ames!hc!beta!cmcl2!rutgers!rochester!udel!burdvax!bpa!sjuvax!bbanerje
From: bbanerje@sjuvax.UUCP (B. Banerjee)
Newsgroups: comp.sys.amiga
Subject: Re: Question about uu*code
Keywords: BITNET, uuencode, uudecode, security, checksums
Message-ID: <853@sjuvax.UUCP>
Date: 13 Sep 87 12:07:03 GMT
References: <241@n8emr.UUCP> <3687@zen.berkeley.edu> <890@hao.UCAR.EDU> <3689@zen.berkeley.edu>
Reply-To: bbanerje@sjuvax.UUCP (B. Banerjee)
Distribution: usa
Organization: St. Joseph's University, Phila. PA.
Lines: 86

bryce@hoser.berkeley.edu (Bryce Nesbitt) writes in Article <3689@zen.berkeley.edu>

In article <890@hao.UCAR.EDU> hull@hao.UCAR.EDU (Howard Hull) writes:

>> .... The  versions are  identical except that  the one  posted to
>> comp.sources.misc is more recent; it adds BITNET compatibility to
>> uudecode. If you are not on BITNET it makes no difference.

>> BITNET has an incorrect ASCII<->EBCDIC table!!  I finally talked to
>> such a site, thus the upgrade.

>> If you are on BITNET, and need a uudecode that can deal with your
>> machine,  just write.  I'll send  you a  uuencoded file.  :-) :-)
>> (Strip the :-)'s... I can tell you  how to fix it with "ed". They
>> just swapped ~ and ^.)

Unfortunately, there's no single correct ASCII-EBCDIC table.  You
also might have a problem even if you're *not* on BITNET.

Imagine the following situation:

---- Incoming Article via Bitnet -->| Bitnet-site|--> Outgoing article
							via uucp.
Now let's say you change that Bitnet to 'Foonet'.
That's where you have the problem.  Did you take every conceivable
mapping from FEBCDIC (Foonet Binary Coded ...) to ASCII into account?
If the article passed through a Bitnet (or Foonet) site on its way
to you, then it may have been corrupted.

>> >Also, I notice that an occasional encoded program has some sort of little
>> >printable ASCII table before the begin... 
>> 
>> >Would you also make some kind of comment stating that you either do or do not
>> >appreciate this particular version, if so, why, if not, why not?
>> 
>> The particular version  aside, I feel the idea  is unecessary. It
>> only works  for new files created  by it. An old  file will still
>> fail to decode unless you fixed the problem directly (like my new
>> BITNET version  does). It  takes up space  for little  good. That
>> particular version also did not do checksums or filesize, which I
>> consider more important.
>> 
>> Naturally, all versions of my uudecode will decode a file even if
>> it has a table in front. If  you insist on a table, you can write
>> it starting with the current uu*codes as a base.
>> 

This variant is known as the 'Dumas' uu{en,de}code, after the Gentleman
who authored it.  The idea is simple.  If you write a table of the
printable ascii characters before the actual beginning of the uuencoded
stuff, then *any* simple character transliterations due to bad mapping
can be undone.  This is true whether it is done by Bitnet or Foonet.
This version is *also* backwards compatible (Assumes standard ascii
if the table is missing), and (I think!) calculates a checksum.

A very nice addition is for multi-part uudecoded stuff (Part 1/3, etc.).
If the  input to be decoded ends with some line (of the form:
'include partb'; then 'partb is automaically read and decoded as well.
This doesn't break anything, as in the case of mult-part binaries, they
must be joined in an editor anyway.

The companion uuencode writes out the uuencoded output with the leading
character table, and (optionally) splits up the output into equally
sized pieces automagically.

Unfortunately, Mr. Dumas posted an update to comp.sys.atari.st recently, but
didn't include the source this time out (He had posted previous versions
of the source).  I think that he wants to try it out on various systems
before releasing it officially.

Anyhow, to re-iterate:

1. Both this and the Dumas version handle old-style uudencoded stuff.
2. Both versions add some sort of checksumming.
3. The Dumas version has some very useful capabilities that this version
lacks.
4. Each can (probably) decode the output of the other.
5. Keeping around multiple versions of uuencode is counterproductive.

Everyone has to decide for themselves which one they want.  But make
sure that your decision is an informed one.


		Binayak Banerjee
	{allegra | astrovax | bpa | burdvax}!sjuvax!bbanerje
		bbanerje%sjuvax.sju.edu@relay.cs.net


 
 
>From ames!think!husc6!sri-unix!rutgers!ucla-cs!zen!bryce Mon Sep 14 15:33:11 1987
Path: amdahl!ames!think!husc6!sri-unix!rutgers!ucla-cs!zen!bryce
From: bryce@hoser.berkeley.edu (Bryce Nesbitt)
Newsgroups: comp.sys.amiga
Subject: Re: Question about uu*code
Keywords: BITNET, uuencode, uudecode, security, checksums
Message-ID: <3739@zen.berkeley.edu>
Date: 14 Sep 87 22:33:11 GMT
References: <241@n8emr.UUCP> <3687@zen.berkeley.edu> <890@hao.UCAR.EDU> <3689@zen.berkeley.edu> <853@sjuvax.UUCP>
Sender: news@zen.berkeley.edu
Distribution: usa
Organization: Tubular Transport Devices, Ltd.
Lines: 95

In article <853@sjuvax.UUCP> bbanerje@sjuvax.UUCP (B. Banerjee) writes:
>bryce@hoser.berkeley.edu (Bryce Nesbitt) writes:
>In article <890@hao.UCAR.EDU> hull@hao.UCAR.EDU (Howard Hull) writes:
>
>Unfortunately, there's no single correct ASCII-EBCDIC table.  You
>also might have a problem even if you're *not* on BITNET.

Thank * for ASCII!  It's not perfect, but at least it usaully the same... :-)
I am aware that EBCDIC is not a constant.

>Imagine the following situation:
>
>---- Incoming Article via Bitnet -->| Bitnet-site|--> Outgoing article
>							via uucp.
>[...]
>If the article passed through a Bitnet (or Foonet) site on its way
>to you, then it may have been corrupted.

It does not matter where it was corrupted... it will still decode provided
it was one of the common manglings that files receive as they hop 'round
the world.  This is true for old unenlightened encodes as well as new ones.
...more on this later...

>[The Dumas encode]
>(I think!) calculates a checksum.

I think not.  Unless things have changed in the last month, the Dumas uu*code
had no checksum, no file size, and no sanity checks of any sort.  The way
split files was implemented is incompatible with the checksums that have
been used for quite a while.  (long before I even touched the source to
a uu*code)

>A very nice addition is for multi-part uudecoded stuff (Part 1/3, etc.).

This is good for huge files with limited mailers.  (64K or longer files
can get nuked.)  Even smaller files for Fido or other stange, small
nets.  It is nice that it is automatic.  I think the implementation was
terrible, incompatible, and only lightly thought out.  Write for details.

>...they
>must be joined in an editor anyway.

The other method is to use an editor... as you point out.

>Anyhow, to re-iterate:
>
>1. Both this and the Dumas version handle old-style uudencoded stuff.

True.

>2. Both versions add some sort of checksumming.

Don't think so.

>3. The Dumas version has some very useful capabilities that this version
>lacks.

The character table provides a generic way of handling swapped characters.
The Dumas encode does not decode many common manglings that have nothing
to do with this.  If you can already decode files you have nothing to worry
about except as a possible service to other people.
The split file thing has it uses... but I disagree in that it was incompatible
with checksumming and other points as to implementation.
I feel the Dumas code is sloppy (as did some other people who have no
connection to any of this.)  The implementation is very bad for use on
Unix or the Amiga... it just does not fit.
The Dumas uu*code does not transmit cross-system files very well (without
post-editing the file name).
The Dumas uu*code strays very far from the roots of the uu*code distributed
with Berkeley Unix.  The other one under discussion has the exact syntax.
If you are using the Amiga or Unix you would be better off to add the Dumas
features to the Unix version.

These are the reasons the comp.{sources,binaries}.amiga moderator decided
against the Dumas encodes.

>4. Each can (probably) decode the output of the other.

They collide on the checksum/split file counter.  If you decode
a Dumas file with the Amiga version you get false checksum mismatches.

>5. Keeping around multiple versions of uuencode is counterproductive.

True.  The situation now exists.  Multiple versions is not a problem,
incompatible versions is.  If only Dumas has heard of the checksummed
versions before starting...
(Since his work post-dates the checksums I put the "blame" on him.  However,
I realize that there are all sorts of reasons why he may not have heard
or cared about some other uu*code)
  

|\ /|  . Ack! (NAK, EOT, SOH)
{O o} . 
 (")	bryce@hoser.berkeley.EDU -or- ucbvax!hoser!bryce
  U	


SHAR_EOF
cat << \SHAR_EOF > uuencode.1
.TH UUENCODE 1 "1 Sep 1987"
.UC 4
.SH NAME
uuencode,uudecode \- encode/decode a binary file for transmission via
(plain text) mail
.SH SYNOPSIS
.B uuencode
[source] remotedest |
.B mail
sys1!sys2!..!decode
.br
.B uuencode
>outfile.uue source remotedest
.br
.B uuencode
>outfile.uue <source remotedest
.br
.B uudecode
[file]
.SH DESCRIPTION
.I Uuencode
and
.I uudecode
are used to send a binary file via uucp (or other) mail.  This combination can
be used over indirect mail links even when
.IR uusend (1C)
or other direct binary transmission methods are not available.
.PP
.I Uuencode
takes the named source file (default standard input) and produces an encoded
version on the standard output.  The encoding uses only printing ASCII
characters, and includes the mode of the file and the
.I remotedest
for recreation on the remote system.
.PP
.I Uudecode
reads an encoded file, strips off any leading lines added by mailers,
and recreates the original file with the specified mode and name.  If
there are other uuencoded files in the same input, they will be decoded
as well.
.PP
The intent is that all mail to the user ``decode'' should be filtered
through the uudecode program.  This way the file is created automatically
without human intervention.  This is possible on the uucp network by either
using
.I sendmail
or by making
.I rmail
be a link to
.I Mail
instead of
.I mail.
In each case, an alias must be created in a master file to get
the automatic invocation of uudecode.
.PP
If these facilities are not available, the file can be uudecoded manually.
.PP
The encode file has an ordinary text form and can be edited by any text editor
to change the mode or remote name.
.PP
This version of uuencode automatically adds checksums to each line, and
an overall file size to the end.  Old versions of uudecode will ignore this
extra information, new versions will check it and complain if it is in
error.
.PP
Care has been taken with these versions to compensate for most of the nasty
things editors and networks can do to files.  In particular, lines that
have had trailing spaces truncated are handled, as are files that have
passed through
.I BITNET
hosts.
.SH SEE\ ALSO
uuencode(5), uusend(1C), uucp(1C), uux(1C), mail(1)
.SH AUTHOR
Mark Horton
.br
Checksums and Amiga port by Alan J. Rosenthal
.br
File compatability added back in by Fred Fish
.br
File size check and various refinements by Bryce Nesbitt
.SH BUGS
The file is expanded by 35% (3 bytes become 4, plus control information)
causing it to take longer to transmit.
.PP
The user on the remote system who is invoking
.I uudecode
(often
.I uucp)
must have write permission on the specified file
SHAR_EOF
cat << \SHAR_EOF > uudecode.c
/* #ifndef lint
static char sccsid[] = "@(#)uudecode.c  5.3-1 (Berkeley) 9/1/87";
#endif */

/* Written by Mark Horton */
/* Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums */
/* Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for
   compatibility */
/* Modified by bcn (Bryce Nesbitt,ucbvax!cogsci!bryce) to fix a misleading
   error message on the Amiga port, to fix a bug that prevented decoding
   certain files, to work even if trailing spaces have been removed from a
   file, to check the filesize (if present), to add some error checking, to
   loop for multiple decodes from a single file, and to handle common
   BITNET mangling.  Also kludged around a missing string function in Aztec
   C */

/*
 * uudecode [input]
 *
 * Decode a file encoded with uuencode.  WIll extract multiple encoded
 * modules from a single file.	Can deal with most mangled files, including
 * BITNET.
 */

#include <stdio.h>
#include <ctype.h>

#ifdef AMIGA
#define AMIGA_LATTICE	    /* Set for Amiga Lattice C */
#define MCH_AMIGA
#define MPU68000
#endif

#ifdef unix
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif

#define SUMSIZE 64
#define DEC(c)	(((c) - ' ') & 077)    /* single character decode */

main(argc, argv)
char **argv;
{
FILE	*in, *out;
int	through_loop=0; /* Dejavu indicator */
int	mode;		/* file's mode (from header) */
long	filesize;	/* theoretical file size (from header) */
char	dest[128];
char	buf[80];

#ifdef AMIGA_LATTICE
extern	int Enable_Abort;
	Enable_Abort=1;
#endif

    /* A filename can be specified to be uudecoded, or nothing can
    be specified, and the input will come from STDIN */

    switch (argc)
	{
	case 1:
	in=stdin;
	break;

	case 2:
	if ((in = fopen(argv[1], "r")) == NULL)
	    {
	    fprintf(stderr, "ERROR: can't find %s\n", argv[1]);
	    fprintf(stderr, "USAGE: uudecode [infile]\n");
	    exit(10);
	    }
	break;

	default:
	fprintf(stderr, "USAGE: uudecode [infile]\n");
	exit(11);
	break;
	}

    /* Loop through file, searching for headers.  Decode anything with a
       header, complain if there where no headers. */

for (;;)
{
    /* search file for header line */
    for (;;)
	{
	if (fgets(buf, sizeof buf, in) == NULL)
	    {
	    if (!through_loop)
		{
		fprintf(stderr, "ERROR: no `begin' line!\n");
		exit(12);
		}
	    else
		{
		exit(0);
		}
	    }
	if (strncmp(buf, "begin ", 6) == 0)
	    break;
	}
    sscanf(buf, "begin %o %s", &mode, dest);

#ifdef unix
    /* handle ~user/file format */
    if (dest[0] == '~')
	{
	char *sl;
	struct passwd *getpwnam();
	char *index();
	struct passwd *user;
	char dnbuf[100];

	sl = index(dest, '/');
	if (sl == NULL)
	    {
	    fprintf(stderr, "Illegal ~user\n");
		exit(13);
	    }
	*sl++ = 0;
	user = getpwnam(dest+1);
	if (user == NULL)
	    {
	    fprintf(stderr, "No such user as %s\n", dest);
	    exit(14);
	    }
	strcpy(dnbuf, user->pw_dir);
	strcat(dnbuf, "/");
	strcat(dnbuf, sl);
	strcpy(dest, dnbuf);
	}
#endif

    /* create output file */
    if ((out = fopen(dest, "w")) == NULL)
	{
	fprintf(stderr, "ERROR: can't open output file %s\n", dest);
	exit(15);
	}
#ifdef unix
    chmod(dest, mode);
#endif

    decode(in, out, dest);

    if (fgets(buf, sizeof buf, in) == NULL || strncmp(buf,"end",3))
	{	       /* don't be overly picky about newline ^ */
	fprintf(stderr, "ERROR: no `end' line\n");
	exit(16);
	}

    if (!(fgets(buf,sizeof buf,in) == NULL || strncmp(buf,"size ",3)))
	{
	sscanf(buf, "size %ld", &filesize);
	if (ftell(out) != filesize)
	    {
	    fprintf(stderr, "ERROR: file should have been %ld bytes long but was %ld.\n", filesize, ftell(out));
	    exit(17);
	    }
	}
    through_loop = 1;
}   /* forever */
}   /* main */

/*
 * Copy from in to out, decoding as you go.
 * If a return or newline is encountered too early in a line, it is
 * assumed that means that some editor has truncated trailing spaces.
 */
decode(in, out, dest)
FILE *in;
FILE *out;
char *dest;
{
char buf[81];
char *bp;
int nosum=0;
#ifndef unix
extern errno;
#endif
register int j;
register int n;
int checksum, line;

    for (line = 1; ; line++)	/* for each input line */
	{
	if (fgets(buf, sizeof buf, in) == NULL)
	    {
	    fprintf(stderr, "ERROR: input ended unexpectedly!\n");
	    exit(18);
	    }

	/* Pad end of lines in case some editor truncated trailing
	   spaces */

	for (n=0;n<79;n++)  /* search for first \r, \n or \000 */
	    {
	    if (buf[n]=='\176')     /* If BITNET made a twiddle, */
		buf[n]='\136';     /* we make a caret           */
	    if (buf[n]=='\r'||buf[n]=='\n'||buf[n]=='\000')
		break;
	    }
	for (;n<79;n++)     /* when found, fill rest of line with space */
	    {
	    buf[n]=' ';
	    }
	buf[79]=0;	    /* terminate new string */

	checksum = 0;
	n = DEC(buf[0]);
	if (n <= 0)
	    break;	/* 0 bytes on a line??	Must be the last line */

	bp = &buf[1];

	/* FOUR input characters go into each THREE output charcters */

	while (n >= 4)
	    {
	    j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; putc(j, out); checksum += j;
	    j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; putc(j, out); checksum += j;
	    j = DEC(bp[2]) << 6 | DEC(bp[3]);	   putc(j, out); checksum += j;
	    checksum = checksum % SUMSIZE;
	    bp += 4;
	    n -= 3;
	    }

	    j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4;
		checksum += j;
		if (n >= 1)
		    putc(j, out);
	    j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2;
		checksum += j;
		if (n >= 2)
		    putc(j, out);
	    j = DEC(bp[2]) << 6 | DEC(bp[3]);
		checksum += j;
		if (n >= 3)
		    putc(j, out);
	    checksum = checksum % SUMSIZE;
	    bp += 4;
	    n -= 3;

#ifndef unix
	 /* Error checking under UNIX??? You must be kidding... */
	 /* Check if an error occured while writing to that last line */
	if (errno)
	    {
	    fprintf(stderr, "ERROR: error writing to %s\n",dest);
	    exit(19);
	    }
#endif

	/* The line has been decoded; now check that sum */

	nosum |= !isspace(*bp);
	if (nosum)			/* Is there a checksum at all?? */
	    {
	    if (checksum != DEC(*bp))	/* Does that checksum match? */
		{
		fprintf(stderr, "ERROR: checksum mismatch decoding %s, line %d.\n",dest, line);
		}
	    }	/* sum */
    }	/* line */
}   /* function */

#ifdef unix
/*
 * Return the ptr in sp at which the character c appears;
 * 0 if not found
 */
char *
index(sp, c)
register char *sp, c;
{
    do
	{
	if (*sp == c)
	    return(sp);
	}
    while (*sp++);

    return(0);
}
#endif unix

SHAR_EOF
cat << \SHAR_EOF > uuencode.c
/* #ifndef lint
static char sccsid[] = "@(#)uuencode.c  5.3-1 (Berkeley) 9/1/87";
#endif */

/* Written by Mark Horton */
/* Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums */
/* Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for
   compatibility */
/* Modified by bcn (Bryce Nesbitt,ucbvax!cogsci!bryce) to enable CTRL-C for
   Amiga Lattice C and add a transparant file size trailer for later check. */

/*
 * uuencode >outfile [infile] name
 *
 * Encode a file so it can be mailed to a remote system.  This version
 * transparantly adds line checksums and a file size for sanity checks.
 *
 */

#include <stdio.h>

#ifdef	AMIGA			/* Amiga Lattice C */
#define AMIGA_LATTICE
#define MCH_AMIGA
#define MPU68000
#endif

#ifdef unix
#include <sys/types.h>
#include <sys/stat.h>
#endif

#define SUMSIZE 64  /* 6 bits */
/* ENC is the basic 1 character encode function to make a char printing */
/* Each output character represents 6 bits of input */
#define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
long	totalsize=0;	/* Used to count the file size because ftell() does
			   not return sane results for pipes */

main(argc, argv)
char **argv;
{
    FILE *in;
    int mode;
#ifdef unix
    struct stat sbuf;
#endif
#ifdef AMIGA_LATTICE
    extern int Enable_Abort;	/* Enable CTRL-C for Lattice */
    Enable_Abort=1;
#endif

	/* optional 1st argument */
	if (argc > 2) {
		if ((in = fopen(argv[1], "r")) == NULL) {
			fprintf(stderr, "ERROR: can't find %s\n", argv[1]);
			fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
			exit(10);
		}
		argv++; argc--;
	} else
		in = stdin;

	if (argc != 2) {
		fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
		exit(11);
	}

#ifdef unix
	/* figure out the input file mode */
	fstat(fileno(in), &sbuf);
	mode = sbuf.st_mode & 0777;
#else
	mode = 0644;	    /* Default permissions */
#endif

	printf("\nbegin %o %s\n", mode, argv[1]);

	encode(in, stdout);

	printf("end\n");
	printf("size %ld\n",totalsize);
	exit(0);
}

/*
 * copy from in to out, encoding as you go along.
 */
encode(in, out)
FILE *in;
FILE *out;
{
#ifndef unix
extern errno;
#endif
	char buf[80];
	int i, n, checksum;

	for (;;) {
		/* 1 (up to) 45 character line */
		n = fr(in, buf, 45);
		putc(ENC(n), out);

		checksum = 0;
		for (i=0; i<n; i += 3)
		    checksum = (checksum+outdec(&buf[i], out)) % SUMSIZE;

		putc(ENC(checksum), out);
		putc('\n', out);

#ifndef unix
		/* Error checking under UNIX?? You must be kidding! */
		if (errno) {
		    fprintf(stderr, "ERROR: error writing to output\n");
			exit(12);
		    }
#endif
		if (n <= 0)
			break;
	}
}

/*
 * output one group of 3 bytes, pointed at by p, on file f.
 * return the checksum increment.
 */
int outdec(p, f)
char *p;
FILE *f;
{
	int c1, c2, c3, c4;

	c1 = *p >> 2;
	c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
	c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
	c4 = p[2] & 077;
	putc(ENC(c1), f);
	putc(ENC(c2), f);
	putc(ENC(c3), f);
	putc(ENC(c4), f);

	return((p[0]+p[1]+p[2]) % SUMSIZE);
}

/* fr: like read but stdio */
int
fr(fd, buf, cnt)
FILE *fd;
char *buf;
int cnt;
{
	int c, i;

	for (i=0; i<cnt; i++) {
		c = getc(fd);
		if (c == EOF)
			return(i);
		totalsize++;
		buf[i] = c;
	}
	return (cnt);
}
SHAR_EOF
#	End of shell archive
exit 0