sources-request@mirror.UUCP (03/04/87)
Submitted by: Michael A. Cooper <usc-oberon!mcooper> Mod.sources: Volume 8, Issue 95 Archive-name: qterm #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README Makefile table.c qterm.c qterm.1 # Wrapped by Michael A. Cooper (USC Computing Services, Los Angeles) export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(936 characters)' if test -f 'README' then echo shar: over-writing existing file "'README'" fi cat << \SHAR_EOF > 'README' Q T E R M - Q U E R Y T E R M I N A L Revision 1.23 January, 1987 Qterm is a program that queries terminals to find out what kind of terminal is responding. It is useful to automagically define your terminal type. It prints the name of the terminal (compatible, hopefully, with a termcap/terminfo name) such as "vt100" to standard output. See the manual for details. Qterm was written under 4.2BSD and will probably run without modification on other Berkeley Unix systems. It has been tested under 4.2BSD, 4.3BSD, Sun 3.0 and Sun 3.2. It should work under System V.2, but I have not personally tested it on such a system. (For System V.2, compile with USG5 defined). Mike Michael A. Cooper, University Computing Services, U of Southern California UUCP: {sdcrdcf, uscvax}!usc-oberon!mcooper BITNET: mcooper@uscvaxq ARPA: mcooper@usc-oberon.USC.EDU PHONE: (213) 743-3462 SHAR_EOF echo shar: extracting "'Makefile'" '(449 characters)' if test -f 'Makefile' then echo shar: over-writing existing file "'Makefile'" fi cat << \SHAR_EOF > 'Makefile' # # $Header: Makefile,v 1.1 86/12/22 10:45:46 mcooper Exp $ # # Makefile for QTERM # BIN=/usr/usc/bin MAN=/usr/usc/man/man1 OBJS = qterm.o table.o # # Use "-DUSG5" for $(CFLAGS) below, if your system is Unix System V. # CFLAGS = -O qterm: $(OBJS) cc $(CFLAGS) $(OBJS) -o qterm shar: shar README Makefile table.c qterm.c qterm.1 > qterm.shar clean: rm -f *.o core log install: qterm qterm.1 install qterm $(BIN) install -c qterm.1 $(MAN) SHAR_EOF echo shar: extracting "'table.c'" '(2400 characters)' if test -f 'table.c' then echo shar: over-writing existing file "'table.c'" fi cat << \SHAR_EOF > 'table.c' #ifndef lint static char *RCSid = "$Header: table.c,v 1.3 86/11/13 15:40:26 mcooper Locked $"; #endif /* *------------------------------------------------------------------ * * $Source: /big/mcooper/src/qterm/RCS/table.c,v $ * $Revision: 1.3 $ * $Date: 86/11/13 15:40:26 $ * $State: Exp $ * $Author: mcooper $ * $Locker: mcooper $ * *------------------------------------------------------------------ * * Michael A. Cooper * University Computing Services, * University of Southern California * (mcooper@usc-oberon.arpa) * *------------------------------------------------------------------ * $Log: table.c,v $ * Revision 1.3 86/11/13 15:40:26 mcooper * z29 -> h29. "h29" is recognized * more. * * Revision 1.2 86/07/01 23:13:04 mcooper * Added vt220 and f220 entries. * * Revision 1.1 86/07/01 22:58:12 mcooper * Initial revision * *------------------------------------------------------------------ */ #include <stdio.h> /* * The Master Table */ char *terms[] = { /* Terminal Sends: Terminal Name: Real Name: */ /* --------------- -------------- ---------- */ "\33[?1;0c", "vt100", "Base vt100", "\33[?1;1c", "vt100", "vt100 with STP", "\33[?1;2c", "vt100", "ANSI/VT100 Clone", "\33[?1;3c", "vt100", "vt100 with AVO and STP", "\33[?1;4c", "vt100", "vt100 with GPO", "\33[?1;5c", "vt100", "vt100 with GPO and STP", "\33[?1;6c", "vt100", "vt100 with GPO and AVO", "\33[?1;7c", "vt100", "vt100 with GPO, STP, and AVO", "\33[?6c", "vt100", "Generic vt100", "\33[?8c", "vt100", "TeleVideo 970", "\33[0n", "vt100", "AT&T Unix PC 7300", "\33[?l;0c", "vt100", "AT&T Unix PC 7300", "\33[?12c", "vt100", "Concept from Pro 350/UNIX", "\33[?;c", "vt100", "Concept From Pro 350/UNIX", "\33[=1;1c", "avt-4p-s", "Concept with 4 pages memory", "\33[=1;2c", "avt-8p-s", "Concept with 8 pages memory", "\33iBO", "h29", "Zenith z29 in zenith mode", "\33/K", "h29", "Zenith z29 in zenith mode", "\33/Z", "vt52", "Generic vt52", "\33[?12;7;0;102c", "vt125", "DEC Pro 350 in vt125 mode", "\33[?10c", "la120", "DEC Writer III", "\33[?1;11c", "cit101e", "CIE CIT-101 Enhanced w/Graphics", /* "\33[?1;11c", "xt100+", "Northern Tech LANPARSCOPE", */ "\33[?62;1;2;6;7;8;9c", "vt220", "DEC VT220", "\33[62;1;2;6;8c", "f220", "Freedom 220 DEC clone", NULL }; SHAR_EOF echo shar: extracting "'qterm.c'" '(16314 characters)' if test -f 'qterm.c' then echo shar: over-writing existing file "'qterm.c'" fi cat << \SHAR_EOF > 'qterm.c' #ifndef lint static char *RCSid = "$Header: qterm.c,v 1.23 87/01/09 13:55:44 mcooper Locked $"; #endif /* *------------------------------------------------------------------ * * $Source: /big/src/usc/bin/qterm/RCS/qterm.c,v $ * $Revision: 1.23 $ * $Date: 87/01/09 13:55:44 $ * $State: Exp $ * $Author: mcooper $ * $Locker: mcooper $ * *------------------------------------------------------------------ * * Michael A. Cooper * University Computing Services, * University of Southern California * (mcooper@usc-oberon.arpa) * *------------------------------------------------------------------ * $Log: qterm.c,v $ * Revision 1.23 87/01/09 13:55:44 mcooper * Fixed bug with -s option that caused "ers:" * to be printed instead of the string * received from the terminal. * * Revision 1.22 86/12/11 15:57:16 mcooper * Should now work under System V thanks to Brian L. Matthews * (cxsea!blm). * * Revision 1.21 86/10/13 12:52:54 mcooper * Fixed bug that caused problems with * send strings not being sent from .qterm * files. * * Revision 1.20 86/08/25 15:45:58 mcooper * BUG FIX: When the -f flag was specified and the user's * tables did not produce the terminal's entry, * the internal terminal tables where not tried * as documented. * * Revision 1.19 86/08/12 15:31:22 mcooper * Fixed bug that caused terminals to wedge due * to qterm failing to match receive strings * from the .qterm file. * * Revision 1.18 86/08/11 13:49:42 mcooper * Fixed bug that caused qterm to wedge. Problem * due to alarms not being set correctly. * * Revision 1.17 86/08/08 14:40:09 mcooper * - Only send/listen for strings if the previously sent string * is not the same as the current string. * - Fixed -s option. * * Revision 1.16 86/08/08 13:16:05 mcooper * Major re-write: Added ~/.qterm file that contains * the users own copy of terminal tables. * * Revision 1.15 86/07/21 12:35:54 mcooper * Now works under System V (Define USG5). * * Revision 1.14 86/07/01 22:57:45 mcooper * Moved terminal table to seperate * file (table.c). * * Revision 1.13 86/06/30 11:17:53 mcooper * More terminals to main table... * * Revision 1.12 86/06/19 13:57:51 mcooper * Added responses for concept from a Pro running * 2.9bsd. * * Revision 1.11 86/06/18 15:58:45 mcooper * Cleanup for release. * * Revision 1.10 86/06/17 23:06:55 mcooper * Added Unix PC responses. * * Revision 1.9 86/06/16 14:19:09 mcooper * Added vt100 responses from vt100 manual. * * Revision 1.8 86/06/16 13:23:40 mcooper * Print additional information about * what the actual terminal is. * * Revision 1.7 86/06/12 10:59:27 mcooper * *** empty log message *** * * Revision 1.6 86/06/11 19:48:35 mcooper * Added alternate string and table entries for concepts. * * Revision 1.5 86/05/19 12:30:32 mcooper * General clean up. * * Revision 1.4 86/05/18 17:56:11 mcooper * Added another vt100. This one is for when you rlogin * from a Pro 2.9bsd host on a HDS Concept. * * Revision 1.3 86/05/08 09:24:13 mcooper * Added another vt100 description. * * Revision 1.2 86/05/06 18:23:35 mcooper * More cleanup - de-linted (almost). * * Revision 1.1 86/05/06 14:56:57 mcooper * Initial revision * *------------------------------------------------------------------ */ /* * [Edit with tabstop=4] * * qterm - Query Terminal * * qterm is used to query a terminal to determine the name of the terminal. * This is done by sending a fairly universal string "\33Z" to the terminal, * reading in a response, and comparing it against a master table of responses * and names. The "name" printed to standard output should be one found in * the termcap(5) database. * * Putting a line in your ".login" file such as: * * setenv TERM `qterm` * * or the following lines in your ".profile" file: * * TERM=`qterm` * export TERM * * will set your terminal type automagically. * * If you add a terminal to the master table, please also send me a copy * so that I may put it into my version. * * Michael Cooper * ARPA: mcooper@usc-oberon.ARPA * UUCP: mcooper@usc-oberon.UUCP * BITNET: mcooper@uscvaxq */ #include <stdio.h> #include <pwd.h> #include <signal.h> #include <sys/ioctl.h> #include <setjmp.h> #ifdef USG5 # include <termio.h> #else # include <sys/file.h> # include <sgtty.h> #endif #define SEND "\033Z" /* send this to query terminal */ #define ALTSEND "\033[c" /* alternate string */ #define STRFILE ".qterm" /* file containing terminal strings */ #define dprintf if(debug)printf #define MAXTERMS 100 #define TRUE 1 #define FALSE 0 #define T_STR 0 #define T_NAME 1 #define T_LNAME 2 int tabmark = 0; int tabtotal = 0; int has_set = 0; #define BUF 666 struct qt { char qt_sendstr[BUFSIZ]; /* String to send to terminal */ char qt_recvstr[BUFSIZ]; /* String expected in response */ char qt_termname[BUFSIZ]; /* Terminal name */ char qt_fullname[BUFSIZ]; /* Full terminal name & description */ }; struct qt *compare(); static struct qt termtab[MAXTERMS]; #ifdef USG5 struct termio _ntty, _otty; #else struct sgttyb _tty; #endif int _tty_ch = 2; #ifdef USG5 # define crmode() (_ntty.c_lflag &= ~ICANON,\ _ntty.c_cc[VMIN] = 1, _ntty.c_cc[VTIME] = 0,\ ioctl(_tty_ch, TCSETAF, &_ntty)) # define nocrmode() (_ntty.c_lflag |= ICANON,\ _ntty.c_cc[VMIN] = _otty.c_cc[VMIN],\ _ntty.c_cc[VTIME] = _otty.c_cc[VTIME],\ ioctl(_tty_ch, TCSETAF, &_ntty)) # define echo() (_ntty.c_lflag |= ECHO,\ ioctl(_tty_ch, TCSETAF, &_ntty)) # define noecho() (_ntty.c_lflag &= ~ECHO,\ ioctl(_tty_ch, TCSETAF, &_ntty)) #else # define crmode() (_tty.sg_flags |= CBREAK,\ ioctl(_tty_ch, TIOCSETP, &_tty)) # define nocrmode() (_tty.sg_flags &= ~CBREAK,\ ioctl(_tty_ch, TIOCSETP, &_tty)) # define echo() (_tty.sg_flags |= ECHO, \ ioctl(_tty_ch, TIOCSETP, &_tty)) # define noecho() (_tty.sg_flags &= ~ECHO, \ ioctl(_tty_ch, TIOCSETP, &_tty)) #endif #define SIZE 512 #define CMASK 0377 #define ESC '\033' static char recvbuf[SIZE]; static char *progname; int debug; /* debug mode */ int aflag; /* alternate string */ int sflag; /* print strings */ int qflag; /* quiet mode */ int fflag; /* use strings file */ int found = FALSE; int index = 0; int finish(), wakeup(), done(); char *decode(); jmp_buf env; main(argc, argv) char *argv[]; { register int x; progname = argv[0]; for (x = 1; x < argc; x++) { if (argv[x][0] != '-') break; switch (argv[x][1]) { case 'a': aflag = TRUE; break; case 't': case 's': sflag = TRUE; break; case 'q': qflag = TRUE; break; case 'f': fflag = TRUE; break; case 'd': debug = TRUE; break; default: usage(); exit(1); } } setbuf(stdout, 0); if(debug) setbuf(stderr, 0); dprintf("[ %s debug mode enabled ]\n\n", progname); if(!isatty(0)) fprintf(stderr,"Not a tty.\n"); #ifdef USG5 if(ioctl(_tty_ch, TCGETA, &_otty) < 0) #else if(ioctl(_tty_ch, TIOCGETP, &_tty) < 0) #endif { perror("gtty"); exit(1); } #ifdef USG5 _ntty = _otty; #endif if(crmode() < 0) { perror("crmode"); exit(1); } if(noecho() < 0) { perror("noecho"); exit(1); } dprintf("[ initilizing term table... ]\n"); mktable(); dprintf("[ table done ]\n"); if(!fflag) { dointernal(); } else dprintf("!fflag. not doing dointernal().\n"); index = tabmark; dprintf("main: we'll do a dotab()\n"); dotab(); dprintf("main: dotab done\n"); putc('\r', stderr); (void) nocrmode(); (void) echo(); if(!found) { dprintf("end of main\n"); notrecognized(); } } done() { putc('\r', stderr); (void) nocrmode(); (void) echo(); exit(0); } /* * finish - clean things up. */ finish() { dprintf("finish called\n"); putc('\r', stderr); (void) nocrmode(); (void) echo(); if(recvbuf[0] != NULL) (void) prinfo(compare(recvbuf, 0, tabtotal), 1); dprintf("finish done\n"); if(!found) notrecognized(); exit(0); } prinfo(t, what) struct qt *t; int what; { int len = 0; int st = FALSE; dprintf("prinfo startup\n"); if((t->qt_termname[0] != NULL) && (recvbuf[0] != NULL)) { if(debug || sflag) { len = strlen(recvbuf); fprintf(stderr, "%s receives %d character%s:", progname, len, (len == 1) ? "" : "s"); fprintf(stderr, " %s\n", decode(recvbuf)); } if(!qflag) if(t->qt_fullname[0] != NULL) fprintf(stderr, "Terminal recognized as %s (%s)\n", t->qt_termname, t->qt_fullname); else fprintf(stderr, "Terminal recognized as %s\n", t->qt_termname); printf("%s\n", t->qt_termname); found = TRUE; done(); /*NOTREACHED*/ } else { found = FALSE; if(what) { dprintf("prinfo(): doing notrecognized()\n"); notrecognized(); done(); /*NOTREACHED*/ } } dprintf("prinfo done\n"); return(st); } /* * compare - actually compare what we received against the table. */ struct qt * compare(str, start, stop) char *str; int start; int stop; { register int i = 0; int len; dprintf("compare(%s, %d, %d) startup.\n", decode(str), start, stop); alarm(0); i = start; while(i <= stop) { dprintf("compare(): tr = '%s'\n", decode(termtab[i].qt_recvstr)); if(strncmp(str, termtab[i].qt_recvstr, strlen(termtab[i].qt_recvstr)) == 0) { found = TRUE; return(&termtab[i]); } ++i; } found = FALSE; } /* * getch - read in a character at a time. */ getch() { char c; (void) read(0, &c, 1); return(c & CMASK); } /* * decode - print str in a readable fashion */ char * decode(str) char *str; { char buf[BUFSIZ]; char tmp[10]; strcpy(buf, ""); while(*str) { if (*str == ESC) { strcat(buf, "<esc> "); } else if((*str <= 33) || (*str >= 127)) { sprintf(tmp,"\\%o ", *str); strcat(buf, tmp); } else { sprintf(tmp,"%c ", *str); strcat(buf, tmp); } *++str; } return(buf); } usage() { fprintf(stderr, "usage: %s [ -asq ]\n", progname); } mktable() { register int i, z; FILE *fd, *fopen(); char file[BUFSIZ]; char buf[BUFSIZ]; char lbuf[4][BUFSIZ]; char *home, *msg, *fixctl(); int iserr = 0; extern char *terms[]; struct passwd *pwd; i = z = 0; /* * Copy internal table */ while(terms[z] != NULL && i < MAXTERMS) { (void) strcpy(termtab[i].qt_sendstr, (aflag) ? ALTSEND : SEND); (void) strcpy(termtab[i].qt_recvstr, terms[z + T_STR]); (void) strcpy(termtab[i].qt_termname, terms[z + T_NAME]); (void) strcpy(termtab[i].qt_fullname, terms[z + T_LNAME]); z += 3; ++i; } tabmark = i; /* * Try and read the user's own table */ if((home = (char *) getenv("HOME")) == NULL) { if((pwd = (struct passwd *) getpwuid(getuid())) == NULL) { fprintf(stderr, "Who the hell are you????\n"); exit(1); } home = pwd->pw_dir; } dprintf("home = '%s'\n", home); sprintf(file, "%s/%s", home, STRFILE); dprintf("strfile = '%s'\n", file); if(fflag && (fd = fopen(file, "r")) != NULL) { while(fgets(buf, sizeof(buf), fd) && i < MAXTERMS) { if(buf[0] == '#' || buf[0] == '\n') continue; lbuf[0][0] = NULL; lbuf[1][0] = NULL; lbuf[2][0] = NULL; lbuf[3][0] = NULL; (void) sscanf(buf, "%s%s%s\t%[^\n]", lbuf[0], lbuf[1], lbuf[2], lbuf[3]); if(lbuf[0][0] == NULL) continue; if(lbuf[1][0] == NULL) { iserr = TRUE; msg = "receive string"; } if(lbuf[2][0] == NULL) { iserr = TRUE; msg = "terminal name"; } if(iserr) { fprintf(stderr, "%s: Error parsing %s.\n", file, msg); exit(1); } (void) strcpy(termtab[i].qt_sendstr, fixctl(lbuf[0])); (void) strcpy(termtab[i].qt_recvstr, fixctl(lbuf[1])); (void) strcpy(termtab[i].qt_termname, lbuf[2]); (void) strcpy(termtab[i].qt_fullname, lbuf[3]); dprintf("entry %d:\n", i); dprintf("qt_sendstr = %s\n", decode(termtab[i].qt_sendstr)); dprintf("qt_recvstr = %s\n", decode(termtab[i].qt_recvstr)); dprintf("qt_termname = '%s'\n", termtab[i].qt_termname); dprintf("qt_fullname = '%s'\n", termtab[i].qt_fullname); ++i; } } tabtotal = i; dprintf("termtab total = %d\n", tabtotal); dprintf("termtab mark = %d\n", tabmark); } listen(q) struct qt *q; { register int i; register char c; char end, begin; dprintf("listen startup\n"); alarm(0); dprintf("listen: listening for '%s'\n", decode(q->qt_recvstr)); if (q->qt_recvstr[0] == NULL) { begin = ESC; end = 'c'; } else { begin = q->qt_recvstr[0]; end = q->qt_recvstr[strlen(q->qt_recvstr)-1]; } dprintf("listen: read initial character...\n"); if(setjmp(env)) { dprintf("listen: setjmp TRUE\n"); if(found) done(); ++index; (void) fflush(stdin); dprintf("listen: dotab()\n"); dotab(); } else { dprintf("listen: setjmp FALSE...set alarm\n"); signal(SIGALRM, wakeup); alarm(3); dprintf("listen: read char\n"); recvbuf[0] = getch(); alarm(0); dprintf("recvbuf[0] = '\\%o'\n", recvbuf[0]); } i = 0; if(recvbuf[0] == begin) { dprintf("listen begin\n"); while(c != end) { if(setjmp(env)) { dprintf("listen: setjmp (2) return\n"); return; } else { signal(SIGALRM, wakeup); alarm(2); dprintf("listen: read (2) char\n"); c = getch(); alarm(0); dprintf("recvbuf[0] = '\\%o'\n", recvbuf[0]); } recvbuf[++i] = c; } if(debug) fprintf(stderr,"\n[ Received terminator. ]\n"); } else { dprintf("listen: Not Recognized. exiting...\n"); notrecognized(); putc('\r',stderr); (void) nocrmode(); (void) echo(); exit(1); } dprintf("listen done\n"); } notrecognized() { if(!qflag) fprintf(stderr, "Terminal NOT recognized - defaults to \"dumb\".\n"); puts("dumb"); } wakeup() { dprintf("wakeup called\n"); longjmp(env, 1); dprintf("wakeUP: done\n"); } dotab() { int wakeup(); int st = FALSE; static int firsttime = TRUE; dprintf("dotab startup\n"); dprintf("index = %d\n", index); if(index > tabtotal) { /* * if we haven't reset things yet, do so. * now try the internal tables if the user's * tables failed. */ if(!has_set) { tabtotal = tabmark; index = 0; has_set = 1; dprintf("dotab(): has_set now true.\n"); dotab(); } dprintf("dotab(): index > tabtotal\n"); finish(); } if(!found || fflag) { while(!found && termtab[index].qt_sendstr[0] != NULL && !st) { dprintf("dotab: termtab PASS %d\n", index); dprintf("dotab: sending str %s\n", decode(termtab[index].qt_sendstr)); (void) fflush(stdin); if(firsttime || strncmp(termtab[index].qt_sendstr, termtab[index-1].qt_sendstr, strlen(termtab[index].qt_sendstr))) { firsttime = FALSE; dprintf("dotab(): sendstr's didn't match.\n"); dprintf("dotab: str1 %s\n", decode(termtab[index].qt_sendstr)); dprintf("dotab: str2 %s\n", decode(termtab[index-1].qt_sendstr)); fprintf(stderr, termtab[index].qt_sendstr); (void) fflush(stdout); (void) fflush(stderr); (void) listen(&termtab[index]); } else { dprintf("dotab(): sendstr's DID match. No str sent.\n"); dprintf("dotab: str1 %s\n", decode(termtab[index].qt_sendstr)); dprintf("dotab: str2 %s\n", decode(termtab[index-1].qt_sendstr)); } firsttime = FALSE; dprintf("dotab(): recbuf = '%s'\n", decode(recvbuf)); dprintf("dotab(): qt_rec = '%s'\n", decode(termtab[index].qt_recvstr)); st = prinfo(compare(recvbuf, tabmark, tabtotal), !fflag); dprintf("st = %d\n", st); ++index; } dprintf("dotab(): mark 1\n"); } dprintf("i'm here (2)\n"); if(!found) { dprintf("end of dotab\n"); dointernal(); if(!found) { dprintf("dotab: dointernal failed.\n"); notrecognized(); } } done(); } dointernal() { struct qt q; dprintf("DOINTERNAL startup.\n"); (void) fflush(stdin); fprintf(stderr, (aflag) ? ALTSEND : SEND); (void) fflush(stdout); (void) fflush(stderr); q.qt_recvstr[0] = NULL; (void) listen(&q); (void) prinfo(compare(recvbuf, 0, tabmark), 1); if(found) done(); dprintf("dointernal end.\n"); } char * fixctl(str) char *str; { register int i; char buf[BUFSIZ]; i = 0; while(*str) { if(*str == '^') buf[i++] = *++str & 037; else buf[i++] = *str; *++str; } buf[i] = NULL; return(buf); } SHAR_EOF echo shar: extracting "'qterm.1'" '(3334 characters)' if test -f 'qterm.1' then echo shar: over-writing existing file "'qterm.1'" fi cat << \SHAR_EOF > 'qterm.1' .\" .\" $Header: qterm.1,v 1.1 86/12/22 10:45:25 mcooper Exp $ .\" .TH QTERM 1 8/8/86 .ds ]W USC Computing Services .SH NAME qterm \- Query Terminal .SH SYNOPSIS qterm [ .B \-a ] [ .B \-f ] [ .B \-s ] [ .B \-q ] .SH DESCRIPTION .I Qterm is used to query a terminal to determine its name. This is done by sending the fairly universal string ``<ESCAPE>Z'' to the terminal, reading in a response, and comparing it against a master table of possible responses. The ``name'' printed to standard output should be one found in the .I termcap(5) database. .PP For .I csh(1) users, putting a line in your .I .login file such as: .sp 1 .in +.5i setenv TERM `qterm` .in -.5i .sp 1 should automagically set your terminal type. For .I sh(1) users, putting these lines in your .I .profile file should set your terminal type: .sp 1 .in +.5i TERM=`qterm` .br export TERM .in -.5i .sp 1 .SH OPTIONS .IP \-a Use the alternate string ``<ESCAPE>[c'' when asking the terminal to identify itself. This string is recognized by most ANSI compatible terminals. .IP \-f If the file .B $HOME/.qterm is present, it's contents are scanned to produce information for querying terminals. In this way, a user may setup different values for certain terminals. After the contents of this file have been scanned, .I qterm proceeds to query the terminal with the information provided in the file .B $HOME/.qterm. If an un-intelligable response is received (or non at all), .I qterm will proceed to use its own internal information to determine the terminal type. .IP \-s Display the response received from the terminal in a ``nice'' fashion. .IP \-q Be ``quiet'' and only print the terminal name to standard output. .SH ".QTERM FILE" .PP The format of the file $HOME/.qterm consists of four fields each seperated by white space (tabs and/or spaces). The first field is the string that should be used to query the terminal. The second field is the string to expect in response to the query. The third field is the terminal name (compatible with .I termcap(5)) to print to standard output. The fourth field is optional and may contain a description of the exact manufacturer and model name of the terminal to be used in a message printed to standard error. .PP Blank lines or lines starting with the character ``#'' are ignored and may be used as comment lines. A character preceeded by a ``^'' is taken to mean the .I control character. (i.e. ``^['' is interpretted as an <ESCAPE>). .PP Below is a sample file: .sp 2 .nf # # QTerm File # ^[Z\0\0\0\0\0^[[?1;1c\0\0\0\0\0vt100\0\0\0\0\0A vt100 with STP ^[Z\0\0\0\0\0^[[?1;2c\0\0\0\0\0vt100\0\0\0\0\0ANSI/VT100 Clone ^[Z\0\0\0\0\0^[[?1;3c\0\0\0\0\0vt100\0\0\0\0\0A vt100 with AVO and STP ^[Z\0\0\0\0\0^[[?1;4c\0\0\0\0\0vt100\0\0\0\0\0A vt100 with GPO ^[Z\0\0\0\0\0^[iBO\0\0\0\0\0\0\0\0z29\0\0\0\0\0\0\0Zenith in Zenith Mode .fi .sp .SH AUTHOR Michael A. Cooper, .br USC Computing Services, Los Angeles. .SH FILES /etc/termcap \- termcap(5) database .SH SEE ALSO csh(1), sh(1), termcap(5) .SH DIAGNOSTICS .IP "\fITerminal not recognized - defaults to dumb.\fP" .I QTerm did not receive a response from the terminal, or the response did not match any that .I qterm has stored internally. Use the \-s option to check to see which is the case. .SH BUGS Many terminals do not send a response at all. SHAR_EOF # End of shell archive exit 0 -- Michael A. Cooper, University Computing Services, U of Southern California UUCP: {sdcrdcf, uscvax}!usc-oberon!mcooper BITNET: mcooper@uscvaxq ARPA: mcooper@usc-oberon.USC.EDU PHONE: (213) 743-3462