home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / qterm / qterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  7.3 KB  |  337 lines

  1. #ifndef lint
  2. static char *RCSid = "$Header: qterm.c,v 1.11 86/06/18 15:58:45 mcooper Release $";
  3. #endif
  4.  
  5. /*
  6.  *------------------------------------------------------------------
  7.  *
  8.  * $Source: /usr/src/local/qterm/RCS/qterm.c,v $
  9.  * $Revision: 1.11 $
  10.  * $Date: 86/06/18 15:58:45 $
  11.  * $State: Release $
  12.  * $Author: mcooper $
  13.  * $Locker: mcooper $
  14.  *
  15.  *------------------------------------------------------------------
  16.  *
  17.  * Michael Cooper (mcooper@usc-oberon.arpa)
  18.  * University Computing Services,
  19.  * University of Southern California,
  20.  * Los Angeles, California,   90089-0251
  21.  * (213) 743-3469
  22.  *
  23.  *------------------------------------------------------------------
  24.  * $Log:    qterm.c,v $
  25.  * Revision 1.11  86/06/18  15:58:45  mcooper
  26.  * Cleanup for release.
  27.  * 
  28.  * Revision 1.10  86/06/17  23:06:55  mcooper
  29.  * Added Unix PC responses.
  30.  * 
  31.  * Revision 1.9  86/06/16  14:19:09  mcooper
  32.  * Added vt100 responses from vt100 manual.
  33.  * 
  34.  * Revision 1.8  86/06/16  13:23:40  mcooper
  35.  * Print additional information about
  36.  * what the actual terminal is.
  37.  * 
  38.  * Revision 1.7  86/06/12  10:59:27  mcooper
  39.  * *** empty log message ***
  40.  * 
  41.  * Revision 1.6  86/06/11  19:48:35  mcooper
  42.  * Added alternate string and table entries for concepts.
  43.  * 
  44.  * Revision 1.5  86/05/19  12:30:32  mcooper
  45.  * General clean up.
  46.  * 
  47.  * Revision 1.4  86/05/18  17:56:11  mcooper
  48.  * Added another vt100.  This one is for when you rlogin
  49.  * from a Pro 2.9bsd host on a HDS Concept.
  50.  * 
  51.  * Revision 1.3  86/05/08  09:24:13  mcooper
  52.  * Added another vt100 description.
  53.  * 
  54.  * Revision 1.2  86/05/06  18:23:35  mcooper
  55.  * More cleanup - de-linted (almost).
  56.  * 
  57.  * Revision 1.1  86/05/06  14:56:57  mcooper
  58.  * Initial revision
  59.  * 
  60.  *------------------------------------------------------------------
  61.  */
  62.  
  63. /*
  64.  * qterm - Query Terminal
  65.  *
  66.  * qterm is used to query a terminal to determine the name of the terminal.
  67.  * This is done by sending a fairly universal string "\33Z" to the terminal,
  68.  * reading in a response, and comparing it against a master table of responses
  69.  * and names.  The "name" printed to standard output should be one found in
  70.  * the termcap(5) database.
  71.  *
  72.  * Putting a line in your .login files such as:
  73.  *
  74.  *    setenv TERM `qterm`
  75.  *
  76.  * will set your terminal type automagically.
  77.  * 
  78.  * If you add a terminal to the master table, please also send me a copy
  79.  * so that I may put it into my version.
  80.  *
  81.  * Michael Cooper
  82.  * ARPA:     mcooper@usc-oberon.ARPA
  83.  * UUCP:     mcooper@usc-oberon.UUCP
  84.  * BITNET:    mcooper@uscvaxq.BITNET
  85.  */
  86.  
  87. #include <stdio.h>
  88. #include <sgtty.h>
  89. #include <signal.h>
  90. #include <sys/ioctl.h>
  91. #include <sys/file.h>
  92.  
  93. #define SEND        "\033Z"        /* send this to query terminal */
  94. #define ALTSEND        "\033[c"    /* alternate string */
  95.  
  96. #define TRUE        1
  97. #define FALSE        0
  98.  
  99. #define T_STR        0
  100. #define T_NAME        1
  101. #define T_LNAME        2
  102.  
  103. /*
  104.  * The Master Table
  105.  */
  106. char *terms[] = {
  107. /*  Terminal Sends:        Terminal Name:     Real Name:         */
  108. /*    ---------------        --------------     ----------         */
  109.     "\33[?1;0c",        "vt100",        "Base vt100",
  110.     "\33[?1;1c",        "vt100",        "vt100 with STP",
  111.     "\33[?1;2c",        "vt100",        "ANSI/VT100 Clone",
  112.     "\33[?1;3c",        "vt100",        "vt100 with AVO and STP",
  113.     "\33[?1;4c",        "vt100",        "vt100 with GPO",
  114.     "\33[?1;5c",        "vt100",        "vt100 with GPO and STP",
  115.     "\33[?1;6c",        "vt100",        "vt100 with GPO and AVO",
  116.     "\33[?1;7c",        "vt100",        "vt100 with GPO, STP, and AVO",
  117.     "\33[?12c",            "vt100",        "Generic vt100",
  118.     "\33[?6c",            "vt100",        "Generic vt100",
  119.     "\33[?8c",            "vt100",        "TeleVideo 970",
  120.     "\33[0n",            "vt100",        "AT&T Unix PC 7300",
  121.     "\33[?l;0c",        "vt100",        "AT&T Unix PC 7300",
  122.     "\33[=1;1c",        "avt-4p-s",        "Concept with 4 pages memory",
  123.     "\33[=1;2c",        "avt-8p-s",        "Concept with 8 pages memory",
  124.     "\33iBO",            "z29",            "Zenith z29 in zenith mode",
  125.     "\33/K",            "z29",            "Zenith z29 in zenith mode",
  126.     "\33/Z",            "vt52",            "Generic vt52",
  127.     "\33[?12;7;0;102c",    "vt125",        "DEC Pro 350 in vt125 mode",
  128.     "\33[?10c",            "la120",        "DEC Writer III",
  129.     NULL
  130. };
  131.  
  132. struct sgttyb _tty;
  133. int _tty_ch = 2;
  134.  
  135. #define crmode()     (_tty.sg_flags |= CBREAK,  stty(_tty_ch,&_tty))
  136. #define nocrmode()     (_tty.sg_flags &= ~CBREAK, stty(_tty_ch,&_tty))
  137. #define echo()         (_tty.sg_flags |= ECHO,    stty(_tty_ch,&_tty))
  138. #define noecho()     (_tty.sg_flags &= ~ECHO,   stty(_tty_ch,&_tty))
  139.  
  140. #define SIZE         512
  141. #define CMASK         0377
  142. #define ESC            '\033'
  143.  
  144. static char buf[SIZE];
  145. static char *progname;
  146. int debug;                    /* debug mode             */
  147. int aflag;                    /* alternate string     */
  148. int sflag;                    /* print strings        */
  149. int qflag;                    /* quiet mode             */
  150.  
  151. main(argc, argv)
  152. char *argv[];
  153. {
  154.     register int i, x;
  155.     register char c;
  156.     int finish();
  157.     int still_ok = 1;
  158.  
  159.     progname = argv[0];
  160.  
  161.     for (x = 1; x < argc; x++) {
  162.         if (argv[x][0] != '-')
  163.             break;
  164.         switch (argv[x][1]) {
  165.             case 'a':
  166.                 aflag = TRUE;
  167.                 break;
  168.             case 't':
  169.             case 's':
  170.                 sflag = TRUE;
  171.                 break;
  172.             case 'q':
  173.                 qflag = TRUE;
  174.                 break;
  175.             case 'd':
  176.                 debug = TRUE;
  177.                 break;
  178.             default:
  179.                 usage();
  180.                 exit(1);
  181.         }
  182.     }
  183.  
  184.     setbuf(stdout, 0);
  185.  
  186.     if(debug)
  187.         fprintf(stderr,"[ %s debug mode enabled ]\n\n", progname);
  188.  
  189.     if(!isatty(0))
  190.         fprintf(stderr,"Not a tty.\n");
  191.  
  192.     if(gtty(_tty_ch, &_tty) < 0) {
  193.         perror("gtty");
  194.         exit(1);
  195.     }
  196.     if(crmode() < 0) {
  197.         perror("crmode");
  198.         exit(1);
  199.     }
  200.     if(noecho() < 0) {
  201.         perror("noecho");
  202.         exit(1);
  203.     }
  204.  
  205.     (void) signal(SIGALRM, finish);
  206.     (void) alarm(2);
  207.  
  208.     if(debug) {
  209.         fprintf(stderr, "[ sending string: ");
  210.         decode((aflag) ? ALTSEND : SEND);
  211.         fprintf(stderr, " ]\n");
  212.     }
  213.     fprintf(stderr, (aflag) ? ALTSEND : SEND);
  214.     (void) fflush(stdout);
  215.     (void) fflush(stderr);
  216.     buf[0] = getch();
  217.     if(buf[0] == ESC) {
  218.         i = 0;
  219.         while(still_ok) {
  220.             c = getch();
  221.             buf[++i] = c;
  222.             /*
  223.              * Most ANSI comptibles have 'c' for the
  224.              * last char printed.
  225.              */
  226.             if(c == 'c')
  227.                 still_ok = 0;
  228.         }
  229.         if(debug)
  230.             fprintf(stderr,"\n[ Received 'c' terminator. ]\n");
  231.     } else {
  232.         if(!qflag)
  233.             fprintf(stderr,
  234.             "Terminal not recognized - defaults to \"dumb\".\n");
  235.         printf("dumb\n");
  236.         (void) nocrmode();
  237.         (void) echo();
  238.         exit(1);
  239.     }
  240.     finish();
  241. }
  242.  
  243. /*
  244.  * finish - this is where we come no matter what.
  245.  */
  246. finish()
  247. {
  248.     (void) nocrmode();
  249.     (void) echo();
  250.     compare();
  251.     exit(0);
  252. }
  253.  
  254. /*
  255.  * compare - actually compare what we received against the terminal
  256.  *         tables.
  257.  */
  258. compare()
  259. {
  260.     char *term, *longname;
  261.     register int i = 0;
  262.     int okay = 1;
  263.     int len;
  264.  
  265.     if(debug || sflag) {
  266.         len = strlen(buf);
  267.         fprintf(stderr, "%s receives %d character%c: ", progname,
  268.             len, (len == 1) ? 0 : 's');
  269.         decode(buf);
  270.         fprintf(stderr, "\n");
  271.     }
  272.  
  273.     while(okay) {
  274.         if(terms[i] == NULL) {
  275.             okay = 0;
  276.             term = "dumb";
  277.             buf[0] = NULL;
  278.             continue;
  279.         }
  280.         if(strcmp(buf, terms[i + T_STR]) == 0) {
  281.             term = terms[i + T_NAME];
  282.             longname = terms[i + T_LNAME];
  283.             okay = 0;
  284.         }
  285.         i += 3;
  286.     }
  287.  
  288.     if(buf[0] != NULL) {
  289.         if(!qflag)
  290.             if(*longname)
  291.                 fprintf(stderr, "Terminal recognized as %s (%s)\n", 
  292.                     term, longname);
  293.             else
  294.                 fprintf(stderr, "Terminal recognized as %s\n", term);
  295.     } else {
  296.         if(!qflag)
  297.             fprintf(stderr, 
  298.               "Terminal NOT recognized - defaults to \"%s\".\n",
  299.               term);
  300.     }
  301.     printf("%s\n", term);
  302.         
  303. }
  304.  
  305. /*
  306.  * getch - read in a character at a time.
  307.  */
  308. getch()
  309. {
  310.     char c;
  311.  
  312.     (void) read(0, &c, 1);
  313.     return(c & CMASK);
  314. }
  315.  
  316. /*
  317.  * decode - print str in a readable fashion
  318.  */
  319. decode(str)
  320. char *str;
  321. {
  322.     while(*str) {
  323.         if (*str == ESC)
  324.             fprintf(stderr, "<esc> ");
  325.         else if((*str <= 33) || (*str >= 127))
  326.             fprintf(stderr,"\\%o ", *str);
  327.         else
  328.             fprintf(stderr,"%c ", *str);
  329.         *++str;
  330.     }
  331. }
  332.  
  333. usage()
  334. {
  335.     fprintf(stderr, "usage: %s [ -asq ]\n", progname);
  336. }
  337.