home *** CD-ROM | disk | FTP | other *** search
- /* 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 very
- misleading error message on the Amiga port, enable CTRL-C for LATTICE,
- and add a transparant file size trailer for later check. */
- /* Modified by Ueli Kaufmann (Ueli_Kaufmann@augs1.adsp.sub.org) for use
- in xprascii.library */
-
- #include <exec/types.h>
-
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
-
- #include "xproto.h"
- #include "xprascii.h"
-
- LONG AtoL(UBYTE *);
-
-
- #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') + ' ': '`')
-
- #define DEC(c) (((c) - ' ') & '\077') /* single character decode */
-
- VOID __stdargs upderr(struct XPR_IO *io, UBYTE *err, ...);
-
-
-
- VOID uuencode_header(UBYTE *name, UBYTE *buf)
- {
- sprintf(buf, "\nbegin 644 %s\n", name);
- }
-
-
- VOID uuencode_footer(UBYTE *buf, ULONG size)
- {
- sprintf(buf, "end\nsize %ld\n", size);
- }
-
-
- STATIC UBYTE outdec(UBYTE *buf_source, UBYTE *buf_dest)
- {
- buf_dest[0] = ENC( (buf_source[0] >> 2));
- buf_dest[1] = ENC(((buf_source[0] << 4) & '\060' | (buf_source[1] >> 4) & '\017'));
- buf_dest[2] = ENC(((buf_source[1] << 2) & '\074' | (buf_source[2] >> 6) & '\003'));
- buf_dest[3] = ENC(( buf_source[2] & '\077'));
-
- return((UBYTE)((buf_source[0] + buf_source[1] + buf_source[2]) % SUMSIZE));
- }
-
-
- VOID uuencode(UBYTE *buf_source, UBYTE *buf_dest, UBYTE *temp, UBYTE len)
- {
- UBYTE checksum, i, j;
-
- checksum = 0;
- for(i=0, j=0; i<len; i+=3, j+=4)
- checksum = (checksum + outdec(&buf_source[i], &temp[j])) % SUMSIZE;
- temp[j] = '\0';
-
- sprintf(buf_dest, "%lc%s%lc\n", ENC(len), temp, ENC(checksum));
- }
-
-
-
-
-
-
-
-
-
-
- struct my_fgets_data {
- ULONG inbuf;
- ULONG bufpos;
- };
-
-
-
-
- STATIC UBYTE *my_fgets(struct XPR_IO *io, UBYTE *buf_dest, ULONG maxlen, UBYTE *buf_source, VOID *fp_source, struct my_fgets_data *myfgd)
- {
- ULONG len, limit;
- UBYTE *ptr;
-
- VOID kprintf(UBYTE *, ...);
-
-
- if(myfgd->inbuf < maxlen)
- {
- if(myfgd->inbuf)
- movmem(buf_source + myfgd->bufpos, buf_source, 1024 - myfgd->bufpos);
-
- myfgd->inbuf += io->xpr_fread(buf_source + myfgd->inbuf, 1, 1024 - myfgd->inbuf, fp_source);
-
- myfgd->bufpos = 0;
-
- buf_source[myfgd->inbuf] = '\0';
- }
-
- if(myfgd->inbuf == 0)
- return(NULL);
-
- ptr = buf_source + myfgd->bufpos;
- len = 0;
- for(;;)
- {
- len++;
- if(ptr[0] == '\n' || ptr[0] == '\r' || ptr[0] == '\0')
- {
- if(ptr[1] == '\n' || ptr[1] == '\r')
- len++;
-
- break;
- }
-
- ptr++;
- }
-
-
- if(len == 0)
- return(NULL);
-
- limit = (myfgd->inbuf > maxlen) ? maxlen : myfgd->inbuf;
-
- if(len > limit)
- len = limit;
-
- memcpy(buf_dest, buf_source + myfgd->bufpos, len);
-
- buf_dest[len] = '\0';
- myfgd->inbuf -= len;
- myfgd->bufpos += len;
-
- return(buf_dest);
- }
-
-
- STATIC VOID uudecode(struct XPR_IO *io, UBYTE *fileName, UBYTE *buf_source, UBYTE *buf_dest, VOID *fp_source, VOID *fp_dest, struct my_fgets_data *myfgd)
- {
- ULONG line;
- LONG n;
- BOOL nosum=FALSE;
- UBYTE *buf_destptr, *bp, c, checksum;
-
- for(line=0; ; line++) /* for each input line */
- {
- if((buf_destptr = my_fgets(io, buf_dest, 80, buf_source, fp_source, myfgd)) == NULL)
- {
- upderr(io, "Input ended unexpectedly!");
- return;
- }
-
- for(n=0; n<79; n++) /* search for first \r, \n or \0 */
- {
- if(buf_destptr[n]=='\r' || buf_destptr[n]=='\n' || buf_destptr[n]=='\0')
- break;
- }
-
- for(; n<79; n++) /* when found, fill rest of line with space */
- buf_destptr[n] = ' ';
-
- buf_destptr[79] = '\0'; /* terminate new string */
-
- checksum = 0;
- n = DEC(buf_destptr[0]);
-
- if(n <= 0)
- break; /* 0 bytes on a line?? Must be the last line */
-
- bp = &buf_destptr[1];
-
-
- /* FOUR input characters go into each THREE output charcters */
-
- while(n >= 4)
- {
- c = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4;
- checksum += c;
- *buf_destptr++ = c;
-
- c = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2;
- checksum += c;
- *buf_destptr++ = c;
-
- c = DEC(bp[2]) << 6 | DEC(bp[3]);
- checksum += c;
- *buf_destptr++ = c;
-
- checksum = checksum % SUMSIZE;
- bp += 4;
- n -= 3;
- }
-
- c = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4;
- checksum += c;
- if(n >= 1)
- *buf_destptr++ = c;
-
- c = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2;
- checksum += c;
- if(n >= 2)
- *buf_destptr++ = c;
-
- c = DEC(bp[2]) << 6 | DEC(bp[3]);
- checksum += c;
- if(n >= 3)
- *buf_destptr++ = c;
-
- checksum = checksum % SUMSIZE;
- bp += 4;
- n -= 3;
-
- io->xpr_fwrite(buf_dest, 1, buf_destptr - buf_dest, fp_dest);
-
- /* 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? */
- upderr(io, "checksum mismatch decoding %s, line %ld.", fileName, line);
- }
- }
- }
-
-
- BOOL ProcessUUeFile(struct XPR_IO *io, UBYTE *buf_source, UBYTE *buf_dest, VOID *fp_source)
- {
- struct XPR_UPDATE xpru;
- struct my_fgets_data myfgd;
- VOID *fp_dest=0;
- LONG fileMode; /* ignored.. */
- BOOL thruLoop=FALSE; /* Dejavu indicator */
- BOOL success;
- UBYTE *buf_destptr, fileName[34], msgBuf[80];
-
- success = TRUE;
-
- myfgd.inbuf = 0;
- myfgd.bufpos= 0;
-
- /* Loop through file, searching for headers. Decode anything with a
- header, complain if there where no headers. */
-
-
- for(;;)
- {
- xpru.xpru_updatemask = XPRU_MSG | XPRU_FILENAME;
- xpru.xpru_msg = "";
- xpru.xpru_filename = "";
- io->xpr_update(&xpru);
-
-
- for(;;) /* search file for header line */
- {
- if((buf_destptr = my_fgets(io, buf_dest, 80, buf_source, fp_source, &myfgd)) == NULL)
- {
- if(thruLoop == FALSE)
- upderr(io, "No `begin' line!");
- return(FALSE);
- }
-
- if(strncmp(buf_destptr, "begin ", 6) == 0)
- break;
- }
-
- sscanf(buf_destptr, "begin %o %s", &fileMode, fileName);
-
- #if 0
-
- UBYTE *tmpptr;
-
- /* sscanf()-replacement */
-
- tmpptr = buf_destptr; /* search file for file name */
- while(iscntrl(tmpptr[1]) == FALSE)
- tmpptr++;
- tmpptr[1] = '\0';
-
- while(isspace(tmpptr[-1]) == FALSE)
- tmpptr--;
-
- strcpy(fileName, tmpptr);
-
- #endif
- if((fp_dest = (void *)io->xpr_fopen(fileName, "w")) == NULL) /* create output file */
- {
- upderr(io, "Cannot open output file `%s'", fileName);
- success = FALSE;
- break;
- }
-
-
- xpru.xpru_updatemask = XPRU_MSG | XPRU_FILENAME;
- sprintf(msgBuf, "Starting uudecode %s", io->xpr_filename);
- xpru.xpru_msg = msgBuf;
- xpru.xpru_filename = fileName;
- io->xpr_update(&xpru);
-
- uudecode(io, fileName, buf_source, buf_dest, fp_source, fp_dest, &myfgd);
-
- io->xpr_fclose(fp_dest);
- fp_dest = NULL;
-
- if((buf_destptr = my_fgets(io, buf_dest, 80, buf_source, fp_source, &myfgd)) == NULL ||
- strncmp(buf_destptr, "end", 3))
- {
- success = FALSE;
- upderr(io, "No `end' line"); /* don't be overly picky about newline ^ */
- break;
- }
-
- if(!((buf_destptr = my_fgets(io, buf_dest, 80, buf_source, fp_source, &myfgd)) == NULL ||
- strncmp(buf_destptr, "size ", 3)))
- {
- ULONG total, fileSize;
-
- total = io->xpr_finfo(fileName, 1);
-
- /*
- ** sscanf()-replacement
- ** filesize = AtoL(&buf_destptr[5]);
- */
-
- sscanf(buf_destptr, "size %ld", &fileSize);
- if(total != fileSize)
- {
- success = FALSE;
- upderr(io, "Filesize error (should=%ld is=%ld)", fileSize, total);
- break;
- }
- }
- thruLoop = TRUE;
- }
-
- if(fp_dest != NULL)
- io->xpr_fclose(fp_dest);
-
- return(success);
- }
-
-
- /* end of source-code */
-