Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!cbatt!ucbvax!MITRE-BEDFORD.ARPA!jhs From: jhs@MITRE-BEDFORD.ARPA.UUCP Newsgroups: comp.sys.atari.8bit Subject: Re: uuendecode/hexbin for the 8-bits... Message-ID: <8701301546.AA00827@mitre-bedford.ARPA> Date: Fri, 30-Jan-87 10:46:16 EST Article-I.D.: mitre-be.8701301546.AA00827 Posted: Fri Jan 30 10:46:16 1987 Date-Received: Sat, 31-Jan-87 07:46:55 EST References: <1959@ncoast.UUCP> Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 234 Brad: Attached is the uuencode/decode definition and a c program for it. I have fixed the uudecode that I posted so I think it now will work correctly. This version is in BASIC, so even those who don't have a c compiler can use it. Also, the inner workings are in machine language, so it is already fairly fast, possibly faster than your c version will be. I am (slowly) working on a version which does encoding as well. It may be a couple of months until I finish it, though, at the present rate of distractions. Uuencoding has its problems. Some of the characters in the character set get changed by some hosts. Lines ending in blanks sometimes get shortened in transit. I have a file of reports of such problems which you should probably read if you are serious about doing another version. -John Sangster jhs@mitre-bedford.arpa ----------------i-n-f-o---o-n---u-u-e-n-c-o-d-e-/-d-e-c-o-d-e----------------- From: randy@NLM-VAX.arpa (Rand Huntzinger) Organization: National Library of Medicine, Bethesda, Md ------------ Uudecode reads a file of the following format: header line(1)->begin data lines(many)-> trailer line(1)->end where: The header line fields contain: is a three digit number specifying a Unix file mode (specifies who can read and write the file. You can ignore this on a non-Unix machine. is the name of the file encoded below. You can use this if it is compatable with file names on your system. The data lines contain: is one character generated by adding the number of bytes encoded on this line to 32 (ASCII space). is the -32 bytes of binary data encoded into text to produce 4 bytes of text for every 3 bytes of binary data as follows: Input: Byte 1 Byte 2 Byte 3 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 \ / \ / \ / \ / \ / \ / \ / \ / ----- + ---- ----- + ------ ------ + ----- ----- + ---- | | | | + 32 + 32 + 32 + 32 | | | | V V V V Output: Byte 1 Byte 2 Byte 3 Byte 4 In other words, encoding involves taking 3 bytes, breaking it into 4 six bit chunks, adding 32 to each six bit value to make it an ascii character, and output them. To decode, you reverse this. Strip the parity bit, subtract 32 from each byte and repack into three words by shifting and or'ing the pieces. I don't think I'll spell this out, since it is an obvious reversal of the above steps. The last line in the section simply says 'end'. The file may contain junk before the begin statement and after the end statement. So the decoder usually skips until it sees begin, extracts the file name and decodes until it sees the end line. Be sure when you implement it that you use the length byte to determine the length of the decoded text, since stuff going though news sometimes gets padding added to the text. Also, you need to do this is you want to get the file length correct. I've included a posted uudecode source for the Atari 520 ST below. I've never used it, but it does give you something to look at. I don't know whether you read C, but it might still be of help. There is nothing which says it's copyrighted, so I assume it's public domain. If not, the copyright was removed before I saw it. Some of the cruft in it indicates it was originally written for Unix. I seem to have lost the credits on this one, I don't see who posted it. =========================================================================== /* * uudecode input * Modified for the ST - cannot use putc because of CR/LF problems * * create the specified file, decoding as you go. * used with uuencode. */ #include #include int_isconio; #define NULL 0 /* single character decode */ #define DEC(c)(((c) - ' ') & 077) intoutfile;/* File descriptor of output file */ charoutbuf[BUFSIZ];/* Output buffer for my character out code */ char*nextc= outbuf;/* Pointer to the next character */ #define lputc(outchar){*nextc++ = outchar;if (nextc >= &outbuf[BUFSIZ])do_write();} main(argc, argv) char **argv; { FILE *in; FILE *fopen(); int mode; char dest[128]; char buf[80]; _isconio = 1; /* mandatory input arg */ if (argc != 2) { printf("Usage: uudec filename\n"); exit(1); } if ((in = fopen(argv[1], "r")) == NULL) { printf("Cannot open: %s\n", argv[1]); exit(1); } _isconio = 0; /* search for header line */ for (;;) { if (fgets(buf, sizeof buf, in) == NULL) { printf("No begin line\n"); exit(3); } if (strncmp(buf, "begin ", 6) == 0) break; } sscanf(buf, "begin %o %s", &mode, dest); /* handle ~user/file format */ if (dest[0] == '~') { printf("Cannot handle user formats\n"); exit(1); } /* create output file */ if ((outfile = Fcreate(dest, 0)) < 0) {printf("Cannot create: %s\n", argv[2]); exit(1); } decode(in); if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) { printf("No end line\n"); exit(5); } exit(0); } /* * copy from in to outfile, decoding as you go along. */ decode(in) FILE *in; { 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, n); bp += 4; n -= 3; } } do_write(); } /* * 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, n) char *p; { 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) lputc(c1); if (n >= 2) lputc(c2); if (n >= 3) lputc(c3); } do_write() {longbytect; if (nextc != &outbuf[0]) {bytect = nextc - &outbuf[0]; if (Fwrite(outfile, bytect, outbuf) < 0) {printf("Write error on output file\n"); exit(1); } nextc = outbuf; } }