mrapple@quack.UUCP (Nick Sayer) (10/09/89)
Source follows: /* atob: version 4.0 * stream filter to change printable ascii from "btoa" back into 8 bit bytes * if bad chars, or Csums do not match: exit(1) [and NO output] * * Paul Rutter Joe Orost * philabs!per petsd!joe */ #include <stdio.h> #define reg register #define streq(s0, s1) strcmp(s0, s1) == 0 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) long int Ceor = 0; long int Csum = 0; long int Crot = 0; long int word = 0; long int bcount = 0; fatal() { fprintf(stderr, "bad format or Csum to atob\n"); exit(1); } #define DE(c) ((c) - '!') decode(c) reg c; { if (c == 'z') { if (bcount != 0) { fatal(); } else { byteout(0); byteout(0); byteout(0); byteout(0); } } else if ((c >= '!') && (c < ('!' + 85))) { if (bcount == 0) { word = DE(c); ++bcount; } else if (bcount < 4) { word = times85(word); word += DE(c); ++bcount; } else { word = times85(word) + DE(c); byteout((int)((word >> 24) & 255)); byteout((int)((word >> 16) & 255)); byteout((int)((word >> 8) & 255)); byteout((int)(word & 255)); word = 0; bcount = 0; } } else { fatal(); } } FILE *tmp_file; byteout(c) reg c; { Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; putc(c, tmp_file); } main(argc, argv) char **argv; int argc; { reg c; reg long int i; char tmp_name[100]; char buf[100]; long int n1, n2, oeor, osum, orot; if (argc != 1) { fprintf(stderr,"bad args to %s\n", argv[0]); exit(2); } sprintf(tmp_name, "/tmp/atob.%x", getpid()); tmp_file = fopen(tmp_name, "w+"); if (tmp_file == NULL) { fatal(); } setbuf(tmp_file,NULL); /* hack to prevent w+ bugs */ unlink(tmp_name); /* Make file disappear */ /*search for header line*/ for (;;) { if (fgets(buf, sizeof buf, stdin) == NULL) { fatal(); } if (streq(buf, "xbtoa Begin\n")) { break; } } while ((c = getchar()) != EOF) { if (c == '\n') { continue; } else if (c == 'x') { break; } else { decode(c); } } if(scanf("btoa End N %ld %lx E %lx S %lx R %lx\n", &n1, &n2, &oeor, &osum, &orot) != 5) { fatal(); } if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) { fatal(); } else { /*copy OK tmp file to stdout*/; fseek(tmp_file, 0L, 0); for (i = n1; --i >= 0;) { putchar(getc(tmp_file)); } } exit(0); } This is the standard atob.c file, except that the line "setbuf(tmp_file,NULL);" has been added right after checking to make sure tmp_file!=NULL (i.e. after making sure the file really was opened). I've been told this fixes a bug having to do with the way v7 munges buffering when opening a file "w+." This seems to MODIFY the behaivor, but not fix it, as the result of running this program on a known-good btoa file is that you get exactly the correct number of ^? (EOF) characters. This is consistent. The same bug fix applied to vnews (actually visual.c in news B) results in the same behavior. Adding an ftell after the fseek near the end of the file results, of course, in 0 being returned. Anyone have any opinions? --------------------------------------------------------------------- Nick Sayer | ...{ lll-winken!cheers ucdavis!uop } !quack!mrapple .... or.... cheers!quack!mrapple@apple.com or quack!mrapple@uop.edu Packet radio: N6QQQ @ WB6V | FredMail: NSAYER@MADERA%NORCAL Disclaimer: The BBC would like to appologise for that announcement