+/*
+ * getterminaltype
+ *
+ * Ask the other end to send along its terminal type and speed.
+ * Output is the variable terminaltype filled in.
+ */
+static char ttytype_sbbuf[] = { IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE };
+void
+getterminaltype()
+{
+ void ttloop();
+
+ settimer(baseline);
+ willoption(TELOPT_TTYPE, 1);
+ willoption(TELOPT_TSPEED, 1);
+ while ((hiswants[TELOPT_TTYPE] != hisopts[TELOPT_TTYPE]) ||
+ (hiswants[TELOPT_TSPEED] != hisopts[TELOPT_TSPEED])) {
+ ttloop();
+ }
+ if (hisopts[TELOPT_TSPEED] == OPT_YES) {
+ static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
+
+ bcopy(sbbuf, nfrontp, sizeof sbbuf);
+ nfrontp += sizeof sbbuf;
+ }
+ if (hisopts[TELOPT_TTYPE] == OPT_YES) {
+
+ bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf);
+ nfrontp += sizeof ttytype_sbbuf;
+ }
+ if (hisopts[TELOPT_TSPEED] == OPT_YES) {
+ while (sequenceIs(tspeedsubopt, baseline))
+ ttloop();
+ }
+ if (hisopts[TELOPT_TTYPE] == OPT_YES) {
+ char first[256], last[256];
+
+ while (sequenceIs(ttypesubopt, baseline))
+ ttloop();
+
+ if (!terminaltypeok(&terminaltype[5])) {
+ (void) strncpy(first, terminaltype, sizeof(first));
+ for(;;) {
+ /*
+ * Save the unknown name, and request the next name.
+ */
+ (void) strncpy(last, terminaltype, sizeof(last));
+ _gettermname();
+ if (terminaltypeok(&terminaltype[5]))
+ break;
+ if (strncmp(last, terminaltype, sizeof(last)) == 0) {
+ /*
+ * We've hit the end. If this is the same as
+ * the first name, just go with it.
+ */
+ if (strncmp(first, terminaltype, sizeof(first) == 0))
+ break;
+ /*
+ * Get the terminal name one more type, so that
+ * RFC1091 compliant telnets will cycle back to
+ * the start of the list.
+ */
+ _gettermname();
+ if (strncmp(first, terminaltype, sizeof(first) != 0))
+ (void) strncpy(terminaltype, first, sizeof(first));
+ break;
+ }
+ }
+ }
+ }
+} /* end of getterminaltype */
+
+_gettermname()
+{
+ settimer(baseline);
+ bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf);
+ nfrontp += sizeof ttytype_sbbuf;
+ while (sequenceIs(ttypesubopt, baseline))
+ ttloop();
+}
+
+terminaltypeok(s)
+char *s;
+{
+ char buf[1024];
+
+ if (terminaltype == NULL)
+ return(1);
+
+ /*
+ * tgetent() will return 1 if the type is known, and
+ * 0 if it is not known. If it returns -1, it couldn't
+ * open the database. But if we can't open the database,
+ * it won't help to say we failed, because we won't be
+ * able to verify anything else. So, we treat -1 like 1.
+ */
+ if (tgetent(buf, s) == 0)
+ return(0);
+ return(1);
+}
+