[comp.sys.atari.st] uuencode & uudecode

awacs-doca@BUCKNER-EMH.ARPA (09/17/87)

To all:

    I'm a newcomer to this mailing list and this is the first I've heard
of these two programs. Would someone please tell me:
1.  Their purpose
2.  Instructions for use
3.  Means of decoding

    From what I've read, I assume that if you want to send a program of some st over this network, you might send it encoded (so it appears as text and easier to transmit as data?). Then you must decode to run it. The way I'm tied in to
this network, I can only -read- a file in ascii, not copy it direct to disk;
such as in an xmodem download from a bbs. I would like to try some of the programs that are available on score.stanford.edu, but when I get them, they all
start with lines of roughly the same length all beginning with 'M'.

     Anyway, can somebody shed some light on this gap in my data bank?

                   Barry C. Watson (BCW) awacs-doca.

rich@lakesys.UUCP (09/18/87)

What you might want to do issimply to capture the information, then send it 
out as a file from your capture buffer.

When on disk, use a text editor to read it in, and remove  *all the 
message header lines to where the encoded programs starts. Also remove 
that comes at the end, after the end$ line. Be sure to remove ALL of the 
more -- etc....  lines between the two. 

Then use UUdecode, and decode the file. Works for me every time.

Lake Systems & Milwaukee            |      Who and where ????
 Atari ST user's/Xenix              |     User's helping user's

koster@msudoc.UUCP (09/18/87)

In article <211@lakesys.UUCP> rich@+++.UUCP (Rich Dankert) writes:
>What you might want to do issimply to capture the information, then send it 
>out as a file from your capture buffer.
>
>When on disk, use a text editor to read it in, and remove  *all the 
>message header lines to where the encoded programs starts. Also remove 
>that comes at the end, after the end$ line. Be sure to remove ALL of the 
>more -- etc....  lines between the two. 
>
>Then use UUdecode, and decode the file. Works for me every time.
>
>Lake Systems & Milwaukee            |      Who and where ????
> Atari ST user's/Xenix              |     User's helping user's

After seeing several requests for a UUdecode in some format other than
UUCoded, I thought it might be nice for some wonderful person to put
some source up on the net.  The result follows.

I have compiled the below under Megamax, but not any other compilers.  I
expect that it should go OK on MWC, as well as [garf] Alcyon.

There's another post up here somewhere that has a more current version
of uudecode/uuencode.  I have tried the code below, and while it isn't
the most full featured version of uudecode, it works.

Later.

{ihnp4|uumich}!msudoc!koster

(*-----------------------------cut here--------------------------*)
/*
 * Uudecode -- decode a uuencoded file back to binary form.
 *
 * Useage: (CLI) uudec <uuencoded filename>
 *         (GEM) click on uudec.ttp
 *               enter <uuncoded filename> in dialog box
 *               hit CR
 *
 * Result: File specified in first line of uuencoded file is created,
 *         contents of uuencoded file are decoded and placed into
 *         the created file.
 *
 * How it works:
 *         The bits of every three consecutive bytes of the binary file are
 *         encoded into four consecutive printable ascii bytes according
 *         to the following diagram:
 *
 *               |         |         |         |         |
 *               |x1x2|3456|x7x8|1234|x5x6|7812|x3x4|5678|
 *               -----------------------------------------
 *
 *         where the long vertical bars separate bytes and the short
 *         vertical bars separate half bytes.  The x'ed bits are not
 *         important to us (they are given values which result in
 *         printable ascii characters).  The first eight digits
 *         increasing in order from 1 to 8 mark the positions of the
 *         first byte of the group of three binary bytes.  The next
 *         eight mark the second byte and so on.  Each line of the
 *         encoded file contains a count character followed a number
 *         (multiple of four) of encoded bytes.  To decode we merely
 *         need to go through the usual bit pushing.
 *
 * Problems: Contact J. Franco (franco@indiana.CSNET)
 *
 * Comment: This should work.  I successfully downloded the recently posted
 *          RTXDEMO with no trouble whatsoever (and that is a pretty big
 *          file).
 *
 * Note:    This is the latest of a number of hacks of a uudecoder originally
 *          intended for the IBM PC. (3/6/86 - JVF)
 */

