]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
telnet: new addon
authorDaniel Weismueller <whytea@ipfire.org>
Thu, 9 Aug 2012 14:59:31 +0000 (16:59 +0200)
committerDaniel Weismueller <whytea@ipfire.org>
Thu, 9 Aug 2012 14:59:31 +0000 (16:59 +0200)
18 files changed:
config/rootfiles/packages/telnet [new file with mode: 0644]
lfs/telnet [new file with mode: 0644]
make.sh
src/patches/netkit-telnet-0.17-ipv6.diff [new file with mode: 0644]
src/patches/netkit-telnet-0.17-nodns.patch [new file with mode: 0644]
src/patches/netkit-telnet-0.17-reallynodns.patch [new file with mode: 0644]
src/patches/telnet-0.17-8bit.patch [new file with mode: 0644]
src/patches/telnet-0.17-CAN-2005-468_469.patch [new file with mode: 0644]
src/patches/telnet-0.17-argv.patch [new file with mode: 0644]
src/patches/telnet-0.17-cleanup_race.patch [new file with mode: 0644]
src/patches/telnet-0.17-conf.patch [new file with mode: 0644]
src/patches/telnet-0.17-env.patch [new file with mode: 0644]
src/patches/telnet-0.17-errno_test_sys_bsd.patch [new file with mode: 0644]
src/patches/telnet-0.17-issue.patch [new file with mode: 0644]
src/patches/telnet-0.17-pek.patch0 [new file with mode: 0644]
src/patches/telnet-0.17-sa-01-49.patch [new file with mode: 0644]
src/patches/telnet-client-cvs.patch0 [new file with mode: 0644]
src/patches/telnet-gethostbyname.patch [new file with mode: 0644]

