home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1989 Southwest Research Institute
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Southwest Research Institute. The name of Southwest Research
- * Institute may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)dg.c 1.5 6/29/89 Copyright (c) 1989\
- by Southwest Research Institute, San Antonio, Texas";
- #endif
-
- #include <stdio.h>
- #include <signal.h>
- #include <sgtty.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
-
- #define queue_char( c ) *end_of_queue++ = c
- #define flush_the_queue() {\
- write(1, write_queue, end_of_queue - write_queue);\
- end_of_queue = write_queue;\
- }
-
- char buf1[256];
- char buf0[256];
-
- char write_queue[2048];
- char motion_buf[16];
- char *end_of_queue;
-
- int master, slave, child, pid;
- char linec, linen;
-
- struct baud_tab {
- char *baud_string;
- int baud_rate;
- } baud_tab[] = {
- "50", B50,
- "75", B75,
- "110", B110,
- "134", B134,
- "150", B150,
- "200", B200,
- "300", B300,
- "600", B600,
- "1200", B1200,
- "1800", B1800,
- "2400", B2400,
- "4800", B4800,
- "9600", B9600,
- "19200", EXTA,
- NULL, 0
- };
-
- struct sgttyb tmode;
- int savemode;
- int fd, tflag;
- char *host;
-
- done()
- {
- union wait status;
-
- if (wait3(&status, WNOHANG, 0) == 0)
- return;
-
- ioctl (0, TIOCNXCL, &tmode);
- tmode.sg_flags = savemode;
- ioctl (0, TIOCSETP, &tmode);
- kill(pid, SIGTERM);
- kill(0, SIGTERM);
- exit(0);
-
- }
-
-
- main( argc, argv)
- int argc;
- char **argv;
- {
- int baud = B9600;
- int is_host = 0;
-
- end_of_queue = write_queue;
-
- if ((argc > 3) || (argc < 2) ) {
- fprintf(stderr, "dg /dev/tty?|hostname [buad]\n");
- fprintf(stderr, "type ^~ to exit\n");
- exit(1);
- }
-
- host = argv[1];
- if (gethostbyname(host) != NULL)
- is_host = 1;
-
- if (is_host) {
- setup_master();
- signal(SIGCHLD, done);
- fd = master;
- } else {
- fd = open(*(++argv), 2);
- argc--;
-
- if (argc > 1) {
- baud = find_baud(*(++argv));
- }
-
- if (fd < 0) {
- fprintf(stderr, "dg: can't open the line to the DG or find a host\n");
- exit(1);
- }
- }
- ioctl (fd,TIOCGETP, &tmode);
- tmode.sg_flags = RAW + TANDEM;
- tmode.sg_ispeed = baud;
- tmode.sg_ospeed = baud;
- ioctl (fd,TIOCSETP, &tmode);
- ioctl (fd,TIOCEXCL, &tmode);
-
- ioctl (0,TIOCGETP, &tmode);
- savemode = tmode.sg_flags;
- tmode.sg_flags = RAW;
- ioctl (0,TIOCSETP, &tmode);
-
- pid = fork();
- if (pid) {
- write(fd, buf1, strlen(buf1));
- writer();
- } else {
- if (is_host) {
- if (fork()) {
- reader();
- } else {
- start_telnet();
- }
- } else {
- reader();
- }
- }
- }
-
- queue_string(string)
- char *string;
- {
- register char *cp;
-
- cp = string;
- while (*cp)
- *end_of_queue++ = *cp++;
- }
-
- find_baud(string)
- char *string;
- {
- struct baud_tab *btp;
-
- btp = baud_tab;
-
- while(btp->baud_string != NULL) {
- if (strcmp (string, btp->baud_string) == 0)
- return(btp->baud_rate);
- btp++;
- }
- fprintf(stderr, "dg: unknown baud rate\n");
- fprintf(stderr, "known baud rates are:\n");
-
- btp = baud_tab;
- while(btp->baud_string != NULL) {
- fprintf(stderr, "\t%s\n", btp->baud_string);
- btp++;
- }
- exit(1);
- }
-
- start_telnet()
- {
- int t;
- char *term, *getenv(), *telnet, *tail, *rindex();
-
- telnet = "/usr/ucb/telnet";
- tail = "telnet";
-
- if ((t = open("/dev/tty", 2)) >= 0) {
- ioctl(t, TIOCNOTTY, (char *)0);
- close(t);
- }
- setup_slave();
- close(master);
- dup2(slave, 0);
- dup2(slave, 1);
- dup2(slave, 2);
- close(slave);
- execl(telnet, tail, host, (char *)0);
- perror(telnet);
- fail();
- }
-
- fail()
- {
- kill(0, SIGTERM);
- exit(0);
- }
-
- setup_master()
- {
- char line[11];
-
- for (linec = 'p'; linec <= 's'; linec++) {
- sprintf(line, "/dev/pty%c0", linec);
- if (access(line, 0) != 0)
- break;
- for (linen = 0; linen < 16; linen++) {
- sprintf(line, "/dev/pty%c%1x", linec, linen);
- master = open(line, 2);
- if (master >= 0) {
- return;
- }
- }
- }
- fprintf(stderr, "Can't find a pty\n");
- fail();
- }
-
- setup_slave()
- {
- char line[11];
-
- sprintf(line, "/dev/tty%c%1x", linec, linen);
- slave = open(line, 2);
- if (slave < 0) {
- perror(line);
- fail();
- }
- }
-
- reader()
- {
- register int count;
- register int index;
- register int row, col;
- register char *cp, *end, c;
-
- for(;;) {
- count = read(fd, buf0, 256);
- end = buf0 + count;
- for (cp = buf0; cp < end; cp++) {
- c = *cp & 0177;
- switch(c) {
- case '\000':
- break;
- case '\003':
- break;
- case '\005': /* read cursor position - this is a real hack */
- queue_string("\033[1;1H");
- write(fd, "\037\000\000", 3);
- break;
- case '\031': /* bc=^y */
- queue_string("\010");
- break;
- case '\020': /* cm=4^p%r%.%. */
- cp++;
- if (cp >= end) {
- count = read(fd, buf0, 1);
- end = buf0 + count;
- cp = buf0;
- }
- col = *cp & 0177;
- cp++;
- if (cp >= end) {
- count = read(fd, buf0, 1);
- end = buf0 + count;
- cp = buf0;
- }
- row = *cp & 0177;
- col++;
- row++;
- sprintf(motion_buf, "\033[%d;%dH", row, col);
- queue_string(motion_buf);
- break;
- case '\036': /* extended commands */
- cp++;
- if (cp >= end) {
- count = read(fd, buf0, 1);
- end = buf0 + count;
- cp = buf0;
- }
- switch(*cp) {
- case '\105': /* reverse video off */
- queue_string("\033[m");
- break;
- case '\104': /* reverse video on */
- queue_string("\033[7m");
- break;
- default:
- break;
- }
- break;
- case '\027': /* up=^w */
- queue_string("\033[A");
- break;
- case '\013': /* ce=^k */
- queue_string("\033[K");
- break;
- case '\024': /* us=^t */
- /* start underscore */
- queue_string("\033[4m");
- break;
- case '\025': /* ue=^u */
- /* end undersore */
- queue_string("\033[m");
- break;
- case '\034': /* so=^\ */
- queue_string("\033[m");
- break;
- case '\035': /* se=^] */
- queue_string("\033[1m");
- break;
- case '\030': /* kr=^x */
- queue_string("\033[C");
- break;
- case '\032': /* kd=^z */
- queue_string("\033[B");
- break;
- case '\010': /* kh=^h */
- queue_string("\033[1;1H");
- break;
- case '\022': /* is=^r */
- break;
- case '\012': /* nl */
- queue_string("\n\r");
- break;
- default:
- queue_char((int)c);
- }
- }
- flush_the_queue();
- }
-
- }
-
- writer()
- {
- register int count;
- register int index;
- register int row, col;
- register char *cp, *end, c;
-
- for(;;) {
- count = read(0, buf1, 256);
- index = 0;
- while (index < count) {
- if (tflag && (buf1[index] == '~') ) {
- kill(pid, SIGTERM);
- ioctl (0, TIOCNXCL, &tmode);
- tmode.sg_flags = savemode;
- ioctl (0, TIOCSETP, &tmode);
- exit(0);;
- } else {
- tflag = 0;
- }
- if (buf1[index] == '^')
- tflag = 1;
- ++index;
- }
- write(fd, buf1, count);
- }
- }
-
-
-