/* Program to "scrub" a WordStar text file back to a standard ASCII file. VERSION LIST, most recent version first 28/Apr/84 Revised to work on IBM-PC using Lattice. (P.H. Mack) 26/Sep/82 Forces MSB of all characters to 0, then scans for control codes. TAB, CR and LF are passed unchanged to the output file. US (soft hyphen) is replaced by a hard hyphen. Checking for legal CP/M filename on destination file added. Expanded "usage" message. Added "working" messages. Bill Bolton. This program was developed from a program called SCRUB on BDS "C" User Group disk "Utilities 2" (Volume 2 in the Software Tools RCPM BDSCAT.ALL). */ /* Macros for constant definitions */ #include "STDIO.H" #define VERSION 2 /* main version number */ #define REVISION 1 /* sub version number */ #define DEL 0x7F /* ASCII delete character */ #define WORKING 1024 /* number of chars between progress markers */ #define NEXTLINE (WORKING * 32) /* number of progess chars on a screen line */ #define BUFSIZ 1024 #define CPMEOF 0x1A int _fmode = 0x8000; FILE *fdin, *fdout, *fopen(); char *fname[3]; /* Argument vector indices */ /*************************************************** main to open the files for scrub() and handle invocation errors. ****************************************************/ main(argc,argv) int argc; char *argv[]; { char inbuf[BUFSIZ],outbuf[BUFSIZ]; char buf[12]; cprintf("\nWordStar file Scrubber Version %d.%d\n",VERSION,REVISION); cprintf("Bill Bolton, Software Tools\n"); if( argc != 3 ){ usage(); exit(); } else { fname[1]=argv[1];fname[2]=argv[2]; if((fdin = fopen(fname[1],"r")) == NULL){ cprintf("\nCannot find file %s\n",fname[1]); usage(); exit(); } else { if(bad_name(fname[2])) { cprintf("\nBad file name %s\n",fname[2]); usage(); exit(); } else { if((fdout = fopen(fname[2],"w")) == NULL ){ cprintf("\nCan't open %s\n",fname[2]); exit(); } else { cprintf("\nWorking\n\r "); scrub(fdin,fdout); } } } } fclose(fdin); fclose(fdout); exit(); } /*************************************************** procedure scrub -- copy file to file deleting unwanted control chars ****************************************************/ scrub(filein,fileout) FILE *filein; /* the input file buffer */ FILE *fileout; /* the output file buffer */ { int c; /* 1 char buffer */ unsigned count; /* count of characters processed */ unsigned count1; /* high word of count */ unsigned killed; /* numbers of bytes deleted */ unsigned hyphen; /* number of soft hyphens replaced */ count = 0; killed = 0; hyphen = 0; while( (c = getc(filein) & 0x7F) != EOF && c != CPMEOF ){ count++; if (count % WORKING == 0) cprintf("*"); /* still alive */ if (count % NEXTLINE == 0) cprintf("\n\t"); /* new line every so often */ if( c >= ' ' && c < '\177' ) /* visable character ? */ putc(c,fileout); else switch(c) { case '\r': case '\n': case '\t': putc(c,fileout); /* ok control chars */ break; case '\037': /* replace WS soft hyphen */ putc('-',fileout); hyphen++; break; default: killed++; break; /* ignore it */ } } putc(CPMEOF,fileout); /* sent textual end of file */ cprintf("\n"); cprintf("\n%u characters processed\n",count); cprintf("%u characters were deleted\n",killed); cprintf("%u soft hyphens replaced\n",hyphen); } /*************************************************** check for bad name ****************************************************/ int bad_name(buf) char *buf; { char fcb[36]; setfcb(fcb,buf); if (fcb[0] < 0 || fcb[0] > 15) /* check for valid drive */ return(ERROR); return(valid_check(fcb)); } /*************************************************** ****************************************************/ int valid_check(buf) char *buf; { int index; for (index = 1; index < 12; ++index){ if (bad_char(index,buf)) return(-1); } return(0); } /*************************************************** Checks if a character is legal in a CP/M directory entry or file control block ****************************************************/ int bad_char(index,buf) int index; char *buf; { char temp[1]; /* Transient storage for > del test */ int space; if (index == 1 || index == 9) /* Reset at start of filename & typ */ space = 0; switch (buf[index]){ case '*': case ',': case '.': case ':': case ';': case '<': case '=': case '>': case '?': case '[': case ']': case DEL: return(-1); case ' ': /* Space is conditionally illegal */ if (space == 7) /* Filename is all spaces is a */ return(-1); /* definite error */ space++; /* Else just keep track of how many */ return(0); } if (buf[index] < ' ' || (buf[index] >= 'a' && buf[index] <= 'z')) return(-1); if (buf[index] > DEL){ /* Bit 7 set may be legal attribute */ temp[0] = buf[index] & DEL; /* so force it to 0 and try again */ return (bad_char(0,temp)); } else return(space); /* Space preceeding char IS illegal */ } /*************************************************** usage description ****************************************************/ usage() { cprintf("\nUsage:\n\n\r"); cprintf("\tSCRUB d:file1 d:file2\n\n\r"); cprintf("Where:\n\r"); cprintf("\tfile1 = source file, (* and ? not allowed)\n\r"); cprintf("\tfile2 = destination file, (* and ? not allowed)\n\r"); cprintf("\td: = optional drive identifier\n\n\r"); cprintf("i.e.\tSCRUB A:FOOBAR.WST B:FUBAR.DOC\n\r"); } /* end of scrub */