diff --git a/config/rootfiles/packages/telnet b/config/rootfiles/packages/telnet
new file mode 100644 (file)
index 0000000..b603dc7
--- /dev/null
@@ -0,0 +1,3 @@
+usr/bin/telnet\r
+#usr/man/man1/telnet.1\r
+#usr/man/man5/issue.net.5
\ No newline at end of file
diff --git a/lfs/telnet b/lfs/telnet
new file mode 100644 (file)
index 0000000..a43beba
--- /dev/null
@@ -0,0 +1,106 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER        = 0.17
+THISAPP    = netkit-telnet-$(VER)
+DL_FILE    = $(THISAPP).tar.gz
+DL_FROM    = $(URL_IPFIRE)
+DIR_APP    = $(DIR_SRC)/$(THISAPP)
+TARGET     = $(DIR_INFO)/$(THISAPP)
+PROG       = telnet
+PAK_VER    = 1
+
+DEPS       = ""
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+objects = $(DL_FILE) \
+       telnet-client.tar.gz
+
+$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
+telnet-client.tar.gz = $(DL_FROM)/telnet-client.tar.gz
+
+$(DL_FILE)_MD5 = d6beabaaf53fe6e382c42ce3faa05a36
+telnet-client.tar.gz_MD5 = d74983062470c5a3e7ae14f34c489e00
+
+install : $(TARGET)
+
+check : $(patsubst %,$(DIR_CHK)/%,$(objects))
+
+download :$(patsubst %,$(DIR_DL)/%,$(objects))
+
+md5 : $(subst %,%_MD5,$(objects))
+
+dist: 
+       @$(PAK)
+
+###############################################################################
+# Downloading, checking, md5sum
+###############################################################################
+
+$(patsubst %,$(DIR_CHK)/%,$(objects)) :
+       @$(CHECK)
+
+$(patsubst %,$(DIR_DL)/%,$(objects)) :
+       @$(LOAD)
+
+$(subst %,%_MD5,$(objects)) :
+       @$(MD5)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+       @$(PREBUILD)
+       @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+       cd ${DIR_APP} && mv telnet telnet-netkit
+       cd ${DIR_APP} && tar zxf $(DIR_DL)/telnet-client.tar.gz
+       cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/telnet-client-cvs.patch0
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-env.patch
+       cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/telnet-0.17-pek.patch0
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-issue.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-sa-01-49.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-8bit.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-argv.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-conf.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-cleanup_race.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-CAN-2005-468_469.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-gethostbyname.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/netkit-telnet-0.17-ipv6.diff
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/netkit-telnet-0.17-nodns.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-errno_test_sys_bsd.patch
+       cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/netkit-telnet-0.17-reallynodns.patch
+       cd $(DIR_APP) && ./configure --prefix=/usr
+       cd $(DIR_APP) && make 
+       cd $(DIR_APP) && make install
+       rm -f /usr/sbin/telnetd
+       rm -f /usr/man/man8/in.telnetd.8
+       rm -f /usr/man/man8/telnetd.8
+       @rm -rf $(DIR_APP)
+       @$(POSTBUILD)
diff --git a/make.sh b/make.sh
index 265677b57728d1c2fa8bf3a6688cb64fe7100326..57dbd693809b5a5794584516f45d8e7218eee48f 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -767,6 +767,7 @@ buildipfire() {
   ipfiremake lcd4linux
   ipfiremake mtr
   ipfiremake tcpick
+  ipfiremake telnet
   echo Build on $HOSTNAME > $BASEDIR/build/var/ipfire/firebuild
   cat /proc/version >> $BASEDIR/build/var/ipfire/firebuild
   echo >> $BASEDIR/build/var/ipfire/firebuild
diff --git a/src/patches/netkit-telnet-0.17-ipv6.diff b/src/patches/netkit-telnet-0.17-ipv6.diff
new file mode 100644 (file)
index 0000000..e3719f1
--- /dev/null
@@ -0,0 +1,265 @@
+diff -uNr netkit-telnet-0.17/telnetd/telnetd.c netkit-telnet-0.17.ipv6/telnetd/telnetd.c\r
+--- netkit-telnet-0.17/telnetd/telnetd.c       2006-07-13 08:37:18.000000000 +0200\r
++++ netkit-telnet-0.17.ipv6/telnetd/telnetd.c  2006-07-14 08:36:11.000000000 +0200\r
+@@ -49,6 +49,7 @@\r
+ /* #include <netinet/ip.h> */ /* Don't think this is used at all here */\r
+ #include <arpa/inet.h>\r
+ #include <assert.h>\r
++#include <sys/poll.h>\r
+ #include "telnetd.h"\r
+ #include "pathnames.h"\r
+ #include "setproctitle.h"\r
+@@ -68,7 +69,7 @@\r
+ #define HAS_IPPROTO_IP\r
+ #endif\r
\r
+-static void doit(struct sockaddr_in *who);\r
++static void doit(struct sockaddr *who, socklen_t wholen);\r
+ static int terminaltypeok(const char *s);\r
\r
+ /*\r
+@@ -90,7 +91,7 @@\r
+ int\r
+ main(int argc, char *argv[], char *env[])\r
+ {\r
+-      struct sockaddr_in from;\r
++      struct sockaddr from;\r
+       int on = 1;\r
+       socklen_t fromlen;\r
+       register int ch;\r
+@@ -248,64 +249,89 @@\r
+       argc -= optind;\r
+       argv += optind;\r
\r
+-      if (debug) {\r
+-          int s, ns;\r
+-          socklen_t foo;\r
+-          struct servent *sp;\r
+-          struct sockaddr_in sn;\r
++      int s = 0;\r
\r
+-          memset(&sn, 0, sizeof(sn));\r
+-          sn.sin_family = AF_INET;\r
++      if (debug) {\r
++          struct addrinfo *ai;\r
++          unsigned int nfds = 0;\r
++          struct pollfd fds[2];\r
\r
+           if (argc > 1) {\r
+-              usage();\r
+-              /* NOTREACHED */\r
+-          } else if (argc == 1) {\r
+-                  if ((sp = getservbyname(*argv, "tcp"))!=NULL) {\r
+-                      sn.sin_port = sp->s_port;\r
+-                  } \r
+-                  else {\r
+-                      int pt = atoi(*argv);\r
+-                      if (pt <= 0) {\r
+-                          fprintf(stderr, "telnetd: %s: bad port number\n",\r
+-                                  *argv);\r
+-                          usage();\r
+-                          /* NOTREACHED */\r
+-                      }\r
+-                      sn.sin_port = htons(pt);\r
+-                 }\r
++              usage();\r
++              /* NOTREACHED */\r
+           } else {\r
+-              sp = getservbyname("telnet", "tcp");\r
+-              if (sp == 0) {\r
+-                  fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");\r
+-                  exit(1);\r
+-              }\r
+-              sn.sin_port = sp->s_port;\r
+-          }\r
++              struct addrinfo hints;\r
++\r
++              memset (&hints, '\0', sizeof (hints));\r
++              hints.ai_socktype = SOCK_STREAM;\r
++              hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;\r
++              hints.ai_protocol = IPPROTO_TCP;\r
++\r
++              if (argc == 0) {\r
++                  if (getaddrinfo(NULL, "telnet", &hints, &ai) != 0) {\r
++                     fprintf(stderr, "telnetd: %s: bad port number\n", *argv);\r
++                      usage();\r
++                      /* NOTREACHED */\r
++                  }\r
++              } else {\r
++                  if (getaddrinfo(NULL, *argv, &hints, &ai) != 0) {\r
++                      fprintf(stderr, "telnetd: %s: bad port number\n", *argv);\r
++                      usage();\r
++                      /* NOTREACHED */\r
++                  }\r
++                }\r
++          }   \r
\r
+-          s = socket(AF_INET, SOCK_STREAM, 0);\r
+-          if (s < 0) {\r
++          struct addrinfo *runp;\r
++          int b = 0;\r
++          for (runp = ai; ((runp != NULL) && (nfds < sizeof (fds) / sizeof (fds[0]))); runp = runp->ai_next) {\r
++              fds[nfds].fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);\r
++              if (fds[nfds].fd < 0) {\r
+                   perror("telnetd: socket");;\r
+-                  exit(1);\r
++                  exit(1);\r
++              }\r
++              fds[nfds].events = POLLIN;\r
++              (void) setsockopt(fds[nfds].fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));\r
++\r
++              if (bind(fds[nfds].fd, runp->ai_addr, runp->ai_addrlen) != 0) {\r
++                  // Unable to bind to given port. One of the reason can be\r
++                  // that we can't bind to both IPv4 and IPv6\r
++                  break;\r
++              } else {                        \r
++                  b++;\r
++              }\r
++\r
++              if (listen(fds[nfds].fd, 1) < 0) {\r
++                  perror("listen");\r
++                  exit(1);\r
++              }\r
++                nfds++;\r
+           }\r
+-          (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));\r
+-          if (bind(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {\r
+-              perror("bind");\r
+-              exit(1);\r
+-          }\r
+-          if (listen(s, 1) < 0) {\r
+-              perror("listen");\r
+-              exit(1);\r
++          freeaddrinfo(ai);\r
++\r
++          if (b == 0) {\r
++              perror("bind");\r
++              exit(1);\r
+           }\r
+-          foo = sizeof(sn);\r
+-          ns = accept(s, (struct sockaddr *)&sn, &foo);\r
+-          if (ns < 0) {\r
+-              perror("accept");\r
+-              exit(1);\r
++\r
++          int n = poll (fds, nfds, -1);\r
++          if (n > 0) {\r
++              unsigned int i;\r
++              for (i = 0; i < nfds; i++) {\r
++                  if (fds[i].revents & POLLIN) {\r
++                      struct sockaddr_storage rem;\r
++                      socklen_t remlen = sizeof(rem);\r
++                      int fd = accept(fds[i].fd, (struct sockaddr *) &rem, &remlen);\r
++\r
++                      if (fd < 0) {\r
++                          perror("accept");\r
++                          exit(1);\r
++                      }\r
++\r
++                      s = fd;\r
++                  }\r
++              }\r
+           }\r
+-          (void) dup2(ns, 0);\r
+-          (void) close(ns);\r
+-          (void) close(s);\r
+       } else if (argc > 0) {\r
+               usage();\r
+               /* NOT REACHED */\r
+@@ -313,13 +339,13 @@\r
\r
+       openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);\r
+       fromlen = sizeof (from);\r
+-      if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {\r
++      if (getpeername(s, &from, &fromlen) < 0) {\r
+               fprintf(stderr, "%s: ", progname);\r
+               perror("getpeername");\r
+               _exit(1);\r
+       }\r
+       if (keepalive &&\r
+-          setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {\r
++          setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {\r
+               syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");\r
+       }\r
\r
+@@ -333,13 +359,13 @@\r
+               if (tos < 0)\r
+                       tos = 020;      /* Low Delay bit */\r
+               if (tos\r
+-                 && (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)\r
++                 && (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)\r
+                  && (errno != ENOPROTOOPT) )\r
+                       syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");\r
+       }\r
+ #endif        /* defined(HAS_IPPROTO_IP) && defined(IP_TOS) */\r
+-      net = 0;\r
+-      doit(&from);\r
++      net = s;\r
++      doit(&from, fromlen);\r
+       /* NOTREACHED */\r
+       return 0;\r
+ }  /* end of main */\r
+@@ -608,10 +634,9 @@\r
+  * Get a pty, scan input lines.\r
+  */\r
+ static void\r
+-doit(struct sockaddr_in *who)\r
++doit(struct sockaddr *who, socklen_t wholen)\r
+ {\r
+       const char *host;\r
+-      struct hostent *hp;\r
+       int level;\r
+       char user_name[256];\r
\r
+@@ -623,12 +648,18 @@\r
+               fatal(net, "All network ports in use");\r
\r
+       /* get name of connected client */\r
+-      hp = gethostbyaddr((char *)&who->sin_addr, sizeof (struct in_addr),\r
+-              who->sin_family);\r
+-      if (hp)\r
+-              host = hp->h_name;\r
+-      else\r
+-              host = inet_ntoa(who->sin_addr);\r
++      int error = -1;\r
++      char namebuf[255];\r
++\r
++      error = getnameinfo(who, wholen, namebuf, sizeof(namebuf), NULL, 0, 0);\r
++      \r
++      if (error) {\r
++              perror("getnameinfo: localhost");\r
++              perror(gai_strerror(error));\r
++              exit(1);                \r
++      }\r
++      \r
++      host = namebuf;\r
\r
+       /*\r
+        * We must make a copy because Kerberos is probably going\r
+@@ -649,13 +680,21 @@\r
\r
+       /* Get local host name */\r
+       {\r
+-              struct hostent *h;\r
++              struct addrinfo hints;\r
++              struct addrinfo *res;\r
++              int e;\r
++\r
++              memset(&hints, '\0', sizeof(hints));\r
++              hints.ai_socktype = SOCK_STREAM;\r
++              hints.ai_flags = AI_ADDRCONFIG;\r
++\r
+               gethostname(host_name, sizeof(host_name));\r
+-              h = gethostbyname(host_name);\r
+-              if (h) {\r
+-                  strncpy(host_name, h->h_name, sizeof(host_name));\r
+-                  host_name[sizeof(host_name)-1] = 0;\r
++              if ((e = getaddrinfo(host_name, NULL, &hints, &res)) != 0) {\r
++                      perror("getaddrinfo: localhost");\r
++                      perror(gai_strerror(e));\r
++                      exit(1);\r
+               }\r
++              freeaddrinfo(res);\r
+       }\r
\r
+ #if   defined(AUTHENTICATE) || defined(ENCRYPT)\r
diff --git a/src/patches/netkit-telnet-0.17-nodns.patch b/src/patches/netkit-telnet-0.17-nodns.patch
new file mode 100644 (file)
index 0000000..1dba79b
--- /dev/null
@@ -0,0 +1,43 @@
+--- netkit-telnet-0.17.orig/telnetd/telnetd.c  2007-03-13 16:31:20.000000000 +0000
++++ netkit-telnet-0.17.orig/telnetd/telnetd.c  2007-03-13 16:31:26.000000000 +0000
+@@ -653,6 +653,11 @@ doit(struct sockaddr *who, socklen_t who
+       error = getnameinfo(who, wholen, namebuf, sizeof(namebuf), NULL, 0, 0);
+       
++      /* if we can't get a hostname now, settle for an address */     
++      if(error == EAI_AGAIN)
++              error = getnameinfo(who, wholen, namebuf, sizeof(namebuf),
++                              NULL, 0, NI_NUMERICHOST);
++              
+       if (error) {
+               perror("getnameinfo: localhost");
+               perror(gai_strerror(error));
+@@ -681,7 +686,7 @@ doit(struct sockaddr *who, socklen_t who
+       /* Get local host name */
+       {
+               struct addrinfo hints;
+-              struct addrinfo *res;
++              struct addrinfo *res = 0;
+               int e;
+               memset(&hints, '\0', sizeof(hints));
+@@ -690,11 +695,14 @@ doit(struct sockaddr *who, socklen_t who
+               gethostname(host_name, sizeof(host_name));
+               if ((e = getaddrinfo(host_name, NULL, &hints, &res)) != 0) {
+-                      perror("getaddrinfo: localhost");
+-                      perror(gai_strerror(e));
+-                      exit(1);
++                      if(e != EAI_AGAIN) {
++                              fprintf(stderr, "getaddrinfo: localhost %s\n", 
++                                      gai_strerror(e));
++                              exit(1);
++                      }
+               }
+-              freeaddrinfo(res);
++              if(res)
++                      freeaddrinfo(res);
+       }
+ #if   defined(AUTHENTICATE) || defined(ENCRYPT)
+
diff --git a/src/patches/netkit-telnet-0.17-reallynodns.patch b/src/patches/netkit-telnet-0.17-reallynodns.patch
new file mode 100644 (file)
index 0000000..32f7af5
--- /dev/null
@@ -0,0 +1,88 @@
+--- netkit-telnet-0.17.orig/telnetd/telnetd.c.reallynodns      2009-03-12 14:32:29.000000000 -0700
++++ netkit-telnet-0.17.orig/telnetd/telnetd.c  2009-03-12 14:51:59.000000000 -0700
+@@ -85,6 +85,7 @@
+ int keepalive = 1;
+ char *loginprg = _PATH_LOGIN;
+ char *progname;
++int lookupself = 1;
+ extern void usage(void);
+@@ -111,7 +112,7 @@
+       progname = *argv;
+-      while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:L:")) != EOF) {
++      while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:L:N")) != EOF) {
+               switch(ch) {
+ #ifdef        AUTHENTICATE
+@@ -210,6 +211,10 @@
+                       keepalive = 0;
+                       break;
++                case 'N':
++                        lookupself = 0;
++                        break;
++
+ #ifdef        SecurID
+               case 's':
+                       /* SecurID required */
+@@ -393,6 +398,7 @@
+ #endif
+       fprintf(stderr, " [-L login_program]");
+       fprintf(stderr, " [-n]");
++      fprintf(stderr, " [-N]");
+ #ifdef        SecurID
+       fprintf(stderr, " [-s]");
+ #endif
+@@ -691,15 +697,20 @@
+               memset(&hints, '\0', sizeof(hints));
+               hints.ai_socktype = SOCK_STREAM;
+-              hints.ai_flags = AI_ADDRCONFIG;
++              hints.ai_flags = AI_CANONNAME;
+               gethostname(host_name, sizeof(host_name));
+-              if ((e = getaddrinfo(host_name, NULL, &hints, &res)) != 0) {
+-                      if(e != EAI_AGAIN) {
+-                              fprintf(stderr, "getaddrinfo: localhost %s\n", 
+-                                      gai_strerror(e));
+-                              exit(1);
+-                      }
++                /*
++                 * Optionally canonicalize the local host name, in case
++                 * gethostname() returns foo, we want foo.example.com
++                 */
++              if (lookupself &&
++                    (e = getaddrinfo(host_name, NULL, &hints, &res)) == 0) {
++                        if (res->ai_canonname) {
++                                strncpy(host_name, res->ai_canonname,
++                                                        sizeof(host_name)-1);
++                                host_name[sizeof(host_name)-1] = 0;
++                        }
+               }
+               if(res)
+                       freeaddrinfo(res);
+--- netkit-telnet-0.17.orig/telnetd/telnetd.8.reallynodns      2009-03-12 14:54:54.000000000 -0700
++++ netkit-telnet-0.17.orig/telnetd/telnetd.8  2009-03-12 14:56:58.000000000 -0700
+@@ -42,7 +42,7 @@
+ protocol server
+ .Sh SYNOPSIS
+ .Nm /usr/sbin/in.telnetd
+-.Op Fl hns
++.Op Fl hnNs
+ .Op Fl a Ar authmode
+ .Op Fl D Ar debugmode
+ .Op Fl L Ar loginprg
+@@ -175,6 +175,10 @@
+ if the client is still there, so that idle connections
+ from machines that have crashed or can no longer
+ be reached may be cleaned up.
++.It Fl N
++Do not use DNS to canonicalize the local hostname;
++.Fn gethostname 2
++returns a fully qualified name.
+ .It Fl s
+ This option is only enabled if
+ .Nm telnetd
diff --git a/src/patches/telnet-0.17-8bit.patch b/src/patches/telnet-0.17-8bit.patch
new file mode 100644 (file)
index 0000000..89818b5
--- /dev/null
@@ -0,0 +1,33 @@
+diff -ru netkit-telnet-0.17.orig/telnet/main.c netkit-telnet-0.17/telnet/main.c
+--- netkit-telnet-0.17.orig/telnet/main.c      2003-05-15 20:07:40.000000000 +0200
++++ netkit-telnet-0.17/telnet/main.c   2003-05-16 00:18:28.000000000 +0200
+@@ -143,7 +143,7 @@
+       while ((ch = getopt(argc, argv, "78DEKLS:X:ab:cde:fFk:l:n:rt:x")) != -1) {
+               switch(ch) {
+               case '8':
+-                      eight = 3;      /* binary output and input */
++                      binary = 3;     /* send TELNET BINARY option for output and input */
+                       break;
+               case '7':
+                       eight = 0;
+@@ -165,7 +165,7 @@
+ #endif
+                       break;
+               case 'L':
+-                      eight |= 2;     /* binary output only */
++                      binary = 2;     /* send TELNET BINARY option for output only */
+                       break;
+               case 'S':
+                   {
+diff -ru netkit-telnet-0.17.orig/telnet/telnet.1 netkit-telnet-0.17/telnet/telnet.1
+--- netkit-telnet-0.17.orig/telnet/telnet.1    2003-05-15 20:07:40.000000000 +0200
++++ netkit-telnet-0.17/telnet/telnet.1 2003-05-15 23:38:37.000000000 +0200
+@@ -76,6 +76,8 @@
+ .Pp
+ The options are as follows:
+ .Bl -tag -width Ds
++.It Fl 7
++Strip 8th bit on input and output. Telnet is 8-bit clean by default but doesn't send the TELNET BINARY option unless forced.
+ .It Fl 8
+ Specifies an 8-bit data path.
+ This causes an attempt to negotiate the
diff --git a/src/patches/telnet-0.17-CAN-2005-468_469.patch b/src/patches/telnet-0.17-CAN-2005-468_469.patch
new file mode 100644 (file)
index 0000000..57e1372
--- /dev/null
@@ -0,0 +1,179 @@
+--- netkit-telnet-0.17/telnet/telnet.c.CAN-2005-468_469        2005-03-17 13:48:58.000000000 +0100
++++ netkit-telnet-0.17/telnet/telnet.c 2005-03-17 14:02:27.000000000 +0100
+@@ -1310,22 +1310,66 @@
+ }
+-unsigned char slc_reply[128];
++#define SLC_REPLY_SIZE 128
++unsigned char *slc_reply;
+ unsigned char *slc_replyp;
++unsigned char *slc_replyend;
+       void
+ slc_start_reply(void)
+ {
++        slc_reply = (unsigned char *)malloc(SLC_REPLY_SIZE);
++        if (slc_reply == NULL) {
++/*@*/           printf("slc_start_reply: malloc()/realloc() failed!!!\n");
++                slc_reply = slc_replyp = slc_replyend = NULL;
++                return;
++      }
++
+       slc_replyp = slc_reply;
++      slc_replyend = slc_reply + SLC_REPLY_SIZE;
+       *slc_replyp++ = IAC;
+       *slc_replyp++ = SB;
+       *slc_replyp++ = TELOPT_LINEMODE;
+       *slc_replyp++ = LM_SLC;
+ }
++static int
++slc_assure_buffer(int want_len);
++
++      static int
++slc_assure_buffer(int want_len)
++{
++        if ((slc_replyp + want_len) >= slc_replyend) {
++                int len;
++              int old_len = slc_replyp - slc_reply;
++              unsigned char *p;
++
++                len = old_len
++                      + (want_len / SLC_REPLY_SIZE + 1) * SLC_REPLY_SIZE;
++                p = (unsigned char *)realloc(slc_reply, len);
++                if (p == NULL)
++                        free(slc_reply);
++                slc_reply = p;
++                if (slc_reply == NULL) {
++/*@*/                   printf("slc_add_reply: realloc() failed!!!\n");
++                        slc_reply = slc_replyp = slc_replyend = NULL;
++                        return 1;
++                }
++                slc_replyp = slc_reply + old_len;
++                slc_replyend = slc_reply + len;
++        }
++      return 0;
++}
++
+       void
+ slc_add_reply(unsigned char func, unsigned char flags, cc_t value)
+ {
++      if (slc_assure_buffer(6))
++              return;
++
++      if (slc_replyp == NULL)
++              return;
++
+       if ((*slc_replyp++ = func) == IAC)
+               *slc_replyp++ = IAC;
+       if ((*slc_replyp++ = flags) == IAC)
+@@ -1339,6 +1383,12 @@
+ {
+     int len;
++    if (slc_assure_buffer(2))
++      return;
++
++    if (slc_replyp == NULL)
++      return;
++
+     *slc_replyp++ = IAC;
+     *slc_replyp++ = SE;
+     len = slc_replyp - slc_reply;
+@@ -1456,7 +1506,7 @@
+       }
+ }
+-#define       OPT_REPLY_SIZE  256
++#define       OPT_REPLY_SIZE  1024
+ unsigned char *opt_reply;
+ unsigned char *opt_replyp;
+ unsigned char *opt_replyend;
+@@ -1490,10 +1540,38 @@
+ env_opt_start_info(void)
+ {
+       env_opt_start();
+-      if (opt_replyp)
++      if (opt_replyp && (opt_replyp > opt_reply))
+           opt_replyp[-1] = TELQUAL_INFO;
+ }
++static int
++env_opt_assure_buffer(int want_len);
++
++      static int
++env_opt_assure_buffer(int want_len)
++{
++        if ((opt_replyp + want_len) >= opt_replyend) {
++              int len;
++              unsigned char *p;
++              int old_len = opt_replyp - opt_reply;
++
++              len = old_len
++                      + (want_len / OPT_REPLY_SIZE + 1) * OPT_REPLY_SIZE;
++              p = (unsigned char *)realloc(opt_reply, len);
++              if (p == NULL)
++                      free(opt_reply);
++              opt_reply = p;
++              if (opt_reply == NULL) {
++/*@*/                 printf("env_opt_add: realloc() failed!!!\n");
++                      opt_reply = opt_replyp = opt_replyend = NULL;
++                      return 1;
++              }
++              opt_replyp = opt_reply + old_len;
++              opt_replyend = opt_reply + len;
++      }
++      return 0;
++}
++
+       void
+ env_opt_add(unsigned char *ep)
+ {
+@@ -1515,25 +1593,12 @@
+               return;
+       }
+       vp = env_getvalue(ep, 1);
+-      if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
+-                              strlen((char *)ep) + 6 > opt_replyend)
+-      {
+-              int len;
+-              unsigned char *p;
+-              opt_replyend += OPT_REPLY_SIZE;
+-              len = opt_replyend - opt_reply;
+-              p = (unsigned char *)realloc(opt_reply, len);
+-              if (p == NULL)
+-                      free(opt_reply);
+-              opt_reply = p;
+-              if (opt_reply == NULL) {
+-/*@*/                 printf("env_opt_add: realloc() failed!!!\n");
+-                      opt_reply = opt_replyp = opt_replyend = NULL;
+-                      return;
+-              }
+-              opt_replyp = opt_reply + len - (opt_replyend - opt_replyp);
+-              opt_replyend = opt_reply + len;
+-      }
++
++      /* use the double length in case it gots escaped */
++      if (env_opt_assure_buffer((vp ? strlen((char *)vp)*2 : 0) +
++                              strlen((char *)ep)*2 + 6))
++              return;
++
+       if (opt_welldefined((char *)ep))
+ #ifdef        OLD_ENVIRON
+               if (telopt_environ == TELOPT_OLD_ENVIRON)
+@@ -1588,8 +1653,14 @@
+ {
+       int len;
++        if (opt_reply == NULL)          /*XXX*/
++                return;                 /*XXX*/
++
++
+       len = opt_replyp - opt_reply + 2;
+       if (emptyok || len > 6) {
++              if (env_opt_assure_buffer(2))
++                      return;
+               *opt_replyp++ = IAC;
+               *opt_replyp++ = SE;
+               if (NETROOM() > len) {
diff --git a/src/patches/telnet-0.17-argv.patch b/src/patches/telnet-0.17-argv.patch
new file mode 100644 (file)
index 0000000..6f71bed
--- /dev/null
@@ -0,0 +1,12 @@
+diff -ur netkit-telnet-0.17/telnetd/setproctitle.c netkit-telnet-0.17.new/telnetd/setproctitle.c
+--- netkit-telnet-0.17/telnetd/setproctitle.c  1999-12-11 00:06:39.000000000 +0100
++++ netkit-telnet-0.17.new/telnetd/setproctitle.c      2004-06-28 16:48:51.153514392 +0200
+@@ -139,7 +139,7 @@
+       (void) strcpy(Argv[0], buf);
+       p = &Argv[0][i];
+       while (p < LastArgv)
+-              *p++ = ' ';
++              *p++ = '\0';
+       Argv[1] = NULL;
+ }
diff --git a/src/patches/telnet-0.17-cleanup_race.patch b/src/patches/telnet-0.17-cleanup_race.patch
new file mode 100644 (file)
index 0000000..bc3c0f5
--- /dev/null
@@ -0,0 +1,11 @@
+--- netkit-telnet-0.17/telnetd/telnetd.c.cleanup_race  2005-01-11 18:39:49.578123000 -0500
++++ netkit-telnet-0.17/telnetd/telnetd.c       2005-01-11 18:42:45.909616000 -0500
+@@ -1081,6 +1081,8 @@
+       if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
+           ptyflush();
+     }
++    /* to avoid a race for wtmp lock */
++    signal(SIGCHLD, SIG_IGN);
+     cleanup(0);
+ }  /* end of telnet */
+       
diff --git a/src/patches/telnet-0.17-conf.patch b/src/patches/telnet-0.17-conf.patch
new file mode 100644 (file)
index 0000000..512f104
--- /dev/null
@@ -0,0 +1,23 @@
+--- netkit-telnet-0.17/configure.confverb      2000-07-29 20:00:29.000000000 +0200
++++ netkit-telnet-0.17/configure       2004-07-05 10:50:36.492963840 +0200
+@@ -263,14 +263,19 @@
+ cat <<EOF >__conftest.cc
+ #include <unistd.h>
+ #include <signal.h>
+-int count=0;
++volatile int count=0;
+ void handle(int foo) { count++; }
+ int main() {
++    sigset_t sset;
+     int pid=getpid();
++    sigemptyset(&sset);
++    sigaddset(&sset, SIGINT);
++    sigprocmask(SIG_UNBLOCK, &sset, NULL);
+     signal(SIGINT, handle);
+     kill(pid,SIGINT);
+     kill(pid,SIGINT);
+     kill(pid,SIGINT);
++    sleep(1);
+     if (count!=3) return 1;
+     return 0;
+ }
diff --git a/src/patches/telnet-0.17-env.patch b/src/patches/telnet-0.17-env.patch
new file mode 100644 (file)
index 0000000..88e7c01
--- /dev/null
@@ -0,0 +1,84 @@
+--- netkit-telnet-0.17-pre-20000204/telnet/commands.c.env      Thu Apr  8 19:30:20 1999
++++ netkit-telnet-0.17-pre-20000204/telnet/commands.c  Tue May 16 17:19:47 2000
+@@ -1815,11 +1815,11 @@
+ }
+       unsigned char *
+-env_getvalue(unsigned char *var)
++env_getvalue(unsigned char *var, int exported_only)
+ {
+-      struct env_lst *ep;
++      struct env_lst *ep = env_find(var);
+-      if ((ep = env_find(var)))
++      if (ep && (!exported_only || ep->export))
+               return(ep->value);
+       return(NULL);
+ }
+--- netkit-telnet-0.17-pre-20000204/telnet/telnet.c.env        Tue May 16 17:19:47 2000
++++ netkit-telnet-0.17-pre-20000204/telnet/telnet.c    Tue May 16 17:19:47 2000
+@@ -438,7 +438,7 @@
+ #endif
+           case TELOPT_XDISPLOC:       /* X Display location */
+-              if (env_getvalue((unsigned char *)"DISPLAY"))
++              if (env_getvalue((unsigned char *)"DISPLAY", 0))
+                   new_state_ok = 1;
+               break;
+@@ -693,7 +693,7 @@
+               resettermname = 0;
+               if (tnamep && tnamep != unknown)
+                       free(tnamep);
+-              if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) &&
++              if ((tname = (char *)env_getvalue((unsigned char *)"TERM", 0)) &&
+                               (setupterm(tname, 1, &errret) == 0)) {
+                       tnamep = mklist(ttytype, tname);
+               } else {
+@@ -870,7 +870,7 @@
+           unsigned char temp[50], *dp;
+           int len;
+-          if ((dp = env_getvalue((unsigned char *)"DISPLAY")) == NULL) {
++          if ((dp = env_getvalue((unsigned char *)"DISPLAY", 0)) == NULL) {
+               /*
+                * Something happened, we no longer have a DISPLAY
+                * variable.  So, turn off the option.
+@@ -1527,7 +1527,7 @@
+                       env_opt_add(ep);
+               return;
+       }
+-      vp = env_getvalue(ep);
++      vp = env_getvalue(ep, 1);
+       if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
+                               strlen((char *)ep) + 6 > opt_replyend)
+       {
+@@ -2170,7 +2170,7 @@
+       send_will(TELOPT_LINEMODE, 1);
+       send_will(TELOPT_NEW_ENVIRON, 1);
+       send_do(TELOPT_STATUS, 1);
+-      if (env_getvalue((unsigned char *)"DISPLAY"))
++      if (env_getvalue((unsigned char *)"DISPLAY", 0))
+           send_will(TELOPT_XDISPLOC, 1);
+       if (binary)
+           tel_enter_binary(binary);
+--- netkit-telnet-0.17-pre-20000204/telnet/externs.h.env       Mon Feb  8 15:56:11 1999
++++ netkit-telnet-0.17-pre-20000204/telnet/externs.h   Tue May 16 17:19:47 2000
+@@ -203,7 +203,7 @@
+ void env_send (unsigned char *);
+ void env_list (void);
+ unsigned char * env_default(int init, int welldefined);
+-unsigned char * env_getvalue(unsigned char *var);
++unsigned char * env_getvalue(unsigned char *var, int exported_only);
+ void set_escape_char(char *s);
+ unsigned long sourceroute(char *arg, char **cpp, int *lenp);
+@@ -335,7 +335,7 @@
+ void     env_opt_end (int);
+ unsigned char     *env_default (int, int);
+-unsigned char     *env_getvalue (unsigned char *);
++unsigned char     *env_getvalue (unsigned char *, int);
+ int get_status (void);
+ int dosynch (void);
diff --git a/src/patches/telnet-0.17-errno_test_sys_bsd.patch b/src/patches/telnet-0.17-errno_test_sys_bsd.patch
new file mode 100644 (file)
index 0000000..9a4fcba
--- /dev/null
@@ -0,0 +1,24 @@
+diff -up netkit-telnet-0.17/telnet/sys_bsd.c.errnosysbsd netkit-telnet-0.17/telnet/sys_bsd.c
+--- netkit-telnet-0.17/telnet/sys_bsd.c.errnosysbsd    2007-09-20 10:57:58.000000000 +0200
++++ netkit-telnet-0.17/telnet/sys_bsd.c        2007-09-20 11:10:08.000000000 +0200
+@@ -375,6 +375,7 @@ TerminalNewMode(int f)
+     int onoff;
+     int old;
+     cc_t esc;
++    int err;
+     globalmode = f&~MODE_FORCE;
+     if (prevmode == f)
+@@ -407,6 +408,12 @@ TerminalNewMode(int f)
+           tcsetattr(tin, TCSADRAIN, &tmp_tc);
+ #endif        /* USE_TERMIO */
+           old = ttyflush(SYNCHing|flushout);
++            if (old < 0) {
++            err = errno;
++              if (! ((err == EINTR) || (err == EAGAIN) || (err == ENOSPC))) {
++                break;
++              }
++            }
+       } while (old < 0 || old > 1);
+     }
diff --git a/src/patches/telnet-0.17-issue.patch b/src/patches/telnet-0.17-issue.patch
new file mode 100644 (file)
index 0000000..c00df43
--- /dev/null
@@ -0,0 +1,81 @@
+--- netkit-telnet-0.17/telnetd/utility.c.issue Sun Dec 12 09:59:45 1999
++++ netkit-telnet-0.17/telnetd/utility.c       Wed Jul 18 11:14:11 2001
+@@ -460,13 +460,13 @@
+       putlocation = where;
+       while (*cp) {
+-              if (*cp != '%') {
++              if (*cp != '%' && *cp != '\\') {
+                       putchr(*cp++);
+                       continue;
+               }
+               switch (*++cp) {
+-              case 't':
++              case 'l':
+                       slash = strrchr(line, '/');
+                       if (slash == NULL)
+                               putstr(line);
+@@ -474,21 +474,28 @@
+                               putstr(slash+1);
+                       break;
++              case 'n':
+               case 'h':
+                       putstr(editedhost);
+                       break;
++              case 't':
+               case 'd':
+                       (void)time(&t);
+                       (void)strftime(db, sizeof(db), fmtstr, localtime(&t));
+                       putstr(db);
+                       break;
++              case '\\':
++                      putchr('\\');
++                      break;
++                        
+               case '%':
+                       putchr('%');
+                       break;
+               case 'D':
++              case 'o':
+                       {
+                               char    buff[128];
+@@ -515,7 +522,7 @@
+                                                       c = fgetc(fp);
+                                               } while (c != EOF && c != '\n');
+                                               continue;
+-                                      } else if (c == '%') {
++                                      } else if (c == '%' || c == '\\') {
+                                               buff[0] = c;
+                                               c = fgetc(fp);
+                                               if (c == EOF) break;
+--- netkit-telnet-0.17/telnetd/issue.net.5.issue       Sun Jul 30 19:57:09 2000
++++ netkit-telnet-0.17/telnetd/issue.net.5     Wed Jul 18 11:03:09 2001
+@@ -15,16 +15,17 @@
+ .Pa /etc/issue.net
+ is a text file which contains a message or system identification to be
+ printed before the login prompt of a telnet session. It may contain
+-various `%-char' sequences. The following sequences are supported by
++various `%-char' (or, alternatively, '\\-char') sequences. The following
++sequences are supported by
+ .Ic telnetd :
+ .Bl -tag -offset indent -compact -width "abcde"
+-.It %t
++.It %l
+ - show the current tty
+-.It %h
++.It %h, %n
+ - show the system node name (FQDN)
+-.It %D
++.It %D, %o
+ - show the name of the NIS domain
+-.It %d
++.It %d, %t
+ - show the current time and date
+ .It %s
+ - show the name of the operating system
diff --git a/src/patches/telnet-0.17-pek.patch0 b/src/patches/telnet-0.17-pek.patch0
new file mode 100644 (file)
index 0000000..0f4c400
--- /dev/null
@@ -0,0 +1,37 @@
+diff -u telnet/commands.c telnet.new/commands.c
+--- telnet/commands.c  Sat Sep  1 12:55:18 2001
++++ telnet.new/commands.c      Sat Sep  1 12:54:36 2001
+@@ -2354,6 +2354,7 @@
+       hints.ai_flags = AI_CANONNAME;
+       if (portp == NULL) {
+               portp = "telnet";
++              telnetport = 1;
+       } else if (*portp == '-') {
+               portp++;
+               telnetport = 1;
+@@ -2397,7 +2398,6 @@
+           if (error) {
+               warn("%s: %s", aliasp, gai_strerror(error));
+               close(net);
+-              freeaddrinfo(ares);
+               continue;
+           }
+           if (bind(net, ares->ai_addr, ares->ai_addrlen) < 0) {
+@@ -2414,7 +2414,7 @@
+               perror("setsockopt (IP_OPTIONS)");
+ #endif
+ #if   defined(IPPROTO_IP) && defined(IP_TOS)
+-      {
++      if (res->ai_family == AF_INET) {
+ # if  defined(HAS_GETTOS)
+           struct tosent *tp;
+           if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
+@@ -2438,7 +2438,7 @@
+           char hbuf[NI_MAXHOST];
+           
+           if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
+-                  NULL, 0, NI_NUMERICHOST) != 0) {
++                  NULL, 0, niflags) != 0) {
+               strcpy(hbuf, "(invalid)");
+           }
+           fprintf(stderr, "telnet: connect to address %s: %s\n", hbuf,
diff --git a/src/patches/telnet-0.17-sa-01-49.patch b/src/patches/telnet-0.17-sa-01-49.patch
new file mode 100644 (file)
index 0000000..64ed23c
--- /dev/null
@@ -0,0 +1,208 @@
+diff -up netkit-telnet-0.17/telnetd/ext.h.sa-01-49 netkit-telnet-0.17/telnetd/ext.h
+--- netkit-telnet-0.17/telnetd/ext.h.sa-01-49  1999-12-12 15:59:44.000000000 +0100
++++ netkit-telnet-0.17/telnetd/ext.h   2011-01-20 22:39:54.000000000 +0100
+@@ -86,7 +86,10 @@ extern char *neturg;                /* one past last b
+ extern int pcc, ncc;
+ /* printf into netobuf */
+-void netoprintf(const char *fmt, ...) __attribute((format (printf, 1, 2))); 
++/* void netoprintf(const char *fmt, ...) __attribute((format (printf, 1, 2))); */
++#define netoprintf output_data
++int   output_data(const char *, ...) __attribute((format (printf, 1, 2))); 
++void  output_datalen(const char *, int);
+ extern int pty, net;
+ extern char *line;
+@@ -182,7 +185,10 @@ void tty_setsofttab(int);
+ void tty_tspeed(int);
+ void willoption(int);
+ void wontoption(int);
++
++#if 0
+ void writenet(unsigned char *, int);
++#endif
+ #if defined(ENCRYPT)
+ extern void (*encrypt_output)(unsigned char *, int);
+diff -up netkit-telnet-0.17/telnetd/slc.c.sa-01-49 netkit-telnet-0.17/telnetd/slc.c
+--- netkit-telnet-0.17/telnetd/slc.c.sa-01-49  1999-12-12 15:59:44.000000000 +0100
++++ netkit-telnet-0.17/telnetd/slc.c   2011-01-20 22:39:54.000000000 +0100
+@@ -183,7 +183,7 @@ int end_slc(unsigned char **bufp) {
+       else {
+           snprintf(slcbuf+slcoff, sizeof(slcbuf)-slcoff, "%c%c", IAC, SE);
+           slcoff += 2;
+-          writenet(slcbuf, slcoff);
++          output_datalen(slcbuf, slcoff);
+           netflush();  /* force it out immediately */
+       }
+     }
+diff -up netkit-telnet-0.17/telnetd/state.c.sa-01-49 netkit-telnet-0.17/telnetd/state.c
+--- netkit-telnet-0.17/telnetd/state.c.sa-01-49        1999-12-12 20:41:44.000000000 +0100
++++ netkit-telnet-0.17/telnetd/state.c 2011-01-20 22:43:34.000000000 +0100
+@@ -37,6 +37,7 @@
+ char state_rcsid[] = 
+   "$Id: state.c,v 1.12 1999/12/12 19:41:44 dholland Exp $";
++#include <stdarg.h>
+ #include "telnetd.h"
+ int not42 = 1;
+@@ -1365,7 +1366,7 @@ void send_status(void) {
+     ADD(IAC);
+     ADD(SE);
+-    writenet(statusbuf, ncp - statusbuf);
++    output_datalen(statusbuf, ncp - statusbuf);
+     netflush();       /* Send it on its way */
+     DIAG(TD_OPTIONS, {printsub('>', statusbuf, ncp - statusbuf); netflush();});
+diff -up netkit-telnet-0.17/telnetd/termstat.c.sa-01-49 netkit-telnet-0.17/telnetd/termstat.c
+--- netkit-telnet-0.17/telnetd/termstat.c.sa-01-49     1999-12-12 15:59:45.000000000 +0100
++++ netkit-telnet-0.17/telnetd/termstat.c      2011-01-20 22:39:54.000000000 +0100
+@@ -128,7 +128,6 @@ static int _terminit = 0;
+       void
+ localstat()
+ {
+-      void netflush();
+       int need_will_echo = 0;
+       /*
+diff -up netkit-telnet-0.17/telnetd/utility.c.sa-01-49 netkit-telnet-0.17/telnetd/utility.c
+--- netkit-telnet-0.17/telnetd/utility.c.sa-01-49      2011-01-20 22:39:54.000000000 +0100
++++ netkit-telnet-0.17/telnetd/utility.c       2011-01-20 22:48:02.000000000 +0100
+@@ -38,8 +38,10 @@ char util_rcsid[] = 
+   "$Id: utility.c,v 1.11 1999/12/12 14:59:45 dholland Exp $";
+ #define PRINTOPTIONS
++#define _GNU_SOURCE
+ #include <stdarg.h>
++#include <stdio.h>
+ #include <sys/utsname.h>
+ #ifdef AUTHENTICATE
+@@ -52,6 +54,53 @@ char util_rcsid[] = 
+  * utility functions performing io related tasks
+  */
++/*
++ * This function appends data to nfrontp and advances nfrontp.
++ * Returns the number of characters written altogether (the
++ * buffer may have been flushed in the process).
++ */
++
++int
++output_data(const char *format, ...)
++{
++      va_list args;
++      int len;
++      char *buf;
++
++      va_start(args, format);
++      if ((len = vasprintf(&buf, format, args)) == -1)
++              return -1;
++      output_datalen(buf, len);
++      va_end(args);
++      free(buf);
++      return (len);
++}
++
++void
++output_datalen(const char *buf, int len)
++{
++      int remaining, copied;
++      
++      remaining = BUFSIZ - (nfrontp - netobuf);
++      while (len > 0) {
++              /* Free up enough space if the room is too low*/
++              if ((len > BUFSIZ ? BUFSIZ : len) > remaining) {
++                      netflush();
++                      remaining = BUFSIZ - (nfrontp - netobuf);
++              }
++
++              /* Copy out as much as will fit */
++              copied = remaining > len ? len : remaining;
++              memmove(nfrontp, buf, copied);
++              nfrontp += copied;
++              len -= copied;
++              remaining -= copied;
++              buf += copied;
++      }
++      return;
++}
++
++/**
+ void
+ netoprintf(const char *fmt, ...)
+ {
+@@ -67,7 +116,7 @@ netoprintf(const char *fmt, ...)
+       va_end(ap);
+       if (len<0 || len==maxsize) {
+-       /* didn't fit */
++              / * did not fit * /
+        netflush();
+       }
+       else {
+@@ -76,6 +125,7 @@ netoprintf(const char *fmt, ...)
+    }
+    nfrontp += len;
+ }
++*/
+ /*
+  * ttloop
+@@ -273,10 +323,15 @@ netflush(void)
+     int n;
+     if ((n = nfrontp - nbackp) > 0) {
++
++#if 0
++      /* XXX This causes output_data() to recurse and die */
+       DIAG(TD_REPORT,
+           { netoprintf("td: netflush %d chars\r\n", n);
+             n = nfrontp - nbackp;  /* update count */
+           });
++#endif
++
+ #if   defined(ENCRYPT)
+       if (encrypt_output) {
+               char *s = nclearto ? nclearto : nbackp;
+@@ -310,11 +365,14 @@ netflush(void)
+           }
+       }
+     }
+-    if (n < 0) {
+-      if (errno == EWOULDBLOCK || errno == EINTR)
+-              return;
+-      cleanup(0);
+-    }
++
++       if (n == -1) {
++              if (errno == EWOULDBLOCK || errno == EINTR)
++                return;
++              cleanup(0);
++              /* NOTREACHED */
++       }
++
+     nbackp += n;
+ #if   defined(ENCRYPT)
+     if (nbackp > nclearto)
+@@ -332,7 +390,7 @@ netflush(void)
+     return;
+ }  /* end of netflush */
+-
++#if 0
+ /*
+  * writenet
+  *
+@@ -355,7 +413,7 @@ void writenet(register unsigned char *pt
+       nfrontp += len;
+ }  /* end of writenet */
+-
++#endif
+ /*
+  * miscellaneous functions doing a variety of little jobs follow ...
diff --git a/src/patches/telnet-client-cvs.patch0 b/src/patches/telnet-client-cvs.patch0
new file mode 100644 (file)
index 0000000..5fc57a7
--- /dev/null
@@ -0,0 +1,1721 @@
+diff -uNr telnet/Makefile telnet.obsd-cvs/Makefile
+--- telnet/Makefile    Mon Jul 27 18:25:13 1998
++++ telnet.obsd-cvs/Makefile   Sat Mar 10 10:54:26 2001
+@@ -36,22 +36,20 @@
+ PROG= telnet
+-CFLAGS+=-DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DSKEY -Dunix
+-CFLAGS+=-DENV_HACK -D_USE_OLD_CURSES_
++CFLAGS+=-DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK -DSKEY -Dunix
+ CFLAGS+=-I${.CURDIR}/../../lib
+-LDADD+=       -locurses -ltelnet
+-DPADD=        ${LIBOLDCURSES} ${LIBTELNET}
++LDADD+=       -lcurses -ltelnet
++DPADD=        ${LIBCURSES} ${LIBTELNET
+ SRCS= authenc.c commands.c main.c network.c ring.c sys_bsd.c telnet.c \
+       terminal.c tn3270.c utilities.c
+ .include <bsd.own.mk> # for KERBEROS
+-.if (${KERBEROS} == "yes")
++.if (${KERBEROS:L} == "yes")
+ CFLAGS+=-DENCRYPTION -DAUTHENTICATION -DKRB4
+ LDADD+= -lkrb -ldes
+ DPADD+= ${LIBDES} ${LIBKRB}
+ .endif
+ .include <bsd.prog.mk>
+-
+diff -uNr telnet/commands.c telnet.obsd-cvs/commands.c
+--- telnet/commands.c  Fri Apr  9 02:30:20 1999
++++ telnet.obsd-cvs/commands.c Sat Mar 10 10:51:22 2001
+@@ -1,4 +1,4 @@
+-/*    $OpenBSD: commands.c,v 1.20 1999/01/04 07:55:05 art Exp $       */
++/*    $OpenBSD: commands.c,v 1.34 2000/11/08 21:49:44 aaron Exp $     */
+ /*    $NetBSD: commands.c,v 1.14 1996/03/24 22:03:48 jtk Exp $        */
+ /*
+@@ -69,7 +69,7 @@
+       int status;
+       if(argc != 3) {
+-              printf("%s sequence challenge\n", argv[0]);
++              printf("usage: %s sequence challenge\n", argv[0]);
+               return 0;
+       }
+@@ -2175,17 +2175,19 @@
+     int gotmachine = 0;
+     int l1 = strlen(m1);
+     int l2 = strlen(m2);
+-    char m1save[64];
++    char m1save[MAXHOSTNAMELEN];
+     if (skiprc)
+       return;
+-    strcpy(m1save, m1);
++    strncpy(m1save, m1, sizeof(m1save));
+     m1 = m1save;
+     if (rcname[0] == 0) {
+       char *home = getenv("HOME");
++      if (home == NULL || *home == '\0')
++          return;
+       snprintf (rcname, sizeof(rcname), "%s/.telnetrc",
+                 home ? home : "");
+     }
+@@ -2248,15 +2250,9 @@
+     int
+ tn(int argc, char *argv[])
+ {
+-    struct hostent *host = 0, *alias = 0;
+-#if defined(AF_INET6)
+-    struct sockaddr_in6 sin6;
+-#endif
++    struct addrinfo hints, *res, *res0;
++    int error;
+     struct sockaddr_in sin;
+-    struct sockaddr_in ladr;
+-    struct sockaddr *sa;
+-    int sa_size;
+-    struct servent *sp = 0;
+     unsigned long temp;
+ #if !defined(__linux__)
+     extern char *inet_ntoa();
+@@ -2266,15 +2262,18 @@
+     int srlen;
+ #endif
+     char *cmd, *hostp = 0, *portp = 0, *user = 0, *aliasp = 0;
+-    int family, port = 0;
+-
++    int retry;
++#ifdef NI_WITHSCOPEID
++    const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
++#else
++    const int niflags = NI_NUMERICHOST;
++#endif
++    
+     /* clear the socket address prior to use */
+     memset((char *)&sin, 0, sizeof(sin));
+     if (connected) {
+       printf("?Already connected to %s\r\n", hostname);
+-      seteuid(getuid());
+-      setuid(getuid());
+       return 0;
+     }
+     if (argc < 2) {
+@@ -2324,8 +2323,6 @@
+       }
+     usage:
+       printf("usage: %s [-l user] [-a] host-name [port]\r\n", cmd);
+-      seteuid(getuid());
+-      setuid(getuid());
+       return 0;
+     }
+     if (hostp == 0)
+@@ -2340,185 +2337,80 @@
+       temp = sourceroute(hostp, &srp, &srlen);
+       if (temp == 0) {
+           herror(srp);
+-          seteuid(getuid());
+-          setuid(getuid());
+           return 0;
+       } else if (temp == -1) {
+           printf("Bad source route option: %s\r\n", hostp);
+-          seteuid(getuid());
+-          setuid(getuid());
+           return 0;
+       } else {
+           abort();
+       }
+-    } else {
+-#endif
+-      memset (&sin, 0, sizeof(sin));
+-#if defined(HAVE_INET_PTON) && defined(AF_INET6)
+-      memset (&sin6, 0, sizeof(sin6));
+-
+-      if(inet_pton(AF_INET6, hostp, &sin6.sin6_addr)) {
+-          sin6.sin6_family = family = AF_INET6;
+-          sa = (struct sockaddr *)&sin6;
+-          sa_size = sizeof(sin6);
+-          strcpy(_hostname, hostp);
+-          hostname =_hostname;
+-      } else
+-#endif
+-          if(inet_aton(hostp, &sin.sin_addr)){
+-              sin.sin_family = family = AF_INET;
+-              sa = (struct sockaddr *)&sin;
+-              sa_size = sizeof(sin);
+-              strcpy(_hostname, hostp);
+-              hostname = _hostname;
+-          } else {
+-#ifdef HAVE_GETHOSTBYNAME2
+-              host = gethostbyname2(hostp, AF_INET6);
+-              if(host == NULL)
+-                  host = gethostbyname2(hostp, AF_INET);
+-#else
+-              host = gethostbyname(hostp);
+-#endif
+-              if (host) {
+-                  strncpy(_hostname, host->h_name, sizeof(_hostname));
+-                  family = host->h_addrtype;
+-
+-                  switch(family) {
+-                  case AF_INET:
+-                      memset(&sin, 0, sizeof(sin));
+-                      sa_size = sizeof(sin);
+-                      sa = (struct sockaddr *)&sin;
+-                      sin.sin_family = family;
+-
+-                      memcpy(&sin.sin_addr, *host->h_addr_list, sizeof(struct in_addr));
+-                      break;
+-#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6)
+-                  case AF_INET6:
+-                      memset(&sin6, 0, sizeof(sin6));
+-                      sa_size = sizeof(sin6);
+-                      sa = (struct sockaddr *)&sin6;
+-                      sin6.sin6_family = family;
+-                      memcpy(&sin6.sin6_addr, *host->h_addr_list, sizeof(struct in6_addr));
+-                      break;
+-#endif
+-                  default:
+-                      fprintf(stderr, "Bad address family: %d\n", family);
+-                      return 0;
+-                  }
+-                  
+-                  _hostname[sizeof(_hostname)-1] = '\0';
+-                  hostname = _hostname;
+-              } else {
+-                  herror(hostp);
+-                  seteuid(getuid());
+-                  setuid(getuid());
+-                  return 0;
+-              }
+-          }
+-#if   defined(IP_OPTIONS) && defined(IPPROTO_IP)
+-    }
++    } else
+ #endif
+-    if (portp) {
+-      if (*portp == '-') {
+-          portp++;
+-          telnetport = 1;
+-      } else
+-          telnetport = 0;
+-      port = atoi(portp);
+-      if (port == 0) {
+-          sp = getservbyname(portp, "tcp");
+-          if (sp)
+-              port = sp->s_port;
+-          else {
+-              printf("%s: bad port number\r\n", portp);
+-              seteuid(getuid());
+-              setuid(getuid());
+-              return 0;
+-          }
+-      } else {
+-          port = htons(port);
+-      }
+-    } else {
+-      if (sp == 0) {
+-          sp = getservbyname("telnet", "tcp");
+-          if (sp == 0) {
+-              fprintf(stderr, "telnet: tcp/telnet: unknown service\r\n");
+-              seteuid(getuid());
+-              setuid(getuid());
+-              return 0;
+-          }
+-          port = sp->s_port;
++    {
++      hostname = hostp;
++      memset(&hints, 0, sizeof(hints));
++      hints.ai_family = PF_UNSPEC;
++      hints.ai_socktype = SOCK_STREAM;
++      hints.ai_flags = AI_CANONNAME;
++      if (portp == NULL) {
++              portp = "telnet";
++      } else if (*portp == '-') {
++              portp++;
++              telnetport = 1;
++      }
++      h_errno = 0;
++      error = getaddrinfo(hostp, portp, &hints, &res0);
++      if (error) {
++          if (error == EAI_SERVICE)
++              warnx("%s: bad port", portp);
++          else
++              warnx("%s: %s", hostp, gai_strerror(error));
++         if (h_errno)
++              herror(hostp);
++         return 0;
+       }
+-      telnetport = 1;
+     }
+-    switch(family) {
+-    case AF_INET:
+-      sin.sin_port = port;
+-      printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr));
+-      break;
+-#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6)
+-    case AF_INET6: {
+-#ifndef INET6_ADDRSTRLEN
+-#define INET6_ADDRSTRLEN 46 
+-#endif
+-      char buf[INET6_ADDRSTRLEN];
+-
+-      sin6.sin6_port = port;
+-#ifdef HAVE_INET_NTOP
+-      printf("Trying %s...\r\n", inet_ntop(AF_INET6,
+-                                           &sin6.sin6_addr,
+-                                           buf,
+-                                           sizeof(buf)));
+-#endif
+-      break;
+-    }
+-#endif
+-    default:
+-      abort();
+-    }
+-
+-    do {
+-      net = socket(family, SOCK_STREAM, 0);
+-      seteuid(getuid());
+-      setuid(getuid());
+-      if (net < 0) {
+-          perror("telnet: socket");
+-          return 0;
++    net = -1;
++    retry = 0;
++    for (res = res0; res; res = res->ai_next) {
++      if (1 /* retry */) {
++          char hbuf[NI_MAXHOST];
++          
++          if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
++                  NULL, 0, niflags) != 0) {
++              strcpy(hbuf, "(invalid)");
++          }
++          printf("Trying %s...\r\n", hbuf);
+       }
++      net = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
++      if (net < 0)
++          continue;
++          
+       if (aliasp) {
+-          memset ((caddr_t)&ladr, 0, sizeof (ladr));
+-          temp = inet_addr(aliasp);
+-          if (temp != INADDR_NONE) {
+-              ladr.sin_addr.s_addr = temp;
+-              ladr.sin_family = AF_INET;
+-              alias = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET);
+-          } else {
+-              alias = gethostbyname(aliasp);
+-              if (alias) {
+-                  ladr.sin_family = alias->h_addrtype;
+-#if   defined(h_addr)         /* In 4.3, this is a #define */
+-                  memmove((caddr_t)&ladr.sin_addr,
+-                      alias->h_addr_list[0], alias->h_length);
+-#else /* defined(h_addr) */
+-                  memmove((caddr_t)&ladr.sin_addr, alias->h_addr,
+-                      alias->h_length);
+-#endif        /* defined(h_addr) */
+-              } else {
+-                  herror(aliasp);
+-                  return 0;
+-              }
++          struct addrinfo ahints, *ares;
++          memset(&ahints, 0, sizeof(ahints));
++          ahints.ai_family = PF_UNSPEC;
++          ahints.ai_socktype = SOCK_STREAM;
++          ahints.ai_flags = AI_PASSIVE;
++          error = getaddrinfo(aliasp, "0", &ahints, &ares);
++          if (error) {
++              warn("%s: %s", aliasp, gai_strerror(error));
++              close(net);
++              freeaddrinfo(ares);
++              continue;
+           }
+-            ladr.sin_port = htons(0);
+-  
+-            if (bind (net, (struct sockaddr *)&ladr, sizeof(ladr)) < 0) {
+-                perror(aliasp);; 
++          if (bind(net, ares->ai_addr, ares->ai_addrlen) < 0) {
++              perror(aliasp);
+                 (void) close(net);   /* dump descriptor */
+-              return 0;
++              freeaddrinfo(ares);
++              continue;
+             }
++          freeaddrinfo(ares);
+         }
+  #if  defined(IP_OPTIONS) && defined(IPPROTO_IP)
+-      if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)
++      if (srp && res->ai_family == AF_INET
++       && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)
+               perror("setsockopt (IP_OPTIONS)");
+ #endif
+ #if   defined(IPPROTO_IP) && defined(IP_TOS)
+@@ -2542,65 +2434,32 @@
+               perror("setsockopt (SO_DEBUG)");
+       }
+-      if (connect(net, sa, sa_size) < 0) {
+-          int retry = 0;
+-
+-          if (host && host->h_addr_list[1]) {
+-              int oerrno = errno;
+-              retry = 1;
+-
+-              switch(family) {
+-              case AF_INET :
+-                  fprintf(stderr, "telnet: connect to address %s: ",
+-                          inet_ntoa(sin.sin_addr));
+-                  ++host->h_addr_list;
+-                  memcpy(&sin.sin_addr, *host->h_addr_list, sizeof(struct in_addr));
+-                  break;
+-#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6)
+-              case AF_INET6: {
+-                  char buf[INET6_ADDRSTRLEN];
+-
+-                  fprintf(stderr, "telnet: connect to address %s: ",
+-                          inet_ntop(AF_INET6, &sin6.sin6_addr, buf,
+-                                    sizeof(buf)));
+-                  ++host->h_addr_list;
+-                  memcpy(&sin6.sin6_addr, *host->h_addr_list, sizeof(struct in6_addr));
+-                  break;
+-              }
+-#endif
+-              default:
+-                  abort();
+-              }
+-                   
+-              errno = oerrno;
+-              perror(NULL);
+-
+-              switch(family) {
+-              case AF_INET :
+-                      printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr));
+-                      break;
+-#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6)
+-              case AF_INET6: {
+-                  printf("Trying %s...\r\n", inet_ntop(AF_INET6,
+-                                           &sin6.sin6_addr,
+-                                           buf,
+-                                           sizeof(buf)));
+-                  break;
+-              }
+-#endif
+-              }
+-              
+-              (void) NetClose(net);
+-              continue;
++      if (connect(net, res->ai_addr, res->ai_addrlen) < 0) {
++          char hbuf[NI_MAXHOST];
++          
++          if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
++                  NULL, 0, NI_NUMERICHOST) != 0) {
++              strcpy(hbuf, "(invalid)");
+           }
+-          perror("telnet: Unable to connect to remote host");
+-          return 0;
++          fprintf(stderr, "telnet: connect to address %s: %s\n", hbuf,
++              strerror(errno));
++      
++          close(net);
++          net = -1;
++          retry++;
++          continue;
+       }
++
+       connected++;
+ #if   defined(AUTHENTICATION) || defined(ENCRYPTION)
+       auth_encrypt_connect(connected);
+ #endif        /* defined(AUTHENTICATION) */
+-    } while (connected == 0);
++      break;
++    }
++    freeaddrinfo(res0);
++    if (net < 0) {
++        return 0;
++    }
+     cmdrc(hostp, hostname);
+     if (autologin && user == NULL) {
+       struct passwd *pw;
+@@ -2652,6 +2511,9 @@
+         encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)",
+ #endif
+       zhelp[] =       "suspend telnet",
++#ifdef SKEY
++      skeyhelp[] =    "compute response to s/key challenge",
++#endif
+       shellhelp[] =   "invoke a subshell",
+       envhelp[] =     "change environment variables ('environ ?' for more)",
+       modestring[] = "try to enter line or character mode ('mode ?' for more)";
+@@ -2690,7 +2552,7 @@
+       { "environ",    envhelp,        env_cmd,        0 },
+       { "?",          helphelp,       help,           0 },
+ #if   defined(SKEY)
+-      { "skey",       NULL,           skey_calc,      0 },
++      { "skey",       skeyhelp,       skey_calc,      0 },
+ #endif                
+       { 0,            0,              0,              0 }
+ };
+diff -uNr telnet/externs.h telnet.obsd-cvs/externs.h
+--- telnet/externs.h   Mon Feb  8 22:56:11 1999
++++ telnet.obsd-cvs/externs.h  Sat Mar 10 10:54:35 2001
+@@ -1,4 +1,4 @@
+-/*    $OpenBSD: externs.h,v 1.4 1998/03/12 17:31:32 deraadt Exp $     */
++/*    $OpenBSD: externs.h,v 1.5 1998/03/12 2001/01/22 11:03:38 fgsch Exp $    */
+ /* $KTH: externs.h,v 1.16 1997/11/29 02:28:35 joda Exp $ */
+ /*
+@@ -447,7 +447,7 @@
+     *Ibackp,           /* Oldest byte of 3270 data */
+     Ibuf[],            /* 3270 buffer */
+     *Ifrontp,          /* Where next 3270 byte goes */
+-    tline[],
++    tline[200],
+     *transcom;         /* Transparent command */
+ extern int
+diff -uNr telnet/main.c telnet.obsd-cvs/main.c
+--- telnet/main.c      Wed Apr  7 23:23:35 1999
++++ telnet.obsd-cvs/main.c     Sat Mar 10 09:59:35 2001
+@@ -1,4 +1,4 @@
+-/*    $OpenBSD: main.c,v 1.7 1998/05/15 03:16:38 art Exp $    */
++/*    $OpenBSD: main.c,v 1.10 2001/01/21 22:46:37 aaron Exp $ */
+ /*    $NetBSD: main.c,v 1.5 1996/02/28 21:04:05 thorpej Exp $ */
+ /*
+@@ -81,10 +81,10 @@
+           prompt,
+ #ifdef        AUTHENTICATION
+           "[-8] [-E] [-K] [-L] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
+-          "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] [-b hostalias ]",
++          "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] [-b hostalias ] ",
+ #else
+           "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
+-          "\n\t[-n tracefile] [-b hostalias ]",
++          "\n\t[-n tracefile] [-b hostalias ] ",
+ #endif
+ #if defined(TN3270) && defined(unix)
+ # ifdef AUTHENTICATION
+@@ -95,13 +95,11 @@
+ #else
+           "[-r] ",
+ #endif
++          "\n\r "
+ #ifdef ENCRYPTION
+-          "[-x] [host-name [port]]"
+-#else
+-
+-          "[host-name [port]]"
++          "[-x] " 
+ #endif
+-      );
++          "[host-name [port]]");
+       exit(1);
+ }
+@@ -276,8 +274,8 @@
+                       break;
+               case 't':
+ #if defined(TN3270) && defined(unix)
++                      (void)strncpy(tline, optarg, sizeof(tline));
+                       transcom = tline;
+-                      (void)strcpy(transcom, optarg);
+ #else
+                       fprintf(stderr,
+                          "%s: Warning: -t ignored, no TN3270 support.\n",
+diff -uNr telnet/sys_bsd.c telnet.obsd-cvs/sys_bsd.c
+--- telnet/sys_bsd.c   Wed Apr  7 21:38:31 1999
++++ telnet.obsd-cvs/sys_bsd.c  Sat Mar 10 10:55:18 2001
+@@ -1,4 +1,4 @@
+-/*    $OpenBSD: sys_bsd.c,v 1.6 1998/12/28 11:13:51 deraadt Exp $     */
++/*    $OpenBSD: sys_bsd.c,v 1.8 2000/10/10 15:41:10 millert Exp $     */
+ /*    $NetBSD: sys_bsd.c,v 1.11 1996/02/28 21:04:10 thorpej Exp $     */
+ /*
+@@ -35,6 +35,7 @@
+  */
+ #include "telnet_locl.h"
++#include <err.h>
+ /*
+  * The following routines try to encapsulate what is system dependent
+@@ -198,9 +199,10 @@
+ TerminalFlushOutput(void)
+ {
+ #ifdef        TIOCFLUSH
+-    (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
++    int com = FWRITE;
++    (void) ioctl(fileno(stdout), TIOCFLUSH, (int *) &com);
+ #else
+-    (void) ioctl(fileno(stdout), TCFLSH, (char *) 0);
++    (void) ioctl(fileno(stdout), TCFLSH, (int *) 0);
+ #endif
+ }
+diff -uNr telnet/telnet.c telnet.obsd-cvs/telnet.c
+--- telnet/telnet.c    Wed Apr  7 23:22:14 1999
++++ telnet.obsd-cvs/telnet.c   Sat Mar 10 11:02:34 2001
+@@ -1,4 +1,4 @@
+-/*    $OpenBSD: telnet.c,v 1.6 1998/07/27 15:29:29 millert Exp $      */
++/*    $OpenBSD: telnet.c,v 1.11 2000/11/10 15:33:13 provos millert Exp $      */
+ /*    $NetBSD: telnet.c,v 1.7 1996/02/28 21:04:15 thorpej Exp $       */
+ /*
+@@ -35,6 +35,8 @@
+  */
+ #include "telnet_locl.h"
++#include <curses.h>
++#include <term.h>
+ #define        strip(x) (eight ? (x) : ((x) & 0x7f))
+@@ -523,10 +525,9 @@
+ }
+ /*
+- * Given a buffer returned by tgetent(), this routine will turn
+- * the pipe seperated list of names in the buffer into an array
+- * of pointers to null terminated names.  We toss out any bad,
+- * duplicate, or verbose names (names with spaces).
++ * This routine will turn a pipe seperated list of names in the buffer
++ * into an array of pointers to NUL terminated names.  We toss out any
++ * bad, duplicate, or verbose names (names with spaces).
+  */
+ int is_unique P((char *, char **, char **));
+@@ -554,7 +555,7 @@
+       /*
+        * Count up the number of names.
+        */
+-      for (n = 1, cp = buf; *cp && *cp != ':'; cp++) {
++      for (n = 1, cp = buf; *cp; cp++) {
+               if (*cp == '|')
+                       n++;
+       }
+@@ -659,25 +660,6 @@
+       return (1);
+ }
+-static char termbuf[1024];
+-
+-int telnet_setupterm  P((char *tname, int fd, int *errp)); /* XXX move elsewhere */
+-      /*ARGSUSED*/
+-      int
+-telnet_setupterm(char *tname, int fd, int *errp)
+-{
+-      (void)fd;
+-      if (tgetent(termbuf, tname) == 1) {
+-              termbuf[1023] = '\0';
+-              if (errp)
+-                      *errp = 1;
+-              return(0);
+-      }
+-      if (errp)
+-              *errp = 0;
+-      return(-1);
+-}
+-
+ int resettermname = 1;
+ char *gettermname P((void));  /* XXX move elsewhere */
+@@ -687,15 +669,15 @@
+       char *tname;
+       static char **tnamep = 0;
+       static char **next;
+-      int err;
++      int errret;
+       if (resettermname) {
+               resettermname = 0;
+               if (tnamep && tnamep != unknown)
+                       free(tnamep);
+               if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) &&
+-                              (telnet_setupterm(tname, 1, &err) == 0)) {
+-                      tnamep = mklist(termbuf, tname);
++                              (setupterm(tname, 1, &errret) == 0)) {
++                      tnamep = mklist(ttytype, tname);
+               } else {
+                       if (tname && ((int)strlen(tname) <= 40)) {
+                               unknown[0] = tname;
+@@ -1482,10 +1464,15 @@
+       void
+ env_opt_start(void)
+ {
+-      if (opt_reply)
+-              opt_reply = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE);
+-      else
+-              opt_reply = (unsigned char *)malloc(OPT_REPLY_SIZE);
++      unsigned char *p;
++      
++      if (opt_reply) {
++              p = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE);
++              if (p == NULL)
++                      free(opt_reply);
++      } else
++              p = (unsigned char *)malloc(OPT_REPLY_SIZE);
++      opt_reply = p;  
+       if (opt_reply == NULL) {
+ /*@*/         printf("env_opt_start: malloc()/realloc() failed!!!\n");
+               opt_reply = opt_replyp = opt_replyend = NULL;
+@@ -1532,9 +1519,13 @@
+                               strlen((char *)ep) + 6 > opt_replyend)
+       {
+               int len;
++              unsigned char *p;
+               opt_replyend += OPT_REPLY_SIZE;
+               len = opt_replyend - opt_reply;
+-              opt_reply = (unsigned char *)realloc(opt_reply, len);
++              p = (unsigned char *)realloc(opt_reply, len);
++              if (p == NULL)
++                      free(opt_reply);
++              opt_reply = p;
+               if (opt_reply == NULL) {
+ /*@*/                 printf("env_opt_add: realloc() failed!!!\n");
+                       opt_reply = opt_replyp = opt_replyend = NULL;
+@@ -1945,7 +1936,7 @@
+                               command(0, "z\n", 2);
+                               continue;
+                       }
+-                      if (sc == escape) {
++                      if (sc == escape && escape != _POSIX_VDISABLE) {
+                               command(0, (char *)tbp, tcc);
+                               bol = 1;
+                               count += tcc;
+@@ -1962,7 +1953,7 @@
+               }
+               if ((sc == '\n') || (sc == '\r'))
+                       bol = 1;
+-      } else if (sc == escape) {
++      } else if (sc == escape && escape != _POSIX_VDISABLE) {
+           /*
+            * Double escape is a pass through of a single escape character.
+            */
+diff -uNr telnet/telnet_locl.h telnet.obsd-cvs/telnet_locl.h
+--- telnet/telnet_locl.h       Thu Mar 12 06:57:44 1998
++++ telnet.obsd-cvs/telnet_locl.h      Sat Mar 10 11:12:37 2001
+@@ -1,4 +1,4 @@
+-/*    $OpenBSD: telnet_locl.h,v 1.1 1998/03/12 04:57:44 art Exp $     */
++/*    $OpenBSD: telnet_locl.h,v 1.2 1999/12/11 09:08:09 itojun Exp $  */
+ /* $KTH: telnet_locl.h,v 1.13 1997/11/03 21:37:55 assar Exp $ */
+ /*
+@@ -86,7 +86,5 @@
+ #include "defines.h"
+ #include "types.h"
+-#undef AF_INET6 /* XXX - it has not been tested and it doesn't exist yet */
+-
+ /* prototypes */
+diff -uNr libtelnet/kerberos.c libtelnet.obsd-cvs/kerberos.c
+--- libtelnet/kerberos.c       Mon Feb  8 23:38:17 1999
++++ libtelnet.obsd-cvs/kerberos.c      Sat Mar 10 11:11:03 2001
+@@ -320,11 +320,10 @@
+           char ts[MAXPATHLEN];
+           struct passwd *pw = getpwnam(UserNameRequested);
+-          if(pw){
++          if (pw) {
+               snprintf(ts, sizeof(ts),
+-                       "%s%u",
+-                       TKT_ROOT,
+-                       (unsigned)pw->pw_uid);
++                      "%s%u", TKT_ROOT, (unsigned)pw->pw_uid);
++              /* XXX allocation failure? */
+               setenv("KRBTKFILE", ts, 1);
+           }
+           Data(ap, KRB_ACCEPT, NULL, 0);
+@@ -609,16 +608,26 @@
+ {
+     unsigned char *p = buf;
+     
+-    p += krb_put_nir(cred->service, cred->instance, cred->realm, p);
++    memcpy (p, cred->service, ANAME_SZ);
++    p += ANAME_SZ;
++    memcpy (p, cred->instance, INST_SZ);
++    p += INST_SZ;
++    memcpy (p, cred->realm, REALM_SZ);
++    p += REALM_SZ;
+     memcpy(p, cred->session, 8);
+     p += 8;
+     *p++ = cred->lifetime;
+     *p++ = cred->kvno;
+-    p += krb_put_int(cred->ticket_st.length, p, 4);
++    p += krb_put_int(cred->ticket_st.length, p, 4, 4);
+     memcpy(p, cred->ticket_st.dat, cred->ticket_st.length);
+     p += cred->ticket_st.length;
+-    p += krb_put_int(cred->issue_date, p, 4);
+-    p += krb_put_nir(cred->pname, cred->pinst, NULL, p);
++    p += krb_put_int(cred->issue_date, p, 4, 4);
++    strncpy (cred->pname, p, ANAME_SZ);
++    cred->pname[ANAME_SZ - 1] = '\0';
++    p += ANAME_SZ;
++    strncpy (cred->pinst, p, INST_SZ);
++    cred->pinst[INST_SZ - 1] = '\0';
++    p += INST_SZ;
+     return p - buf;
+ }
+@@ -627,7 +636,16 @@
+ {
+     unsigned char *p = buf;
+-    p += krb_get_nir(p, cred->service, cred->instance, cred->realm);
++    strncpy (cred->service, p, ANAME_SZ);
++    cred->service[ANAME_SZ - 1] = '\0';
++    p += ANAME_SZ;
++    strncpy (cred->instance, p, INST_SZ);
++    cred->instance[INST_SZ - 1] = '\0';
++    p += INST_SZ;
++    strncpy (cred->realm, p, REALM_SZ);
++    cred->realm[REALM_SZ - 1] = '\0';
++    p += REALM_SZ;
++
+     memcpy(cred->session, p, 8);
+     p += 8;
+     cred->lifetime = *p++;
+@@ -636,7 +654,10 @@
+     memcpy(cred->ticket_st.dat, p, cred->ticket_st.length);
+     cred->ticket_st.mbz = 0;
+     p += krb_get_int(p, (u_int32_t *)&cred->issue_date, 4, 0);
+-    p += krb_get_nir(p, cred->pname, cred->pinst, NULL);
++    p += krb_get_nir(p, 
++                  cred->pname, sizeof(cred->pname),
++                  cred->pinst, sizeof(cred->pinst),
++                  NULL, 0);
+     return 0;
+ }
+--- telnet/telnet.1    Thu Nov 12 01:01:46 1998
++++ telnet.obsd-cvs/telnet.1   Thu Nov  9 19:52:41 2000
+@@ -1,4 +1,4 @@
+-.\"   $OpenBSD: telnet.1,v 1.14 1998/11/11 23:01:46 aaron Exp $
++.\"   $OpenBSD: telnet.1,v 1.27 2000/11/09 17:52:41 aaron Exp $
+ .\"   $NetBSD: telnet.1,v 1.5 1996/02/28 21:04:12 thorpej Exp $
+ .\"
+ .\" Copyright (c) 1983, 1990, 1993
+@@ -36,45 +36,34 @@
+ .\"
+ .Dd February 3, 1994
+ .Dt TELNET 1
+-.Os BSD 4.2
++.Os
+ .Sh NAME
+ .Nm telnet
+-.Nd user interface to the 
++.Nd user interface to the
+ .Tn TELNET
+ protocol
+ .Sh SYNOPSIS
+ .Nm telnet
+-.Op Fl 8
+-.Op Fl E
+-.Op Fl F
+-.Op Fl K
+-.Op Fl L
+-.Op Fl S Ar tos
++.Op Fl 8EFKLacdfrx
+ .Op Fl X Ar authtype
+-.Op Fl a
+ .Op Fl b Ar hostalias
+-.Op Fl c
+-.Op Fl d
+ .Op Fl e Ar escapechar
+-.Op Fl f
+ .Op Fl k Ar realm
+ .Op Fl l Ar user
+ .Op Fl n Ar tracefile
+-.Op Fl r
+-.Op Fl x
+ .Oo
+ .Ar host
+ .Op Ar port
+ .Oc
+ .Sh DESCRIPTION
+ The
+-.Nm telnet
++.Nm
+ command
+-is used to communicate with another host using the 
++is used to communicate with another host using the
+ .Tn TELNET
+ protocol.
+ If
+-.Nm telnet
++.Nm
+ is invoked without the
+ .Ar host
+ argument, it enters command mode,
+@@ -85,11 +74,11 @@
+ .Ic open
+ command with those arguments.
+ .Pp
+-Options:
+-.Bl -tag -width indent
++The options are as follows:
++.Bl -tag -width Ds
+ .It Fl 8
+-Specifies an 8-bit data path.  This causes an attempt to
+-negotiate the
++Specifies an 8-bit data path.
++This causes an attempt to negotiate the
+ .Dv TELNET BINARY
+ option on both input and output.
+ .It Fl E
+@@ -103,18 +92,9 @@
+ .It Fl K
+ Specifies no automatic login to the remote system.
+ .It Fl L
+-Specifies an 8-bit data path on output.  This causes the
+-BINARY option to be negotiated on output.
+-.It Fl S Ar tos
+-Sets the IP type-of-service (TOS) option for the telnet
+-connection to the value
+-.Ar tos ,
+-which can be a numeric TOS value
+-or, on systems that support it, a symbolic
+-TOS name found in the
+-.Pa /etc/iptos
+-file.
+-.It Fl X Ar atype 
++Specifies an 8-bit data path on output.
++This causes the BINARY option to be negotiated on output.
++.It Fl X Ar atype
+ Disables the
+ .Ar atype
+ type of authentication.
+@@ -144,7 +124,8 @@
+ .It Fl c
+ Disables the reading of the user's
+ .Pa \&.telnetrc
+-file.  (See the
++file.
++(See the
+ .Ic toggle skiprc
+ command on this man page.)
+ .It Fl d
+@@ -152,7 +133,7 @@
+ .Ic debug
+ toggle to
+ .Dv TRUE .
+-.It Fl e Ar escapechar 
++.It Fl e Ar escapechar
+ Sets the initial
+ .Nm
+ escape character to
+@@ -169,14 +150,14 @@
+ If Kerberos authentication is being used, the
+ .Fl k
+ option requests that
+-.Nm telnet
++.Nm
+ obtain tickets for the remote host in
+ realm
+ .Ar realm
+ instead of the remote host's realm, as determined
+ by
+ .Xr krb_realmofhost 3 .
+-.It Fl l Ar user 
++.It Fl l Ar user
+ When connecting to the remote system, if the remote system
+ understands the
+ .Ev ENVIRON
+@@ -189,7 +170,7 @@
+ This option may also be used with the
+ .Ic open
+ command.
+-.It Fl n Ar tracefile 
++.It Fl n Ar tracefile
+ Opens
+ .Ar tracefile
+ for recording trace information.
+@@ -210,35 +191,38 @@
+ Indicates the official name, an alias, or the Internet address
+ of a remote host.
+ .It Ar port
+-Indicates a port number (address of an application).  If a number is
+-not specified, the default
+-.Nm telnet
++Indicates a port number (address of an application).
++If a number is not specified, the default
++.Nm
+ port is used.
+ .El
+ .Pp
+-When in rlogin mode, a line of the form ~.  disconnects from the
++When in rlogin mode, a line of the form ~.
++disconnects from the
+ remote host; ~ is the telnet escape character.
+ Similarly, the line ~^Z suspends the telnet session.
+ The line ~^] escapes to the normal telnet escape prompt.
+ .Pp
+ Once a connection has been opened,
+-.Nm telnet
++.Nm
+ will attempt to enable the
+ .Dv TELNET LINEMODE
+ option.
+ If this fails,
+-.Nm telnet
++.Nm
+ will revert to one of two input modes:
+ either ``character at a time''
+ or ``old line by line''
+ depending on what the remote system supports.
+ .Pp
+-When 
++When
+ .Dv LINEMODE
+ is enabled, character processing is done on the
+-local system, under the control of the remote system.  When input
++local system, under the control of the remote system.
++When input
+ editing or character echoing is to be disabled, the remote system
+-will relay that information.  The remote system will also relay
++will relay that information.
++The remote system will also relay
+ changes to any special characters that happen on the remote
+ system, so that they can take effect on the local system.
+ .Pp
+@@ -252,7 +236,7 @@
+ (this would mostly be used to enter passwords
+ without the password being echoed).
+ .Pp
+-If the 
++If the
+ .Dv LINEMODE
+ option is enabled, or if the
+ .Ic localchars
+@@ -267,7 +251,7 @@
+ characters are trapped locally, and sent as
+ .Tn TELNET
+ protocol sequences to the remote side.
+-If 
++If
+ .Dv LINEMODE
+ has ever been enabled, then the user's
+ .Ic susp
+@@ -278,9 +262,9 @@
+ protocol sequences,
+ and
+ .Ic quit
+-is sent as a 
++is sent as a
+ .Dv TELNET ABORT
+-instead of 
++instead of
+ .Dv BREAK .
+ There are options (see
+ .Ic toggle
+@@ -296,17 +280,26 @@
+ (in the case of
+ .Ic quit
+ and
+-.Ic intr  ) .
++.Ic intr ) .
+ .Pp
+ While connected to a remote host,
+-.Nm telnet
++.Nm
+ command mode may be entered by typing the
+-.Nm telnet
++.Nm
+ ``escape character'' (initially ``^]'').
+ When in command mode, the normal terminal editing conventions are available.
++Note that the escape character will return to the command mode of the initial
++invocation of
++.Nm
++that has the controlling terminal.
++Use the
++.Cm send escape
++command to switch to command mode in subsequent
++.Nm
++processes on remote hosts.
+ .Pp
+ The following
+-.Nm telnet
++.Nm
+ commands are available.
+ Only enough of each command to uniquely identify it need be typed
+ (this is also true for arguments to the
+@@ -320,26 +313,28 @@
+ .Ic display
+ commands).
+ .Bl -tag -width "mode type"
+-.It Ic auth Ar argument Op Ar ... 
++.It Ic auth Ar argument Op Ar ...
+ The
+ .Ic auth
+ command manipulates the information sent through the
+ .Dv TELNET AUTHENTICATE
+-option.  Valid arguments for the
+-auth command are as follows:
++option.
++Valid arguments for the
++.Ic auth
++command are as follows:
+ .Bl -tag -width "disable type"
+ .It Ic disable Ar type
+ Disables the specified
+ .Ar type
+-of authentication.  To
+-obtain a list of available types, use the
++of authentication.
++To obtain a list of available types, use the
+ .Ic auth disable \&?
+ command.
+ .It Ic enable Ar type
+ Enables the specified
+ .Ar type
+-of authentication.  To
+-obtain a list of available types, use the
++of authentication.
++To obtain a list of available types, use the
+ .Ic auth enable \&?
+ command.
+ .It Ic status
+@@ -350,7 +345,7 @@
+ Close a
+ .Tn TELNET
+ session and return to command mode.
+-.It Ic display Ar argument Op Ar ... 
++.It Ic display Ar argument Op Ar ...
+ Displays all, or some, of the
+ .Ic set
+ and
+@@ -368,26 +363,27 @@
+ .It Ic disable Ar type Ic [input|output]
+ Disables the specified
+ .Ar type
+-of encryption.  If you
+-omit
++of encryption.
++If you omit
+ .Ic input
+ and
+ .Ic output ,
+ both input and output
+-are disabled.  To obtain a list of available
+-types, use the
++are disabled.
++To obtain a list of available types, use the
+ .Ic encrypt disable \&?
+ command.
+ .It Ic enable Ar type Ic [input|output]
+ Enables the specified
+ .Ar type
+-of encryption.  If you
+-omit
++of encryption.
++If you omit
+ .Ic input
+ and
+ .Ic output ,
+ both input and output are
+-enabled.  To obtain a list of available types, use the
++enabled.
++To obtain a list of available types, use the
+ .Ic encrypt enable \&?
+ command.
+ .It Ic input
+@@ -407,18 +403,20 @@
+ .Ic encrypt stop output
+ command.
+ .It Ic start Ic [input|output]
+-Attempts to start encryption.  If you omit
++Attempts to start encryption.
++If you omit
+ .Ic input
+ and
+-.Ic output,
+-both input and output are enabled.  To
+-obtain a list of available types, use the
++.Ic output ,
++both input and output are enabled.
++To obtain a list of available types, use the
+ .Ic encrypt enable \&?
+ command.
+ .It Ic status
+ Lists the current status of encryption.
+ .It Ic stop Ic [input|output]
+-Stops encryption.  If you omit
++Stops encryption.
++If you omit
+ .Ic input
+ and
+ .Ic output ,
+@@ -431,7 +429,7 @@
+ .Ic encrypt stop
+ commands.
+ .El
+-.It Ic environ Ar arguments Op Ar ... 
++.It Ic environ Ar arguments Op Ar ...
+ The
+ .Ic environ
+ command is used to manipulate the
+@@ -456,7 +454,7 @@
+ .Ic environ
+ command are:
+ .Bl -tag -width Fl
+-.It Ic define Ar variable value 
++.It Ic define Ar variable value
+ Define the variable
+ .Ar variable
+ to have a value of
+@@ -466,15 +464,15 @@
+ .Ar value
+ may be enclosed in single or double quotes so
+ that tabs and spaces may be included.
+-.It Ic undefine Ar variable 
++.It Ic undefine Ar variable
+ Remove
+ .Ar variable
+ from the list of environment variables.
+-.It Ic export Ar variable 
++.It Ic export Ar variable
+ Mark the variable
+ .Ar variable
+ to be exported to the remote side.
+-.It Ic unexport Ar variable 
++.It Ic unexport Ar variable
+ Mark the variable
+ .Ar variable
+ to not be exported unless
+@@ -508,7 +506,7 @@
+ suspending a user's session for later reattachment,
+ the logout argument indicates that you
+ should terminate the session immediately.
+-.It Ic mode Ar type 
++.It Ic mode Ar type
+ .Ar type
+ is one of several options, depending on the state of the
+ .Tn TELNET
+@@ -529,40 +527,40 @@
+ option, or, if the remote side does not understand the
+ .Dv LINEMODE
+ option, then attempt to enter ``old-line-by-line'' mode.
+-.It Ic isig Pq Ic \-isig 
+-Attempt to enable (disable) the 
++.It Ic isig Pq Ic \-isig
++Attempt to enable (disable) the
+ .Dv TRAPSIG
+-mode of the 
++mode of the
+ .Dv LINEMODE
+ option.
+-This requires that the 
++This requires that the
+ .Dv LINEMODE
+ option be enabled.
+-.It Ic edit Pq Ic \-edit 
+-Attempt to enable (disable) the 
++.It Ic edit Pq Ic \-edit
++Attempt to enable (disable) the
+ .Dv EDIT
+-mode of the 
++mode of the
+ .Dv LINEMODE
+ option.
+-This requires that the 
++This requires that the
+ .Dv LINEMODE
+ option be enabled.
+-.It Ic softtabs Pq Ic \-softtabs 
+-Attempt to enable (disable) the 
++.It Ic softtabs Pq Ic \-softtabs
++Attempt to enable (disable) the
+ .Dv SOFT_TAB
+-mode of the 
++mode of the
+ .Dv LINEMODE
+ option.
+-This requires that the 
++This requires that the
+ .Dv LINEMODE
+ option be enabled.
+-.It Ic litecho Pq Ic \-litecho 
+-Attempt to enable (disable) the 
++.It Ic litecho Pq Ic \-litecho
++Attempt to enable (disable) the
+ .Dv LIT_ECHO
+-mode of the 
++mode of the
+ .Dv LINEMODE
+ option.
+-This requires that the 
++This requires that the
+ .Dv LINEMODE
+ option be enabled.
+ .It Ic \&?
+@@ -579,7 +577,7 @@
+ Open a connection to the named host.
+ If no port number
+ is specified,
+-.Nm telnet
++.Nm
+ will attempt to contact a
+ .Tn TELNET
+ server at the default port.
+@@ -594,24 +592,29 @@
+ .Ev ENVIRON
+ option.
+ When connecting to a non-standard port,
+-.Nm telnet
++.Nm
+ omits any automatic initiation of
+ .Tn TELNET
+-options.  When the port number is preceded by a minus sign,
++options.
++When the port number is preceded by a minus sign,
+ the initial option negotiation is done.
+ After establishing a connection, the file
+ .Pa \&.telnetrc
+ in the
+-user's home directory is opened.  Lines beginning with a ``#'' are
+-comment lines.  Blank lines are ignored.  Lines that begin
+-without white space are the start of a machine entry.  The
+-first thing on the line is the name of the machine that is
+-being connected to.  The rest of the line, and successive
+-lines that begin with white space are assumed to be
+-.Nm telnet
++user's home directory is opened.
++Lines beginning with a ``#'' are
++comment lines.
++Blank lines are ignored.
++Lines that begin
++without whitespace are the start of a machine entry.
++The first thing on the line is the name of the machine that is
++being connected to.
++The rest of the line, and successive
++lines that begin with whitespace are assumed to be
++.Nm
+ commands and are processed as if they had been typed
+ in manually to the
+-.Nm telnet
++.Nm
+ command prompt.
+ .It Ic quit
+ Close any open
+@@ -619,7 +622,7 @@
+ session and exit
+ .Nm telnet .
+ An end-of-file (in command mode) will also close a session and exit.
+-.It Ic send Ar arguments 
++.It Ic send Ar arguments
+ Sends one or more special character sequences to the remote host.
+ The following are the arguments which may be specified
+ (more than one argument may be specified at a time):
+@@ -673,7 +676,7 @@
+ sequence.
+ .It Ic escape
+ Sends the current
+-.Nm telnet
++.Nm
+ escape character (initially ``^]'').
+ .It Ic ga
+ Sends the
+@@ -788,12 +791,12 @@
+ .Ic send
+ command.
+ .El
+-.It Ic set Ar argument value 
+-.It Ic unset Ar argument value 
++.It Ic set Ar argument value
++.It Ic unset Ar argument value
+ The
+ .Ic set
+ command will set any one of a number of
+-.Nm telnet
++.Nm
+ variables to a specific value or to
+ .Dv TRUE .
+ The special value
+@@ -811,7 +814,8 @@
+ .Ic display
+ command.
+ The variables which may be set or unset, but not toggled, are
+-listed here.  In addition, any of the variables for the
++listed here.
++In addition, any of the variables for the
+ .Ic toggle
+ command may be explicitly set or unset using
+ the
+@@ -832,7 +836,8 @@
+ sequence (see
+ .Ic send ayt
+ preceding) is sent to the
+-remote host.  The initial value for the "Are You There"
++remote host.
++The initial value for the "Are You There"
+ character is the terminal's status character.
+ .It Ic echo
+ This is the value (initially ``^E'') which, when in
+@@ -841,7 +846,7 @@
+ echoing of entered characters (for entering, say, a password).
+ .It Ic eof
+ If
+-.Nm telnet
++.Nm
+ is operating in
+ .Dv LINEMODE
+ or ``old line by line'' mode, entering this character
+@@ -854,7 +859,7 @@
+ character.
+ .It Ic erase
+ If
+-.Nm telnet
++.Nm
+ is in
+ .Ic localchars
+ mode (see
+@@ -862,7 +867,7 @@
+ .Ic localchars
+ below),
+ and if
+-.Nm telnet
++.Nm
+ is operating in ``character at a time'' mode, then when this
+ character is typed, a
+ .Dv TELNET EC
+@@ -879,14 +884,14 @@
+ character.
+ .It Ic escape
+ This is the
+-.Nm telnet
++.Nm
+ escape character (initially ``^['') which causes entry
+ into
+-.Nm telnet
++.Nm
+ command mode (when connected to a remote system).
+ .It Ic flushoutput
+ If
+-.Nm telnet
++.Nm
+ is in
+ .Ic localchars
+ mode (see
+@@ -916,12 +921,13 @@
+ .Dv LINEMODE ,
+ these are the
+ characters that, when typed, cause partial lines to be
+-forwarded to the remote system.  The initial value for
++forwarded to the remote system.
++The initial value for
+ the forwarding characters are taken from the terminal's
+ eol and eol2 characters.
+ .It Ic interrupt
+ If
+-.Nm telnet
++.Nm
+ is in
+ .Ic localchars
+ mode (see
+@@ -945,7 +951,7 @@
+ character.
+ .It Ic kill
+ If
+-.Nm telnet
++.Nm
+ is in
+ .Ic localchars
+ mode (see
+@@ -953,7 +959,7 @@
+ .Ic localchars
+ below),
+ and if
+-.Nm telnet
++.Nm
+ is operating in ``character at a time'' mode, then when this
+ character is typed, a
+ .Dv TELNET EL
+@@ -970,7 +976,7 @@
+ character.
+ .It Ic lnext
+ If
+-.Nm telnet
++.Nm
+ is operating in
+ .Dv LINEMODE
+ or ``old line by line'' mode, then this character is taken to
+@@ -985,7 +991,7 @@
+ character.
+ .It Ic quit
+ If
+-.Nm telnet
++.Nm
+ is in
+ .Ic localchars
+ mode (see
+@@ -1009,7 +1015,7 @@
+ character.
+ .It Ic reprint
+ If
+-.Nm telnet
++.Nm
+ is operating in
+ .Dv LINEMODE
+ or old line by line'' mode, then this character is taken to
+@@ -1031,8 +1037,9 @@
+ This character, at the beginning of a line, followed by
+ a "." closes the connection; when followed by a ^Z it
+ suspends the
+-.Nm telnet
+-command.  The initial state is to
++.Nm
++command.
++The initial state is to
+ disable the
+ .Ic rlogin
+ escape character.
+@@ -1066,7 +1073,7 @@
+ character.
+ .It Ic susp
+ If
+-.Nm telnet
++.Nm
+ is in
+ .Ic localchars
+ mode, or
+@@ -1093,12 +1100,13 @@
+ .Ic option
+ tracing being
+ .Dv TRUE ,
+-will be written.  If it is set to
++will be written.
++If it is set to
+ .Dq Fl ,
+ then tracing information will be written to standard output (the default).
+ .It Ic worderase
+ If
+-.Nm telnet
++.Nm
+ is operating in
+ .Dv LINEMODE
+ or ``old line by line'' mode, then this character is taken to
+@@ -1117,25 +1125,32 @@
+ .Pq Ic unset
+ commands.
+ .El
+-.It Ic slc Ar state 
++.It Ic skey Ar sequence challenge
++The
++.Ic skey
++command computes a response to the S/Key challenge.
++See
++.Xr skey 1
++for more information on the S/Key system.
++.It Ic slc Ar state
+ The
+ .Ic slc
+ command (Set Local Characters) is used to set
+ or change the state of the special
+-characters when the 
++characters when the
+ .Dv TELNET LINEMODE
+ option has
+-been enabled.  Special characters are characters that get
+-mapped to 
++been enabled.
++Special characters are characters that get mapped to
+ .Tn TELNET
+ commands sequences (like
+ .Ic ip
+ or
+-.Ic quit  )
++.Ic quit )
+ or line editing characters (like
+ .Ic erase
+ and
+-.Ic kill  ) .
++.Ic kill ) .
+ By default, the local special characters are exported.
+ .Bl -tag -width Fl
+ .It Ic check
+@@ -1144,15 +1159,15 @@
+ character settings, and if there are any discrepancies with
+ the local side, the local side will switch to the remote value.
+ .It Ic export
+-Switch to the local defaults for the special characters.  The
+-local default characters are those of the local terminal at
++Switch to the local defaults for the special characters.
++The local default characters are those of the local terminal at
+ the time when
+-.Nm telnet
++.Nm
+ was started.
+ .It Ic import
+ Switch to the remote defaults for the special characters.
+ The remote default characters are those of the remote system
+-at the time when the 
++at the time when the
+ .Tn TELNET
+ connection was established.
+ .It Ic \&?
+@@ -1165,13 +1180,13 @@
+ .Nm telnet .
+ This includes the peer one is connected to, as well
+ as the current mode.
+-.It Ic toggle Ar arguments Op Ar ... 
++.It Ic toggle Ar arguments Op Ar ...
+ Toggle (between
+ .Dv TRUE
+ and
+ .Dv FALSE )
+ various flags that control how
+-.Nm telnet
++.Nm
+ responds to events.
+ These flags may be set explicitly to
+ .Dv TRUE
+@@ -1206,7 +1221,7 @@
+ sequences; see
+ .Ic set
+ above for details),
+-.Nm telnet
++.Nm
+ refuses to display any data on the user's terminal
+ until the remote system acknowledges (via a
+ .Dv TELNET TIMING MARK
+@@ -1220,13 +1235,14 @@
+ done an "stty noflsh", otherwise
+ .Dv FALSE
+ (see
+-.Xr stty  1  ) .
++.Xr stty 1 ) .
+ .It Ic autodecrypt
+ When the
+ .Dv TELNET ENCRYPT
+ option is negotiated, by
+ default the actual encryption (decryption) of the data
+-stream does not start automatically.  The
++stream does not start automatically.
++The
+ .Ic autoencrypt
+ .Pq Ic autodecrypt
+ command states that encryption of the
+@@ -1238,7 +1254,8 @@
+ .Dv TELNET AUTHENTICATION
+ option
+ .Tn TELNET
+-attempts to use it to perform automatic authentication.  If the
++attempts to use it to perform automatic authentication.
++If the
+ .Dv AUTHENTICATION
+ option is not supported, the user's login
+ name are propagated through the
+@@ -1314,7 +1331,7 @@
+ The initial value for this toggle is
+ .Dv FALSE .
+ .It Ic debug
+-Toggles socket level debugging (useful only to the super-user).
++Toggles socket level debugging (useful only to the superuser).
+ The initial value for this toggle is
+ .Dv FALSE .
+ .It Ic encdebug
+@@ -1340,7 +1357,7 @@
+ .Ic brk ,
+ .Ic ec ,
+ and
+-.Ic el  ;
++.Ic el ;
+ see
+ .Ic send
+ above).
+@@ -1379,7 +1396,7 @@
+ .Dv FALSE .
+ .It Ic options
+ Toggles the display of some internal
+-.Nm telnet
++.Nm
+ protocol processing (having to do with
+ .Tn TELNET
+ options).
+@@ -1404,8 +1421,8 @@
+ skips the reading of the
+ .Pa \&.telnetrc
+ file in the user's home
+-directory when connections are opened.  The initial
+-value for this toggle is
++directory when connections are opened.
++The initial value for this toggle is
+ .Dv FALSE .
+ .It Ic termdata
+ Toggles the display of all terminal data (in hexadecimal format).
+@@ -1416,9 +1433,10 @@
+ .Ic verbose_encrypt
+ toggle is
+ .Dv TRUE ,
+-.Nm telnet
++.Nm
+ prints out a message each time encryption is enabled or
+-disabled.  The initial value for this toggle is
++disabled.
++The initial value for this toggle is
+ .Dv FALSE .
+ .It Ic \&?
+ Displays the legal
+@@ -1430,22 +1448,24 @@
+ .Nm telnet .
+ This command only works when the user is using the
+ .Xr csh 1 .
+-.It Ic \&! Op Ar command 
++.It Ic \&! Op Ar command
+ Execute a single command in a subshell on the local
+-system.  If
++system.
++If
+ .Ar command
+ is omitted, then an interactive
+ subshell is invoked.
+-.It Ic \&? Op Ar command 
+-Get help.  With no arguments,
+-.Nm telnet
++.It Ic \&? Op Ar command
++Get help.
++With no arguments,
++.Nm
+ prints a help summary.
+ If a command is specified,
+-.Nm telnet
++.Nm
+ will print the help information for just that command.
+ .El
+ .Sh ENVIRONMENT
+-.Nm telnet
++.Nm
+ uses at least the
+ .Ev HOME ,
+ .Ev SHELL ,
+@@ -1464,16 +1484,18 @@
+ .El
+ .Sh HISTORY
+ The
+-.Nm telnet
++.Nm
+ command appeared in
+ .Bx 4.2 .
+ .Sh NOTES
+ On some remote systems, echo has to be turned off manually when in
+ ``old line by line'' mode.
+ .Pp
+-In ``old line by line'' mode or 
++In ``old line by line'' mode or
+ .Dv LINEMODE
+ the terminal's
+ .Ic eof
+ character is only recognized (and sent to the remote system)
+ when it is the first character on a line.
++.Pp
++Source routing is not supported yet for IPv6.
diff --git a/src/patches/telnet-gethostbyname.patch b/src/patches/telnet-gethostbyname.patch
new file mode 100644 (file)
index 0000000..e1c1976
--- /dev/null
@@ -0,0 +1,48 @@
+--- netkit-telnet-0.17/telnet/commands.c.old   2006-04-30 10:24:49.000000000 -0700
++++ netkit-telnet-0.17/telnet/commands.c       2006-04-30 10:37:10.000000000 -0700
+@@ -1669,9 +1669,15 @@
+               /* If this is not the full name, try to get it via DNS */
+               if (strchr(hbuf, '.') == 0) {
+-                      struct hostent *he = gethostbyname(hbuf);
+-                      if (he != 0)
+-                              strncpy(hbuf, he->h_name, sizeof hbuf-1);
++                      struct addrinfo hints;
++                      struct addrinfo *res;
++                      memset (&hints, '\0', sizeof (hints));
++                      hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME;
++                      if (getaddrinfo (hbuf, NULL, &hints, &res) == 0) {
++                              if (res->ai_canonname != NULL)
++                                      strncpy(hbuf, res->ai_canonname, sizeof hbuf-1);
++                              freeaddrinfo (res);
++                      }
+                       hbuf[sizeof hbuf-1] = '\0';
+               }
+@@ -2832,17 +2838,15 @@
+               if (!c)
+                       cp2 = 0;
+-              if ((tmp = inet_addr(cp)) != -1) {
+-                      sin_addr.s_addr = tmp;
+-              } else if ((host = gethostbyname(cp))) {
+-#if   defined(h_addr)
+-                      memmove((caddr_t)&sin_addr,
+-                              host->h_addr_list[0], 
+-                              sizeof(sin_addr));
+-#else
+-                      memmove((caddr_t)&sin_addr, host->h_addr, 
+-                              sizeof(sin_addr));
+-#endif
++              struct addrinfo hints;
++              memset (&hints, '\0', sizeof (hints));
++              // XXX The code here seems to allow only IPv4 addresses.
++              hints.ai_family = AF_INET;
++              hints.ai_flags = AI_ADDRCONFIG;
++              struct addrinfo *aires;
++              if (getaddrinfo (cp, NULL, &hints, &aires) == 0) {
++                      sin_addr = ((struct sockaddr_in *) aires->ai_addr)->sin_addr;
++                      freeaddrinfo (aires);
+               } else {
+                       *cpp = cp;
+                       return(0);