/* 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 */ /* * DjG - Don Glostein * made changes to code for compiling on non-unix compilers. Main changes * were to the long constants. Originally, not all of them were declared * as such and some compilers promoted in undefined ways. Unlink() function * call moved to end. If done while file was open, on some operating systems * this produced an error at best, and lost clusters at worst. * Introduced code for temp_file to be not in the /tmp directory, for non * unix systems. Introduced SETMODE for those operating systems that default * to new line translation (text mode) for stdin/stdout buffered streams. * NOTE: check the SETMODE and TEMPFILE defines. Make sure they are right for * your machine. * NOTE: if this code is compiled with no defines, then it will default to the * unix operating system version. */ #include /* include for all */ #ifdef MSC #include #include #define SETMODE(x) setmode(fileno((x)),O_BINARY) #define TEMPFILE "atob.%x" #endif #ifdef MWC_ATARI #define SETMODE(x) ((x)->_ff &= ~(_FASCII)) #define TEMPFILE "atob.%x" #endif /* following take care of unix systems */ #ifndef TEMPFILE #define TEMPFILE "/usr/tmp/atob.%x" #endif #ifndef SETMODE #define SETMODE(x) #endif #define reg register #define streq(s0, s1) strcmp(s0, s1) == 0 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) long int Ceor = 0L; long int Csum = 0L; long int Crot = 0L; long int word = 0L; int bcount = 0; FILE *tmp_file= (FILE *)NULL; char tmp_name[100]= {'\0'}; fatal() { fprintf(stderr, "bad format or Csum to atob\n"); if (tmp_file != (FILE *)NULL) unlink(tmp_name); 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(); } } 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; { reg c; reg long int i; int ret; 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,TEMPFILE,getpid()); tmp_file = fopen(tmp_name, "w+"); if (tmp_file == NULL) { perror("couldn't open temp file"); fatal(); } else { /* successful opens, reset mode on text conversion systems */ SETMODE(stdin); SETMODE(tmp_file); SETMODE(stdout); } /*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((ret= scanf("btoa End N %ld %lx E %lx S %lx R %lx\n", &n1, &n2, &oeor, &osum, &orot)) != 5) { fprintf(stderr,"\nscanf returned %d",ret); 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)); } } unlink(tmp_name); /* Make file disappear */ exit(0); }