home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / PCCP019.ZIP / COMSCRPT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-08  |  15.8 KB  |  738 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<signal.h>
  10. #include<process.h>
  11.  
  12. #define DLLSBREG 0
  13. #define DLMSBREG 1
  14. #define INTCTLREG 1
  15. #define INTIDREG 2
  16. #define LCTLREG 3
  17. #define MCTLREG 4
  18. #define STATREG 5
  19. #define MSTATREG 6
  20.  
  21. #define DCDMASK 0x80
  22. #define CTSMASK 0x10
  23. #define TXMTMASK 0x20
  24. #define RXRDYMASK 0x01
  25.  
  26. #define INTACK 0x20
  27.  
  28. #define DB7 0x02
  29. #define DB8 0x03
  30. #define STOP2 0x04
  31. #define PARITYEN 0x08
  32. #define PARITYEVEN 0x10
  33. #define DLAB 0x80
  34.  
  35. #define INTBASE1 0x20
  36. #define INTMASK1 0x21
  37. #define INTBASE2 0xa0
  38. #define INTMASK2 0xa1
  39.  
  40. #define TBUFSIZ 4096
  41.  
  42. #define PROGSIZ 256
  43.  
  44. struct line
  45.     {
  46.     char type;
  47.     union
  48.         {
  49.         unsigned char byte;
  50.         int number;
  51.         struct
  52.             {
  53.             int retries;
  54.             int hits;
  55.             unsigned char label;
  56.             }
  57.             retry;
  58.         struct
  59.             {
  60.             unsigned char label;
  61.             unsigned char string[81];
  62.             }
  63.             l_and_s;
  64.         unsigned char string[81];
  65.         }
  66.         stuff;
  67.     }
  68.     program[PROGSIZ];
  69.  
  70. #define MAXNSCANS 16
  71.  
  72. struct
  73.     {
  74.     unsigned char index;
  75.     unsigned char *str;
  76.     unsigned char hitlabel;
  77.     }
  78.     scans[MAXNSCANS];
  79.  
  80. int nscans;
  81.  
  82. short int labels[256]; /* Not a #define cause we use unsigned char all over */
  83.  
  84. int index, basereg;
  85. char buf[TBUFSIZ];
  86. unsigned char diffintmask, irqnum;
  87. void (interrupt far *oldvect)();
  88.  
  89. void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
  90.               _bx, _dx, _cx, _ax, _ip, _cs, _flags)
  91.     unsigned _es, _ds, _di, _si, _bp, _sp;
  92.     unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
  93.     {
  94.     if(inp(basereg+STATREG)&0x01)
  95.         {
  96.         buf[index++]=inp(basereg)&0xff;
  97.         index=index%TBUFSIZ;
  98.         }
  99.     outp(INTBASE1, INTACK);
  100.     outp(INTBASE2, INTACK);
  101.     }
  102.  
  103. unsigned char newintmask, oldintmask, lctl, dlmsb, dllsb;
  104. unsigned intnum;
  105. unsigned char oldlctl, olddllsb, olddlmsb, oldintctl, oldmctl;
  106.  
  107. setup()
  108.     {
  109.     outp(basereg+LCTLREG, DLAB);
  110.     olddllsb=inp(basereg+DLLSBREG);
  111.     olddlmsb=inp(basereg+DLMSBREG);
  112.     outp(basereg+DLLSBREG, dllsb);
  113.     outp(basereg+DLMSBREG, dlmsb);
  114.     oldlctl=inp(basereg+LCTLREG);
  115.     outp(basereg+LCTLREG, lctl);
  116.     _dos_setvect(intnum, inthndl);
  117.     oldintctl=inp(basereg+INTCTLREG);
  118.     outp(basereg+INTCTLREG, 0x00);
  119.     oldmctl=inp(basereg+MCTLREG);
  120.     outp(basereg+MCTLREG, 0x0b);
  121.     newintmask=diffintmask;
  122.     newintmask&=oldintmask;
  123.     if(intnum==10)
  124.         outp(INTMASK2, newintmask);
  125.     else
  126.         outp(INTMASK1, newintmask);
  127.     outp(INTBASE1, INTACK); /* Clean up leftovers */
  128.     outp(INTBASE2, INTACK);
  129.     outp(basereg+INTCTLREG, 0x01);
  130.     outp(INTBASE1, INTACK); /* What a zoo! */
  131.     outp(INTBASE2, INTACK);
  132.     }
  133.  
  134. cleanup()
  135.     {
  136.     if(intnum==10)
  137.         outp(INTMASK2, oldintmask);
  138.     else
  139.         outp(INTMASK1, oldintmask);
  140.     outp(basereg+LCTLREG, DLAB);
  141.     outp(basereg+DLLSBREG, olddllsb);
  142.     outp(basereg+DLMSBREG, olddlmsb);
  143.     outp(basereg+LCTLREG, oldlctl);
  144.     outp(basereg+INTCTLREG, oldintctl);
  145.     outp(basereg+MCTLREG, oldmctl);
  146.     _dos_setvect(intnum, oldvect);
  147.     }
  148.  
  149. quit()
  150.     {
  151.     cleanup();
  152.     exit(99);
  153.     }
  154.  
  155. sendchar(c)
  156.     unsigned char c;
  157.     {
  158.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  159.         {
  160.         if(kbhit())
  161.             getch(); /* Give chance for ^C */
  162.         }
  163.     outp(basereg, c);
  164.     return(0);
  165.     }
  166.  
  167. int follow;
  168.  
  169. sleep()
  170.     {
  171.     long tod, tod1, day;
  172.     day=0;
  173.     _bios_timeofday(_TIME_GETCLOCK, &tod);
  174.     while(1)
  175.         {
  176.         if(_bios_timeofday(_TIME_GETCLOCK, &tod1))
  177.             day=20*60*60*24;
  178.         if((tod1+day-tod)>8)
  179.             break;
  180.         }
  181.     }
  182.  
  183. main(argc, argv)
  184.     int argc;
  185.     char **argv;
  186.     {
  187.     FILE *scriptfd;
  188.     char c, fpname[256], str[81], *strptr;
  189.     char comstr[16], speedstr[16], bitsstr[16];
  190.     int i, j, proglen, value[8], flag, progcnt;
  191.     unsigned speed;
  192.     int comnum;
  193.     char databits, parity, stopbits;
  194.     long timestamp;
  195.     index=follow=0;
  196.     lctl=0;
  197.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  198.     if(!strcmp(getenv("REMOTE"), "YES"))
  199.         {
  200.         printf("You appear to be logged in remotely, judging by the environment\n");
  201.         printf("variable REMOTE, so it strikes me as somewhat peculiar that you\n");
  202.         printf("want to run COMSCRPT. Are you sure you want to do it? (y or n) --> ");
  203.         if(getchar()!='y') /* Note getchar() and not getch()! */
  204.             {
  205.             printf("I didn't think so!\n");
  206.             exit(99);
  207.             }
  208.         else
  209.             printf("OK, you're the boss!");
  210.         }
  211.     if(argc!=2)
  212.         {
  213.         printf("USAGE: comscrpt <script file basename>\n");
  214.         printf("The environment variable TERMPATH is used for the script file if set.\n");
  215.         exit(1);
  216.         }
  217.     fpname[0]='\0';
  218.     if(getenv("TERMPATH")==NULL)
  219.         sprintf(fpname, "%s.scr", argv[1]);
  220.     else
  221.         sprintf(fpname, "%s\\%s.scr", getenv("TERMPATH"), argv[1]);
  222.     if((scriptfd=fopen(fpname, "r"))==NULL)
  223.         {
  224.         printf("Error opening script file %s.\n", fpname);
  225.         exit(2);
  226.         }
  227.     fgets(str, 80, scriptfd);
  228.     if(sscanf(str, "%s %s %s", comstr, speedstr, bitsstr)!=3)
  229.         {
  230.         printf("Can't read init params.\n");
  231.         exit(10);
  232.         }
  233.     comnum=atoi(comstr)-1;
  234.     newintmask=0;
  235.     switch(comnum)
  236.         {
  237.         case 0:
  238.             irqnum=4;
  239.             diffintmask=0xff&~0x10;
  240.             basereg=0x3f8;
  241.             break;
  242.         case 1:
  243.             irqnum=3;
  244.             diffintmask=0xff&~0x08;
  245.             basereg=0x2f8;
  246.             break;
  247.         case 2:
  248.             irqnum=4;
  249.             diffintmask=0xff&~0x10;
  250.             basereg=0x3e8;
  251.             break;
  252.         case 3:
  253.             irqnum=3;
  254.             diffintmask=0xff&~0x08;
  255.             basereg=0x2e8;
  256.             break;
  257.         case 4:
  258.             irqnum=2;
  259.             diffintmask=0xff&~0x02;
  260.             basereg=0x3e8;
  261.             break;
  262.         case 5:
  263.             irqnum=2;
  264.             diffintmask=0xff&~0x02;
  265.             basereg=0x2e8;
  266.             break;
  267.         case 6:
  268.             irqnum=5;
  269.             diffintmask=0xff&~0x20;
  270.             basereg=0x3e8;
  271.             break;
  272.         case 7:
  273.             irqnum=5;
  274.             diffintmask=0xff&~0x20;
  275.             basereg=0x2e8;
  276.             break;
  277.         default:
  278.             printf("Bad port choice.\n");
  279.             exit(4);
  280.         }
  281.     intnum=irqnum+8;
  282.     speed=atoi(speedstr);
  283.     switch(speed)
  284.         {
  285.         case 300:
  286.             dlmsb=0;
  287.             dllsb=0xc0;
  288.             break;
  289.         case 1200:
  290.             dlmsb=0;
  291.             dllsb=0x60;
  292.             break;
  293.         case 2400:
  294.             dlmsb=0;
  295.             dllsb=0x30;
  296.             break;
  297.         case 9600:
  298.             dlmsb=0;
  299.             dllsb=0x0c;
  300.             break;
  301.         case 19200:
  302.             dlmsb=0;
  303.             dllsb=0x06;
  304.             break;
  305.         case 38400:
  306.             dlmsb=0;
  307.             dllsb=0x03;
  308.             break;
  309.         case 57600:
  310.             dlmsb=0;
  311.             dllsb=0x02;
  312.             break;
  313.         default:
  314.             printf("Bad speed.\n");
  315.             exit(5);
  316.         }
  317.     parity=bitsstr[1];
  318.     switch(parity)
  319.         {
  320.         case 'e':
  321.         case 'E':
  322.             lctl |= PARITYEN | PARITYEVEN;
  323.             break;
  324.         case 'o':
  325.         case 'O':
  326.             lctl|=PARITYEN;
  327.             break;
  328.         case 'n':
  329.         case 'N':
  330.             break;
  331.         default:
  332.             printf("Bad parity.\n");
  333.             exit(7);
  334.         }
  335.     databits=bitsstr[0];
  336.     switch(databits)
  337.         {
  338.         case '7':
  339.             lctl|=DB7;
  340.             break;
  341.         case '8':
  342.             lctl|=DB8;
  343.             break;
  344.         default:
  345.             printf("Bad data bits.\n");
  346.             exit(8);
  347.         }
  348.     stopbits=bitsstr[2];
  349.     switch(stopbits)
  350.         {
  351.         case '1':
  352.             break;
  353.         case '2':
  354.             lctl|=STOP2;
  355.             break;
  356.         default:
  357.             printf("Bad stop bits.\n");
  358.             exit(9);
  359.         }
  360.     for(i=0;i<256;++i)
  361.         labels[i]=-1;
  362.     oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
  363.     oldvect=_dos_getvect(intnum);
  364.     signal(SIGINT, quit);
  365.     setup();
  366.     /* Parse */
  367.     printf("Parsing...\n");
  368.     flag=0;
  369.     for(proglen=0;proglen<PROGSIZ;++proglen)
  370.         {
  371.         if(fgets(str, 80, scriptfd)==NULL)
  372.             {
  373.             flag=1;
  374.             proglen++;
  375.             break;
  376.             }
  377.         for(i=0;i<80;++i)
  378.             if(str[i]=='\n')
  379.                 {
  380.                 str[i]='\0';
  381.                 break;
  382.                 }
  383.             else if(str[i]=='\0')
  384.                 break;
  385.         if(!strlen(str))
  386.             proglen--;
  387.         else
  388.             {
  389.             if((str[0]!=';')&&(str[1]!=' '))
  390.                 {
  391.                 printf("Missing first delimiting space at statement %d.\n", proglen);
  392.                 printf("Statement reads:\n%s\n", str);
  393.                 cleanup();
  394.                 exit(11);
  395.                 }
  396.             switch(str[0])
  397.                 {
  398.                 case ':':
  399.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  400.                         {
  401.                         printf("Bad scan of label (:) before statement %d.\n", proglen);
  402.                         cleanup();
  403.                         exit(11);
  404.                         }
  405.                     if((value[0]<0)||(value[0]>255))
  406.                         {
  407.                         printf("Label %d out of range.\n", value[0]);
  408.                         cleanup();
  409.                         exit(11);
  410.                         }
  411.                     if(labels[value[0]]!=-1)
  412.                         {
  413.                         printf("Label %d duplicated at statement %d.\n", value[0], proglen);
  414.                         cleanup();
  415.                         exit(11);
  416.                         }
  417.                     labels[value[0]]=proglen;
  418.                     proglen--;
  419.                     break;
  420.                 case 'g':
  421.                 case 'G':
  422.                     program[proglen].type='g';
  423.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  424.                         {
  425.                         printf("Bad scan of Goto at statement %d.\n", proglen);
  426.                         printf("Statement reads:\n%s\n", str);
  427.                         cleanup();
  428.                         exit(11);
  429.                         }
  430.                     program[proglen].stuff.byte=(unsigned char)value[0];
  431.                     break;
  432.                 case 'r':
  433.                 case 'R':
  434.                     program[proglen].type='r';
  435.                     if(sscanf(str, "%*c %d %d", &value[0], &value[1])!=2)
  436.                         {
  437.                         printf("Bad scan of Retry at statement %d.\n", proglen);
  438.                         printf("Statement reads:\n%s\n", str);
  439.                         cleanup();
  440.                         exit(11);
  441.                         }
  442.                     program[proglen].stuff.retry.hits=0;
  443.                     program[proglen].stuff.retry.label=(unsigned char)value[0];
  444.                     program[proglen].stuff.retry.retries=value[1];
  445.                     break;
  446.                 case 'p':
  447.                 case 'P':
  448.                     program[proglen].type='p';
  449.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  450.                         {
  451.                         printf("Bad scan of Process at statement %d.\n", proglen);
  452.                         printf("Statement reads:\n%s\n", str);
  453.                         cleanup();
  454.                         exit(11);
  455.                         }
  456.                     program[proglen].stuff.number=value[0];
  457.                     break;
  458.                 case '>':
  459.                     program[proglen].type='>';
  460.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  461.                         {
  462.                         printf("Bad scan of > at statement %d.\n", proglen);
  463.                         printf("Statement reads:\n%s\n", str);
  464.                         cleanup();
  465.                         exit(11);
  466.                         }
  467.                     program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
  468.                     flag=j=0;
  469.                     for(i=2;i<80;++i)
  470.                         {
  471.                         if(flag)
  472.                             if(str[i]=='|')
  473.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  474.                             else
  475.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  476.                         if(str[i]==' ')
  477.                             flag=1;
  478.                         if(str[i]=='\0')
  479.                             break;
  480.                         }
  481.                     break;
  482.                 case '?':
  483.                     program[proglen].type='?';
  484.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  485.                         {
  486.                         printf("Bad scan of ? at statement %d.\n", proglen);
  487.                         printf("Statement reads:\n%s\n", str);
  488.                         cleanup();
  489.                         exit(11);
  490.                         }
  491.                     program[proglen].stuff.byte=value[0];
  492.                     break;
  493.                 case '<':
  494.                     program[proglen].type='<';
  495.                     j=0;
  496.                     for(i=2;i<80;++i)
  497.                         {
  498.                         if(str[i]=='|')
  499.                             program[proglen].stuff.string[j++]='\r';
  500.                         else
  501.                             program[proglen].stuff.string[j++]=str[i];
  502.                         if(str[i]=='\0')
  503.                             break;
  504.                         }
  505.                     break;
  506.                 case '!':
  507.                     program[proglen].type='!';
  508.                     j=0;
  509.                     for(i=2;i<80;++i)
  510.                         {
  511.                         if(str[i]=='|')
  512.                             program[proglen].stuff.string[j++]='\n';
  513.                         else if(str[i]=='~')
  514.                             program[proglen].stuff.string[j++]='\007';
  515.                         else
  516.                             program[proglen].stuff.string[j++]=str[i];
  517.                         if(str[i]=='\0')
  518.                             break;
  519.                         }
  520.                     break;
  521.                 case 's':
  522.                     program[proglen].type='s';
  523.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  524.                         {
  525.                         printf("Bad scan of System at statement %d.\n", proglen);
  526.                         printf("Statement reads:\n%s\n", str);
  527.                         cleanup();
  528.                         exit(11);
  529.                         }
  530.                     program[proglen].stuff.l_and_s.label=value[0];
  531.                     flag=j=0;
  532.                     for(i=2;i<80;++i)
  533.                         {
  534.                         if(flag)
  535.                             if(str[i]=='|')
  536.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  537.                             else
  538.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  539.                         if(str[i]==' ')
  540.                             flag=1;
  541.                         if(str[i]=='\0')
  542.                             break;
  543.                         }
  544.                     break;
  545.                 case 'q':
  546.                 case 'Q':
  547.                     program[proglen].type='q';
  548.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  549.                         {
  550.                         printf("Bad scan of Quit at statement %d.\n", proglen);
  551.                         printf("Statement reads:\n%s\n", str);
  552.                         cleanup();
  553.                         exit(11);
  554.                         }
  555.                     if((value[0]<128)||(value[0]==0))
  556.                         {
  557.                         printf("Quit with reserved exit code (!=0&&<128) at statement %d.\n", proglen);
  558.                         cleanup();
  559.                         exit(11);
  560.                         }
  561.                     program[proglen].stuff.number=value[0];
  562.                     break;
  563.                 case ';':
  564.                     proglen--;
  565.                     break;
  566.                 default:
  567.                     printf("Bad command character %c at statement %d.\n", str[0], proglen);
  568.                     printf("Statement reads:\n%s\n", str);
  569.                     cleanup();
  570.                     exit(10);
  571.                 }
  572.             }
  573.         }
  574.     if(!flag)
  575.         {
  576.         printf("Program too long.\n");
  577.         cleanup();
  578.         exit(11);
  579.         }
  580.     /* Check labels */
  581.     printf("Checking branch label validity...\n");
  582.     for(i=0;i<proglen;i++)
  583.         switch(program[i].type)
  584.             {
  585.             case 'g':
  586.             case '?':
  587.                 if(labels[program[i].stuff.byte]==-1)
  588.                     {
  589.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.byte, i, program[i].type);
  590.                     cleanup();
  591.                     exit(13);
  592.                     }
  593.                 break;
  594.             case 'r':
  595.                 if(labels[program[i].stuff.retry.label]==-1)
  596.                     {
  597.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.retry.label, i, program[i].type);
  598.                     cleanup();
  599.                     exit(13);
  600.                     }
  601.                 break;
  602.             case '>':
  603.                 if(labels[program[i].stuff.l_and_s.label]==-1)
  604.                     {
  605.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
  606.                     cleanup();
  607.                     exit(13);
  608.                     }
  609.                 break;
  610.             case 's':
  611.                 if(labels[program[i].stuff.l_and_s.label]==-1)
  612.                     {
  613.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
  614.                     cleanup();
  615.                     exit(13);
  616.                     }
  617.                 break;
  618.             }
  619.     printf("Executing...\n");
  620.     /* Execute */
  621.     progcnt=nscans=0;
  622.     while(1)
  623.         {
  624.         if(progcnt>=proglen)
  625.             {
  626.             printf("\nFell through end of program.\n");
  627.             cleanup();
  628.             exit(100);
  629.             }
  630.         switch(program[progcnt].type)
  631.             {
  632.             case 'g':
  633.                 progcnt=labels[program[progcnt].stuff.byte];
  634.                 break;
  635.             case 'r':
  636.                 if(++program[progcnt].stuff.retry.hits>=program[progcnt].stuff.retry.retries)
  637.                     {
  638.                     program[progcnt].stuff.retry.hits=0;
  639.                     progcnt=labels[program[progcnt].stuff.retry.label];
  640.                     }
  641.                 else
  642.                     progcnt++;
  643.                 break;
  644.             case 'p':
  645.                 timestamp=time(NULL);
  646.                 flag=1;
  647.                 while(flag)
  648.                     {
  649.                     while(1)
  650.                         {
  651.                         if((time(NULL)-timestamp)>program[progcnt].stuff.number)
  652.                             {
  653.                             progcnt++;
  654.                             flag=0;
  655.                             break;
  656.                             }
  657.                         if(follow!=index)
  658.                             {
  659.                             putch(c=buf[follow++]);
  660.                             if((c&0x7f)!='\n')
  661.                                 break;
  662.                             }
  663.                         if(kbhit())
  664.                             getch();
  665.                         }
  666.                     if(!flag)
  667.                         break;
  668.                     for(i=0;i<nscans;++i)
  669.                         if((scans[i].str[scans[i].index]&0x7f)==(c&0x7f))
  670.                             if(scans[i].str[++scans[i].index]=='\0')
  671.                                 {
  672.                                 if(labels[scans[i].hitlabel]==-1)
  673.                                     {
  674.                                     printf("\nGoto unlisted label %d at statement %d.\n", scans[i].hitlabel, progcnt);
  675.                                     cleanup();
  676.                                     exit(12);
  677.                                     }
  678.                                 progcnt=labels[scans[i].hitlabel];
  679.                                 flag=0;
  680.                                 break;
  681.                                 }
  682.                             else;
  683.                         else
  684.                             scans[i].index=0;
  685.                     }
  686.                 nscans=0;
  687.                 break;
  688.             case '>':
  689.                 if(nscans>=MAXNSCANS)
  690.                     {
  691.                     printf("Too many lookfors (>).\n");
  692.                     progcnt++;
  693.                     break;
  694.                     }
  695.                 scans[nscans].index=0;
  696.                 scans[nscans].str=program[progcnt].stuff.l_and_s.string;
  697.                 scans[nscans++].hitlabel=program[progcnt].stuff.l_and_s.label;
  698.                 progcnt++;
  699.                 break;
  700.             case '?':
  701.                 if(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  702.                     progcnt=labels[program[progcnt].stuff.byte];
  703.                 else
  704.                     progcnt++;
  705.                 break;
  706.             case '<':
  707.                 for(i=0;i<80;i++)
  708.                     if(program[progcnt].stuff.string[i]=='\0')
  709.                         break;
  710.                     else if(program[progcnt].stuff.string[i]=='~')
  711.                         sleep();
  712.                     else
  713.                         sendchar(program[progcnt].stuff.string[i]);
  714.                 progcnt++;
  715.                 break;
  716.             case '!':
  717.                 printf("%s", program[progcnt].stuff.string);
  718.                 progcnt++;
  719.                 break;
  720.             case 's':
  721.                 printf("\n");
  722.                 cleanup();
  723.                 if(system(program[progcnt].stuff.l_and_s.string)==-1)
  724.                     {
  725.                     progcnt=labels[program[progcnt].stuff.l_and_s.label];
  726.                     }
  727.                 else
  728.                     progcnt++;
  729.                 setup();
  730.                 printf("\nBack to script.\n");
  731.                 break;
  732.             case 'q':
  733.                 cleanup();
  734.                 exit(program[progcnt].stuff.number);
  735.             }
  736.         }
  737.     }
  738.