#include <stdio.h>
#include <osbind.h>

char *Progname = "UUDECODE";

#define USAGE "Usage: UUDECODE [file]\n"

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

FILE *in, *out, *efopen(), *efopenb(), *fopen(), *fopenb() ;

main(argc, argv)
        int argc; char *argv[];
        {

        int mode;
        char dest[128];
        char buf[80];
        /* optional input arg */
        if (argc > 1) {
                in = efopen(argv[1], "r");
                argv++; argc--;
                }
        else
                in = stdin;
        if (argc != 1) {
                fprintf(stderr, USAGE);
                exit(2);
                }
        /* search for header line */
        for (;;) {
                if (fgets(buf, sizeof buf, in) == NULL) {
                        fprintf(stderr, "No begin line\n");
                        exit(3);
                        }
                if (strncmp(buf, "begin ", 6) == 0)
                        break;
                }
        sscanf(buf, "begin %o %s", &mode, dest);
        out = efopenb(dest, "bw");  /* create output file */
        decode(in, out);
        fclose(out);
        if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
                fprintf(stderr, "No end line\n");
                exit(5);
                }
        }

/*
 * copy from in to out, decoding as you go along.
 */

decode(in, out)
        FILE *in, *out;
        {
        char buf[80];
        char *bp;
        int n;
        for (;;) {
                if (fgets(buf, sizeof buf, in) == NULL) {
                        fprintf(stderr, "Short file\n");
                        break;
                        }
                n = DEC(buf[0]);
                if (n <= 0)
                        break;
                bp = &buf[1];
                while (n > 0) {
                        outdec(bp, out, n);
                        bp += 4;
                        n -= 3;
                        }
                }
        }

/*
 * output a group of 3 bytes (4 input characters).
 * the input chars are pointed to by p, they are to
 * be output to file f.  n is used to tell us not to
 * output all of them at the end of the file.
 */

outdec(p, f, n)
        char *p; FILE *f; int n;
        {
        int c1, c2, c3;
        c1=((*p&64)<<1)   | ((*p&31)<<2)   | ((p[1]&64)>>5) | ((p[1]&16)>>4);
        c2=((p[1]&15)<<4) | ((p[2]&64)>>3) | ((p[2]&28)>>2);
        c3=((p[2]&3)<<6)  | ((p[3]&64)>>1) | ((p[3]&31));
        if (n >= 1)
           { if (c1 == 13)
                  fprintf(f,"%c",13);
             else
                  putc(c1, f);
           }
        if (n >= 2)
           { if (c2 == 13)
                  fprintf(f,"%c",13);
             else
                  putc(c2, f);
           }
        if (n >= 3)
           { if (c3 == 13)
                  fprintf(f,"%c",13);
              else
                  putc(c3, f);
           }
        }


/* 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);
                buf[i] = c;
                }
        return (cnt);
        }

/* If your library already has this function, use it and nuke the code below */

#ifdef noindex
/*
 * Return the ptr in sp at which the character c appears;
 * NULL if not found
 */

char *index(sp, c)
        register char *sp, c;
        {
        do {
                if (*sp == c)
                        return(sp);
                } while (*sp++);
        return(NULL);
        }
#endif


/* Open a file, aborting on failure */

/* Written by Bernie Roehl, June 1985 */

FILE *
efopen(fn, mode)
        char *fn, *mode;
        {
        FILE *unit;
        if ((unit = fopen(fn, mode)) == NULL)
                error("Cannot open file %s", fn);
        else
                return unit;
        }

extern char *Progname;

error(s1, s2)
        char *s1, *s2;
        {
        fprintf(stderr, "%s: ", Progname);
        fprintf(stderr, s1, s2);
        exit(1);
        }



/*
 * efopenb is a slightly modified efopen()
 * All it does is use the ST fopenb() call to open
 * a binary file.
 * Note that this is uuencode so only the input file
 * needs to be opened with this function.
 */

FILE *
efopenb(fn, mode)
        char *fn, *mode;
        {
        FILE *unit;
        if ((unit = fopen(fn, mode)) == NULL)
                error("Cannot open file %s", fn);
        else
                return unit;
        }