D PRG/ATOB-22.C /* * atob version 2.2 for cpm/msdos on packet radio * a program to transform binary to printable ASCII at a minimal* * 'cost' in conversion space - ratio is about 5/4 * * 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 * * * * * 86May30 - corrected 'y' as file name in duplicate target file and * * added ability to have garbage in front of, on the same * * line with the 'xbtoa Begin' line |br| ka2bqe * * 86May19 - modified to command line parsing, and recovery of input * * file name from header line. Should be able to handle ver* * sion 1.0 files w/o file name in header |br| - ka2bqe * * 86May05 - modified to compile/run for packet radio under cpm-80 & * * msdos by Brian B. Riley (ka2bqe) - RATS * * Hacked to work with non-UNIX machines by Brian Lloyd, 86/04/17 * * * */ #include #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; FILE * inf; FILE * outf; #define DE(c) ((c) - '!') /* * main - this is the ASCII-to-BINARY recovery routine. It queries for * and opens files and stream decodes and verifies checksum */ main(argc, argv) char **argv; { reg c; reg long int i; char infile[64]; char outfile[64]; char buf[100]; long int n1, n2, oeor, osum, orot; printf("\n atob: Ascii-to-Binary recovery\n RATS v2.2\n"); if(argc<2) {printf("Usage: atob infile \n");exit(2);} strcpy(infile,argv[1]); /* get inputfile name */ while ((inf = fopen(infile, "r")) == NULL) { printf("\n Error opening file - %s\n Input file: ",infile); if (gets(infile)==NULL) exit(); } /*search for header line*/ while ((c=getc(inf))!=EOF) {/* look for 'x'*/ if (c=='x') { if (fgets(buf, sizeof buf, inf) != NULL) { if (strncmp(buf, "btoa Begin",10) == 0) break; } else {printf("\n\7 *** EOF in header scan.\n" ); exit(0);} } } if (c==EOF) {printf("\n\7 *** EOF in header scan.\n");exit(0);} outfile[0] = '\0'; /* null outfile name string */ sscanf(buf,"btoa Begin %s\n",outfile); if (strlen(outfile) ) { printf("\n Header found ===> File: [%s] ",outfile); } else { printf( "\n Possible OLD header - Enter output file: "); if (gets(outfile)==NULL) exit(); } while ((outf = fopen(outfile,"r")) != NULL) { fclose(outf); printf("\n Target file name exists! Overwrite (Y/N) ? "); gets(buf); if (toupper(buf[0]) == 'Y') {break;} else { printf (" Enter new output filename : "); gets(outfile); } } fclose(outf); printf(" ===> Decoding "); if ((outf = fopen(outfile, "w")) == NULL) { printf( " File OPEN ERROR - [%s] - Disk full ???\n",outfile); fclose(outf); exit(); } while ((c = getc(inf)) != EOF) { if (c == '\n') {continue;} else if (c=='\r') {continue;} else if (c == 'x') {break;} else {decode(c);} } printf(" ===> *** EOF ***\n Checking trailer now"); if(fscanf(inf,"btoa End N %ld %lx E %lx S %lx R %lx\n", &n1, &n2, &oeor, &osum, &orot) != 5) { printf(" ===> \7Failure reading the trailer line.\n" ); exit(0); } if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) { printf(" ===> \7File checksum is bad.\n"); exit(0); } else { printf(" ===> File checksum is good.\n"); } fclose( inf ); fclose( outf ); exit(0); } /* * byteout - outputs a single binary byte to file * */ byteout(c) reg c; { Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000L)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; putc(c, outf); } /* * decode - stream decodes 5 'digit' ASCII back to 4 byte binary * */ decode(c) reg c; { if (c == 'z') { if (bcount != 0) { printf("z not on word boundary in decode.\n"); exit(0); } 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 { printf("Input character out of range in decode.(%02x)\n",c); exit(0); } }