[comp.sys.cbm] UUDECODER source code in C

scott@max.u.washington.edu (02/21/90)

For the those may not have access to a UUDECODER, you may not
be able to take benefit of like UX-Maze file exchange 
which require the files to be uuencoded.
If that is the case may be just may be the following posts
will be of help. This post contains the source code in
C of a UUDECODER tested on msc 3.0 and PCDOS 3.1.
Perhaps if you have access to an IBM/CLONE you could do
the file uudecoding on the IBM before the final transfer
to the C64 or C128.
Or perhaps if you are knowledgeable with programing you
could convert this program for the C64 or perhaps to another
popular language like Pascal or Fortran that is supported
by your system.
  
Sincerely,
Scott K. Stephen
 
 
 
--------------------------- cut here ---------------------------
/* usage for this file is as follows:
 * uudecode <input file name (with extension)>
 *     file is placed in the file name contained on the
 *     first line of the uuencoded file ...
 *
 * The program expects this to look like begin XXX <FN>
 * where XXX are the Unix(tm) file permissions
 *   and <fn> is the Unix file name.  If this name is
 *       too long for DOS, edit it to fit.  It has been
 *       tested with msc v3.0 and PC-DOS 3.1.  the companion
 *       file is uuencode.c ...
 */
#include <stdio.h>
#include <ctype.h>
 
/* single character decode */
#define DEC(c)  (((c) - ' ') & 077)
 
main(argc, argv)
char **argv;
{
        FILE *in, *out;
        struct sbuf;
        int mode;
        char dest[128];
        char buf[80];
 
        /* optional input arg */
        if (argc > 1) {
                if ((in = fopen(argv[1], "r")) == NULL) {
                        perror(argv[1]);
                        exit(1);
                }
                argv++; argc--;
        } else
                in = stdin;
 
        if (argc != 1) {
                printf("Usage: uudecode [infile]\n");
                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);
 
 
        /* create output file */
        out = fopen(dest, "w");
        if (out == NULL) {
                perror(dest);
                exit(4);
        }
        decode(in, out);
 
        if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
                fprintf(stderr, "No end line\n");
                exit(5);
        }
        exit(0);
}
 
/*
 * copy from in to out, decoding as you go along.
 */
decode(in, out)
FILE *in;
FILE *out;
{
        char buf[80];
        char *bp;
        int n;
 
        for (;;) {
                /* for each input line */
                if (fgets(buf, sizeof buf, in) == NULL) {
                        printf("Short file\n");
                        exit(10);
                }
                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 c1, c2, c3;
 
        c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
        c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
        c3 = DEC(p[2]) << 6 | DEC(p[3]);
        if (n >= 1)
                putc(c1, f);
        if (n >= 2)
                putc(c2, f);
        if (n >= 3)
                putc(c3, f);
}
 
 
/* fr: likeread 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);
}
 
/*
 * Return the ptr in sp at which the character c appears;
 * NULL if not found
 */
 
#define NULL    0
 
char *
index(sp, c)
register char *sp, c;
{
        do {
                if (*sp == c)
                        return(sp);
        } while (*sp++);
        return(NULL);
}