[comp.os.vms] bakwrdness

SMART@ditmelb.OZ.AU (Robert Smart) (06/07/88)

The thing I like about the world electronic network is the chance
it gives you to be stupid on a really large stage. My previous
diff for bakwrd had a bug. This seems to work, doubtless has other
bugs. Anyway it has an extra feature: BAKWRD FILE/-n will only
print the last n lines (scrolled backwards on a vt100). The new
bakwrd.c follows (not a diff). Don't forget the rmsio.c patch from
previous posting.

/*
    Program BAKWRD

    Programmed by C.J. BOL, Agricultural University Wageningen.
        bitnet: BOL@HWALHW50
        surf:   LUWRVD::BOL
        phone:  (+31) 08370-84715

    This program reads a file, starting at the fileend, n records
    at the time. So BAKWRD file/10 gives you groups of 10 records in
    correct order, starting with the last 10 records in the file.

    Not supported are relative, indexed and hashed files.

    $ BAKWRD == "$DEV:[USER]BAKWRD "
    $ BAKWRD [file[/n]]

*/
#define MAIN
#include stdio
#include "bakwrd.h"

int line = 0;

main(argc,argv)char *argv[];{
        int *rmsopen(),i,j,n,blk;
        char *pc,fnam[100];

        *fnam = 0;
        if(argc>2) {
            printf("\007Only one argument permitted\n");
            exit();
        }
        if(argc==2)
            strcpy(fnam,argv[1]);

        do{
            jrec     = MAXREC;
            pergroep = groep = 1;
            inrec    = nline = 0;
            if(argc!=2){
                printf("\nfile[/n] >");
                if(!gets(fnam))
                    exit();
            }
            for(i=j=0; fnam[i] ; i++)
                if(fnam[i]>' ')
                    fnam[j++] = toupper(fnam[i]);
            fnam[j] = 0;

            if(*fnam == 0)
                exit();

            if(pc = strchr(fnam,'/')){
                *pc++ = 0;
                pergroep = atoi(pc);
            }

            if(!(fh = rms_open(fnam))){
                printf("?Cannot open [%s]\n",fnam);
                continue;
            }
            rms_info(fh,"fop org rat rfm mrs alq ebk ffb fsz",
                &fop,&org,&rat,&rfm,&mrs,&alq,&ebk,&ffb,&fsz);

            switch(org){
                case 0:  break;
                case 16: printf("\n\007Relative files not supported!\n");
                         continue;
                case 32: printf("\n\007Indexed files not supported!\n");
                         continue;
                case 48: printf("\n\007Hashed files not supported!\n");
                         continue;
                default: printf("\n\007Only sequential files are supported!\n");
                         continue;
            }

            filesize = (ebk-1)*512 + ffb;       /* filesize in char     */

            if (pergroep>1){
                if(mrs<=0)
                    mrs = 255;
                if(pergroep*mrs > MAXREC-pergroep) {
                    pergroep = MAXREC/(mrs+1);
                    if(pergroep==0){
                       printf("\n? Max. recordsize=%d is too big!\n",mrs);
                       rms_close(fh);
                       continue;
                    }
                    printf("\n\007Groupsize modified, now %d\n",pergroep);
                }
            }

            blk   = ebk - (ffb ? 0:1);
            blok1 = blok2 = delim = 0;
            switch(rfm){
                case 1 : typrfm1(blk); break;  /* FIXED LENGTH          */
                case 2 : typrfm2();    break;  /* VAR                   */
                case 3 : typrfm3(blk); break;  /* VAR+FIXEDLENGTHCONTROL*/
                case 5 :                       /* STREAM (LF)           */
                case 6 : typrfm5(blk); break;  /* ..     (CR)           */
                default:
                        printf("\nNot supported record format rfm=%d",rfm);
            }
            if(pergroep<=0){
                if(line>23) printf("\033[H\033M");
                printf("\033[1;24r\033[24H\n");
            }
        }while(argc!=2);
}

addc(c)char c;{
    if(inrec==0 &&(c==' ' || c== '\t')) return; /* skip trailing blanks */
    rec[--jrec] = (c==delim? '\n' : c);
    inrec++;
    if(c == delim){
        if(++nline >= pergroep){
            register extra = (inrec-2)/80; if( extra<0) extra = 0;
            if(pergroep > 1) printf("\n\033[7m group %6d    \033[0m",groep++);
            if(pergroep <=0){ 
                register ii;
                if ( pergroep!=0 && line >= -pergroep) goto nxt;
                /* be clever. If nline<=24 then set scroll lines 1 to 
                   24-nline+1 and scroll that up, then write on line 24-nline+1.
                   Otherwise leave scroll lines 1 to 24, scroll that down, and
                   write on line 1. */
                if( line+1+extra<24){
                    printf("\033[1;%dr\033[%dH\n", 24-line, 24-line);
                    for( ii = 0; ii<extra; ii++) printf("\n");
                    for( ii = 0; ii<extra; ii++) printf("\033M");
                } else {
                    if( line<24) printf("\033[1;24r\033[%dH\033[K", 24-line-1);
                    else printf("\033[H\033M\033[K");
                    for( ii = 0; ii<extra; ii++) printf("\033M\033[K");
                }
            }
            fwrite(rec+jrec+(pergroep==0?1:0),inrec-(pergroep==0?1:0),1,stdout);
           nxt:
            line += 1+extra; /* lines printed so far */
            inrec = nline = 0;
            jrec     = MAXREC;
        }
    }
}