home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / vt100 / chkesc.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  7KB  |  254 lines

  1. /*
  2.   chkesc.c -- Check VT terminal's response to report requests.
  3.  
  4.   Compile with:
  5.     No CFLAGS for BSD, SUNOS, etc;
  6.     -DSYSV to use on AT&T System V;
  7.     -DNOTTYMOD for system-independent version.
  8.  
  9.   Assumes VT102 or higher, 7-bit mode (CSI = "ESC [", ST = "ESC \").
  10.  
  11.   To use, just run it while connected via a VT-102 or higher terminal
  12.   or emulator.  If you're running the system-independent version, you'll
  13.   have to do something like this:
  14.  
  15.     stty raw ; chkesc ; stty -raw
  16.  
  17.   The report is generated to stdout.
  18.  
  19.   Author: F. da Cruz, Columbia University, Oct 1991.
  20.  
  21.   Note: Not yet tested on System V.
  22. */
  23. #ifndef NOTTYMOD
  24. #ifndef SYSV
  25. #define BSD
  26. #endif /* SYSV */
  27. #endif /* NOTTYMOD */
  28.  
  29. #include <stdio.h>            /* Includes */
  30. #include <signal.h>
  31. #include <setjmp.h>
  32.  
  33. #define SP 040                /* Symbols & macros */
  34. #define DEL 0177
  35. #define ESC 033
  36. #define ctl(ch) (((ch) ^ 64 ) & 0xFF )
  37.  
  38. #ifdef BSD                /* Sys-dependent terminal control */
  39. #include <sys/ioctl.h>
  40. struct sgttyb ttold, ttraw;
  41. #endif /* BSD */
  42.  
  43. #ifdef SYSV                /* Sys-dependent terminal control */
  44. #include <termio.h>
  45. struct termio ttold, ttraw;
  46. #endif /* SYSV */
  47.  
  48. int fd;                    /* tty file descriptor */
  49.  
  50. struct escseq {                /* Escape sequence structure */
  51.     char * seq;                /* Report request escape sequence */
  52.     char * fc;                /* Final chars of report */
  53.     char * txt;                /* Descriptive text */
  54. };
  55.  
  56. /* Escape sequence table */
  57.  
  58. struct escseq esctab[] = {
  59.     "\033[c",    "c",  "DA primary device attributes request",
  60.     "\033[>c",   "c",  "DA secondary device attributes request",
  61.     "\033[5n",   "n",  "DSR device operating status request",
  62.     "\033[6n",   "R",  "DSR device operating status request, cursor position",
  63.     "\033[?6n",  "R",  "DECDSR device status request, cursor position",
  64.     "\033[?15n", "n",  "DECDSR printer status request",
  65.     "\033[?25n", "n",  "DECDSR device status request, UDKs",
  66.     "\033[?26n", "n",  "DECDSR device status request, keyboard dialect",
  67.     "\033[2$p",  "y",  "KAM ANSI keyboard action",
  68.     "\033[3$p",  "y",  "CRM ANSI control representation",
  69.     "\033[4$p",  "y",  "IRM ANSI insert/replace mode",
  70.     "\033[10$p", "y",  "HEM ANSI horizontal editing",
  71.     "\033[12$p", "y",  "SRM ANSI send/receive",
  72.     "\033[20$p", "y",  "LNM ANSI newline mode",
  73.     "\033[?1$p", "y",  "DECRQM DEC cursor key mode",                     
  74.     "\033[?2$p", "y",  "DECRQM DEC mode",                                
  75.     "\033[?3$p", "y",  "DECRQM DEC 132 column mode",                     
  76.     "\033[?4$p", "y",  "DECRQM DEC smooth scroll",                      
  77.     "\033[?5$p", "y",  "DECRQM DEC reverse video",                      
  78.     "\033[?6$p", "y",  "DECRQM DEC origin mode", 
  79.     "\033[?7$p", "y",  "DECRQM DEC autowrap mode", 
  80.     "\033[?8$p", "y",  "DECRQM DEC autorepeat keyboard mode", 
  81.     "\033[?18$p","y",  "DECRQM DEC print with formfeed mode", 
  82.     "\033[?19$p","y",  "DECRQM DEC print extend", 
  83.     "\033[?25$p","y",  "DECRQM DEC text cursor enabled", 
  84.     "\033[?42$p","y",  "DECRQM DEC NRC set", 
  85.     "\033[?66$p","y",  "DECRQM DEC numeric keypad mode", 
  86.     "\033[?67$p","y",  "DECRQM DEC backarrow sends BS", 
  87.     "\033[?68$p","y",  "DECRQM DEC keyboard usage", 
  88.     "\033[2;2$u","\033\\", "DECRQTSR DEC VT340 palette request",
  89.     "\033[1$u",  "\033\\", "DECRQTSR DEC terminal state request",
  90.     "\033[&u",   "\033\\", "DECRQUPSS DEC UPSS request",
  91.     "\033[1$w ", "\033\\", "DECRQPSR DEC presentation state request",
  92.     "\033[2$w ", "\033\\", "DECRQPSR DEC tab stop request"
  93. };
  94. nesc = (sizeof(esctab) / sizeof(struct escseq)); /* Number of entries */
  95.  
  96. jmp_buf jbuf;                /* Timeout long jump buffer */
  97. timeout = 0;                /* Timeout flag */
  98. timerh() {                /* Timeout handler */
  99.     timeout = 1;
  100.     alarm(0);
  101.     signal(SIGALRM,SIG_DFL);
  102.     longjmp(jbuf,1);
  103. }
  104.  
  105. char *                    /* Print a character as "text" */
  106. dbchr(c) char c; {
  107.     static char s[8];
  108.     char *cp = s;
  109.  
  110.     c &= 0xff;
  111.     if (c & 0x80) {            /* 8th bit on */
  112.     sprintf(cp++,"~");
  113.     c &= 0x7f;
  114.     }
  115.     if (c < SP) {            /* Control character */
  116.     if (c == ESC)
  117.       sprintf(cp,"ESC");
  118.     else
  119.       sprintf(cp,"^%c",ctl(c));
  120.     } else if (c == DEL) {
  121.     sprintf(cp,"^?");
  122.     } else {                /* Printing character */
  123.     sprintf(cp,"%c",c);
  124.     }
  125.     cp = s;                /* Return pointer to it */
  126.     return(cp);
  127. }
  128.  
  129. echo(tt) char *tt; {            /* Read and echo an escape sequence */
  130.     char c;                /* terminated by string tt. */
  131.     int j;
  132.  
  133.     signal(SIGALRM,timerh);        /* Set timer */
  134.     alarm(2);
  135.     j = 0;                /* Pattern match index */
  136.     if (setjmp(jbuf)) {            /* Timer went off */
  137.     timeout = 1;
  138.     } else {
  139.     timeout = 0;            /* It didn't go off */
  140.     while (1) {
  141.         if (read(fd,&c,1) < 0) {    /* Read report */
  142.         perror("read error");
  143.         break;
  144.         }
  145.         c &= 0x7f;            /* 7 bits only */
  146.         printf("%s ",dbchr(c));    /* Echo it */
  147.         
  148.         if (c == tt[j]) {        /* Try to match terminator */
  149.         j++;
  150.         if (tt[j] == '\0') break;
  151.         } else {
  152.         j = 0;
  153.         }
  154.     }
  155.     }
  156.     alarm(0);                /* Turn off timer */
  157.     signal(SIGALRM,SIG_DFL);    
  158. }
  159.  
  160. /* Output a report-request escape sequence */
  161.  
  162. outesc(s,tt,d) char *s; char *tt; char *d; {
  163.     char *p, c;
  164.     p = s;
  165.     printf("\r\n%s:\r\n",d);        /* Print descriptive text */
  166.     while (*p) {            /* Print text-mode esc seq */
  167.     printf("%s ",dbchr(*p++));
  168.     }
  169.     printf(" (sent)\r\n");
  170.  
  171.     while (c = *s++)            /* Send real escape sequence */
  172.       write(fd,&c,1);
  173.     echo(tt);                /* Read back the echo */
  174.     if (timeout)            /* Print status of echo */
  175.       printf(" (timed out)\r\n");
  176.     else    
  177.       printf(" (received)\r\n");
  178. }
  179.  
  180. main() {                /* Main program */
  181.     int i, j; unsigned char c;
  182.  
  183.     if ((fd = open("/dev/tty",2)) < 0) { /* Open the tty */
  184.     perror("can't open tty");
  185.     exit(1);
  186.     }
  187.  
  188. /* Put tty in raw mode */
  189.  
  190. #ifdef BSD
  191.     if (gtty(fd,&ttold) < 0) {
  192.     perror("can't get modes");
  193.     exit(1);
  194.     }
  195.     if (gtty(fd,&ttraw) < 0) {
  196.     perror("can't get modes");
  197.     exit(1);
  198.     }
  199.     ttraw.sg_flags |= RAW;
  200.     ttraw.sg_flags &= ~(ECHO|CRMOD);
  201.     if (stty(fd,&ttraw) < 0) {
  202.     perror("can't set modes");
  203.     exit(1);
  204.     }
  205. #endif /* BSD */
  206.  
  207. #ifdef SYSV
  208.     if (ioctl(fd,TCGETA,&ttold)  < 0) {
  209.     perror("Sys V get old modes ioctl");
  210.     exit(1);
  211.     }
  212.     if (ioctl(fd,TCGETA,&ttraw)  < 0) {
  213.     perror("Sys V get raw modes ioctl");
  214.     exit(1);
  215.     }
  216.     ttraw.c_lflag &= ~(ISIG|ICANON|ECHO);
  217.     ttraw.c_iflag |= (BRKINT|IGNPAR);
  218.     ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
  219.                         |INPCK|ISTRIP);
  220.     ttraw.c_oflag &= ~OPOST;
  221.     ttraw.c_cc[0] = 003;
  222.     ttraw.c_cc[4] = 1;
  223.     if (ioctl(0,TCSETAW,&ttraw) < 0) {
  224.     perror("Sys V ioctl");
  225.     exit(1);
  226.     }
  227.     printf("Sys V modes OK\r\n");
  228. #endif /* SYSV */
  229.  
  230. /* Loop for all reports */
  231.  
  232.     for (j = 0; j < nesc; j++)
  233.       outesc(esctab[j].seq, esctab[j].fc, esctab[j].txt);
  234.  
  235. /* Restore tty */
  236.  
  237. #ifdef BSD
  238.     if (stty(fd,&ttold) < 0) {
  239.     perror("can't reset modes");
  240.     exit(1);
  241.     }
  242. #endif /* BSD */
  243.  
  244. #ifdef SYSV
  245.     if (ioctl(fd,TCSETAW,&ccold) < 0) {
  246.     perror("can't reset modes");
  247.     exit(1);
  248.     }
  249. #endif /* SYSV */
  250.  
  251.     close(fd);                /* Close the tty device. */
  252.     exit(0);                /* Done. */
  253. }
  254.