home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / tip / tip.c next >
C/C++ Source or Header  |  1990-10-10  |  7KB  |  337 lines

  1. /*
  2.  * Stripped down tip clone  -- Howard Chu, 10-10-90
  3.  *
  4.  * This is a very simple terminal program intended for use with MiNT
  5.  * (and MGR...). I tried to model it on the BSD 4.3 version of tip,
  6.  * but got impatient and thus omitted a number of features. Still,
  7.  * this is useful enough and easy enough to use... You may copy and
  8.  * distribute this program freely as long as you keep all files intact
  9.  * (meaning this source file and the accompanying doc and executable
  10.  * file). You are also welcome to modify the program to suit your own
  11.  * needs, but leave this notice intact. I would also appreciate it
  12.  * if you send me any improvements you may make.
  13.  *    hyc@math.lsa.umich.edu
  14.  */
  15. #include <osbind.h>
  16. #include <xbios.h>
  17.  
  18. #define    Finstat(a)        gemdos(0x105,a)
  19. #define    Foutstat(a)        gemdos(0x106,a)
  20. #define    Fgetchar(a,b)        gemdos(0x107,a,b)
  21. #define    Fputchar(a,b,c)        gemdos(0x108,a,b,c)
  22.  
  23. /* The previous 4 defines don't actually get used. So it goes...
  24.    they're up there because I thought about using them, and I haven't
  25.    incorporated them into my MWC library yet. */
  26.  
  27. #define    Pgetpid()        gemdos(0x10b)
  28. #define Pkill(a,b)        gemdos(0x111,a,b)
  29.  
  30. char iobuf[8192];
  31. struct iorec *rec, oldirec, oldorec;
  32.  
  33. char shell[128], esc='~';
  34. int par=0;    /* none, odd, even - 0, 1, 2 */
  35. int baud=1;    /* see baud table 1=9600 */
  36. int echo=0;
  37. int flow=0;    /* none, xon/xoff, rts/cts */
  38.  
  39. int ucr, rsr, tsr, scr;
  40.  
  41. char *bauds[]={"19200","9600","4800","3600","2400","2000","1800","1200",
  42.         "600","300","200","150","134","110","75","50"};
  43.  
  44. /* Set up a large I/O buffer for the RS232 port, and set initial
  45.    speed, flow control, and parity. */
  46.  
  47. void rs232init(){
  48.     register long m68901reg;
  49.  
  50.     rec=Iorec(0);
  51.  
  52.     oldirec=*rec;
  53.     
  54.     rec->io_buff=iobuf;
  55.     rec->io_bufsiz = 4096;
  56.     rec->io_head = 0;
  57.     rec->io_tail = 0;
  58.     rec->io_low = 100;
  59.     rec->io_high = 4000;
  60.  
  61.     rec++;
  62.  
  63.     oldorec=*rec;
  64.     rec->io_buff=&iobuf[4096];
  65.     rec->io_bufsiz = 4096;
  66.     rec->io_head=0;
  67.     rec->io_tail=0;
  68.     rec->io_low=100;
  69.     rec->io_high=4000;
  70.  
  71.     m68901reg=Rsconf(baud,0,-1,-1,-1,-1);
  72.     scr=m68901reg&0xff;
  73.     m68901reg>>=8;
  74.     tsr=m68901reg&0xff;
  75.     m68901reg>>=8;
  76.     rsr=m68901reg&0xff;
  77.     m68901reg>>=8;
  78.     ucr=m68901reg&0xf8;
  79.     Rsconf(-1,-1,ucr,-1,-1,-1);    /* turn off parity */
  80. }
  81.  
  82. int getbaud(rate)
  83. char *rate;
  84. {
  85.     register int i;
  86.  
  87.     for (i=0;i<16;i++)
  88.         if (!strcmp(rate,bauds[i]))
  89.             break;
  90.  
  91.     if (i==16) {
  92.         Cconws(rate);
  93.         Cconws(": unknown baudrate value\r\n");
  94.         i=(-1);
  95.     }
  96.     return(i);
  97. }
  98.             
  99. main(argc,argv)
  100. int argc; char *argv[];
  101. {
  102.     register int c;
  103.     register int cr=0;
  104.     register int cmd=0;
  105.     char *buf, *getenv();
  106.  
  107.     void docommand();
  108.  
  109.     switch(argc){
  110.     case 1:
  111.         break;
  112.     case 2:
  113.         c=getbaud(argv[1]);
  114.         if (c>=0)
  115.             baud=c;
  116.         break;
  117.     default:
  118.         Cconws("Use: tip [speed]\r\n");
  119.         break;
  120.     }
  121.  
  122.     rs232init();
  123.  
  124.     buf=getenv("SHELL");
  125.     if (buf)
  126.         strcpy(shell,buf);
  127.     
  128.     for(;;) {
  129.         if (Bconstat(1)) {
  130.             c = Bconin(1);
  131.             Bconout(2,c);
  132.         }
  133.         if (Cconis()) {
  134.             c = Crawcin();
  135.             if (cmd) {
  136.                 cmd=0;
  137.                 docommand(c);
  138.                 cr=1;
  139.                 continue;
  140.             } else if (cr && c == esc) {
  141.                 cmd = 1;
  142.                 cr = 0;
  143.                 continue;
  144.             } else if (c == '\r')
  145.                 cr = 1;
  146.             else cr = 0;
  147.             if (Bcostat(1))
  148.                 Bconout(1,c);
  149.             if (echo)
  150.                 Bconout(2,c);
  151.         }
  152.     }
  153.  
  154. }
  155.  
  156. void docommand(c)
  157. int c;
  158. {
  159.     int args=0;
  160.     void dosetvar(), dobreak();
  161.     char *strchr();
  162.  
  163.     if (strchr("!#.?s",c)||(c==4)||(c==26))
  164.         Cconout(esc);
  165.  
  166.     switch (c) {
  167.     case '!':
  168.         if (shell[0]) {
  169.             Cconws("\r\n[sh]\r\n");
  170.             Pexec(0,shell,&args,0L);
  171.         } else {
  172.             Cconws("No shell.\r\n");
  173.         }
  174.         break;
  175. #if    0        /* Not implemented. Too much hassle. */
  176.     case '|':
  177.         Cconws("Local command? ");
  178.         Cconws("List command for remote system? ");
  179.     case '$':
  180.             /* Pipe local command to remote */
  181.     case 'C':
  182.         Cconws("Local command? ");
  183. #endif
  184.     case '.':
  185.     case 4:
  186.         Cconws("\r\n[EOT]\r\n");
  187.         *rec=oldorec;    /* reset to old I/O rec stuff, then exit */
  188.         rec--;
  189.         *rec=oldirec;
  190.         exit(0);
  191.     case 26:        /* Send a STOP to this process */
  192.         {register int i = Pgetpid();
  193.         Pkill(i,17);
  194.         }
  195.         break;
  196.     case 's':
  197.         dosetvar();
  198.         break;
  199.     case '#':
  200.         dobreak();
  201.         break;
  202.     case '?':
  203.         Cconws("\r\n ~!    shell\r\n");
  204.         Cconws(" ~.    exit from tip\r\n");
  205.         Cconws(" ~^D    exit from tip\r\n");
  206.         Cconws(" ~^Z    suspend tip\r\n");
  207.         Cconws(" ~s    set variable\r\n");
  208.         Cconws(" ~#    send break\r\n");
  209.         Cconws(" ~?    get this summary\r\n");
  210.         break;
  211.     default:
  212.         Bconout(1,c);
  213.         break;
  214.     }
  215. }
  216.  
  217. void dobreak()
  218. {
  219. #define    Fselect(a,b,c,d)    gemdos(0x11d,a,b,c,d)
  220.     tsr |= 0x08;
  221.     Rsconf(-1,-1,-1,-1,tsr,-1);
  222.     Fselect(300,0L,0L,0L);        /* sleep 300 milliseconds */
  223.     tsr &=0xf7;
  224.     Rsconf(-1,-1,-1,-1,tsr,-1);
  225. }
  226.  
  227. char *vars[]={"all","baudrate","flowcontrol","localecho","parity","escape","shell"};
  228. char *flows[]={"none","xon/xoff","rts/cts"};
  229. char *pars[]={"none","odd","even"};
  230.  
  231. void dosetvar()
  232. {
  233.     register int i, j;
  234.     char *strpbrk();
  235.     unsigned char buf[130];
  236.     register char *ptr;
  237.  
  238.     Cconws("[set] ");
  239.     buf[0]=128;
  240.     Cconrs(buf);
  241.     Cconout('\n');
  242.  
  243.     i=buf[1];
  244.     if (i==0)
  245.         return;
  246.  
  247.     buf[i+2]='\0';
  248.  
  249.     ptr=strpbrk(&buf[2]," =    ");
  250.     if (ptr)
  251.         i=ptr-&buf[2];
  252.     else
  253.         i=buf[1];
  254.  
  255.     for (j=0;j<7;j++)
  256.         if(!strncmp(&buf[2],vars[j],i))
  257.             break;
  258.  
  259.     if (j==7) {
  260.         Cconws(&buf[2]);
  261.         Cconws(": unknown variable\r\n");
  262.         return;
  263.     }
  264.  
  265.     if (j&&!ptr) {
  266.         Cconws("\r\nno value supplied\r\n");
  267.         return;
  268.     }
  269.  
  270.     ptr++;
  271.     switch(j) {
  272.     case 0:
  273.         Cconws("baudrate=");
  274.         Cconws(bauds[baud]);
  275.         Cconws("\r\nflowcontrol=");
  276.         Cconws(flows[flow]);
  277.         Cconws("\r\nlocalecho=");
  278.         ptr=echo ? "on":"off";
  279.         Cconws(ptr);
  280.         Cconws("\r\nparity=");
  281.         Cconws(pars[par]);
  282.         Cconws("\r\nescape=");
  283.         Cconout(esc);
  284.         Cconws("\r\nshell=");
  285.         Cconws(shell);
  286.         Cconws("\r\n");
  287.         break;
  288.     case 1:
  289.         i=getbaud(ptr);
  290.         if (i>=0) {
  291.             baud=i;
  292.             Rsconf(i,-1,-1,-1,-1,-1);
  293.         }
  294.         break;
  295.     case 2:
  296.         j=buf[1]-i-1;
  297.         for (i=0;i<4;i++)
  298.             if (!strncmp(ptr,flows[i],j))
  299.                 break;
  300.         if (i==4) {
  301.             Cconws(ptr);
  302.             Cconws(": unknown flowcontrol value\r\n");    
  303.             return;
  304.         }
  305.         flow=i;
  306.         Rsconf(-1,i,-1,-1,-1,-1);
  307.         break;
  308.     case 3:
  309.         echo=strcmp(ptr,"on") ? 0 : 1;
  310.         break;
  311.  
  312.     case 4:
  313.         j=buf[1]-i-1;
  314.         for (i=0;i<3;i++)
  315.             if (!strncmp(ptr,pars[i],j))
  316.                 break;
  317.         if (i==3) {
  318.             Cconws(ptr);
  319.             Cconws(": unknown parity value\r\n");
  320.             return;
  321.         }
  322.         par=i;
  323.         ucr &=0x98;
  324.         if (i) {
  325.             ucr |= i|0x24;    /* set 7 bits, parity on */    
  326.         }
  327.         Rsconf(-1,-1,ucr,-1,-1,-1);
  328.         break;
  329.     case 5:
  330.         esc=*ptr;
  331.         break;
  332.     case 6:
  333.         strcpy(shell,ptr);
  334.         break;
  335.     }
  336. }    
  337.