/*
    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 */





