home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992, 1993 Peter Edward Cann, all rights reserved.
- */
-
- #include<stdio.h>
- #include<stdlib.h>
- #include<bios.h>
- #include<dos.h>
- #include<fcntl.h>
- #include<signal.h>
- #include<process.h>
- #include"port.h"
- #include"comscrpt.h"
-
- #define MAXNSCANS 32
-
- struct
- {
- unsigned char index;
- unsigned char *str;
- unsigned char hitlabel;
- }
- scans[MAXNSCANS];
-
- int nscans;
-
- #define MAXKEYS 64
-
- struct
- {
- unsigned char key;
- unsigned char label;
- }
- keys[MAXKEYS];
-
- short int labels[256]; /* Not a #define cause we use unsigned char all over */
-
- unsigned short int rregs[256]; /* Same deal */
-
- short int jregs[256]; /* ditto */
-
- unsigned long tick;
-
- void (interrupt far *oldtick)();
-
- void interrupt far tickhndl()
- {
- tick++;
- }
-
- quit()
- {
- cleanup(0);
- _dos_setvect(0x1c, oldtick);
- exit(99);
- }
-
- char demonflag, flowctlflag;
-
- sendchar(c)
- unsigned char c;
- {
- if(flowctlflag) /* A small ugly speed hack; don't want in loop */
- while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
- {
- if(kbhit())
- if(getch()==24)
- demonflag=1;
- }
- else
- while(!(inp(basereg+STATREG)&TXMTMASK))
- {
- if(kbhit())
- if(getch()==24)
- demonflag=1;
- }
- outp(basereg, c);
- return(0);
- }
-
- int follow;
-
- sleep()
- {
- long tod, tod1;
- tick=0L;
- while(1)
- {
- if(tick>8)
- break;
- }
- }
-
- FILE *scriptfd;
- int mainargc, proglen;
- char **mainargv;
- struct line far *program;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *outfile, *infile;
- char c, fpname[256], str[81], *sptr, spawnpath[81], line[256];
- char comstr[16], speedstr[16], bitsstr[16], *spawnargv[41];
- int i, j, k, argn, mkeyp, lni, lnl;
- int value[8], flag, progcnt, demon, curkey, spawnargc;
- unsigned execretn;
- long timestamp, tstamp, tstamp1;
- program=(struct line *)malloc(PROGSIZ*sizeof(struct line));
- if(!program)
- {
- printf("Unable to allocate program buffer (compiled for %d statements).\n", PROGSIZ);
- exit(123);
- }
- mainargc=argc;
- mainargv=argv;
- index=follow=0;
- printf("Copyright (C) 1992, 1993 Peter Edward Cann, all rights reserved.\n");
- if(!strcmp(getenv("REMOTE"), "YES"))
- {
- printf("You appear to be logged in remotely, judging by the environment\n");
- printf("variable REMOTE, so it strikes me as somewhat peculiar that you\n");
- printf("want to run COMSCRPT. Are you sure you want to do it? (y or n) --> ");
- if(getchar()!='y') /* Note getchar() and not getch()! */
- {
- printf("I didn't think so!\n");
- exit(98);
- }
- else
- printf("OK, you're the boss!");
- }
- if(argc<2)
- {
- printf("USAGE: comscrpt <script file basename> [<sub arg>] ...\n");
- printf("The environment variable PCCPPATH is used for the script file if set.\n");
- exit(1);
- }
- fpname[0]='\0';
- if(getenv("PCCPPATH")!=NULL)
- sprintf(quicke, "%s\\", getenv("PCCPPATH"));
- else
- quicke[0]='\0';
- if((quicke==NULL)||(argv[1][0]=='.')||(argv[1][0]=='\\')||(argv[1][0]&&(argv[1][1]==':')))
- sprintf(fpname, "%s.scr", argv[1]);
- else
- sprintf(fpname, "%s%s.scr", quicke, argv[1]);
- if((scriptfd=fopen(fpname, "r"))==NULL)
- {
- printf("Error opening script file %s.\n", fpname);
- exit(2);
- }
- outfile=infile=NULL;
- flowctlflag=1;
- fgets(str, 80, scriptfd);
- for(i=0;i<80;++i)
- if(str[i]=='\n')
- {
- str[i]='\0';
- break;
- }
- else if(str[i]=='\0')
- break;
- else if(str[i]=='$')
- if((str[i+1]>='1')&&(str[i+1]<='9'))
- {
- j=strlen(str);
- argn=(str[i+1]-'0')+1;
- if(argn>=argc)
- {
- printf("Argument %d cited in port config line but not provided on command line.\n", argn-1);
- cleanup(0);
- exit(101);
- }
- sptr=argv[argn];
- k=j+strlen(sptr)-2; /* Nuke $n */
- if(k>80)
- {
- printf("Expanded port config line too long.\n");
- printf("Raw line reads:\n%s", str);
- cleanup(0);
- exit(101);
- }
- if(k>j)
- for(;j>i;j--,k--)
- str[k]=str[j];
- else if(k<j)
- for(j=i+strlen(sptr),k=i+2;str[j];j++,k++)
- str[j]=str[k];
- for(j=0;sptr[j];j++,i++)
- str[i]=sptr[j];
- i--;
- }
- else
- {
- for(j=i,k=i+1;str[j];j++,k++)
- str[j]=str[k];
- i--;
- }
- value[0]=sscanf(str, "%15s %15s %15s %d",
- comstr, speedstr, bitsstr, &flowctlflag);
- if(value[0]<3)
- {
- printf("Can't read init params.\n");
- exit(10);
- }
- if(value[0]!=4)
- flowctlflag=1;
- comnum=atoi(comstr)-1;
- speed=atoi(speedstr);
- parity=bitsstr[1];
- databits=bitsstr[0];
- stopbits=bitsstr[2];
- for(i=0;i<256;++i)
- labels[i]=-1;
- for(i=0;i<256;++i)
- rregs[i]=0;
- printf("Parsing...\n");
- parse(0,0);
- printf("Checking branch label validity...\n");
- validate(0); /* We want to bomb if the script flunks */
- printf("Liberating excess RAM...\n");
- program=(struct line *)realloc(program, proglen*sizeof(struct line));
- if(program==NULL)
- {
- printf("Gaahh! realloc() bombed. Sorry about that!\n");
- _dos_setvect(0x1c, oldtick);
- exit(70);
- }
- printf("Executing...\n", proglen);
- setport();
- oldtick=_dos_getvect(0x1c);
- readset();
- signal(SIGINT, quit);
- _dos_setvect(0x1c, tickhndl);
- setup();
- /* Execute */
- progcnt=nscans=curkey=0;
- demonflag=0;
- demon=-1;
- while(1)
- {
- if(kbhit())
- if(getch()==24)
- if(demon>=0)
- progcnt=demon;
- if(demonflag)
- {
- demonflag=0;
- if(demon>=0)
- progcnt=demon;
- }
- if(progcnt>=proglen)
- {
- printf("\nFell through end of program.\n");
- while(!(inp(basereg+STATREG)&TXSHMTMASK));
- cleanup(0);
- _dos_setvect(0x1c, oldtick);
- exit(100);
- }
- switch(program[progcnt].type)
- {
- case '=':
- while(!(inp(basereg+STATREG)&TXSHMTMASK))
- if(kbhit())
- if(getch()==24)
- if(demon>=0)
- {
- progcnt=demon;
- demonflag=1;
- break;
- }
- if(demonflag)
- break;
- if(program[progcnt].stuff.port.comnum==-1)
- {
- outp(basereg+LCTLREG, DLAB);
- if(program[progcnt].stuff.port.speed)
- {
- outp(basereg+DLLSBREG, dllsb=((1152/program[progcnt].stuff.port.speed)&0xff));
- outp(basereg+DLMSBREG, dlmsb=((1152/program[progcnt].stuff.port.speed)&0x0fff)>>8);
- }
- else
- {
- outp(basereg+DLLSBREG, 0);
- outp(basereg+DLMSBREG, 0);
- }
- outp(basereg+LCTLREG, lctl);
- }
- else
- {
- cleanup(INHCTL);
- comnum=program[progcnt].stuff.port.comnum;
- speed=program[progcnt].stuff.port.speed;
- databits=program[progcnt].stuff.port.databits;
- parity=program[progcnt].stuff.port.parity;
- stopbits=program[progcnt].stuff.port.stopbits;
- flowctlflag=program[progcnt].stuff.port.flowctlflag;
- setport();
- setup();
- }
- progcnt++;
- break;
- case 'g':
- progcnt=labels[program[progcnt].stuff.byte];
- break;
- case '*':
- if(program[progcnt].stuff.number>=0)
- demon=labels[program[progcnt].stuff.number];
- else
- demon=-1;
- progcnt++;
- break;
- case 'r':
- if(++rregs[program[progcnt].stuff.retry.reg]>=program[progcnt].stuff.retry.retries)
- {
- rregs[program[progcnt].stuff.retry.reg]=0;
- progcnt=labels[program[progcnt].stuff.retry.label];
- }
- else
- progcnt++;
- break;
- case '"':
- sprintf(str, "%d", rregs[program[progcnt].stuff.number]);
- printf("%s", str);
- if(outfile!=NULL)
- fputs(str, outfile);
- progcnt++;
- break;
- case '#':
- if(execretn<=program[progcnt].stuff.rtnchk.value)
- progcnt=labels[program[progcnt].stuff.rtnchk.label];
- else
- progcnt++;
- break;
- case '0':
- rregs[program[progcnt].stuff.byte]=0;
- progcnt++;
- break;
- case 'p':
- tick=0L;
- flag=1;
- lni=lnl=0;
- while(flag)
- {
- while(1)
- {
- if(program[progcnt].stuff.numbers[0]&&(tick>program[progcnt].stuff.numbers[0]))
- {
- progcnt++;
- flag=0;
- break;
- }
- if(lnl>0)
- {
- c=line[lni++];
- if(outfile!=NULL)
- putc(c, outfile);
- if(lni>=lnl)
- lni=lnl=0;
- break;
- }
- else if(follow!=index)
- {
- c=buf[follow++];
- if(follow>=TBUFSIZ)
- follow=0;
- if(!program[progcnt].stuff.numbers[1])
- {
- putch(c);
- if(outfile!=NULL)
- putc(c, outfile);
- break;
- }
- else
- if(c=='\b')
- if(lni>0)
- {
- sendchar('\b');
- putch('\b');
- sendchar(' ');
- putch(' ');
- sendchar('\b');
- putch('\b');
- lni--;
- }
- else
- sendchar(7);
- else if((c=='\r'))
- {
- line[lni++]='\r';
- lnl=lni;
- lni=0;
- putch('\r');
- putch('\n');
- }
- else if((lni<255)&&(c>=' ')&&(c<0x80))
- {
- if(program[progcnt].stuff.numbers[1]==1)
- sendchar(c);
- else
- sendchar('*');
- putch(c);
- line[lni++]=c;
- }
- else
- sendchar(7);
- }
- if(kbhit())
- if(getch()==24)
- {
- demonflag=1;
- flag=0;
- break;
- }
- }
- if(!flag)
- break;
- for(i=0;i<nscans;++i)
- if(scans[i].str[scans[i].index]==c)
- if(scans[i].str[++scans[i].index]=='\0')
- {
- progcnt=labels[scans[i].hitlabel];
- flag=0;
- break;
- }
- else;
- else if(scans[i].str[0]==c)
- scans[i].index=1;
- else
- scans[i].index=0;
- }
- nscans=0;
- break;
- case '>':
- if(nscans>=MAXNSCANS)
- {
- printf("Too many lookfors (>); statement %d; ignoring.\n", progcnt++);
- break;
- }
- scans[nscans].index=0;
- scans[nscans].str=program[progcnt].stuff.l_and_s.string;
- scans[nscans++].hitlabel=program[progcnt].stuff.l_and_s.label;
- progcnt++;
- break;
- case 'f':
- follow=index;
- progcnt++;
- break;
- case 't':
- if(infile==NULL)
- {
- progcnt=labels[program[progcnt].stuff.l_and_s.label];
- break;
- }
- if(fgets(str, 80, infile)==NULL)
- {
- progcnt=labels[program[progcnt].stuff.l_and_s.label];
- break;
- }
- for(i=0;i<80;++i)
- {
- if((str[i]=='\n')||(str[i]=='\r')||(str[i]=='\0'))
- break;
- sendchar(str[i]);
- }
- progcnt++;
- break;
- case 'i':
- if(program[progcnt].stuff.l_and_s.string[0]=='*')
- if(infile!=NULL)
- fclose(infile);
- else;
- else if((infile=fopen(program[progcnt].stuff.l_and_s.string, "r"))==NULL)
- {
- progcnt=labels[program[progcnt].stuff.l_and_s.label];
- break;
- }
- progcnt++;
- break;
- case 'o':
- if(program[progcnt].stuff.l_and_s.string[0]=='*')
- if(outfile!=NULL)
- fclose(outfile);
- else;
- else if((outfile=fopen(program[progcnt].stuff.l_and_s.string, "a"))==NULL)
- {
- progcnt=labels[program[progcnt].stuff.l_and_s.label];
- break;
- }
- else
- setmode(fileno(outfile), O_BINARY);
- progcnt++;
- break;
- case '?':
- if(!((inp(basereg+STATREG)&TXMTMASK)
- &&((inp(basereg+MSTATREG)&CTSMASK)
- ||!flowctlflag)))
- progcnt=labels[program[progcnt].stuff.byte];
- else
- progcnt++;
- break;
- case 'd':
- if(inp(basereg+MSTATREG)&DCDMASK)
- progcnt=labels[program[progcnt].stuff.byte];
- else
- progcnt++;
- break;
- case '<':
- for(i=0;i<80;i++)
- if(program[progcnt].stuff.string[i]=='\0')
- break;
- else if(program[progcnt].stuff.string[i]=='`')
- {
- j=0;
- if(program[progcnt].stuff.string[++i]<'A')
- j=(program[progcnt].stuff.string[i]-'0')<<4;
- else if(program[progcnt].stuff.string[i]<'a')
- j=(program[progcnt].stuff.string[i]-'A'+10)<<4;
- else
- j=(program[progcnt].stuff.string[i]-'a'+10)<<4;
- if(program[progcnt].stuff.string[++i]<'A')
- j+=(program[progcnt].stuff.string[i]-'0');
- else if(program[progcnt].stuff.string[i]<'a')
- j+=(program[progcnt].stuff.string[i]-'A'+10);
- else
- j+=(program[progcnt].stuff.string[i]-'a'+10);
- sendchar(j);
- }
- else if(program[progcnt].stuff.string[i]=='~')
- sleep();
- else if(program[progcnt].stuff.string[i]=='^')
- {
- tick=0L;
- outp(basereg+LCTLREG, lctl|0x40);
- while(1)
- {
- if(tick>10)
- break;
- }
- outp(basereg+LCTLREG, lctl);
- }
- else
- sendchar(program[progcnt].stuff.string[i]);
- progcnt++;
- break;
- case '!':
- printf("%s", program[progcnt].stuff.string);
- if(outfile!=NULL)
- fputs(program[progcnt].stuff.string, outfile);
- progcnt++;
- break;
- case 's':
- printf("\n");
- cleanup(INHCTL);
- if(system(program[progcnt].stuff.l_and_s.string)==-1)
- {
- progcnt=labels[program[progcnt].stuff.l_and_s.label];
- }
- else
- progcnt++;
- setup();
- printf("\nBack to script.\n");
- break;
- case 'x':
- printf("\n");
- cleanup(INHCTL);
- spawnargc=0;
- if(program[progcnt].stuff.l_and_s.string[0]!='\0')
- {
- spawnargv[spawnargc++]=&program[progcnt].stuff.l_and_s.string[0];
- for(j=0,i=1;i<program[progcnt].stuff.l_and_s.ntokens;i++)
- {
- while(program[progcnt].stuff.l_and_s.string[j++]!='\0');
- spawnargv[spawnargc++]=&program[progcnt].stuff.l_and_s.string[j];
- }
- spawnargv[spawnargc++]=NULL;
- strcpy(spawnpath, spawnargv[0]);
- execretn=spawnvp(P_WAIT, spawnpath, spawnargv);
- }
- else
- execretn=65535;
- setup();
- progcnt++;
- break;
- case '+':
- outp(basereg+MCTLREG, 0x0b);
- progcnt++;
- break;
- case '-':
- outp(basereg+MCTLREG, 0x0a);
- progcnt++;
- break;
- case 'k':
- if(curkey>=MAXKEYS)
- {
- printf("Excess key daemon ignored.\n");
- progcnt++;
- break;
- }
- keys[curkey].key=program[progcnt].stuff.l_and_s.string[0];
- keys[curkey++].label=program[progcnt].stuff.l_and_s.label;
- progcnt++;
- break;
- case 'w':
- timestamp=time(NULL);
- while(1)
- {
- if(program[progcnt].stuff.number&&((time(NULL)-timestamp)>program[progcnt].stuff.number))
- {
- printf("\nKeyboard entry timeout.\n");
- progcnt++;
- break;
- }
- if(kbhit())
- {
- c=getch();
- if(c==24)
- if(demon>=0)
- {
- progcnt=demon;
- break;
- }
- for(i=0;i<curkey;i++)
- if(c==keys[i].key)
- {
- progcnt=labels[keys[i].label];
- break;
- }
- if(i>=curkey)
- putch(0x07);
- else
- break;
- }
- }
- curkey=0;
- break;
- case 'm':
- tick=0L;
- flag=1;
- mkeyp=0;
- while(flag)
- {
- while(1)
- {
- if(program[progcnt].stuff.number&&(tick>program[progcnt].stuff.number))
- {
- progcnt++;
- flag=0;
- break;
- }
- if(follow!=index)
- {
- putch(c=buf[follow++]);
- if(follow>=TBUFSIZ)
- follow=0;
- if(outfile!=NULL)
- putc(c, outfile);
- mkeyp=0;
- break;
- }
- if(kbhit())
- {
- c=getch();
- if(c==24)
- if(demon>=0)
- {
- progcnt=demon;
- flag=0;
- break;
- }
- mkeyp=1;
- break;
- }
- }
- if(!flag)
- break;
- if(mkeyp)
- {
- for(i=0;i<curkey;i++)
- if(c==keys[i].key)
- {
- progcnt=labels[keys[i].label];
- break;
- }
- if(i>=curkey)
- putch(0x07);
- else
- break;
- }
- else
- {
- for(i=0;i<nscans;++i)
- if(scans[i].str[scans[i].index]==c)
- if(scans[i].str[++scans[i].index]=='\0')
- {
- progcnt=labels[scans[i].hitlabel];
- flag=0;
- break;
- }
- else;
- else if(scans[i].str[0]==c)
- scans[i].index=1;
- else
- scans[i].index=0;
- }
- }
- nscans=curkey=0;
- break;
- case 'c':
- curkey=nscans=0;
- progcnt++;
- break;
- case 'l':
- if(program[progcnt].stuff.load.label<0)
- jregs[program[progcnt].stuff.load.reg]=-1;
- else
- jregs[program[progcnt].stuff.load.reg]=labels[program[progcnt].stuff.load.label];
- progcnt++;
- break;
- case 'j':
- if(jregs[program[progcnt].stuff.number]<0)
- {
- progcnt++;
- break;
- }
- else
- progcnt=jregs[program[progcnt].stuff.number];
- break;
- case 'q':
- while(!(inp(basereg+STATREG)&TXSHMTMASK));
- cleanup(0);
- _dos_setvect(0x1c, oldtick);
- exit(program[progcnt].stuff.number);
- }
- }
- }