home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / dgtool / dg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-20  |  7.6 KB  |  383 lines

  1. /*
  2.  * Copyright (c) 1989 Southwest Research Institute
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by Southwest Research Institute.  The name of Southwest Research
  11.  * Institute may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char     sccsid[] = "@(#)dg.c    1.5 6/29/89             Copyright (c) 1989\
  20.  by Southwest Research Institute, San Antonio, Texas";
  21. #endif
  22.  
  23. #include <stdio.h>
  24. #include <signal.h>
  25. #include <sgtty.h>
  26. #include <sys/wait.h>
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netdb.h>
  30.  
  31. #define    queue_char( c )    *end_of_queue++ = c 
  32. #define    flush_the_queue()    {\
  33. write(1, write_queue, end_of_queue - write_queue);\
  34. end_of_queue = write_queue;\
  35. }
  36.  
  37. char buf1[256];
  38. char buf0[256];
  39.  
  40. char    write_queue[2048];
  41. char    motion_buf[16];
  42. char    *end_of_queue;
  43.  
  44. int master, slave, child, pid;
  45. char linec, linen;
  46.  
  47. struct baud_tab {
  48.     char    *baud_string;
  49.     int    baud_rate;
  50. } baud_tab[] = {
  51.     "50",    B50,
  52.     "75",    B75,
  53.     "110",    B110,
  54.     "134",    B134,
  55.     "150",    B150,
  56.     "200",    B200,
  57.     "300",    B300,
  58.     "600",    B600,
  59.     "1200", B1200,
  60.     "1800", B1800,
  61.     "2400", B2400,
  62.     "4800",    B4800,
  63.     "9600",    B9600,
  64.     "19200",    EXTA,
  65.     NULL,    0
  66. };
  67.  
  68. struct sgttyb tmode;
  69. int savemode;
  70. int fd, tflag;
  71. char    *host;
  72.  
  73. done()
  74. {
  75.      union wait status;
  76.  
  77.      if (wait3(&status, WNOHANG, 0) == 0)
  78.       return;
  79.  
  80.      ioctl (0, TIOCNXCL, &tmode);
  81.      tmode.sg_flags = savemode;
  82.      ioctl (0, TIOCSETP, &tmode);
  83.      kill(pid, SIGTERM);
  84.      kill(0, SIGTERM);
  85.      exit(0);
  86.  
  87. }
  88.  
  89.  
  90. main( argc, argv)
  91. int    argc;
  92. char    **argv;
  93. {
  94.      int    baud = B9600;
  95.      int    is_host = 0;
  96.  
  97.      end_of_queue = write_queue;
  98.  
  99.      if ((argc > 3) || (argc < 2) ) {
  100.       fprintf(stderr, "dg /dev/tty?|hostname  [buad]\n");
  101.       fprintf(stderr, "type ^~ to exit\n");
  102.       exit(1);
  103.      }
  104.  
  105.      host = argv[1];
  106.      if (gethostbyname(host) != NULL)
  107.       is_host = 1;
  108.  
  109.      if (is_host) {
  110.       setup_master();
  111.       signal(SIGCHLD, done);
  112.       fd = master;
  113.      } else {
  114.       fd = open(*(++argv), 2);
  115.       argc--;
  116.  
  117.       if (argc > 1) {
  118.            baud = find_baud(*(++argv));
  119.       }
  120.  
  121.       if (fd < 0) {
  122.            fprintf(stderr, "dg: can't open the line to the DG or find a host\n");
  123.            exit(1);
  124.       }
  125.      }
  126.      ioctl (fd,TIOCGETP, &tmode);
  127.      tmode.sg_flags = RAW + TANDEM;
  128.      tmode.sg_ispeed = baud;
  129.      tmode.sg_ospeed = baud;
  130.      ioctl (fd,TIOCSETP, &tmode);
  131.      ioctl (fd,TIOCEXCL, &tmode);
  132.  
  133.      ioctl (0,TIOCGETP, &tmode);
  134.      savemode = tmode.sg_flags;
  135.      tmode.sg_flags = RAW;
  136.      ioctl (0,TIOCSETP, &tmode);
  137.  
  138.      pid = fork();
  139.      if (pid) {
  140.       write(fd, buf1, strlen(buf1));
  141.       writer();
  142.      } else {
  143.       if (is_host) {
  144.            if (fork()) {
  145.             reader();
  146.            } else {
  147.             start_telnet();
  148.            }
  149.       } else {
  150.            reader();
  151.       }
  152.      }
  153. }
  154.  
  155. queue_string(string)
  156. char    *string;
  157. {
  158.     register char    *cp;
  159.  
  160.     cp = string;
  161.     while (*cp)
  162.         *end_of_queue++ = *cp++;
  163. }
  164.  
  165. find_baud(string)
  166. char *string;
  167. {
  168.     struct baud_tab    *btp;
  169.  
  170.     btp = baud_tab;
  171.  
  172.     while(btp->baud_string != NULL) {
  173.         if (strcmp (string, btp->baud_string) == 0)
  174.             return(btp->baud_rate);
  175.         btp++;
  176.     }
  177.     fprintf(stderr, "dg: unknown baud rate\n");
  178.     fprintf(stderr, "known baud rates are:\n");
  179.  
  180.     btp = baud_tab;
  181.     while(btp->baud_string != NULL) {
  182.         fprintf(stderr, "\t%s\n", btp->baud_string);
  183.         btp++;
  184.     }
  185.     exit(1);
  186. }
  187.  
  188. start_telnet()
  189. {
  190.      int t;
  191.      char *term, *getenv(), *telnet, *tail, *rindex();
  192.  
  193.      telnet = "/usr/ucb/telnet";
  194.      tail = "telnet";
  195.      
  196.      if ((t = open("/dev/tty", 2)) >= 0) {
  197.       ioctl(t, TIOCNOTTY, (char *)0);
  198.       close(t);
  199.      }
  200.      setup_slave();
  201.      close(master);
  202.      dup2(slave, 0);
  203.      dup2(slave, 1);
  204.      dup2(slave, 2);
  205.      close(slave);
  206.      execl(telnet, tail, host, (char *)0);
  207.      perror(telnet);
  208.      fail();
  209. }
  210.  
  211. fail()
  212. {
  213.      kill(0, SIGTERM);
  214.      exit(0);
  215. }
  216.  
  217. setup_master()
  218. {
  219.      char line[11];
  220.  
  221.      for (linec = 'p'; linec <= 's'; linec++) {
  222.       sprintf(line, "/dev/pty%c0", linec);
  223.       if (access(line, 0) != 0)
  224.            break;
  225.       for (linen = 0; linen < 16; linen++) {
  226.            sprintf(line, "/dev/pty%c%1x", linec, linen);
  227.            master = open(line, 2);
  228.            if (master >= 0) {
  229.             return;
  230.            }
  231.       }
  232.      }
  233.      fprintf(stderr, "Can't find a pty\n");
  234.      fail();
  235. }
  236.  
  237. setup_slave()
  238. {
  239.      char line[11];
  240.  
  241.      sprintf(line, "/dev/tty%c%1x", linec, linen);
  242.      slave = open(line, 2);
  243.      if (slave < 0) {
  244.       perror(line);
  245.       fail();
  246.      }
  247. }
  248.  
  249. reader()
  250. {
  251.      register int    count;
  252.      register int    index;
  253.      register int    row, col;
  254.      register char    *cp, *end, c;
  255.  
  256.      for(;;) {
  257.       count = read(fd, buf0, 256);
  258.       end = buf0 + count;
  259.       for (cp = buf0; cp < end; cp++) {
  260.            c = *cp & 0177;
  261.            switch(c) {
  262.            case '\000':
  263.             break;
  264.            case '\003':
  265.             break;
  266.            case '\005':    /* read cursor position - this is a real hack */
  267.             queue_string("\033[1;1H");
  268.             write(fd, "\037\000\000", 3);
  269.             break;
  270.            case '\031':    /* bc=^y */
  271.             queue_string("\010");
  272.             break;
  273.            case '\020':    /* cm=4^p%r%.%. */
  274.             cp++;
  275.             if (cp >= end) {
  276.              count = read(fd, buf0, 1);
  277.              end = buf0 + count;
  278.              cp = buf0;
  279.             }
  280.             col = *cp & 0177;
  281.             cp++;
  282.             if (cp >= end) {
  283.              count = read(fd, buf0, 1);
  284.              end = buf0 + count;
  285.              cp = buf0;
  286.             }
  287.             row = *cp & 0177;
  288.             col++;
  289.             row++;
  290.             sprintf(motion_buf, "\033[%d;%dH", row, col);
  291.             queue_string(motion_buf);
  292.             break;
  293.            case '\036':    /* extended commands */
  294.             cp++;
  295.             if (cp >= end) {
  296.              count = read(fd, buf0, 1);
  297.              end = buf0 + count;
  298.              cp = buf0;
  299.             }
  300.             switch(*cp) {
  301.             case '\105':    /* reverse video off */
  302.              queue_string("\033[m");
  303.              break;
  304.             case '\104':    /* reverse video on */
  305.              queue_string("\033[7m");
  306.              break;
  307.             default:
  308.              break;
  309.             }
  310.             break;
  311.            case '\027':    /* up=^w */
  312.             queue_string("\033[A");
  313.             break;
  314.            case '\013':    /* ce=^k */
  315.             queue_string("\033[K");
  316.             break;
  317.            case '\024':    /* us=^t */
  318.             /* start underscore */
  319.             queue_string("\033[4m");
  320.             break;
  321.            case '\025':    /* ue=^u */
  322.             /* end undersore */
  323.             queue_string("\033[m");
  324.             break;
  325.            case '\034':    /* so=^\ */
  326.             queue_string("\033[m");
  327.             break;
  328.            case '\035':    /* se=^] */
  329.             queue_string("\033[1m");
  330.             break;
  331.            case '\030':    /* kr=^x */
  332.             queue_string("\033[C");
  333.             break;
  334.            case '\032':    /* kd=^z */
  335.             queue_string("\033[B");
  336.             break;
  337.            case '\010':    /* kh=^h */
  338.             queue_string("\033[1;1H");
  339.             break;
  340.            case '\022':    /* is=^r */
  341.             break;
  342.            case '\012':    /* nl */
  343.             queue_string("\n\r");
  344.             break;
  345.            default:
  346.             queue_char((int)c);
  347.            }
  348.       }
  349.       flush_the_queue();
  350.      }
  351.  
  352. }
  353.  
  354. writer()
  355. {
  356.      register int    count;
  357.      register int    index;
  358.      register int    row, col;
  359.      register char    *cp, *end, c;
  360.  
  361.      for(;;) {
  362.       count = read(0, buf1, 256);
  363.       index = 0;
  364.       while (index < count) {
  365.            if (tflag && (buf1[index] == '~') ) {
  366.              kill(pid, SIGTERM);
  367.             ioctl (0, TIOCNXCL, &tmode);
  368.             tmode.sg_flags = savemode;
  369.             ioctl (0, TIOCSETP, &tmode);
  370.             exit(0);;
  371.            } else {
  372.             tflag = 0;
  373.            }
  374.            if (buf1[index] == '^')
  375.             tflag = 1;
  376.            ++index;
  377.       }
  378.       write(fd, buf1, count);
  379.      }
  380. }
  381.  
  382.  
  383.