+/*
+ * 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 };
+
+ int
+getterminaltype(name)
+ char *name;
+{
+ int retval = -1;
+ void _gettermname();
+
+ settimer(baseline);
+#if defined(AUTHENTICATE)
+ /*
+ * Handle the Authentication option before we do anything else.
+ */
+ send_do(TELOPT_AUTHENTICATION, 1);
+ while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
+ ttloop();
+ if (his_state_is_will(TELOPT_AUTHENTICATION)) {
+ retval = auth_wait(name);
+ }
+#endif
+
+#if defined(ENCRYPT)
+ send_will(TELOPT_ENCRYPT, 1);
+#endif
+ send_do(TELOPT_TTYPE, 1);
+ send_do(TELOPT_TSPEED, 1);
+ send_do(TELOPT_XDISPLOC, 1);
+ send_do(TELOPT_ENVIRON, 1);
+ while (
+#if defined(ENCRYPT)
+ his_do_dont_is_changing(TELOPT_ENCRYPT) ||
+#endif
+ his_will_wont_is_changing(TELOPT_TTYPE) ||
+ his_will_wont_is_changing(TELOPT_TSPEED) ||
+ his_will_wont_is_changing(TELOPT_XDISPLOC) ||
+ his_will_wont_is_changing(TELOPT_ENVIRON)) {
+ ttloop();
+ }
+#if defined(ENCRYPT)
+ /*
+ * Wait for the negotiation of what type of encryption we can
+ * send with. If autoencrypt is not set, this will just return.
+ */
+ if (his_state_is_will(TELOPT_ENCRYPT)) {
+ encrypt_wait();
+ }
+#endif
+ if (his_state_is_will(TELOPT_TSPEED)) {
+ static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
+
+ bcopy(sbbuf, nfrontp, sizeof sbbuf);
+ nfrontp += sizeof sbbuf;
+ }
+ if (his_state_is_will(TELOPT_XDISPLOC)) {
+ static char sbbuf[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
+
+ bcopy(sbbuf, nfrontp, sizeof sbbuf);
+ nfrontp += sizeof sbbuf;
+ }
+ if (his_state_is_will(TELOPT_ENVIRON)) {
+ static char sbbuf[] = { IAC, SB, TELOPT_ENVIRON, TELQUAL_SEND, IAC, SE };
+
+ bcopy(sbbuf, nfrontp, sizeof sbbuf);
+ nfrontp += sizeof sbbuf;
+ }
+ if (his_state_is_will(TELOPT_TTYPE)) {
+
+ bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf);
+ nfrontp += sizeof ttytype_sbbuf;
+ }
+ if (his_state_is_will(TELOPT_TSPEED)) {
+ while (sequenceIs(tspeedsubopt, baseline))
+ ttloop();
+ }
+ if (his_state_is_will(TELOPT_XDISPLOC)) {
+ while (sequenceIs(xdisplocsubopt, baseline))
+ ttloop();
+ }
+ if (his_state_is_will(TELOPT_ENVIRON)) {
+ while (sequenceIs(environsubopt, baseline))
+ ttloop();
+ }
+ if (his_state_is_will(TELOPT_TTYPE)) {
+ char first[256], last[256];
+
+ while (sequenceIs(ttypesubopt, baseline))
+ ttloop();
+
+ /*
+ * If the other side has already disabled the option, then
+ * we have to just go with what we (might) have already gotten.
+ */
+ if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
+ (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))
+ break;
+ if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
+ his_state_is_wont(TELOPT_TTYPE)) {
+ /*
+ * 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 time, 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;
+ }
+ }
+ }
+ }
+ return(retval);
+} /* end of getterminaltype */
+
+ void
+_gettermname()
+{
+ /*
+ * If the client turned off the option,
+ * we can't send another request, so we
+ * just return.
+ */
+ if (his_state_is_wont(TELOPT_TTYPE))
+ return;
+ settimer(baseline);
+ bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf);
+ nfrontp += sizeof ttytype_sbbuf;
+ while (sequenceIs(ttypesubopt, baseline))
+ ttloop();
+}
+
+ int
+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);
+}
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif /* MAXHOSTNAMELEN */
+
+char *hostname;
+char host_name[MAXHOSTNAMELEN];
+char remote_host_name[MAXHOSTNAMELEN];
+
+#ifndef convex
+extern void telnet P((int, int));
+#else
+extern void telnet P((int, int, char *));
+#endif