]> git.ipfire.org Git - people/stevee/ipfire-3.x.git/commitdiff
telnet: FTBFS
authorStefan Schantl <stefan.schantl@ipfire.org>
Sun, 5 Mar 2023 11:41:59 +0000 (12:41 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 Mar 2023 12:06:25 +0000 (12:06 +0000)
* Rebase patchset with debians one.
* Now uses cmake to build.

Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
33 files changed:
telnet/patches/010-full_set_in_18.diff [new file with mode: 0644]
telnet/patches/020-from_18_to_24.diff [new file with mode: 0644]
telnet/patches/022-buffer_overflow_by_HOME.diff [new file with mode: 0644]
telnet/patches/024-can_2004-0911.diff [new file with mode: 0644]
telnet/patches/026-can_2005_0469.diff [new file with mode: 0644]
telnet/patches/030-reject_invalid_port.diff [new file with mode: 0644]
telnet/patches/045-avoid_unsetting_term.diff [new file with mode: 0644]
telnet/patches/100-format_security_error.diff [new file with mode: 0644]
telnet/patches/110-markup_errors.diff [new file with mode: 0644]
telnet/patches/120-some_protocol_refinement.diff [new file with mode: 0644]
telnet/patches/124-support_uservar.diff [new file with mode: 0644]
telnet/patches/130-drain_input_from_child.diff [new file with mode: 0644]
telnet/patches/140-telnetlogin_name_check.diff [new file with mode: 0644]
telnet/patches/142-numeric_hosts.diff [new file with mode: 0644]
telnet/patches/netkit-telnet-0.17-ipv6.diff [deleted file]
telnet/patches/netkit-telnet-0.17-nodns.patch [deleted file]
telnet/patches/netkit-telnet-0.17-reallynodns.patch [deleted file]
telnet/patches/telnet-0.17-8bit.patch [deleted file]
telnet/patches/telnet-0.17-CAN-2005-468_469.patch [deleted file]
telnet/patches/telnet-0.17-argv.patch [deleted file]
telnet/patches/telnet-0.17-cleanup_race.patch [deleted file]
telnet/patches/telnet-0.17-conf.patch [deleted file]
telnet/patches/telnet-0.17-env.patch [deleted file]
telnet/patches/telnet-0.17-errno_test_sys_bsd.patch [deleted file]
telnet/patches/telnet-0.17-issue.patch [deleted file]
telnet/patches/telnet-0.17-pek.patch0 [deleted file]
telnet/patches/telnet-0.17-sa-01-49.patch [deleted file]
telnet/patches/telnet-client-cvs.patch0 [deleted file]
telnet/patches/telnet-gethostbyname.patch [deleted file]
telnet/patches/telnetd-0.17-pty_read.patch0 [deleted file]
telnet/patches/telnetd-0.17.patch0 [deleted file]
telnet/patches/use-cmake-as-buildsystem.patch [new file with mode: 0644]
telnet/telnet.nm

diff --git a/telnet/patches/010-full_set_in_18.diff b/telnet/patches/010-full_set_in_18.diff
new file mode 100644 (file)
index 0000000..d2d0d5d
--- /dev/null
@@ -0,0 +1,2206 @@
+Description: Source patches present in package 0.17-18woody3.
+ Multiple files are touched by this legacy patch.  It has been
+ pruned to reproduce source package netkit-telnet_0.17-18.
+ .
+ Implement IPv6 support.
+ .
+ Read `/etc/telnetrc'.
+ .
+ Various buffer length errors.
+ .
+ Fix IAC+SB crashes due to format errors.
+ .
+ The server accepts numerical TOS together with `-S'.
+ .
+ Remote DOS hole, CAN-2004-0911, moved to a separate file.
+ .
+ Buffer overflow, CAN-2005-0469, moved to a separate file.
+
+Comment: Recovered from source netkit-telnet_0.17-18woody3.diff.gz.
+Author: Herbert Xu, Jason Gunthorpe
+Forwarded: no
+Last-Update: 2015-01-26
+
+--- a/telnet/commands.cc
++++ b/telnet/commands.cc
+@@ -86,10 +86,6 @@
+ #define HELPINDENT ((int) sizeof ("connect"))
+-#ifndef       MAXHOSTNAMELEN
+-#define       MAXHOSTNAMELEN 64
+-#endif        MAXHOSTNAMELEN
+-
+ #if   defined(HAS_IPPROTO_IP) && defined(IP_TOS)
+ int tos = -1;
+ #endif        /* defined(HAS_IPPROTO_IP) && defined(IP_TOS) */
+@@ -98,7 +94,7 @@
+ char  *hostname;
+-static char _hostname[MAXHOSTNAMELEN];
++static char *_hostname;
+ //typedef int (*intrtn_t)(int argc, const char *argv[]);
+@@ -161,7 +157,7 @@
+       assert(argc>=1);
+       if (nargs>=0 && argc!=nargs+1) {
+           fprintf(stderr, "Wrong number of arguments for command.\n");
+-          fprintf(stderr, "Try %s ? for help\n", argv[0]);
++          fprintf(stderr, "Try ? %s for help\n", argv[0]);
+           return 0;    /* is this right? */
+       }
+       if (nargs==-2) {
+@@ -689,9 +685,9 @@
+       "print encryption debugging information" },
+ #endif
+-    { "skiprc", "don't read ~/.telnetrc file",
++    { "skiprc", "don't read the telnetrc files",
+       NULL, &skiprc,
+-      "read ~/.telnetrc file" },
++      "read the telnetrc files" },
+     { "binary",
+       "sending and receiving of binary data",
+       togbinary, NULL,
+@@ -1615,15 +1611,20 @@
+ #endif
+ int tn(int argc, const char *argv[]) {
+-    register struct hostent *host = 0;
+     struct sockaddr_in sn;
+-    struct servent *sp = 0;
+     char *srp = NULL;
+     int srlen;
+-
++    int family = 0;
+     const char *cmd, *volatile user = 0;
+     const char *portp = NULL;
+     char *hostp = NULL;
++    char *resolv_hostp;
++    struct addrinfo hints;
++    struct addrinfo *hostaddr = 0;
++    int res;
++    char name[NI_MAXHOST];
++    char service[NI_MAXSERV];
++    struct addrinfo *tmpaddr;
+     /* clear the socket address prior to use */
+     memset(&sn, 0, sizeof(sn));
+@@ -1632,6 +1633,10 @@
+       printf("?Already connected to %s\n", hostname);
+       return 0;
+     }
++    if (_hostname) {
++      delete[] _hostname;
++      _hostname = 0;
++    }
+     if (argc < 2) {
+       (void) strcpy(line, "open ");
+       printf("(to) ");
+@@ -1662,6 +1667,20 @@
+           autologin = 1;
+           continue;
+       }
++      if (strcmp(*argv, "-6") == 0) {
++          --argc; ++argv;
++#ifdef AF_INET6
++          family = AF_INET6;
++#else
++          puts("IPv6 unsupported");
++#endif
++          continue;
++      }
++      if (strcmp(*argv, "-4") == 0) {
++          --argc; ++argv;
++          family = AF_INET;
++          continue;
++      }
+       if (hostp == 0) {
+           /* this leaks memory - FIXME */
+           hostp = strdup(*argv++);
+@@ -1680,6 +1699,8 @@
+     if (hostp == 0)
+       goto usage;
++    resolv_hostp = hostp;
++
+ #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
+     if (hostp[0] == '@' || hostp[0] == '!') {
+       if ((hostname = strrchr(hostp, ':')) == NULL)
+@@ -1696,78 +1717,94 @@
+       } else {
+           sn.sin_addr.s_addr = temp;
+           sn.sin_family = AF_INET;
++          /*
++           * For source route we just make sure to get the IP given
++           * on the command line when looking up the port.
++           */
++          resolv_hostp = inet_ntoa(sn.sin_addr);
+       }
+     } 
+-    else {
+-#endif
+-      if (inet_aton(hostp, &sn.sin_addr)) {
+-          sn.sin_family = AF_INET;
+-          strcpy(_hostname, hostp);
+-          hostname = _hostname;
+-      } 
+-      else {
+-          host = gethostbyname(hostp);
+-          if (host) {
+-              sn.sin_family = host->h_addrtype;
+-              if (host->h_length > (int)sizeof(sn.sin_addr)) {
+-                  host->h_length = sizeof(sn.sin_addr);
+-              }
+-#if   defined(h_addr)         /* In 4.3, this is a #define */
+-              memcpy((caddr_t)&sn.sin_addr,
+-                              host->h_addr_list[0], host->h_length);
+-#else /* defined(h_addr) */
+-              memcpy((caddr_t)&sn.sin_addr, host->h_addr, host->h_length);
+-#endif        /* defined(h_addr) */
+-              strncpy(_hostname, host->h_name, sizeof(_hostname));
+-              _hostname[sizeof(_hostname)-1] = '\0';
+-              hostname = _hostname;
+-          } else {
+-              herror(hostp);
+-              return 0;
+-          }
+-      }
+-#if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
+-    }
+ #endif
++
++    /* User port or the default name of telnet. */
+     if (portp) {
+       if (*portp == '-') {
+           portp++;
+           telnetport = 1;
+       } else
+           telnetport = 0;
+-      sn.sin_port = atoi(portp);
+-      if (sn.sin_port == 0) {
+-          sp = getservbyname(portp, "tcp");
+-          if (sp)
+-              sn.sin_port = sp->s_port;
+-          else {
+-              printf("%s: bad port number\n", portp);
+-              return 0;
+-          }
+-      } 
+-      else {
+-          sn.sin_port = htons(sn.sin_port);
+-      }
+-    } 
++    }
+     else {
+-      if (sp == 0) {
+-          sp = getservbyname("telnet", "tcp");
+-          if (sp == 0) {
+-              fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
+-              return 0;
+-          }
+-          sn.sin_port = sp->s_port;
+-      }
++      portp = "telnet";
+       telnetport = 1;
+     }
+-    printf("Trying %s...\n", inet_ntoa(sn.sin_addr));
++
++    /* We only understand SOCK_STREAM sockets. */
++    memset(&hints, 0, sizeof(hints));
++    hints.ai_socktype = SOCK_STREAM;
++    hints.ai_flags = AI_NUMERICHOST;
++    hints.ai_family = family;
++        
++    /* Resolve both the host and service simultaneously. */
++    res = getaddrinfo(resolv_hostp, portp, &hints, &hostaddr);
++    if (res == EAI_NONAME) {
++      hints.ai_flags = AI_CANONNAME;
++      res = getaddrinfo(resolv_hostp, portp, &hints, &hostaddr);
++    } else if (hostaddr) {
++      hostaddr->ai_canonname = 0;
++    }
++    if (res || !hostaddr) {
++      fprintf(stderr, "telnet: could not resolve %s/%s: %s\n", resolv_hostp, portp, gai_strerror(res));
++      return 0;
++    }
++     
++    /* Try to connect to every listed round robin IP. */
++    tmpaddr = hostaddr;
++    errno = 0;
+     do {
+-      int x = nlink.connect(debug, host, &sn, srp, srlen, tos);
+-      if (!x) return 0;
+-      else if (x==1) continue;
++      int x;
++
++      if (!tmpaddr) {
++          if (errno)
++              perror("telnet: Unable to connect to remote host");
++          else
++              fputs("telnet: Unable to connect to remote host: "
++                    "Bad port number\n", stderr);
++err:
++          freeaddrinfo(hostaddr);
++          return 0;
++      }
++
++      if (tmpaddr->ai_family == AF_UNIX) {
++nextaddr:
++          tmpaddr = tmpaddr->ai_next;
++          continue;
++      }
++
++      getnameinfo(tmpaddr->ai_addr, tmpaddr->ai_addrlen,
++                  name, sizeof(name), service, sizeof(service),
++                  NI_NUMERICHOST | NI_NUMERICSERV);
++
++      printf("Trying %s...\n", name);
++      x = nlink.connect(debug, tmpaddr, srp, srlen, tos);
++      if (!x)
++          goto err;
++      else if (x==1)
++          goto nextaddr;
++
+       connected++;
+     } while (connected == 0);
++    if (tmpaddr->ai_canonname == 0) {
++      hostname = new char[strlen(hostp)+1];
++      strcpy(hostname, hostp);
++    }
++    else {
++      hostname = new char[strlen(tmpaddr->ai_canonname)+1];
++      strcpy(hostname, tmpaddr->ai_canonname);
++    }
++
+     cmdrc(hostp, hostname);
++    freeaddrinfo(hostaddr);
+     if (autologin && user == NULL) {
+       struct passwd *pw;
+@@ -2013,31 +2050,16 @@
+     return 0;
+ }
+-static char *rcname = 0;
+-static char rcbuf[128];
+-
+-void cmdrc(const char *m1, const char *m2) {
++static void readrc(const char *m1, const char *m2, const char *rcname) {
+     FILE *rcfile;
+     int gotmachine = 0;
+     int l1 = strlen(m1);
+     int l2 = strlen(m2);
+-    char m1save[64];
+-
+-    if (skiprc) return;
++    char m1save[strlen(m1) + 1];
+     strcpy(m1save, m1);
+     m1 = m1save;
+-    if (rcname == 0) {
+-      rcname = getenv("HOME");
+-      if (rcname)
+-          strcpy(rcbuf, rcname);
+-      else
+-          rcbuf[0] = '\0';
+-      strcat(rcbuf, "/.telnetrc");
+-      rcname = rcbuf;
+-    }
+-
+     rcfile = fopen(rcname, "r");
+     if (!rcfile) return;
+@@ -2073,6 +2095,25 @@
+     fclose(rcfile);
+ }
++void cmdrc(const char *m1, const char *m2) {
++    static char *rcname = 0;
++    static char rcbuf[128];
++
++    if (skiprc) return;
++
++    readrc(m1, m2, "/etc/telnetrc");
++    if (rcname == 0) {
++      rcname = getenv("HOME");
++      if (rcname)
++          strcpy(rcbuf, rcname);
++      else
++          rcbuf[0] = '\0';
++      strcat(rcbuf, "/.telnetrc");
++      rcname = rcbuf;
++    }
++    readrc(m1, m2, rcname);
++}
++
+ #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
+ /*
+--- a/telnet/main.cc
++++ b/telnet/main.cc
+@@ -45,7 +45,10 @@
+ #include <sys/types.h>
+ #include <getopt.h>
++#include <stdlib.h>
+ #include <string.h>
++#include <netdb.h>
++#include <errno.h>
+ #include "ring.h"
+ #include "externs.h"
+@@ -80,12 +83,13 @@
+ void usage(void) {
+     fprintf(stderr, "Usage: %s %s%s%s%s\n",
+           prompt,
+-          " [-8] [-E] [-L] [-a] [-d] [-e char] [-l user] [-n tracefile]",
+-          "\n\t",
++          "[-4] [-6] [-8] [-E] [-L] [-a] [-d] [-e char] [-l user]",
++          "\n\t[-n tracefile]",
+ #ifdef TN3270
++          "\n\t"
+           "[-noasynch] [-noasynctty] [-noasyncnet] [-r] [-t transcom]\n\t",
+ #else
+-          "[-r] ",
++          " [-r] ",
+ #endif
+           "[host-name [port]]"
+       );
+@@ -103,6 +107,7 @@
+       extern int optind;
+       int ch;
+       char *user;
++      int family;
+       tninit();               /* Clear out things */
+ #if   defined(CRAY) && !defined(__STDC__)
+@@ -117,12 +122,23 @@
+               prompt = argv[0];
+       user = NULL;
++      family = 0;
+       rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
+       autologin = -1;
+-      while ((ch = getopt(argc, argv, "8EKLS:X:ade:k:l:n:rt:x")) != EOF) {
++      while ((ch = getopt(argc, argv, "468EKLS:X:ade:k:l:n:rt:x")) != EOF) {
+               switch(ch) {
++              case '4':
++                      family = AF_INET;
++                      break;
++              case '6':
++#ifdef AF_INET6
++                      family = AF_INET6;
++#else
++                      fputs("IPv6 unsupported\n", stderr);
++#endif
++                      break;
+               case '8':
+                       eight = 3;      /* binary output and input */
+                       break;
+@@ -137,19 +153,22 @@
+                       break;
+               case 'S':
+                   {
+-#ifdef        HAS_GETTOS
+                       extern int tos;
++                      int num;
+-                      if ((tos = parsetos(optarg, "tcp")) < 0)
++#ifdef        HAS_GETTOS
++                      if ((num = parsetos(optarg, "tcp")) < 0) {
++#else
++                      errno = 0;
++                      num = strtol(optarg, 0, 0);
++                      if (errno) {
++#endif
+                               fprintf(stderr, "%s%s%s%s\n",
+                                       prompt, ": Bad TOS argument '",
+                                       optarg,
+                                       "; will try to use default TOS");
+-#else
+-                      fprintf(stderr,
+-                         "%s: Warning: -S ignored, no parsetos() support.\n",
+-                                                              prompt);
+-#endif
++                      } else
++                              tos = num;
+                   }
+                       break;
+               case 'X':
+@@ -233,6 +252,9 @@
+                       *argp++ = "-l";
+                       *argp++ = user;
+               }
++              if (family) {
++                      *argp++ = family == AF_INET ? "-4" : "-6";
++              }
+               *argp++ = argv[0];              /* host */
+               if (argc > 1)
+                       *argp++ = argv[1];      /* port */
+--- a/telnet/netlink.cc
++++ b/telnet/netlink.cc
+@@ -81,20 +81,23 @@
+     ::close(net);
+ }
+-int netlink::connect(int debug, struct hostent *host, 
+-                   struct sockaddr_in *sn, 
++int netlink::connect(int debug, struct addrinfo *addr, 
+                    char *srcroute, int srlen, int tos) 
+ {
+     int on=1;
+-    net = socket(AF_INET, SOCK_STREAM, 0);
++    net = socket(addr->ai_family, SOCK_STREAM, 0);
+     if (net < 0) {
++      if (errno == EAFNOSUPPORT)
++          return 1;
+       perror("telnet: socket");
+       return 0;
+     }
+ #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
+     if (srcroute) {
++      if (addr->ai_family != AF_INET)
++          fputs("Source route is only supported for IPv4\n", stderr);
+       if (setsockopt(net, IPPROTO_IP, IP_OPTIONS, srcroute, srlen) < 0)
+           perror("setsockopt (IP_OPTIONS)");
+     }
+@@ -108,7 +111,7 @@
+ #endif
+     if (tos < 0) tos = 020;   /* Low Delay bit */
+     if (tos && (setsockopt(net, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
+-      && (errno != ENOPROTOOPT))
++      && (errno != ENOPROTOOPT) && (errno != EOPNOTSUPP))
+       perror("telnet: setsockopt (IP_TOS) (ignored)");
+ #endif        /* defined(IPPROTO_IP) && defined(IP_TOS) */
+@@ -116,27 +119,8 @@
+       perror("setsockopt (SO_DEBUG)");
+     }
+     
+-    if (::connect(net, (struct sockaddr *)sn, sizeof(*sn)) < 0) {
+-#if defined(h_addr)           /* In 4.3, this is a #define */
+-      if (host && host->h_addr_list[1]) {
+-          int oerrno = errno;
+-          
+-          fprintf(stderr, "telnet: connect to address %s: ",
+-                  inet_ntoa(sn->sin_addr));
+-          errno = oerrno;
+-          perror(NULL);
+-          host->h_addr_list++;
+-          if (host->h_length > (int)sizeof(sn->sin_addr)) {
+-              host->h_length = sizeof(sn->sin_addr);
+-          }
+-          memcpy(&sn->sin_addr, host->h_addr_list[0], host->h_length);
+-          close(net);
+-          return 1;
+-      }
+-#endif        /* defined(h_addr) */
+-
+-      perror("telnet: Unable to connect to remote host");
+-      return 0;
++    if (::connect(net, addr->ai_addr, addr->ai_addrlen) < 0) {
++      return 1;
+     }
+     return 2;
+ }
+--- a/telnet/netlink.h
++++ b/telnet/netlink.h
+@@ -6,8 +6,7 @@
+     netlink();
+     ~netlink();
+-    int connect(int debug, struct hostent *host, 
+-              struct sockaddr_in *sin, 
++    int connect(int debug, struct addrinfo *hostaddr, 
+               char *srcroute, int srlen,
+               int tos);
+     void close(int doshutdown);
+--- a/telnet/network.cc
++++ b/telnet/network.cc
+@@ -40,6 +40,7 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
++#include <stdlib.h>
+ #include <errno.h>
+ #include <arpa/telnet.h>
+--- a/telnet/ring.cc
++++ b/telnet/ring.cc
+@@ -165,7 +165,7 @@
+ /////////////////////////////////////////////////// supply //////////////
+-void ringbuf::printf(const char *format, ...) {
++void ringbuf::xprintf(const char *format, ...) {
+     char xbuf[256];
+     va_list ap;
+     va_start(ap, format);
+--- a/telnet/ring.h
++++ b/telnet/ring.h
+@@ -83,7 +83,7 @@
+     // manual supply
+     void putch(char c) { write(&c, 1); }
+     void write(const char *buffer, int ct);
+-    void printf(const char *format, ...);
++    void xprintf(const char *format, ...);
+     int empty_count() { return size - count; }
+     // automatic supply
+--- a/telnet/sys_bsd.cc
++++ b/telnet/sys_bsd.cc
+@@ -189,18 +189,25 @@
+  * Various signal handling routines.
+  */
++#if 0
+ static void deadpeer(int /*sig*/) {
+     setcommandmode();
+     siglongjmp(peerdied, -1);
+ }
++#endif
+ static void intr(int /*sig*/) {
+     if (localchars) {
+       intp();
+     }
+     else {
++#if 0
+         setcommandmode();
+       siglongjmp(toplevel, -1);
++#else
++      signal(SIGINT, SIG_DFL);
++      raise(SIGINT);
++#endif
+     }
+ }
+@@ -214,6 +221,8 @@
+           sendabort();
+       return;
+     }
++    signal(SIGQUIT, SIG_DFL);
++    raise(SIGQUIT);
+ }
+ #ifdef        SIGWINCH
+@@ -238,7 +247,9 @@
+ void sys_telnet_init(void) {
+     signal(SIGINT, intr);
+     signal(SIGQUIT, intr2);
++#if 0
+     signal(SIGPIPE, deadpeer);
++#endif
+ #ifdef        SIGWINCH
+     signal(SIGWINCH, sendwin);
+ #endif
+--- a/telnet/telnet.1
++++ b/telnet/telnet.1
+@@ -42,7 +42,7 @@
+ protocol
+ .Sh SYNOPSIS
+ .Nm telnet
+-.Op Fl 8ELadr
++.Op Fl 468ELadr
+ .Op Fl S Ar tos
+ .Op Fl e Ar escapechar
+ .Op Fl l Ar user
+@@ -68,6 +68,10 @@
+ .Pp
+ Options:
+ .Bl -tag -width indent
++.It Fl 4
++Force IPv4 address resolution.
++.It Fl 6
++Force IPv6 address resolution.
+ .It Fl 8
+ Request 8-bit operation. This causes an attempt to negotiate the
+ .Dv TELNET BINARY
+@@ -474,17 +478,21 @@
+ placing a dash before the port number.
+ .Pp
+ After establishing a connection, any commands associated with the
+-remote host in the user's
++remote host in
++.Pa /etc/telnetrc
++and the user's
+ .Pa .telnetrc
+-file are executed.
++file are executed, in that order.
+ .Pp
+-The format of the .telnetrc file is as follows: Lines beginning with a
++The format of the telnetrc files is as follows: Lines beginning with a
+ #, and blank lines, are ignored.  The rest of the file should consist
+ of hostnames and sequences of
+ .Nm telnet
+ commands to use with that host. Commands should be one per line,
+ indented by whitespace; lines beginning without whitespace are
+-interpreted as hostnames. Upon connecting to a particular host, the
++interpreted as hostnames.  Lines beginning with the special hostname
++.Ql DEFAULT
++will apply to all hosts.  Upon connecting to a particular host, the
+ commands associated with that host are executed.
+ .It Ic quit
+ Close any open session and exit
+@@ -1184,9 +1192,7 @@
+ When the skiprc toggle is
+ .Dv TRUE ,
+ .Tn telnet
+-does not read the 
+-.Pa \&.telnetrc
+-file.  The initial value for this toggle is
++does not read the telnetrc files.  The initial value for this toggle is
+ .Dv FALSE.
+ .It Ic termdata
+ Toggles the display of all terminal data (in hexadecimal format).
+@@ -1239,7 +1245,9 @@
+ .Dv TELNET ENVIRON
+ option.
+ .Sh FILES
+-.Bl -tag -width ~/.telnetrc -compact
++.Bl -tag -width /etc/telnetrc -compact
++.It Pa /etc/telnetrc
++global telnet startup values
+ .It Pa ~/.telnetrc
+ user customized telnet startup values
+ .El
+--- a/telnet/telnet.cc
++++ b/telnet/telnet.cc
+@@ -646,7 +646,7 @@
+     mklist(termbuf, tname, termtypes);
+     next = 0;
+   }
+-  if (next==termtypes.num()) next = 0;
++  if (next==termtypes.num()-1) next = 0;
+   return termtypes[next++];
+ }
+ /*
+@@ -681,7 +681,7 @@
+       }
+ #endif /* TN3270 */
+       name = gettermname();
+-      netoring.printf("%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE,
++      netoring.xprintf("%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE,
+                     TELQUAL_IS, name, IAC, SE);
+     }
+     break;
+@@ -693,7 +693,7 @@
+     if (SB_GET() == TELQUAL_SEND) {
+       long oospeed, iispeed;
+       TerminalSpeeds(&iispeed, &oospeed);
+-      netoring.printf("%c%c%c%c%ld,%ld%c%c", IAC, SB, TELOPT_TSPEED, 
++      netoring.xprintf("%c%c%c%c%ld,%ld%c%c", IAC, SB, TELOPT_TSPEED, 
+                     TELQUAL_IS, oospeed, iispeed, IAC, SE);
+     }
+     break;
+@@ -780,7 +780,7 @@
+       send_wont(TELOPT_XDISPLOC, 1);
+       break;
+       }
+-      netoring.printf("%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC,
++      netoring.xprintf("%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC,
+                     TELQUAL_IS, dp, IAC, SE);
+     }
+     break;
+@@ -798,7 +798,7 @@
+     return;
+   }
+   
+-  netoring.printf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, 
++  netoring.xprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, 
+                 DONT, cmd[0], IAC, SE);
+ }
+@@ -815,7 +815,7 @@
+     /*@*/     printf("lm_do: no command!!!\n");       /* Should not happen... */
+     return;
+   }
+-  netoring.printf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, 
++  netoring.xprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, 
+                 WONT, cmd[0], IAC, SE);
+ }
+@@ -838,7 +838,7 @@
+     k |= MODE_ACK;
+   }
+   
+-  netoring.printf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE,
++  netoring.xprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE,
+                 k, IAC, SE);
+   
+   setconnmode(0);     /* set changed mode */
+@@ -933,11 +933,11 @@
+ void slc_import(int def) {
+   if (def) {
+-    netoring.printf("%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE,
++    netoring.xprintf("%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE,
+                   LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE);
+   }
+   else {
+-    netoring.printf("%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE,
++    netoring.xprintf("%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE,
+                   LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE);
+   }
+ }
+@@ -1142,6 +1142,7 @@
+   }
+ }
++/* OPT_REPLY_SIZE must be a multiple of 2. */
+ #define       OPT_REPLY_SIZE  256
+ unsigned char *opt_reply;
+ unsigned char *opt_replyp;
+@@ -1173,6 +1174,7 @@
+ void env_opt_add(const char *ep) {
+   const char *vp;
++  const unsigned char *tp;
+   unsigned char c;
+   
+   if (opt_reply == NULL)              /*XXX*/
+@@ -1185,11 +1187,12 @@
+     return;
+   }
+   vp = env_getvalue(ep, 1);
+-  if (opt_replyp + (vp ? strlen(vp) : 0) + strlen(ep) + 6 > opt_replyend)
++  tp = opt_replyp + (vp ? strlen(vp) * 2 : 0) + strlen(ep) * 2 + 6;
++  if (tp > opt_replyend)
+     {
+       register int len;
+-      opt_replyend += OPT_REPLY_SIZE;
+-      len = opt_replyend - opt_reply;
++      len = ((tp - opt_reply) + OPT_REPLY_SIZE - 1) & ~(OPT_REPLY_SIZE - 1);
++      opt_replyend = opt_reply + len;
+       opt_reply = (unsigned char *)realloc(opt_reply, len);
+       if (opt_reply == NULL) {
+       /*@*/                   printf("env_opt_add: realloc() failed!!!\n");
+--- a/telnet/terminal.cc
++++ b/telnet/terminal.cc
+@@ -45,6 +45,8 @@
+ #include <signal.h>
+ #include <errno.h>
+ #include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
+ #include "ring.h"
+ #include "defines.h"
+--- a/telnet/utilities.cc
++++ b/telnet/utilities.cc
+@@ -47,6 +47,8 @@
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #include <ctype.h>
++#include <string.h>
++#include <stdlib.h>
+ #include "ring.h"
+ #include "defines.h"
+--- a/telnetd/authenc.c
++++ b/telnetd/authenc.c
+@@ -42,18 +42,6 @@
+     return(0);
+ }
+-void
+-net_encrypt()
+-{
+-#if   defined(ENCRYPT)
+-    char *s = (nclearto > nbackp) ? nclearto : nbackp;
+-    if (s < nfrontp && encrypt_output) {
+-      (*encrypt_output)((unsigned char *)s, nfrontp - s);
+-    }
+-    nclearto = nfrontp;
+-#endif
+-}
+-
+ int
+ telnet_spin()
+ {
+--- a/telnetd/defs.h
++++ b/telnetd/defs.h
+@@ -55,10 +55,11 @@
+ #include <fcntl.h>
+ #include <sys/file.h>
+ #include <sys/stat.h>
+-#include <sys/time.h>
++#include <time.h>
+ #include <sys/ioctl.h>
+ #include <netinet/in.h>
+ #include <arpa/telnet.h>
++#include <sys/uio.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <signal.h>
+--- a/telnetd/ext.h
++++ b/telnetd/ext.h
+@@ -81,12 +81,11 @@
+  */
+ extern char ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp;
+ extern char netibuf[BUFSIZ], *netip;
+-extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
+-extern char *neturg;          /* one past last byte of urgent data */
+ extern int pcc, ncc;
++extern FILE *netfile;
+ /* printf into netobuf */
+-void netoprintf(const char *fmt, ...) __attribute((format (printf, 1, 2))); 
++#define netoprintf(fmt, ...) fprintf(netfile, fmt, ## __VA_ARGS__)
+ extern int pty, net;
+ extern char *line;
+@@ -96,7 +95,7 @@
+ void add_slc(int, int, int);
+ void check_slc(void);
+ void change_slc(int, int, int);
+-void cleanup(int);
++void cleanup(int) __attribute__ ((noreturn));
+ void clientstat(int, int, int);
+ void copy_termbuf(char *, int);
+ void deferslc(void);
+@@ -106,8 +105,8 @@
+ void dooption(int);
+ void dontoption(int);
+ void edithost(const char *, const char *);
+-void fatal(int, const char *);
+-void fatalperror(int, const char *);
++void fatal(int, const char *) __attribute__ ((noreturn));
++void fatalperror(int, const char *) __attribute__ ((noreturn));
+ void get_slc_defaults(void);
+ void init_env(void);
+ void init_termbuf(void);
+@@ -115,6 +114,8 @@
+ void localstat(void);
+ void netclear(void);
+ void netflush(void);
++size_t netbuflen(int);
++void sendurg(const char *, size_t);
+ #ifdef DIAGNOSTICS
+ void printoption(const char *, int);
+@@ -182,10 +183,11 @@
+ void tty_tspeed(int);
+ void willoption(int);
+ void wontoption(int);
+-void writenet(unsigned char *, int);
++#define writenet(b, l) fwrite(b, 1, l, netfile)
++void netopen(void);
+ #if defined(ENCRYPT)
+-extern void (*encrypt_output)(unsigned char *, int);
++extern void (*encrypt_output)(const unsigned char *, int);
+ extern int (*decrypt_input)(int);
+ extern char *nclearto;
+ #endif
+--- a/telnetd/global.c
++++ b/telnetd/global.c
+@@ -87,11 +87,10 @@
+ char  netibuf[BUFSIZ], *netip;
+-char  netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
+-char  *neturg;                /* one past last bye of urgent data */
+-
+ int   pcc, ncc;
++FILE  *netfile;
++
+ int   pty, net;
+ int   SYNCHing;               /* we are in TELNET SYNCH mode */
+--- a/telnetd/issue.net.5
++++ b/telnetd/issue.net.5
+@@ -40,4 +40,4 @@
+ .Sh FILES
+ .Pa /etc/issue.net
+ .Sh "SEE ALSO"
+-.Xr telnetd 8
++.Xr in.telnetd 8
+--- a/telnetd/setproctitle.c
++++ b/telnetd/setproctitle.c
+@@ -139,7 +139,7 @@
+       (void) strcpy(Argv[0], buf);
+       p = &Argv[0][i];
+       while (p < LastArgv)
+-              *p++ = ' ';
++              *p++ = '\0';
+       Argv[1] = NULL;
+ }
+--- a/telnetd/state.c
++++ b/telnetd/state.c
+@@ -179,6 +179,7 @@
+                  */
+             case AO:
+                 {
++                    static const char msg[] = { IAC, DM };
+                     DIAG(TD_OPTIONS, printoption("td: recv IAC", c));
+                     ptyflush();       /* half-hearted */
+                     init_termbuf();
+@@ -191,9 +192,7 @@
+                     }
+                     netclear();       /* clear buffer back */
+-                    *nfrontp++ = (char)IAC;
+-                    *nfrontp++ = (char)DM;
+-                    neturg = nfrontp-1; /* off by one XXX */
++                    sendurg(msg, sizeof(msg));
+                     DIAG(TD_OPTIONS, printoption("td: send IAC", DM));
+                     break;
+                 }
+--- a/telnetd/sys_term.c
++++ b/telnetd/sys_term.c
+@@ -41,8 +41,6 @@
+ #include "telnetd.h"
+ #include "pathnames.h"
+-#include "logout.h"
+-#include "logwtmp.h"
+ #if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ /* mmm, nonstandard */
+@@ -681,7 +679,9 @@
+     memcpy(&argvfoo, &avs.argv, sizeof(argvfoo));
+     execv(loginprg, argvfoo);
++    openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
+     syslog(LOG_ERR, "%s: %m\n", loginprg);
++    closelog();
+     fatalperror(net, loginprg);
+ }
+--- a/telnetd/telnetd.8
++++ b/telnetd/telnetd.8
+@@ -161,7 +161,7 @@
+ .It Fl L Ar loginprg
+ This option may be used to specify a different login program.
+ By default, 
+-.Pa /bin/login
++.Pa /usr/sbin/telnetlogin
+ is used.
+ .It Fl n
+ Disable
+@@ -406,6 +406,7 @@
+ indicates a willingness to decrypt
+ the data stream.
+ .Xr issue.net 5 ) .
++.El
+ .Sh FILES
+ .Pa /etc/services ,
+ .Pa /etc/issue.net
+@@ -458,6 +459,7 @@
+ Telnet Environment Option Interoperability Issues
+ .It Cm RFC-1572
+ Telnet Environment Option
++.El
+ .Sh BUGS
+ Some
+ .Tn TELNET
+--- a/telnetd/telnetd.c
++++ b/telnetd/telnetd.c
+@@ -43,12 +43,16 @@
+ #include "../version.h"
++#include <sys/socket.h>
+ #include <netdb.h>
+ #include <termcap.h>
+ #include <netinet/in.h>
+ /* #include <netinet/ip.h> */ /* Don't think this is used at all here */
+ #include <arpa/inet.h>
+ #include <assert.h>
++#include <poll.h>
++#include <fcntl.h>
++#include <unistd.h>
+ #include "telnetd.h"
+ #include "pathnames.h"
+ #include "setproctitle.h"
+@@ -68,7 +72,7 @@
+ #define HAS_IPPROTO_IP
+ #endif
+-static void doit(struct sockaddr_in *who);
++static void doit(struct sockaddr *who, socklen_t who_len);
+ static int terminaltypeok(const char *s);
+ /*
+@@ -82,15 +86,119 @@
+ int debug = 0;
+ int keepalive = 1;
++#ifdef LOGIN_WRAPPER
++char *loginprg = LOGIN_WRAPPER;
++#else
+ char *loginprg = _PATH_LOGIN;
+-char *progname;
++#endif
+ extern void usage(void);
++static void
++wait_for_connection(const char *service)
++{
++      struct addrinfo hints;
++      struct addrinfo *res, *addr;
++      struct pollfd *fds, *fdp;
++      int nfds;
++      int i;
++      int error;
++      int on = 1;
++
++      memset(&hints, 0, sizeof(hints));
++      hints.ai_family = PF_UNSPEC;
++      hints.ai_flags = AI_PASSIVE;
++      hints.ai_socktype = SOCK_STREAM;
++      error = getaddrinfo(NULL, service, &hints, &res);
++      if (error) {
++              char *p;
++              error = asprintf(&p, "getaddrinfo: %s\n", gai_strerror(error));
++              fatal(2, error >= 0 ? p : "");
++      }
++
++      for (addr = res, nfds = 0; addr; addr = addr->ai_next, nfds++)
++              ;
++      fds = malloc(sizeof(struct pollfd) * nfds);
++      for (addr = res, fdp = fds; addr; addr = addr->ai_next, fdp++) {
++              int s;
++
++              if (addr->ai_family == AF_LOCAL) {
++nextaddr:
++                      fdp--;
++                      nfds--;
++                      continue;
++              }
++
++              s = socket(addr->ai_family, SOCK_STREAM, 0);
++              if (s < 0) {
++                      if (errno == EAFNOSUPPORT || errno == EINVAL) {
++                              goto nextaddr;
++                      }
++                      fatalperror(2, "socket");
++              }
++              if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
++                      fatalperror(2, "setsockopt");
++              }
++              if (bind(s, addr->ai_addr, addr->ai_addrlen)) {
++#ifdef linux
++                      if (fdp != fds && errno == EADDRINUSE) {
++                              close(s);
++                              goto nextaddr;
++                      }
++#endif
++                      fatalperror(2, "bind");
++              }
++              if (listen(s, 1)) {
++                      fatalperror(2, "listen");
++              }
++              if (fcntl(s, F_SETFL, O_NONBLOCK)) {
++                      fatalperror(2, "fcntl");
++              }
++
++              fdp->fd = s;
++              fdp->events = POLLIN;
++      }
++
++      freeaddrinfo(res);
++
++      while (1) {
++              if (poll(fds, nfds, -1) < 0) {
++                      if (errno == EINTR) {
++                              continue;
++                      }
++                      fatalperror(2, "poll");
++              }
++
++              for (i = 0, fdp = fds; i < nfds; i++, fdp++) {
++                      int fd;
++
++                      if (!(fdp->revents & POLLIN)) {
++                              continue;
++                      }
++
++                      fd = accept(fdp->fd, 0, 0);
++                      if (fd >= 0) {
++                              dup2(fd, 0);
++                              close(fd);
++                              goto out;
++                      }
++                      if (errno != EAGAIN) {
++                              fatalperror(2, "accept");
++                      }
++              }
++      }
++
++out:
++      for (i = 0, fdp = fds; i < nfds; i++, fdp++) {
++              close(fdp->fd);
++      }
++      free(fds);
++}
++
+ int
+ main(int argc, char *argv[], char *env[])
+ {
+-      struct sockaddr_in from;
++      struct sockaddr_storage from;
+       int on = 1;
+       socklen_t fromlen;
+       register int ch;
+@@ -103,12 +211,6 @@
+       pfrontp = pbackp = ptyobuf;
+       netip = netibuf;
+-      nfrontp = nbackp = netobuf;
+-#if   defined(ENCRYPT)
+-      nclearto = 0;
+-#endif
+-
+-      progname = *argv;
+       while ((ch = getopt(argc, argv, "d:a:e:lhnr:I:D:B:sS:a:X:L:")) != EOF) {
+               switch(ch) {
+@@ -249,74 +351,18 @@
+       argv += optind;
+       if (debug) {
+-          int s, ns;
+-          socklen_t foo;
+-          struct servent *sp;
+-          struct sockaddr_in sn;
+-
+-          memset(&sn, 0, sizeof(sn));
+-          sn.sin_family = AF_INET;
+-
+-          if (argc > 1) {
+-              usage();
+-              /* NOTREACHED */
+-          } else if (argc == 1) {
+-                  if ((sp = getservbyname(*argv, "tcp"))!=NULL) {
+-                      sn.sin_port = sp->s_port;
+-                  } 
+-                  else {
+-                      int pt = atoi(*argv);
+-                      if (pt <= 0) {
+-                          fprintf(stderr, "telnetd: %s: bad port number\n",
+-                                  *argv);
+-                          usage();
+-                          /* NOTREACHED */
+-                      }
+-                      sn.sin_port = htons(pt);
+-                 }
+-          } else {
+-              sp = getservbyname("telnet", "tcp");
+-              if (sp == 0) {
+-                  fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
+-                  exit(1);
++              if (argc > 1) {
++                      usage();
++                      /* NOTREACHED */
+               }
+-              sn.sin_port = sp->s_port;
+-          }
+-          s = socket(AF_INET, SOCK_STREAM, 0);
+-          if (s < 0) {
+-                  perror("telnetd: socket");;
+-                  exit(1);
+-          }
+-          (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+-          if (bind(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {
+-              perror("bind");
+-              exit(1);
+-          }
+-          if (listen(s, 1) < 0) {
+-              perror("listen");
+-              exit(1);
+-          }
+-          foo = sizeof(sn);
+-          ns = accept(s, (struct sockaddr *)&sn, &foo);
+-          if (ns < 0) {
+-              perror("accept");
+-              exit(1);
+-          }
+-          (void) dup2(ns, 0);
+-          (void) close(ns);
+-          (void) close(s);
+-      } else if (argc > 0) {
+-              usage();
+-              /* NOT REACHED */
++              wait_for_connection((argc == 1) ? *argv : "telnet");
+       }
+       openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
+       fromlen = sizeof (from);
+       if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
+-              fprintf(stderr, "%s: ", progname);
+-              perror("getpeername");
+-              _exit(1);
++              fatalperror(2, "getpeername");
+       }
+       if (keepalive &&
+           setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
+@@ -339,7 +385,8 @@
+       }
+ #endif        /* defined(HAS_IPPROTO_IP) && defined(IP_TOS) */
+       net = 0;
+-      doit(&from);
++      netopen();
++      doit((struct sockaddr *)&from, fromlen);
+       /* NOTREACHED */
+       return 0;
+ }  /* end of main */
+@@ -354,7 +401,7 @@
+ #ifdef BFTPDAEMON
+       fprintf(stderr, " [-B]");
+ #endif
+-      fprintf(stderr, " [-debug]");
++      fprintf(stderr, " [-debug port]");
+ #ifdef DIAGNOSTICS
+       fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
+ #endif
+@@ -373,7 +420,7 @@
+ #ifdef        AUTHENTICATE
+       fprintf(stderr, " [-X auth-type]");
+ #endif
+-      fprintf(stderr, " [port]\n");
++      fprintf(stderr, "\n");
+       exit(1);
+ }
+@@ -608,54 +655,45 @@
+  * Get a pty, scan input lines.
+  */
+ static void
+-doit(struct sockaddr_in *who)
++doit(struct sockaddr *who, socklen_t who_len)
+ {
+       const char *host;
+-      struct hostent *hp;
+       int level;
+       char user_name[256];
++      int i;
++      struct addrinfo hints, *res;
+       /*
+        * Find an available pty to use.
+        */
+       pty = getpty();
+       if (pty < 0)
+-              fatal(net, "All network ports in use");
++              fatalperror(net, "getpty");
+       /* get name of connected client */
+-      hp = gethostbyaddr((char *)&who->sin_addr, sizeof (struct in_addr),
+-              who->sin_family);
+-      if (hp)
+-              host = hp->h_name;
+-      else
+-              host = inet_ntoa(who->sin_addr);
+-
+-      /*
+-       * We must make a copy because Kerberos is probably going
+-       * to also do a gethost* and overwrite the static data...
+-       */
+-      {
+-              int i;
+-              strncpy(remote_host_name, host, sizeof(remote_host_name)-1);
+-              remote_host_name[sizeof(remote_host_name)-1] = 0;
+-
+-              /* Disallow funnies. */
+-              for (i=0; remote_host_name[i]; i++) {
+-                  if (remote_host_name[i]<=32 || remote_host_name[i]>126) 
+-                      remote_host_name[i] = '?';
+-              }
++      if (getnameinfo(who, who_len, remote_host_name,
++                      sizeof(remote_host_name), 0, 0, 0)) {
++              syslog(LOG_ERR, "doit: getnameinfo: %m");
++              *remote_host_name = 0;
++        }
++
++      /* Disallow funnies. */
++      for (i=0; remote_host_name[i]; i++) {
++          if (remote_host_name[i]<=32 || remote_host_name[i]>126) 
++              remote_host_name[i] = '?';
+       }
+       host = remote_host_name;
+       /* Get local host name */
+-      {
+-              struct hostent *h;
+-              gethostname(host_name, sizeof(host_name));
+-              h = gethostbyname(host_name);
+-              if (h) {
+-                  strncpy(host_name, h->h_name, sizeof(host_name));
+-                  host_name[sizeof(host_name)-1] = 0;
+-              }
++      gethostname(host_name, sizeof(host_name));
++      memset(&hints, 0, sizeof(hints));
++      hints.ai_family = PF_UNSPEC;
++      hints.ai_flags = AI_CANONNAME;
++      if ((i = getaddrinfo(host_name, 0, &hints, &res)))
++              syslog(LOG_WARNING, "doit: getaddrinfo: %s", gai_strerror(i));
++      else {
++              strncpy(host_name, res->ai_canonname, sizeof(host_name)-1);
++              host_name[sizeof(host_name)-1] = 0;
+       }
+ #if   defined(AUTHENTICATE) || defined(ENCRYPT)
+@@ -892,7 +930,7 @@
+        * Never look for input if there's still
+        * stuff in the corresponding output buffer
+        */
+-      if (nfrontp - nbackp || pcc > 0) {
++      if (netbuflen(1) || pcc > 0) {
+           FD_SET(f, &obits);
+           if (f >= hifd) hifd = f+1;
+       } 
+@@ -1033,6 +1071,7 @@
+               }
+ #endif        /* LINEMODE */
+               if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
++                  static const char msg[] = { IAC, DM };
+                   netclear(); /* clear buffer back */
+ #ifndef       NO_URGENT
+                   /*
+@@ -1041,8 +1080,7 @@
+                    * royally if we send them urgent
+                    * mode data.
+                    */
+-                  netoprintf("%c%c", IAC, DM);
+-                  neturg = nfrontp-1; /* off by one XXX */
++                  sendurg(msg, sizeof(msg));
+ #endif
+               }
+               if (his_state_is_will(TELOPT_LFLOW) &&
+@@ -1058,23 +1096,21 @@
+           }
+       }
+       
+-      while (pcc > 0) {
+-          if ((&netobuf[BUFSIZ] - nfrontp) < 2)
+-              break;
++      while (pcc > 0 && !netbuflen(0)) {
+           c = *ptyip++ & 0377, pcc--;
+           if (c == IAC)
+-              *nfrontp++ = c;
+-          *nfrontp++ = c;
++              putc(c, netfile);
++          putc(c, netfile);
+           if ((c == '\r'  ) && (my_state_is_wont(TELOPT_BINARY))) {
+               if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
+-                  *nfrontp++ = *ptyip++ & 0377;
++                  putc(*ptyip++ & 0377, netfile);
+                   pcc--;
+               } 
+-              else *nfrontp++ = '\0';
++              else putc('\0', netfile);
+           }
+       }
+-      if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)
++      if (FD_ISSET(f, &obits))
+           netflush();
+       if (ncc > 0)
+           telrcv();
+--- a/telnetd/utility.c
++++ b/telnetd/utility.c
+@@ -41,6 +41,7 @@
+ #include <stdarg.h>
+ #include <sys/utsname.h>
++#include <sys/time.h>
+ #ifdef AUTHENTICATE
+ #include <libtelnet/auth.h>
+@@ -48,34 +49,19 @@
+ #include "telnetd.h"
+-/*
+- * utility functions performing io related tasks
+- */
+-
+-void
+-netoprintf(const char *fmt, ...)
+-{
+-   int len, maxsize;
+-   va_list ap;
+-   int done=0;
+-
+-   while (!done) {
+-      maxsize = sizeof(netobuf) - (nfrontp - netobuf);
+-
+-      va_start(ap, fmt);
+-      len = vsnprintf(nfrontp, maxsize, fmt, ap);
+-      va_end(ap);
+-
+-      if (len<0 || len==maxsize) {
+-       /* didn't fit */
+-       netflush();
+-      }
+-      else {
+-       done = 1;
+-      }
+-   }
+-   nfrontp += len;
+-}
++struct buflist {
++      struct buflist *next;
++      char *buf;
++      size_t len;
++};
++
++static struct buflist head = { next: &head, buf: 0, len: 0 };
++static struct buflist *tail = &head;
++static size_t skip;
++static int trailing;
++static size_t listlen;
++static int doclear;
++static struct buflist *urg;
+ /*
+  * ttloop
+@@ -92,9 +78,7 @@
+     DIAG(TD_REPORT, netoprintf("td: ttloop\r\n"););
+                    
+-    if (nfrontp-nbackp) {
+-      netflush();
+-    }
++    netflush();
+     ncc = read(net, netibuf, sizeof(netibuf));
+     if (ncc < 0) {
+       syslog(LOG_INFO, "ttloop: read: %m\n");
+@@ -168,33 +152,64 @@
+  * character.
+  */
+ static
+-char *
+-nextitem(char *current)
+-{
+-    if ((*current&0xff) != IAC) {
+-      return current+1;
+-    }
+-    switch (*(current+1)&0xff) {
+-    case DO:
+-    case DONT:
+-    case WILL:
+-    case WONT:
+-      return current+3;
+-    case SB:          /* loop forever looking for the SE */
+-      {
+-          register char *look = current+2;
+-
+-          for (;;) {
+-              if ((*look++&0xff) == IAC) {
+-                  if ((*look++&0xff) == SE) {
+-                      return look;
+-                  }
++const char *
++nextitem(
++      const unsigned char *current, const unsigned char *end,
++      const unsigned char *next, const unsigned char *nextend
++) {
++      if (*current++ != IAC) {
++              while (current < end && *current++ != IAC)
++                      ;
++              goto out;
++      }
++
++      if (current >= end) {
++              current = next;
++              if (!current) {
++                      return 0;
+               }
+-          }
++              end = nextend;
++              next = 0;
+       }
+-    default:
+-      return current+2;
+-    }
++
++      switch (*current++) {
++      case DO:
++      case DONT:
++      case WILL:
++      case WONT:
++              current++;
++              break;
++      case SB:                /* loop forever looking for the SE */
++              for (;;) {
++                      int iac;
++
++                      while (iac = 0, current < end) {
++                              if (*current++ == IAC) {
++                                      if (current >= end) {
++                                              iac = 1;
++                                              break;
++                                      }
++iac:
++                                      if (*current++ == SE) {
++                                              goto out;
++                                      }
++                              }
++                      }
++
++                      current = next;
++                      if (!current) {
++                              return 0;
++                      }
++                      end = nextend;
++                      next = 0;
++                      if (iac) {
++                              goto iac;
++                      }
++              }
++      }
++
++out:
++      return next ? next + (current - end) : current;
+ }  /* end of nextitem */
+@@ -216,145 +231,102 @@
+  */
+ void netclear(void)
+ {
+-    register char *thisitem, *next;
+-    char *good;
+-#define       wewant(p)       ((nfrontp > p) && ((*p&0xff) == IAC) && \
+-                              ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
++      doclear++;
++      netflush();
++      doclear--;
++}  /* end of netclear */
+-#if   defined(ENCRYPT)
+-    thisitem = nclearto > netobuf ? nclearto : netobuf;
+-#else
+-    thisitem = netobuf;
+-#endif
++static void
++netwritebuf(void)
++{
++      struct iovec *vector;
++      struct iovec *v;
++      struct buflist *lp;
++      ssize_t n;
++      size_t len;
++      int ltrailing = trailing;
+-    while ((next = nextitem(thisitem)) <= nbackp) {
+-      thisitem = next;
+-    }
++      vector = malloc(listlen * sizeof(struct iovec));
++      if (!vector) {
++              return;
++      }
+-    /* Now, thisitem is first before/at boundary. */
++      len = listlen - (doclear & ltrailing);
++      v = vector;
++      lp = head.next;
++      while (lp != &head) {
++              if (lp == urg) {
++                      len = v - vector;
++                      if (!len) {
++                              n = send(net, lp->buf, 1, MSG_OOB);
++                              if (n > 0) {
++                                      urg = 0;
++                              }
++                              goto epi;
++                      }
++                      break;
++              }
++              v->iov_base = lp->buf;
++              v->iov_len = lp->len;
++              v++;
++              lp = lp->next;
++      }
+-#if   defined(ENCRYPT)
+-    good = nclearto > netobuf ? nclearto : netobuf;
+-#else
+-    good = netobuf;   /* where the good bytes go */
+-#endif
++      vector->iov_base = (char *)vector->iov_base + skip;
++      vector->iov_len -= skip;
++
++      n = writev(net, vector, len);
+-    while (nfrontp > thisitem) {
+-      if (wewant(thisitem)) {
+-          int length;
+-
+-          next = thisitem;
+-          do {
+-              next = nextitem(next);
+-          } while (wewant(next) && (nfrontp > next));
+-          length = next-thisitem;
+-          bcopy(thisitem, good, length);
+-          good += length;
+-          thisitem = next;
+-      } else {
+-          thisitem = nextitem(thisitem);
++epi:
++      free(vector);
++
++      if (n < 0) {
++              if (errno != EWOULDBLOCK && errno != EINTR)
++                      cleanup(0);
++              return;
+       }
+-    }
+-    nbackp = netobuf;
+-    nfrontp = good;           /* next byte to be sent */
+-    neturg = 0;
+-}  /* end of netclear */
++      len = n + skip;
+-/*
+- *  netflush
+- *            Send as much data as possible to the network,
+- *    handling requests for urgent data.
+- */
+-extern int not42;
+-void
+-netflush(void)
+-{
+-    int n;
++      lp = head.next;
++      while (lp->len <= len) {
++              if (lp == tail && ltrailing) {
++                      break;
++              }
+-    if ((n = nfrontp - nbackp) > 0) {
+-      DIAG(TD_REPORT,
+-          { netoprintf("td: netflush %d chars\r\n", n);
+-            n = nfrontp - nbackp;  /* update count */
+-          });
+-#if   defined(ENCRYPT)
+-      if (encrypt_output) {
+-              char *s = nclearto ? nclearto : nbackp;
+-              if (nfrontp - s > 0) {
+-                      (*encrypt_output)((unsigned char *)s, nfrontp-s);
+-                      nclearto = nfrontp;
++              len -= lp->len;
++
++              head.next = lp->next;
++              listlen--;
++              free(lp->buf);
++              free(lp);
++
++              lp = head.next;
++              if (lp == &head) {
++                      tail = &head;
++                      break;
+               }
+       }
+-#endif
+-      /*
+-       * if no urgent data, or if the other side appears to be an
+-       * old 4.2 client (and thus unable to survive TCP urgent data),
+-       * write the entire buffer in non-OOB mode.
+-       */
+-      if ((neturg == 0) || (not42 == 0)) {
+-          n = write(net, nbackp, n);  /* normal write */
+-      } else {
+-          n = neturg - nbackp;
+-          /*
+-           * In 4.2 (and 4.3) systems, there is some question about
+-           * what byte in a sendOOB operation is the "OOB" data.
+-           * To make ourselves compatible, we only send ONE byte
+-           * out of band, the one WE THINK should be OOB (though
+-           * we really have more the TCP philosophy of urgent data
+-           * rather than the Unix philosophy of OOB data).
+-           */
+-          if (n > 1) {
+-              n = send(net, nbackp, n-1, 0);  /* send URGENT all by itself */
+-          } else {
+-              n = send(net, nbackp, n, MSG_OOB);      /* URGENT data */
+-          }
+-      }
+-    }
+-    if (n < 0) {
+-      if (errno == EWOULDBLOCK || errno == EINTR)
+-              return;
+-      cleanup(0);
+-    }
+-    nbackp += n;
+-#if   defined(ENCRYPT)
+-    if (nbackp > nclearto)
+-      nclearto = 0;
+-#endif
+-    if (nbackp >= neturg) {
+-      neturg = 0;
+-    }
+-    if (nbackp == nfrontp) {
+-      nbackp = nfrontp = netobuf;
+-#if   defined(ENCRYPT)
+-      nclearto = 0;
+-#endif
+-    }
+-    return;
+-}  /* end of netflush */
++      skip = len;
++}
+ /*
+- * writenet
+- *
+- * Just a handy little function to write a bit of raw data to the net.
+- * It will force a transmit of the buffer if necessary
+- *
+- * arguments
+- *    ptr - A pointer to a character string to write
+- *    len - How many bytes to write
++ *  netflush
++ *             Send as much data as possible to the network,
++ *     handling requests for urgent data.
+  */
+-void writenet(register unsigned char *ptr, register int len)
++void
++netflush(void)
+ {
+-      /* flush buffer if no room for new data) */
+-      if ((&netobuf[BUFSIZ] - nfrontp) < len) {
+-              /* if this fails, don't worry, buffer is a little big */
+-              netflush();
++      if (fflush(netfile)) {
++              /* out of memory? */
++              cleanup(0);
+       }
+-
+-      bcopy(ptr, nfrontp, len);
+-      nfrontp += len;
+-
+-}  /* end of writenet */
++      if (listlen) {
++              netwritebuf();
++      }
++}
+ /*
+@@ -391,18 +363,30 @@
+       fatal(f, buf);
+ }
+-char editedhost[32];
++char *editedhost;
+ struct utsname kerninfo;
+ void
+ edithost(const char *pat, const char *host)
+ {
+-      char *res = editedhost;
++      char *res;
+       uname(&kerninfo);
+       if (!pat)
+               pat = "";
++
++      res = realloc(editedhost, strlen(pat) + strlen(host) + 1);
++      if (!res) {
++              if (editedhost) {
++                      free(editedhost);
++                      editedhost = 0;
++              }
++              fprintf(stderr, "edithost: Out of memory\n");
++              return;
++      }
++      editedhost = res;
++
+       while (*pat) {
+               switch (*pat) {
+@@ -420,18 +404,12 @@
+                       *res++ = *pat;
+                       break;
+               }
+-              if (res == &editedhost[sizeof editedhost - 1]) {
+-                      *res = '\0';
+-                      return;
+-              }
+               pat++;
+       }
+       if (*host)
+-              (void) strncpy(res, host,
+-                              sizeof editedhost - (res - editedhost) -1);
++              (void) strcpy(res, host);
+       else
+               *res = '\0';
+-      editedhost[sizeof editedhost - 1] = '\0';
+ }
+ static char *putlocation;
+@@ -475,7 +453,9 @@
+                       break;
+               case 'h':
+-                      putstr(editedhost);
++                      if (editedhost) {
++                              putstr(editedhost);
++                      }
+                       break;
+               case 'd':
+@@ -1118,11 +1098,6 @@
+       char xbuf[30];
+       while (cnt) {
+-              /* flush net output buffer if no room for new data) */
+-              if ((&netobuf[BUFSIZ] - nfrontp) < 80) {
+-                      netflush();
+-              }
+-
+               /* add a line of output */
+               netoprintf("%s: ", tag);
+               for (i = 0; i < 20 && cnt; i++) {
+@@ -1143,3 +1118,154 @@
+       } 
+ }
+ #endif /* DIAGNOSTICS */
++
++static struct buflist *
++addbuf(const char *buf, size_t len)
++{
++      struct buflist *bufl;
++
++      bufl = malloc(sizeof(struct buflist));
++      if (!bufl) {
++              return 0;
++      }
++      bufl->next = tail->next;
++      bufl->buf = malloc(len);
++      if (!bufl->buf) {
++              free(bufl);
++              return 0;
++      }
++      bufl->len = len;
++
++      tail = tail->next = bufl;
++      listlen++;
++
++      memcpy(bufl->buf, buf, len);
++      return bufl;
++}
++
++static ssize_t
++netwrite(void *cookie, const char *buf, size_t len)
++{
++      size_t ret;
++      const char *const end = buf + len;
++      int ltrailing = trailing;
++      int ldoclear = doclear;
++
++#define       wewant(p)       ((*p&0xff) == IAC) && \
++                              ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)
++
++      ret = 0;
++
++      if (ltrailing) {
++              const char *p;
++              size_t l;
++              size_t m = tail->len;
++
++              p = nextitem(tail->buf, tail->buf + tail->len, buf, end);
++              ltrailing = !p;
++              if (ltrailing) {
++                      p = end;
++              }
++
++              l = p - buf;
++              tail->len += l;
++              tail->buf = realloc(tail->buf, tail->len);
++              if (!tail->buf) {
++                      return -1;
++              }
++
++              memcpy(tail->buf + m, buf, l);
++              buf += l;
++              len -= l;
++              ret += l;
++              trailing = ltrailing;
++      }
++
++      if (ldoclear) {
++              struct buflist *lpprev;
++
++              skip = 0;
++              lpprev = &head;
++              for (;;) {
++                      struct buflist *lp;
++
++                      lp = lpprev->next;
++
++                      if (lp == &head) {
++                              tail = lpprev;
++                              break;
++                      }
++
++                      if (lp == tail && ltrailing) {
++                              break;
++                      }
++
++                      if (!wewant(lp->buf)) {
++                              lpprev->next = lp->next;
++                              listlen--;
++                              free(lp->buf);
++                              free(lp);
++                      } else {
++                              lpprev = lp;
++                      }
++              }
++      }
++
++      while (len) {
++              const char *p;
++              size_t l;
++
++              p = nextitem(buf, end, 0, 0);
++              ltrailing = !p;
++              if (ltrailing) {
++                      p = end;
++              } else if (ldoclear) {
++                      if (!wewant(buf)) {
++                              l = p - buf;
++                              goto cont;
++                      }
++              }
++
++              l = p - buf;
++              if (!addbuf(buf, l)) {
++                      return ret ? ret : -1;
++              }
++              trailing = ltrailing;
++
++cont:
++              buf += l;
++              len -= l;
++              ret += l;
++      }
++
++      netwritebuf();
++      return ret;
++}
++
++void
++netopen() {
++      static const cookie_io_functions_t funcs = {
++              read: 0, write: netwrite, seek: 0, close: 0
++      };
++
++      netfile = fopencookie(0, "w", funcs);
++}
++
++extern int not42;
++void
++sendurg(const char *buf, size_t len) {
++      if (!not42) {
++              fwrite(buf, 1, len, netfile);
++              return;
++      }
++
++      urg = addbuf(buf, len);
++}
++
++size_t
++netbuflen(int flush) {
++      if (flush) {
++              netflush();
++      }
++      return listlen != 1 ? listlen : tail->len - skip;
++}
+--- a/telnetlogin/telnetlogin.8
++++ b/telnetlogin/telnetlogin.8
+@@ -40,6 +40,7 @@
+ .Nm telnetlogin
+ .Op Fl h Ar host
+ .Op Fl p
++.Op Ar username
+ .Sh DESCRIPTION
+ .Nm telnetlogin
+ is a setuid wrapper that runs
+@@ -62,10 +63,8 @@
+ .Nm telnetd 8
+ normally provides them in.
+ .Nm telnetlogin
+-also only accepts the environment variables
++also does sanity checks on the environment variables
+ .Ev TERM , 
+-.Ev DISPLAY , 
+-.Ev POSIXLY_CORRECT ,
+ and
+ .Ev REMOTEHOST .
+ It also insists that the standard input, output, and error streams are
+@@ -83,7 +82,7 @@
+ .Nm telnetlogin
+ does not permit the
+ .Fl f
+-option to login, and does not permit passing a username, so will not
++option to login, so will not
+ work with telnetds that perform authentication via Kerberos or SSL.
+ .Pp
+ THIS IS PRESENTLY EXPERIMENTAL CODE; USE WITH CAUTION.
+--- a/telnetlogin/telnetlogin.c
++++ b/telnetlogin/telnetlogin.c
+@@ -51,20 +51,24 @@
+ #include <string.h>
+ #include <stdarg.h>
+ #include <stdio.h>
++#include <syslog.h>
+ #ifndef _PATH_LOGIN
+ #define _PATH_LOGIN "/bin/login"
+ #endif
++extern char **environ;
++
+ static const char *remhost = NULL;
++static void die(const char *, ...) __attribute__ ((noreturn));
++
+ static void die(const char *fmt, ...) {
+    va_list ap;
+-   fprintf(stderr, "telnetlogin: ");
++   openlog("telnetlogin", LOG_PID, LOG_AUTHPRIV);
+    va_start(ap, fmt);
+-   vfprintf(stderr, fmt, ap);
++   vsyslog(LOG_CRIT, fmt, ap);
+    va_end(ap);
+-   fprintf(stderr, "\n");
+    exit(1);
+ }
+@@ -86,41 +90,6 @@
+    return 0;
+ }
+-static int check_display(char *disp) {
+-   char *colon, *s;
+-   struct hostent *hp;
+-   int num;
+-
+-   colon = strchr(disp, ':');
+-   if (!colon) return -1;
+-   *colon = 0;  /* temporarily */
+-
+-   if (check_a_hostname(disp)) return -1;
+-
+-   hp = gethostbyname(disp);
+-   if (!hp) return -1;
+-
+-   *colon = ':';
+-   s = colon+1;
+-   while (*s && isdigit(*s)) s++;
+-   if (*s) {
+-      if (*s!='.') return -1;
+-      s++;
+-      while (*s && isdigit(*s)) s++;
+-   }
+-   if (*s) return -1;
+-
+-   num = atoi(colon+1);
+-   if (num<0 || num>99) return -1;
+-
+-   return 0;
+-}
+-
+-static int check_posixly_correct(char *val) {
+-   if (strlen(val)==0 || !strcmp(val, "1")) return 0;
+-   return -1;
+-}
+-
+ static int check_remotehost(char *val) {
+    if (check_a_hostname(val)) return -1;
+    if (remhost && strcmp(val, remhost)) return -1;
+@@ -132,8 +101,6 @@
+    int (*validator)(char *);
+ } legal_envs[] = {
+    { "TERM", check_term },
+-   { "DISPLAY", check_display },
+-   { "POSIXLY_CORRECT", check_posixly_correct },
+    { "REMOTEHOST", check_remotehost },
+    { NULL, NULL }
+ };
+@@ -166,10 +133,7 @@
+    static char argv0[] = "login";
+    int argn, i, j;
+    const char *rh = NULL;
+-   char **envs = __environ;
+-
+-   /* make as sure as possible no library routines or anything can use it */
+-   __environ = NULL;
++   char **envs = environ;
+    /* first, make sure our stdin/stdout/stderr are aimed somewhere */
+    i = open("/", O_RDONLY);
+@@ -194,6 +158,9 @@
+    if (argn < argc && !strcmp(argv[argn], "-p")) {
+       argn++;
+    }
++   if (argn < argc && argv[argn][0] != '-') {
++      argn++;
++   }
+    if (argn < argc) die("Illegal args: too many args");
+    argv[0] = argv0;
+@@ -201,21 +168,22 @@
+    if (envs) for (i=0; envs[i]; i++) {
+       char *testenv = envs[i];
+       size_t testlen = strlen(testenv);
+-      int ok = 0;
+-      for (j=0; legal_envs[j].name && !ok; j++) {
++      for (j=0; legal_envs[j].name; j++) {
+        const char *okenv = legal_envs[j].name;
+        size_t oklen = strlen(okenv);
++       int sign;
+        if (testlen < oklen) continue;
+        if (testenv[oklen]!='=') continue;
+-       if (memcmp(testenv, okenv, oklen)) continue;
++       if ((sign = memcmp(testenv, okenv, oklen)) < 0) {
++          continue;
++       } else if (sign > 0) {
++          break;
++       }
+        if (legal_envs[j].validator(testenv+oklen+1)) {
+           die("Invalid environment: bad value for %s", okenv);
+        }
+-       ok = 1;
+-      }
+-      if (!ok) {
+-       die("Illegal environment: forbidden variable");
++       break;
+       }
+    }
+@@ -234,6 +202,13 @@
+     * but, should we insist that ruid==nobody?
+     */
++#ifdef debian
++   /*
++    * Debian's /bin/login doesn't work properly unless we're really root.
++    */
++   setuid(0);
++#endif
++
+    /*
+     * don't do anything with limits, itimers, or process priority either
+     */
diff --git a/telnet/patches/020-from_18_to_24.diff b/telnet/patches/020-from_18_to_24.diff
new file mode 100644 (file)
index 0000000..4766e93
--- /dev/null
@@ -0,0 +1,609 @@
+Description: Incremental patches from 0.17-18 to 0.17-24.
+ A large set of mixed code patches on top of upstream's source.
+ It has been pruned to reproduce the step from source package
+ netkit-telnet_0.17-18 to netkit-telnet_0.17-24.
+ .
+ Support also Hurd.
+ [telnetd/sys_term.c, telnetd/ext.h]
+ .
+ Do not reset access mode and owner of TTY when client ends the session.
+ [telnetd/sys_term.c (cleanup)] 
+ .
+ Path of telnetlogin.
+ [telnetd/telnetd.8]
+ .
+ Adjust 8-bit mode to be without mandatory binary option.
+ A new command line switch `-7' is added to telnet.
+ [telnet/main.cc, telnet/telnet.cc, telnet/terminal.cc,
+ telnet/defines.h, telnet/externs.h]
+ .
+ Allow telnetrc files to specify a port in addition to host name.
+ [telnet/commands.cc, telnet/proto.h, telnet/telnet.1]
+ .
+ Disable 8-bit mode of client if parity bit is enabled.
+ [telnet/main.cc]
+ .
+ Remove obsolete compiler warnings, and disable trigraph warning.
+ Protect tokens ifter #endif.
+ [configure, telnet/terminal.cc]
+ .
+ Support option `-b' in client.
+ [telnet/commands.cc, telnet/main.cc, telnet/netlink.cc,
+ telnet/netlink.h, telnet/telnet.1]
+ .
+ Accept numeric telnet options.
+ [telnet/command.cc]
+ .
+ Buffer overflow due to $HOME, moved to a separate file.
+ .
+ Remote DOS hole, CAN-2004-0911, moved to a separate file.
+ .
+ Buffer overflow, CAN-2005-0469, moved to a separate file.
+
+Comment: interdiff netkit-telnet_0.17-{18woody3,29}.diff
+Author: Herbert Xu, Robert Millan
+Bug-Debian: http://bugs.debian.org/149325
+ http://bugs.debian.org/150812
+ http://bugs.debian.org/144921
+ http://bugs.debian.org/194736
+ http://bugs.debian.org/203544
+ http://bugs.debian.org/242018
+Forwarded: no
+Last-Update: 2015-01-27
+
+--- a/telnet/commands.cc
++++ b/telnet/commands.cc
+@@ -476,6 +476,7 @@
+ int send_tncmd(int (*func)(int, int), const char *cmd, const char *name) {
+     char **cpp;
+     extern char *telopts[];
++    long opt;
+     if (isprefix(name, "help") || isprefix(name, "?")) {
+       register int col, len;
+@@ -502,16 +503,23 @@
+                                       name, cmd);
+       return 0;
+     }
++
++    opt = cpp - telopts;
+     if (cpp == 0) {
+-      fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
++      char *end;
++
++      opt = strtol(name, &end, 10);
++      if (*end || opt < 0 || opt > 255) {
++          fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
+                                       name, cmd);
+-      return 0;
++          return 0;
++      }
+     }
+     if (!connected) {
+       printf("?Need to be connected first.\n");
+       return 0;
+     }
+-    (*func)(cpp - telopts, 1);
++    (*func)(opt, 1);
+     return 1;
+ }
+@@ -1615,7 +1623,7 @@
+     char *srp = NULL;
+     int srlen;
+     int family = 0;
+-    const char *cmd, *volatile user = 0;
++    const char *cmd, *volatile user = 0, *srchostp = 0;
+     const char *portp = NULL;
+     char *hostp = NULL;
+     char *resolv_hostp;
+@@ -1662,6 +1670,14 @@
+           --argc;
+           continue;
+       }
++      if (strcmp(*argv, "-b") == 0) {
++          --argc; ++argv;
++          if (argc == 0)
++              goto usage;
++          srchostp = *argv++;
++          --argc;
++          continue;
++      }
+       if (strcmp(*argv, "-a") == 0) {
+           --argc; ++argv;
+           autologin = 1;
+@@ -1744,6 +1760,20 @@
+     hints.ai_socktype = SOCK_STREAM;
+     hints.ai_flags = AI_NUMERICHOST;
+     hints.ai_family = family;
++
++    if (srchostp) {
++      res = getaddrinfo(srchostp, "0", &hints, &hostaddr);
++      if (res) {
++          fprintf(stderr, "telnet: could not resolve %s: %s\n", srchostp,
++                  gai_strerror(res));
++          return 0;
++      }
++      hints.ai_family = hostaddr->ai_family;
++      res = nlink.bind(hostaddr);
++      freeaddrinfo(hostaddr);
++      if (res < 0)
++          return 0;
++    }
+         
+     /* Resolve both the host and service simultaneously. */
+     res = getaddrinfo(resolv_hostp, portp, &hints, &hostaddr);
+@@ -1803,7 +1833,7 @@
+       strcpy(hostname, tmpaddr->ai_canonname);
+     }
+-    cmdrc(hostp, hostname);
++    cmdrc(hostp, hostname, portp);
+     freeaddrinfo(hostaddr);
+     if (autologin && user == NULL) {
+       struct passwd *pw;
+@@ -2050,15 +2080,21 @@
+     return 0;
+ }
+-static void readrc(const char *m1, const char *m2, const char *rcname) {
++static void readrc(const char *m1, const char *m2, const char *port,
++                 const char *rcname)
++{
+     FILE *rcfile;
+     int gotmachine = 0;
+     int l1 = strlen(m1);
+     int l2 = strlen(m2);
+-    char m1save[strlen(m1) + 1];
++    int lport = strlen(port);
++    char m1save[l1 + 1];
++    char portsave[lport + 1];
+     strcpy(m1save, m1);
+     m1 = m1save;
++    strcpy(portsave, port);
++    port = portsave;
+     rcfile = fopen(rcname, "r");
+     if (!rcfile) return;
+@@ -2083,6 +2119,13 @@
+               strncpy(line, &line[7], sizeof(line) - 7);
+           else
+               continue;
++
++          if (line[0] == ':') {
++              if (!strncasecmp(&line[1], port, lport))
++                  continue;
++              strncpy(line, &line[lport + 1], sizeof(line) - lport - 1);
++          }
++
+           if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
+               continue;
+           gotmachine = 1;
+@@ -2095,13 +2138,13 @@
+     fclose(rcfile);
+ }
+-void cmdrc(const char *m1, const char *m2) {
++void cmdrc(const char *m1, const char *m2, const char *port) {
+     static char *rcname = 0;
+     static char rcbuf[128];
+     if (skiprc) return;
+-    readrc(m1, m2, "/etc/telnetrc");
++    readrc(m1, m2, port, "/etc/telnetrc");
+     if (rcname == 0) {
+       rcname = getenv("HOME");
+       if (rcname)
+@@ -2111,7 +2154,7 @@
+       strcat(rcbuf, "/.telnetrc");
+       rcname = rcbuf;
+     }
+-    readrc(m1, m2, rcname);
++    readrc(m1, m2, port, rcname);
+ }
+ #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
+--- a/telnet/main.cc
++++ b/telnet/main.cc
+@@ -84,7 +84,7 @@
+     fprintf(stderr, "Usage: %s %s%s%s%s\n",
+           prompt,
+           "[-4] [-6] [-8] [-E] [-L] [-a] [-d] [-e char] [-l user]",
+-          "\n\t[-n tracefile]",
++          "\n\t[-n tracefile] [ -b addr ]",
+ #ifdef TN3270
+           "\n\t"
+           "[-noasynch] [-noasynctty] [-noasyncnet] [-r] [-t transcom]\n\t",
+@@ -106,7 +106,7 @@
+       extern char *optarg;
+       extern int optind;
+       int ch;
+-      char *user;
++      char *user, *srcaddr;
+       int family;
+       tninit();               /* Clear out things */
+@@ -115,19 +115,22 @@
+ #endif
+       TerminalSaveState();
++      if ((old_tc.c_cflag & (CSIZE|PARENB)) != CS8)
++              eight = 0;
+       if ((prompt = strrchr(argv[0], '/'))!=NULL)
+               ++prompt;
+       else
+               prompt = argv[0];
+-      user = NULL;
++      user = srcaddr = NULL;
+       family = 0;
+       rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
+       autologin = -1;
+-      while ((ch = getopt(argc, argv, "468EKLS:X:ade:k:l:n:rt:x")) != EOF) {
++      while ((ch = getopt(argc, argv,
++                          "4678EKLS:X:ab:de:k:l:n:rt:x")) != EOF) {
+               switch(ch) {
+               case '4':
+                       family = AF_INET;
+@@ -139,8 +142,11 @@
+                       fputs("IPv6 unsupported\n", stderr);
+ #endif
+                       break;
++              case '7':
++                      eight = 0;      /* 7-bit ouput and input */
++                      break;
+               case '8':
+-                      eight = 3;      /* binary output and input */
++                      binary = 3;     /* binary output and input */
+                       break;
+               case 'E':
+                       rlogin = escapechar = _POSIX_VDISABLE;
+@@ -149,7 +155,7 @@
+                       //autologin = 0;
+                       break;
+               case 'L':
+-                      eight |= 2;     /* binary output only */
++                      binary |= 2;    /* binary output only */
+                       break;
+               case 'S':
+                   {
+@@ -229,6 +235,9 @@
+                               "%s: -x ignored, no encryption support.\n",
+                               prompt);
+                       break;
++              case 'b':
++                      srcaddr = optarg;
++                      break;
+               case '?':
+               default:
+                       usage();
+@@ -252,6 +261,10 @@
+                       *argp++ = "-l";
+                       *argp++ = user;
+               }
++              if (srcaddr) {
++                      *argp++ = "-b";
++                      *argp++ = srcaddr;
++              }
+               if (family) {
+                       *argp++ = family == AF_INET ? "-4" : "-6";
+               }
+--- a/telnet/netlink.cc
++++ b/telnet/netlink.cc
+@@ -79,20 +79,56 @@
+       shutdown(net, 2);
+     }
+     ::close(net);
++    net = -1;
++}
++
++int netlink::bind(struct addrinfo *addr)
++{
++    int res;
++
++    res = socket(addr->ai_family);
++    if (res < 2) {
++      if (res == 1)
++          perror("telnet: socket");
++      return -1;
++    }
++
++    if (::bind(net, addr->ai_addr, addr->ai_addrlen) < 0) {
++      perror("telnet: bind");
++      return -1;
++    }
++
++    return 0;
++}
++
++int netlink::socket(int family)
++{
++    if (this->family != family)
++      close(0);
++
++    if (net < 0) {
++      this->family = family;
++      net = ::socket(family, SOCK_STREAM, 0);
++      if (net < 0) {
++          if (errno == EAFNOSUPPORT)
++              return 1;
++          perror("telnet: socket");
++          return 0;
++      }
++    }
++
++    return 2;
+ }
+ int netlink::connect(int debug, struct addrinfo *addr, 
+                    char *srcroute, int srlen, int tos) 
+ {
+     int on=1;
++    int res;
+-    net = socket(addr->ai_family, SOCK_STREAM, 0);
+-    if (net < 0) {
+-      if (errno == EAFNOSUPPORT)
+-          return 1;
+-      perror("telnet: socket");
+-      return 0;
+-    }
++    res = socket(addr->ai_family);
++    if (res < 2)
++      return res;
+ #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
+     if (srcroute) {
+--- a/telnet/netlink.h
++++ b/telnet/netlink.h
+@@ -1,11 +1,15 @@
+ class netlink {
++ private:
++    int family;
+  protected:
+     int net;
+  public:
+     netlink();
+     ~netlink();
++    int bind(struct addrinfo *hostaddr);
++    int socket(int family);
+     int connect(int debug, struct addrinfo *hostaddr, 
+               char *srcroute, int srlen,
+               int tos);
+--- a/telnet/telnet.1
++++ b/telnet/telnet.1
+@@ -44,6 +44,7 @@
+ .Nm telnet
+ .Op Fl 468ELadr
+ .Op Fl S Ar tos
++.Op Fl b Ar address
+ .Op Fl e Ar escapechar
+ .Op Fl l Ar user
+ .Op Fl n Ar tracefile
+@@ -93,6 +94,8 @@
+ option if supported by the remote system. The username is retrieved
+ via
+ .Xr getlogin 3 .
++.It Fl b Ar address
++Use bind(2) on the local socket to bind it to a specific local address.
+ .It Fl d
+ Sets the initial value of the
+ .Ic debug
+@@ -492,7 +495,15 @@
+ indented by whitespace; lines beginning without whitespace are
+ interpreted as hostnames.  Lines beginning with the special hostname
+ .Ql DEFAULT
+-will apply to all hosts.  Upon connecting to a particular host, the
++will apply to all hosts.  Hostnames including
++.Ql DEFAULT
++may be followed immediately by a colon and a port number or string.
++If a port is specified it must match exactly with what is specified
++on the command line.  If no port was specified on the command line,
++then the value
++.Ql telnet
++is used.
++Upon connecting to a particular host, the
+ commands associated with that host are executed.
+ .It Ic quit
+ Close any open session and exit
+--- a/telnet/telnet.cc
++++ b/telnet/telnet.cc
+@@ -88,7 +88,8 @@
+ char  will_wont_resp[256];
+ int
+-eight = 0,
++  eight = 3,
++  binary = 0,
+   autologin = 0,      /* Autologin anyone? */
+   skiprc = 0,
+   connected,
+@@ -1743,8 +1744,8 @@
+     send_do(TELOPT_STATUS, 1);
+     if (env_getvalue("DISPLAY", 0))
+       send_will(TELOPT_XDISPLOC, 1);
+-    if (eight)
+-      tel_enter_binary(eight);
++    if (binary)
++      tel_enter_binary(binary);
+   }
+ #endif /* !defined(TN3270) */
+   
+--- a/telnet/terminal.cc
++++ b/telnet/terminal.cc
+@@ -157,9 +157,11 @@
+     if (localflow)
+       mode |= MODE_FLOW;
+-    if (my_want_state_is_will(TELOPT_BINARY))
++    if ((eight & 1) || my_want_state_is_will(TELOPT_BINARY))
+       mode |= MODE_INBIN;
++    if (eight & 2)
++      mode |= MODE_OUT8;
+     if (his_want_state_is_will(TELOPT_BINARY))
+       mode |= MODE_OUTBIN;
+@@ -451,10 +453,13 @@
+               // breaks SunOS.
+               tmp_tc.c_iflag |= ISTRIP;
+       }
+-      if (f & MODE_OUTBIN) {
++      if (f & (MODE_OUTBIN|MODE_OUT8)) {
+               tmp_tc.c_cflag &= ~(CSIZE|PARENB);
+               tmp_tc.c_cflag |= CS8;
+-              tmp_tc.c_oflag &= ~OPOST;
++              if (f & MODE_OUTBIN)
++                      tmp_tc.c_oflag &= ~OPOST;
++              else
++                      tmp_tc.c_oflag |= OPOST;
+       } else {
+               tmp_tc.c_cflag &= ~(CSIZE|PARENB);
+               tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
+@@ -470,7 +475,7 @@
+ #ifdef        SIGINFO
+       signal(SIGINFO, ayt);
+-#endif        SIGINFO
++#endif        /* SIGINFO */
+ #if defined(NOKERNINFO)
+       tmp_tc.c_lflag |= NOKERNINFO;
+@@ -506,7 +511,7 @@
+ #ifdef        SIGINFO
+       signal(SIGINFO, ayt_status);
+-#endif        SIGINFO
++#endif        /* SIGINFO */
+ #ifdef        SIGTSTP
+       signal(SIGTSTP, SIG_DFL);
+--- a/telnetd/ext.h
++++ b/telnetd/ext.h
+@@ -88,7 +88,7 @@
+ #define netoprintf(fmt, ...) fprintf(netfile, fmt, ## __VA_ARGS__)
+ extern int pty, net;
+-extern char *line;
++extern const char *line;
+ extern int SYNCHing;          /* we are in TELNET SYNCH mode */
+ void _termstat(void);
+--- a/telnetd/sys_term.c
++++ b/telnetd/sys_term.c
+@@ -204,17 +204,17 @@
+  *
+  * Returns the file descriptor of the opened pty.
+  */
+-static char linedata[PATH_MAX];
+-char *line = linedata;
++const char *line;
+ static int ptyslavefd=-1;
+ int getpty(void) {
+     int masterfd;
+-    if (openpty(&masterfd, &ptyslavefd, line, NULL, NULL)) {
++    if (openpty(&masterfd, &ptyslavefd, NULL, NULL, NULL)) {
+       return -1;
+     }
++    line = ttyname(ptyslavefd);
+     return masterfd;
+ }
+@@ -720,25 +720,11 @@
+  * clean up anything that needs to be cleaned up.
+  */
+ void cleanup(int sig) {
+-    char *p;
++    const char *p;
+     (void)sig;
+     p = line + sizeof("/dev/") - 1;
+     if (logout(p)) logwtmp(p, "", "");
+-#ifdef PARANOID_TTYS
+-    /*
+-     * dholland 16-Aug-96 chmod the tty when not in use
+-     * This will make it harder to attach unwanted stuff to it
+-     * (which is a security risk) but will break some programs.
+-     */
+-    chmod(line, 0600);
+-#else
+-    chmod(line, 0666);
+-#endif
+-    chown(line, 0, 0);
+-    *p = 'p';
+-    chmod(line, 0666);
+-    chown(line, 0, 0);
+     shutdown(net, 2);
+     exit(0);
+ }
+--- a/telnetd/telnetd.8
++++ b/telnetd/telnetd.8
+@@ -161,7 +161,7 @@
+ .It Fl L Ar loginprg
+ This option may be used to specify a different login program.
+ By default, 
+-.Pa /usr/sbin/telnetlogin
++.Pa /usr/lib/telnetlogin
+ is used.
+ .It Fl n
+ Disable
+--- a/telnet/defines.h
++++ b/telnet/defines.h
+@@ -50,3 +50,5 @@
+ #define       MODE_COMMAND_LINE(m)    ((m)==-1)
+ #define       CONTROL(x)      ((x)&0x1f)              /* CTRL(x) is not portable */
++
++#define MODE_OUT8     0x8000                  /* binary mode sans -opost */
+--- a/telnet/proto.h
++++ b/telnet/proto.h
+@@ -13,7 +13,7 @@
+ void auth_encrypt_user(char *);
+ void auth_name(unsigned char *, int);
+ void auth_printsub(unsigned char *, int, unsigned char *, int);
+-void cmdrc(const char *m1, const char *m2);
++void cmdrc(const char *, const char *, const char *);
+ void env_init(void);
+ int getconnmode(void);
+ void init_network(void);
+--- a/telnet/externs.h
++++ b/telnet/externs.h
+@@ -48,9 +48,7 @@
+ typedef unsigned char cc_t;
+ #endif
+-#ifdef __linux__
+ #include <unistd.h>   /* get _POSIX_VDISABLE */
+-#endif
+ #ifndef       _POSIX_VDISABLE
+ #error "Please fix externs.h to define _POSIX_VDISABLE"
+@@ -60,7 +58,8 @@
+ extern int autologin;         /* Autologin enabled */
+ extern int skiprc;            /* Don't process the ~/.telnetrc file */
+-extern int eight;             /* use eight bit mode (binary in and/or out */
++extern int eight;             /* use eight bit mode (binary in and/or out) */
++extern int binary;            /* use binary option (in and/or out) */
+ extern int flushout;          /* flush output */
+ extern int connected;         /* Are we connected to the other side? */
+ extern int globalmode;                /* Mode tty should be in */
+@@ -225,6 +224,8 @@
+ //#if 0
+ extern struct termios new_tc;
++extern struct termios old_tc;
++
+ #define termEofChar           new_tc.c_cc[VEOF]
+ #define termEraseChar         new_tc.c_cc[VERASE]
diff --git a/telnet/patches/022-buffer_overflow_by_HOME.diff b/telnet/patches/022-buffer_overflow_by_HOME.diff
new file mode 100644 (file)
index 0000000..f9233c3
--- /dev/null
@@ -0,0 +1,42 @@
+Description: Fix buffer overflow when $HOME is large.
+ Very long values of $HOME will extend beyond fixed rcbuf[128].
+ In its stead, use dynamic allocation.
+
+Author: Josh Martin
+Bug-Debian: http://bugs.debian.org/264846
+Comment: Introduced in netkit-telnet_0.17-25.
+Forwarded: no
+Last-Update: 2004-08-13
+
+--- netkit-telnet-0.17.orig/telnet/commands.cc
++++ netkit-telnet-0.17/telnet/commands.cc
+@@ -2139,22 +2139,18 @@
+ }
+ void cmdrc(const char *m1, const char *m2, const char *port) {
+-    static char *rcname = 0;
+-    static char rcbuf[128];
++    char *rcname = NULL;
+     if (skiprc) return;
+     readrc(m1, m2, port, "/etc/telnetrc");
+-    if (rcname == 0) {
+-      rcname = getenv("HOME");
+-      if (rcname)
+-          strcpy(rcbuf, rcname);
+-      else
+-          rcbuf[0] = '\0';
+-      strcat(rcbuf, "/.telnetrc");
+-      rcname = rcbuf;
+-    }
++    if (asprintf (&rcname, "%s/.telnetrc", getenv ("HOME")) == -1)
++      {
++        perror ("asprintf");
++        return;
++      }
+     readrc(m1, m2, port, rcname);
++    free (rcname);
+ }
+ #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
diff --git a/telnet/patches/024-can_2004-0911.diff b/telnet/patches/024-can_2004-0911.diff
new file mode 100644 (file)
index 0000000..558e717
--- /dev/null
@@ -0,0 +1,40 @@
+Description: Fix remote DOS hole, CAN-2004-0911.
+ telnetd/utility.c (netwritebuf): Check that `listlen' is positive
+ before any action.  Otherwise do nothing, just return.
+ .
+ Patch made public in bug report.
+
+Author: Herbert Xu
+Bug-Debian: http://bugs.debian.org/273694
+Comment: Introduced in ntekit-telnet_0.17-26.
+Forwarded: no
+Last-Update: 2004-07-27
+
+Index: netkit-telnet-0.17/telnetd/utility.c
+===================================================================
+RCS file: /home/gondolin/herbert/src/CVS/debian/netkit-telnet/telnetd/utility.c,v
+retrieving revision 1.8
+diff -u -r1.8 utility.c
+--- netkit-telnet-0.17/telnetd/utility.c       18 Jan 2002 09:13:36 -0000      1.8
++++ netkit-telnet-0.17/telnetd/utility.c       25 Sep 2004 01:22:51 -0000
+@@ -246,6 +246,9 @@
+       size_t len;
+       int ltrailing = trailing;
++      if (!listlen)
++              return;
++
+       vector = malloc(listlen * sizeof(struct iovec));
+       if (!vector) {
+               return;
+@@ -323,9 +326,7 @@
+               /* out of memory? */
+               cleanup(0);
+       }
+-      if (listlen) {
+-              netwritebuf();
+-      }
++      netwritebuf();
+ }
diff --git a/telnet/patches/026-can_2005_0469.diff b/telnet/patches/026-can_2005_0469.diff
new file mode 100644 (file)
index 0000000..7c4c802
--- /dev/null
@@ -0,0 +1,37 @@
+Description: Buffer overflow in LINEMODE suboptions, CAN-2005-0469.
+ telnet/telnet.cc (slc_add_reply): Check that sufficiently space
+ still is available beyond `slc_replyp'.
+ .
+ Extracted by comparison of netkit-telnet_0.17-18woody3,
+ netkit-telnet_0.17-29, and netkit-telnet-ssl_0.17.24+0.1-7.1.
+
+Author: Martin 'Joey' Schultze.
+Comment: Introduced in netkit-telnet_0.17-28.
+Forwarded: no
+Last-Update: 2015-01-26
+
+--- netkit-telnet-0.17.orig/telnet/telnet.cc
++++ netkit-telnet-0.17/telnet/telnet.cc
+@@ -1051,6 +1051,7 @@
+ unsigned char slc_reply[128];
++unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)];
+ unsigned char *slc_replyp;
+ void slc_start_reply(void) {
+@@ -1062,6 +1063,14 @@
+ }
+ void slc_add_reply(int func, int flags, int value) {
++  /* A sequence of up to 6 bytes my be written for this member of the SLC
++   * suboption list by this function.  The end of negotiation command,
++   * which is written by slc_end_reply(), will require 2 additional
++   * bytes.  Do not proceed unless there is sufficient space for these
++   * items.
++   */
++  if (&slc_replyp[6+2] > slc_reply_eom)
++    return;
+   if ((*slc_replyp++ = func) == IAC)
+     *slc_replyp++ = IAC;
+   if ((*slc_replyp++ = flags) == IAC)
diff --git a/telnet/patches/030-reject_invalid_port.diff b/telnet/patches/030-reject_invalid_port.diff
new file mode 100644 (file)
index 0000000..e4ea902
--- /dev/null
@@ -0,0 +1,35 @@
+Description: Reject invalid port numbers.
+ Check that any port number is within the range of a short integer.
+Author: Justin Pryzby
+Bug-Debian: http://bugs.debian.org/300273
+Comment: interdiff netkit-telnet_0.17-{29.34}.diff
+Forwarded: no
+Last-Update: 2005-10-09
+
+diff -u netkit-telnet-0.17/telnet/commands.cc netkit-telnet-0.17/telnet/commands.cc
+--- netkit-telnet-0.17/telnet/commands.cc
++++ netkit-telnet-0.17/telnet/commands.cc
+@@ -1747,8 +1747,22 @@
+       if (*portp == '-') {
+           portp++;
+           telnetport = 1;
+-      } else
++      } else {
+           telnetport = 0;
++          if (*portp >='0' && *portp<='9') {
++             char *end;
++             long int p;
++
++             p=strtol(portp, &end, 10);
++             if (ERANGE==errno && (LONG_MIN==p || LONG_MAX==p)) {
++                fprintf(stderr, "telnet: port %s overflows\n", portp);
++                return 0;
++             } else if (p<=0 || p>=65536) {
++                fprintf(stderr, "telnet: port %s out of range\n", portp);
++                return 0;
++             }
++          }
++      }
+     }
+     else {
+       portp = "telnet";
diff --git a/telnet/patches/045-avoid_unsetting_term.diff b/telnet/patches/045-avoid_unsetting_term.diff
new file mode 100644 (file)
index 0000000..e003936
--- /dev/null
@@ -0,0 +1,20 @@
+Description: Avoid unsetting environment variable TERM.
+ Do not reset TERM to "UNKNOWN", when it is unknown in the local host.
+Author: Philippe Troin
+Bug-Debian: http://bugs.debian.org/237324
+Comment: interdiff netkit-telnet_0.17-{34,36}.diff
+Forwarded: no
+Last-Update: 2008-06-22
+
+diff -u netkit-telnet-0.17/telnet/telnet.cc netkit-telnet-0.17/telnet/telnet.cc
+--- netkit-telnet-0.17/telnet/telnet.cc
++++ netkit-telnet-0.17/telnet/telnet.cc
+@@ -640,7 +640,7 @@
+   if (resettermname) {
+     resettermname = 0;
+     tname = env_getvalue("TERM", 0);
+-    if (!tname || my_setupterm(tname, 1, &err)) {
++    if (!tname /* || my_setupterm(tname, 1, &err) */) {
+       termbuf[0] = 0;
+       tname = "UNKNOWN";
+     }
diff --git a/telnet/patches/100-format_security_error.diff b/telnet/patches/100-format_security_error.diff
new file mode 100644 (file)
index 0000000..2e57181
--- /dev/null
@@ -0,0 +1,53 @@
+Description: Format string is not a string literal.
+ Hardened builds are failing due to "-Werror=format-security".
+ Insertion of a trivial format string resolves the failure.
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Forwarded: no
+Last-Update: 2015-01-09
+
+--- netkit-telnet-0.17/telnetd/utility.c.orig  2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetd/utility.c       2015-01-09 23:11:41.695499612 +0100
+@@ -890,17 +890,17 @@
+                       case ENV_VAR:
+                           if (pointer[1] == TELQUAL_SEND)
+                               goto def_case;
+-                          netoprintf("\" VAR " + noquote);
++                          netoprintf("%s", "\" VAR " + noquote);
+                           noquote = 2;
+                           break;
+                       case ENV_VALUE:
+-                          netoprintf("\" VALUE " + noquote);
++                          netoprintf("%s", "\" VALUE " + noquote);
+                           noquote = 2;
+                           break;
+                       case ENV_ESC:
+-                          netoprintf("\" ESC " + noquote);
++                          netoprintf("%s", "\" ESC " + noquote);
+                           noquote = 2;
+                           break;
+--- netkit-telnet-0.17/telnet/utilities.cc.orig        2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnet/utilities.cc     2015-01-09 23:33:05.219513739 +0100
+@@ -583,17 +583,17 @@
+                       case ENV_VAR:
+                           if (pointer[1] == TELQUAL_SEND)
+                               goto def_case;
+-                          fprintf(NetTrace, "\" VAR " + noquote);
++                          fprintf(NetTrace, "%s", "\" VAR " + noquote);
+                           noquote = 2;
+                           break;
+                       case ENV_VALUE:
+-                          fprintf(NetTrace, "\" VALUE " + noquote);
++                          fprintf(NetTrace, "%s", "\" VALUE " + noquote);
+                           noquote = 2;
+                           break;
+                       case ENV_ESC:
+-                          fprintf(NetTrace, "\" ESC " + noquote);
++                          fprintf(NetTrace, "%s", "\" ESC " + noquote);
+                           noquote = 2;
+                           break;
diff --git a/telnet/patches/110-markup_errors.diff b/telnet/patches/110-markup_errors.diff
new file mode 100644 (file)
index 0000000..8509eee
--- /dev/null
@@ -0,0 +1,69 @@
+Description: Nit picking on troff macros.
+ Annoying misprints which Lintian complains on.
+ .
+ A minor inconsistency bug, misnaming the original escape character.
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Bug-Debian: http://bugs.debian.org/676258
+Forwarded: no
+Last-Update: 2015-01-10
+
+--- netkit-telnet-0.17/telnet/telnet.1.orig    2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnet/telnet.1 2015-01-10 01:35:37.775594668 +0100
+@@ -711,7 +711,7 @@
+ .It Ic escape
+ This is the
+ .Nm telnet
+-escape character (initially \*(Lq^[\*(Rq) which causes entry
++escape character (initially \*(Lq^]\*(Rq) which causes entry
+ into
+ .Nm telnet
+ command mode (when connected to a remote system).
+@@ -1167,10 +1167,12 @@
+ is sent as
+ .Ic abort  ,
+ and
+-.Ic eof and
+-.B suspend
++.Ic eof
++and
++.Ic suspend
+ are sent as
+-.Ic eof and
++.Ic eof
++and
+ .Ic susp ,
+ see
+ .Ic send
+--- netkit-telnet-0.17/telnetd/issue.net.5.orig        2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetd/issue.net.5     2015-01-10 01:01:20.827572027 +0100
+@@ -22,7 +22,7 @@
+ - show the current tty
+ .It %h
+ - show the system node name (FQDN)
+-.It %D
++.It \&%D
+ - show the name of the NIS domain
+ .It %d
+ - show the current time and date
+--- netkit-telnet-0.17/telnetd/telnetd.8.orig  2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetd/telnetd.8       2015-01-10 00:30:52.891551907 +0100
+@@ -261,7 +261,7 @@
+ .Ed
+ .Pp
+ The pseudo-terminal allocated to the client is configured
+-to operate in \*(lqcooked\*(rq mode, and with 
++to operate in \*(Lqcooked\*(Rq mode, and with 
+ .Dv XTABS
+ .Dv CRMOD
+ enabled (see
+--- netkit-telnet-0.17/telnetlogin/telnetlogin.8.orig  2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetlogin/telnetlogin.8       2015-01-10 01:18:25.835583309 +0100
+@@ -60,7 +60,7 @@
+ accepts only the subset of options to
+ .Xr login 1
+ shown above, in the order listed. This is the order 
+-.Nm telnetd 8
++.Xr telnetd 8
+ normally provides them in.
+ .Nm telnetlogin
+ also does sanity checks on the environment variables
diff --git a/telnet/patches/120-some_protocol_refinement.diff b/telnet/patches/120-some_protocol_refinement.diff
new file mode 100644 (file)
index 0000000..752e632
--- /dev/null
@@ -0,0 +1,351 @@
+Description: Selected protocol refinement.
+ Let the manual pages express NEW-ENVIRON as the only
+ supported environment mechanism.
+ .
+ Let the diagnostic printout correctly identify the observed
+ modi of local flow control.
+ .
+ Let the server in debug mode correctly decode only the suboption
+ part of a status response, by ignoring the initial `IAC SB'.
+ .
+ Let the server and client decode suboptions containing also ENV_USERVAR
+ in addition to the already known ENV_VAR.
+ .
+ Make the command `status' be as verbose as in other clients.
+ .
+ Several calls to printsub() were missing in `telnet.cc', thus failing
+ to display options that the client sends to the server.  Instead only
+ the received responses were display in some few negotiations, namely
+ TELOPT_TTYPE, TELOPT_TSPEED, TELOPT_XDISPLOC and TELOPT_LINEMODE
+
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Forwarded: no
+Last-Update: 2015-03-09
+
+--- netkit-telnet-0.17/telnet/telnet.1.orig    2015-01-10 01:35:37.775594668 +0100
++++ netkit-telnet-0.17/telnet/telnet.1 2015-01-13 22:22:47.371626252 +0100
+@@ -90,7 +90,7 @@
+ .Ev USER
+ variable
+ of the
+-.Ev ENVIRON
++.Ev NEW-ENVIRON
+ option if supported by the remote system. The username is retrieved
+ via
+ .Xr getlogin 3 .
+@@ -131,7 +131,7 @@
+ sending the specified name as the 
+ .Dv USER
+ environment variable, so it requires that the remote system support the
+-.Ev TELNET ENVIRON
++.Ev TELNET NEW-ENVIRON
+ option. This option implies the
+ .Fl a
+ option, and may also be used with the
+@@ -327,7 +327,7 @@
+ command is used to propagate environment variables across the 
+ .Nm telnet
+ link using the
+-.Dv TELNET ENVIRON
++.Dv TELNET NEW-ENVIRON
+ protocol option.
+ All variables exported from the shell are defined, but only the 
+ .Ev DISPLAY
+@@ -1044,7 +1044,7 @@
+ attempts to use it to perform automatic authentication.  If the
+ .Dv TELNET AUTHENTICATION
+ option is not supported, the user's login name is propagated using the
+-.Dv TELNET ENVIRON
++.Dv TELNET NEW-ENVIRON
+ option.
+ Setting this flag is the same as specifying the
+ .Ar a
+@@ -1255,7 +1255,7 @@
+ environment variables.
+ Other environment variables may be propagated
+ to the other side via the
+-.Dv TELNET ENVIRON
++.Dv TELNET NEW-ENVIRON
+ option.
+ .Sh FILES
+ .Bl -tag -width /etc/telnetrc -compact
+--- netkit-telnet-0.17/telnetd/telnetd.8.orig  2015-01-10 00:30:52.891551907 +0100
++++ netkit-telnet-0.17/telnetd/telnetd.8       2015-01-13 23:06:04.039624516 +0100
+@@ -250,7 +250,6 @@
+ DO TSPEED
+ DO XDISPLOC
+ DO NEW-ENVIRON
+-DO ENVIRON
+ WILL SUPPRESS GO AHEAD
+ DO ECHO
+ DO LINEMODE
+@@ -372,9 +371,6 @@
+ .It "DO NEW-ENVIRON"
+ Indicates a desire to be able to request environment
+ variable information, as described in RFC 1572.
+-.It "DO ENVIRON"
+-Indicates a desire to be able to request environment
+-variable information, as described in RFC 1408.
+ .It "DO LINEMODE"
+ Only sent if
+ .Nm telnetd
+--- netkit-telnet-0.17/telnet/utilities.cc.orig        2015-01-09 23:33:05.219513739 +0100
++++ netkit-telnet-0.17/telnet/utilities.cc     2015-03-09 15:07:32.965473513 +0100
+@@ -335,10 +335,14 @@
+               break;
+           }
+           switch (pointer[1]) {
+-          case 0:
++          case LFLOW_OFF:
+               fprintf(NetTrace, " OFF"); break;
+-          case 1:
++          case LFLOW_ON:
+               fprintf(NetTrace, " ON"); break;
++          case LFLOW_RESTART_ANY:
++              fprintf(NetTrace, " RESTART-ANY"); break;
++          case LFLOW_RESTART_XON:
++              fprintf(NetTrace, " RESTART-XON"); break;
+           default:
+               fprintf(NetTrace, " %d (unknown)", pointer[1]);
+           }
+@@ -454,7 +458,7 @@
+                       pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
+                       pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
+                       pointer[2]&MODE_ACK ? "|ACK" : "");
+-                  fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
++                  fprintf(NetTrace, "%s", tbuf[0] ? &tbuf[1] : "0");
+               }
+               if (pointer[2]&~(MODE_MASK))
+                   fprintf(NetTrace, " (0x%x)", pointer[2]);
+@@ -580,10 +584,14 @@
+                   register int noquote = 2;
+                   for (i = 2; i < length; i++ ) {
+                       switch (pointer[i]) {
++                      case ENV_USERVAR:
+                       case ENV_VAR:
+                           if (pointer[1] == TELQUAL_SEND)
+                               goto def_case;
+-                          fprintf(NetTrace, "%s", "\" VAR " + noquote);
++                          if (pointer[i] == ENV_VAR)
++                              fprintf(NetTrace, "%s", "\" VAR " + noquote);
++                          else
++                              fprintf(NetTrace, "%s", "\" USERVAR " + noquote);
+                           noquote = 2;
+                           break;
+@@ -624,7 +632,7 @@
+           if (TELOPT_OK(pointer[0]))
+               fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
+           else
+-              fprintf(NetTrace, "%d (unknown)", pointer[i]);
++              fprintf(NetTrace, "%d (unknown)", pointer[0]);
+           for (i = 1; i < length; i++)
+               fprintf(NetTrace, " %d", pointer[i]);
+           break;
+--- netkit-telnet-0.17/telnetd/utility.c.orig  2015-01-09 23:11:41.695499612 +0100
++++ netkit-telnet-0.17/telnetd/utility.c       2015-01-14 18:03:48.552691379 +0100
+@@ -643,10 +643,14 @@
+               break;
+           }
+           switch (pointer[1]) {
+-          case 0:
++          case LFLOW_OFF:
+               netoprintf(" OFF"); break;
+-          case 1:
++          case LFLOW_ON:
+               netoprintf(" ON"); break;
++          case LFLOW_RESTART_ANY:
++              netoprintf(" RESTART-ANY"); break;
++          case LFLOW_RESTART_XON:
++              netoprintf(" RESTART-XON"); break;
+           default:
+               netoprintf(" %d (unknown)", pointer[1]);
+           }
+@@ -792,15 +796,6 @@
+           netoprintf("STATUS");
+           switch (pointer[1]) {
+-          default:
+-              if (pointer[1] == TELQUAL_SEND)
+-                  netoprintf(" SEND");
+-              else
+-                  netoprintf(" %d (unknown)", pointer[1]);
+-              for (i = 2; i < length; i++) {
+-                  netoprintf(" ?%d?", pointer[i]);
+-              }
+-              break;
+           case TELQUAL_IS:
+               netoprintf(" IS\r\n");
+@@ -852,6 +847,15 @@
+                   }
+               }
+               break;
++          default:
++              if (pointer[1] == TELQUAL_SEND)
++                  netoprintf(" SEND");
++              else
++                  netoprintf(" %d (unknown)", pointer[1]);
++              for (i = 2; i < length; i++) {
++                  netoprintf(" ?%d?", pointer[i]);
++              }
++              break;
+           }
+           break;
+         }
+@@ -887,10 +891,14 @@
+                   register int noquote = 2;
+                   for (i = 2; i < length; i++ ) {
+                       switch (pointer[i]) {
++                      case ENV_USERVAR:
+                       case ENV_VAR:
+                           if (pointer[1] == TELQUAL_SEND)
+                               goto def_case;
+-                          netoprintf("%s", "\" VAR " + noquote);
++                          if (pointer[i] == ENV_VAR)
++                              netoprintf("%s", "\" VAR " + noquote);
++                          else
++                              netoprintf("%s", "\" USERVAR " + noquote);
+                           noquote = 2;
+                           break;
+@@ -1080,7 +1088,7 @@
+           if (TELOPT_OK(pointer[0]))
+               netoprintf("%s (unknown)", TELOPT(pointer[0]));
+           else
+-              netoprintf("%d (unknown)", pointer[i]);
++              netoprintf("%d (unknown)", pointer[0]);
+           for (i = 1; i < length; i++) {
+               netoprintf(" %d", pointer[i]);
+           }
+--- netkit-telnet-0.17/telnet/commands.cc.orig 2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnet/commands.cc      2015-01-21 23:20:17.488735411 +0100
+@@ -1605,7 +1605,7 @@
+ }
+ static int status(void) {
+-    int notmuch = 1;
++    int notmuch = 0;
+     return dostatus(notmuch);
+ }
+--- netkit-telnet-0.17/telnet/telnet.cc.orig   2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnet/telnet.cc        2015-01-22 14:34:01.402828217 +0100
+@@ -684,6 +684,15 @@
+       name = gettermname();
+       netoring.xprintf("%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE,
+                     TELQUAL_IS, name, IAC, SE);
++      {
++      unsigned char tbuf[7 + 20];     /* 20 chars for terminal name.  */
++      int len;
++
++      len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%s%c%c",
++                     IAC, SB, TELOPT_TTYPE, TELQUAL_IS, name, IAC, SE);
++      if (len > 6 && len < sizeof(tbuf))
++        printsub('>', &tbuf[2], len - 2);
++      }
+     }
+     break;
+   case TELOPT_TSPEED:
+@@ -696,6 +705,16 @@
+       TerminalSpeeds(&iispeed, &oospeed);
+       netoring.xprintf("%c%c%c%c%ld,%ld%c%c", IAC, SB, TELOPT_TSPEED, 
+                     TELQUAL_IS, oospeed, iispeed, IAC, SE);
++      {
++      unsigned char tbuf[8 + 20];     /* 20 characters for two speeds.  */
++      int len;
++
++      len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%ld,%ld%c%c",
++                     IAC, SB, TELOPT_TSPEED, TELQUAL_IS,
++                     oospeed, iispeed, IAC, SE);
++      if (len > 7 && len < sizeof(tbuf))
++        printsub('>', &tbuf[2], len - 2);
++      }
+     }
+     break;
+   case TELOPT_LFLOW:
+@@ -783,6 +802,15 @@
+       }
+       netoring.xprintf("%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC,
+                     TELQUAL_IS, dp, IAC, SE);
++      {
++      unsigned char tbuf[7 + 30];     /* 30 chars for display name.  */
++      int len;
++
++      len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%s%c%c",
++                     IAC, SB, TELOPT_XDISPLOC, TELQUAL_IS, dp, IAC, SE);
++      if (len > 6 && len < sizeof(tbuf))
++        printsub('>', &tbuf[2], len - 2);
++      }
+     }
+     break;
+     
+@@ -801,6 +829,14 @@
+   
+   netoring.xprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, 
+                 DONT, cmd[0], IAC, SE);
++  {
++    unsigned char tbuf[8];
++    int len;
++
++    len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%c%c%c",
++                 IAC, SB, TELOPT_LINEMODE, DONT, cmd[0], IAC, SE);
++    printsub('>', &tbuf[2], len - 2);
++  }
+ }
+ void lm_wont(unsigned char * /*cmd*/, int len) {
+@@ -818,6 +854,14 @@
+   }
+   netoring.xprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, 
+                 WONT, cmd[0], IAC, SE);
++  {
++    unsigned char tbuf[8];
++    int len;
++
++    len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%c%c%c",
++                 IAC, SB, TELOPT_LINEMODE, WONT, cmd[0], IAC, SE);
++    printsub('>', &tbuf[2], len - 2);
++  }
+ }
+ void lm_dont(unsigned char * /*cmd*/, int len) {
+@@ -841,6 +885,14 @@
+   
+   netoring.xprintf("%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_MODE,
+                 k, IAC, SE);
++  {
++    unsigned char tbuf[8];
++    int len;
++
++    len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%c%c%c",
++                 IAC, SB, TELOPT_LINEMODE, LM_MODE, k, IAC, SE);
++    printsub('>', &tbuf[2], len - 2);
++  }
+   
+   setconnmode(0);     /* set changed mode */
+ }
+@@ -933,14 +985,23 @@
+ }
+ void slc_import(int def) {
++  unsigned char cmd, tbuf[10];
++  int len;
++
+   if (def) {
++    cmd = SLC_DEFAULT;
+     netoring.xprintf("%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE,
+                   LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE);
+   }
+   else {
++    cmd = SLC_VARIABLE;
+     netoring.xprintf("%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_LINEMODE,
+                   LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE);
+   }
++
++  len = snprintf((char *) tbuf, sizeof(tbuf), "%c%c%c%c%c%c%c%c%c",
++               IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, cmd, 0, IAC, SE);
++  printsub('>', &tbuf[2], len - 2);
+ }
+ void slc_export(void) {
diff --git a/telnet/patches/124-support_uservar.diff b/telnet/patches/124-support_uservar.diff
new file mode 100644 (file)
index 0000000..a4f919e
--- /dev/null
@@ -0,0 +1,170 @@
+Description: Support user variables in environment.
+ Include conditionally protected code, allowing the server to accept
+ variables from the client marked as user defined, i.e., ENV_USERVAR,
+ into the environment.  The code is made active by the compiler macro
+ ACCEPT_USERVAR.  This would let clients from Solaris and FreeBSD set
+ variables exported by the user.
+ [telnetd/state.c (suboption)]
+ .
+ Fix incorrect offset while diagnostically printing suboptions.
+ [telnetd/state.c (send_status)]
+ .
+ Add LANG and LC_* to the list of acceptable environment variables.
+ [telnetd/state.c (envvarok)]
+ .
+ Let the client executable announce most environment variables as user
+ defined, i.e., as ENV_USERVAR.  A new function wellknown_var() checks
+ whether a proposed variable name is known well enough to be kept as
+ ENV_VAR, thus nominally undergo more scrutiny at the server's end.
+ These addition are also conditioned by the macro ACCEPT_USERVAR:
+ [telnet/telnet.cc (env_opt_add)]
+
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Bug-Debian: http://bugs.debian.org/237268
+Forwarded: no
+Last-Update: 2015-03-09
+
+--- netkit-telnet-0.17/telnetd/state.c.orig    2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetd/state.c 2015-03-07 13:53:41.241039630 +0100
+@@ -1157,7 +1157,7 @@
+     }  /* end of case TELOPT_XDISPLOC */
+     case TELOPT_ENVIRON: {
+-      register int c;
++      register int c, is_uservar = 0;
+       register char *cp, *varp, *valp;
+       if (SB_EOF())
+@@ -1168,12 +1168,17 @@
+       else if (c != TELQUAL_INFO)
+               return;
+-      while (!SB_EOF() && SB_GET() != ENV_VAR)
+-              ;
++      while (!SB_EOF()) {
++          c = SB_GET();
++          if (c == ENV_VAR || c == ENV_USERVAR)
++              break;
++      }
+       if (SB_EOF())
+               return;
++      is_uservar = (c == ENV_USERVAR) ? 1 : 0;
++
+       cp = varp = (char *)subpointer;
+       valp = 0;
+@@ -1184,14 +1189,20 @@
+               cp = valp = (char *)subpointer;
+               break;
+               
++          case ENV_USERVAR:
+           case ENV_VAR:
+               *cp = '\0';
+-              if (envvarok(varp)) {
++              if (envvarok(varp)
++#ifdef ACCEPT_USERVAR
++                  || is_uservar
++#endif
++                 ) {
+                   if (valp)
+                       (void)setenv(varp, valp, 1);
+                   else
+                       unsetenv(varp);
+               }
++              is_uservar = (c == ENV_USERVAR) ? 1 : 0;
+               cp = varp = (char *)subpointer;
+               valp = 0;
+               break;
+@@ -1208,7 +1219,11 @@
+           }
+       }
+       *cp = '\0';
+-      if (envvarok(varp)) {
++      if (envvarok(varp)
++#ifdef ACCEPT_USERVAR
++          || is_uservar
++#endif
++         ) {
+           if (valp)
+               (void)setenv(varp, valp, 1);
+           else
+@@ -1367,7 +1382,7 @@
+     writenet(statusbuf, ncp - statusbuf);
+     netflush();       /* Send it on its way */
+-    DIAG(TD_OPTIONS, {printsub('>', statusbuf, ncp - statusbuf); netflush();});
++    DIAG(TD_OPTIONS, {printsub('>', statusbuf + 2, ncp - statusbuf - 2); netflush();});
+ }
+ /* check that variable is safe to pass to login or shell */
+@@ -1399,6 +1414,8 @@ static int envvarok(char *varp) {
+     if (!strcmp(varp, "USER")) return 1;
+     if (!strcmp(varp, "LOGNAME")) return 1;
+     if (!strcmp(varp, "POSIXLY_CORRECT")) return 1;
++    if (!strcmp(varp, "LANG")) return 1;
++    if (!strncmp(varp, "LC_", 3)) return 1;
+     /* optionally syslog(LOG_INFO) here */
+     return 0;
+--- netkit-telnet-0.17/telnet/telnet.cc.orig   2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnet/telnet.cc        2015-03-09 14:35:22.513396375 +0100
+@@ -1213,6 +1213,40 @@ void env_opt(unsigned char *buf, int len
+   }
+ }
++#ifdef ACCEPT_USERVAR
++namespace {
++  const struct stems {
++    const char *stem; /* Initial part, or a full name. */
++    const int len;    /* Naught indicates a full name. */
++  } wellknown_stems[] = {
++    { "ACCT", 0 },
++    { "DISPLAY", 0 },
++    { "JOB",  0 },
++    { "LANG", 0 },
++    { "LC_",  3 },
++    { "LOGNAME", 0 },
++    { "POSIXLY_CORRECT", 0 },
++    { "PRINTER", 0 },
++    { "SSH_", 4 },
++    { "SYSTEMTYPE", 0 },
++    { "TERM", 0 },
++    { "USER", 0 },
++    { "XAUTHORITY", 0 },
++    { NULL,   0 }
++  };
++
++  int wellknown_var(const char *name) {
++    const stems *stem;
++      for (stem = wellknown_stems; stem->stem != NULL; stem++)
++      if ((stem->len ? strncmp(name, stem->stem, stem->len)
++                      : strcmp(name, stem->stem)) == 0)
++        return 1;
++
++    return 0;
++  }
++} /* Anonymous namespace */
++#endif /* ACCEPT_USERVAR */
++
+ /* OPT_REPLY_SIZE must be a multiple of 2. */
+ #define       OPT_REPLY_SIZE  256
+ unsigned char *opt_reply;
+@@ -1273,7 +1307,16 @@ void env_opt_add(const char *ep) {
+       opt_replyp = opt_reply + len - (opt_replyend - opt_replyp);
+       opt_replyend = opt_reply + len;
+     }
++
++#ifdef ACCEPT_USERVAR
++  if (wellknown_var(ep))
++    *opt_replyp++ = ENV_VAR;
++  else
++    *opt_replyp++ = ENV_USERVAR;
++#else /* !ACCEPT_USERVAR */
+   *opt_replyp++ = ENV_VAR;
++#endif
++
+   for (;;) {
+     while ((c = *ep++)!=0) {
+       switch(c) {
diff --git a/telnet/patches/130-drain_input_from_child.diff b/telnet/patches/130-drain_input_from_child.diff
new file mode 100644 (file)
index 0000000..e756096
--- /dev/null
@@ -0,0 +1,135 @@
+Description: Drain input stream from child process.
+ When the server process receives SIGCHILD, there might
+ well be data pending in the PTY buffer, intended for
+ the client waiting eagerly at the network link.
+ .
+ Replace the old signal handler for SIGCHILD with a simpler
+ version that sets a semaphor.  That semaphor is then sampled
+ at a suitable time during the I/O main loop, and execution
+ is transferred to the old handler after flushing the queue.
+ .
+ In the original signal handler, call waitpid() in order to
+ remove the child process from the kernel's process list.
+ .
+ Make some small adjustment to debugging output.
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Bug-Debian: http://bugs.debian.org/607415
+Forwarded: no
+Last-Update: 2015-01-20
+
+--- netkit-telnet-0.17/telnetd/sys_term.c.orig 2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetd/sys_term.c      2015-03-07 15:44:01.185237034 +0100
+@@ -39,6 +39,8 @@
+ #include <utmp.h>
++#include <sys/wait.h>
++
+ #include "telnetd.h"
+ #include "pathnames.h"
+@@ -720,11 +722,16 @@
+  * clean up anything that needs to be cleaned up.
+  */
+ void cleanup(int sig) {
++    int stat = 0;
+     const char *p;
+-    (void)sig;
++
++    if (sig == SIGCHLD) {
++      if (waitpid(-1, &stat, WNOHANG) > 0)
++          stat = WEXITSTATUS(stat);
++    }
+     p = line + sizeof("/dev/") - 1;
+     if (logout(p)) logwtmp(p, "", "");
+     shutdown(net, 2);
+-    exit(0);
++    exit(stat);
+ }
+--- netkit-telnet-0.17/telnetd/telnetd.c.orig  2015-01-09 20:22:23.000000000 +0100
++++ netkit-telnet-0.17/telnetd/telnetd.c       2015-01-20 13:59:40.625777998 +0100
+@@ -92,9 +92,17 @@
+ char *loginprg = _PATH_LOGIN;
+ #endif
++static int got_sigchld = 0;
++
+ extern void usage(void);
+ static void
++catch_sigchld(int sig)
++{
++      got_sigchld = 1;
++}
++
++static void
+ wait_for_connection(const char *service)
+ {
+       struct addrinfo hints;
+@@ -870,9 +878,9 @@
+      */
+     signal(SIGTTOU, SIG_IGN);
+ #endif
+-    
+-    signal(SIGCHLD, cleanup);
+-    
++
++    signal(SIGCHLD, catch_sigchld);
++
+ #ifdef TIOCNOTTY
+     {
+       register int t;
+@@ -1091,6 +1099,11 @@
+                                  ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0,
+                                  IAC, SE);
+               }
++
++              DIAG((TD_REPORT | TD_PTYDATA),
++                   netoprintf("td: ptyread %d chars\r\n", pcc););
++              DIAG(TD_PTYDATA, printdata("pd", ptyibuf, pcc));
++
+               pcc--;
+               ptyip = ptyibuf+1;
+           }
+@@ -1116,6 +1129,11 @@
+           telrcv();
+       if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
+           ptyflush();
++
++      if (got_sigchld) {
++          netflush();
++          cleanup(SIGCHLD);   /* Not returning.  */
++      }
+     }
+     cleanup(0);
+ }  /* end of telnet */
+--- netkit-telnet-0.17/telnetd/utility.c.orig  2015-01-14 18:03:48.552691379 +0100
++++ netkit-telnet-0.17/telnetd/utility.c       2015-01-19 16:06:55.783013012 +0100
+@@ -1110,7 +1110,7 @@
+               /* add a line of output */
+               netoprintf("%s: ", tag);
+               for (i = 0; i < 20 && cnt; i++) {
+-                      netoprintf("%02x", *ptr);
++                      netoprintf("%02x", (unsigned char) *ptr);
+                       if (isprint(*ptr)) {
+                               xbuf[i] = *ptr;
+                       } else {
+--- netkit-telnet-0.17/telnetd/telnetd.8.orig  2015-01-13 23:06:04.039624516 +0100
++++ netkit-telnet-0.17/telnetd/telnetd.8       2015-01-20 14:35:13.973804769 +0100
+@@ -124,12 +124,13 @@
+ program.
+ .El
+ .It Fl D Ar debugmode
+-This option may be used for debugging purposes.  This allows
++This option may be used for debugging purposes.  It allows
+ .Nm telnetd
+ to print out debugging information to the connection, allowing the
+ user to see what
+ .Nm telnetd
+-is doing.  There are several possible values for
++is doing.  Repeated use of the option arranges composite debug reports.
++There are several possible values for
+ .Ar debugmode:
+ .Bl -tag -width exercise
+ .It Cm options
diff --git a/telnet/patches/140-telnetlogin_name_check.diff b/telnet/patches/140-telnetlogin_name_check.diff
new file mode 100644 (file)
index 0000000..945a4c1
--- /dev/null
@@ -0,0 +1,19 @@
+Description: Logical error in host name check.
+ Mutually exclusive conditions were juxtaposed with logical AND,
+ resulting in a test never being effective.
+Author: Ian Beckwith <ianb@debian.org>
+Comment: Incorporated from netkit-telnet-ssl.
+Forwarded: no
+Last Update: 2015-01-30
+
+--- netkit-telnet-0.17.orig/telnetlogin/telnetlogin.c
++++ netkit-telnet-0.17/telnetlogin/telnetlogin.c
+@@ -76,7 +76,7 @@
+    int i=0;
+    /* should we check length? */
+    for (i=0; hname[i]; i++) {
+-      if (hname[i]<=32 && hname[i]>126) return -1;
++      if ((hname[i]<=32) || (hname[i]>126)) return -1;
+    }
+    return 0;
+ }
diff --git a/telnet/patches/142-numeric_hosts.diff b/telnet/patches/142-numeric_hosts.diff
new file mode 100644 (file)
index 0000000..4529939
--- /dev/null
@@ -0,0 +1,76 @@
+Description: Resolve remote host as numeric host identifier.
+ Implement a new switch '-N' in the server, avoiding reverse DNS
+ resolution and instead registering a numeric host representation.
+ The environment variable REMOTEHOST is set to this numeric address.
+ .
+ The change could be of benefit in PAM rules for access control as well
+ as for accounting and tracing of network activity.  In addition, the use
+ of '-N' mitigates cases when a hostile third party might have gained
+ control of reverse DNS resolution and is trying to inject fake answers.
+
+Author: Dean Gaudet
+Bug-Debian: http://bugs.debian.org/258371
+Comment: The patch was first applied to netkit-telnet-ssl.
+Last-Update: 2004-12-05
+
+--- netkit-telnet-0.17/telnetd/telnetd.c.orig
++++ netkit-telnet-0.17/telnetd/telnetd.c
+@@ -86,6 +86,7 @@ int  hostinfo = 1;                   /* do we print login
+ int debug = 0;
+ int keepalive = 1;
++int numeric_hosts = 0;
+ #ifdef LOGIN_WRAPPER
+ char *loginprg = LOGIN_WRAPPER;
+ #else
+@@ -220,7 +221,7 @@ main(int argc, char *argv[], char *env[]
+       pfrontp = pbackp = ptyobuf;
+       netip = netibuf;
+-      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:lhnNr:I:D:B:sS:a:X:L:")) != EOF) {
+               switch(ch) {
+ #ifdef        AUTHENTICATE
+@@ -319,6 +320,10 @@ main(int argc, char *argv[], char *env[]
+                       keepalive = 0;
+                       break;
++              case 'N':
++                      numeric_hosts = 1;
++                      break;
++
+ #ifdef        SecurID
+               case 's':
+                       /* SecurID required */
+@@ -680,7 +685,8 @@ doit(struct sockaddr *who, socklen_t who
+       /* get name of connected client */
+       if (getnameinfo(who, who_len, remote_host_name,
+-                      sizeof(remote_host_name), 0, 0, 0)) {
++                      sizeof(remote_host_name), 0, 0, 
++                      numeric_hosts ? NI_NUMERICHOST : 0)) {
+               syslog(LOG_ERR, "doit: getnameinfo: %m");
+               *remote_host_name = 0;
+         }
+--- netkit-telnet-0.17/telnetd/telnetd.8.orig
++++ netkit-telnet-0.17/telnetd/telnetd.8
+@@ -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
+@@ -176,6 +176,9 @@
+ 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
++Disable reverse DNS lookups and use the numeric IP address in logs
++and REMOTEHOST environment variable.
+ .It Fl s
+ This option is only enabled if
+ .Nm telnetd
diff --git a/telnet/patches/netkit-telnet-0.17-ipv6.diff b/telnet/patches/netkit-telnet-0.17-ipv6.diff
deleted file mode 100644 (file)
index e3719f1..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-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/telnet/patches/netkit-telnet-0.17-nodns.patch b/telnet/patches/netkit-telnet-0.17-nodns.patch
deleted file mode 100644 (file)
index 1dba79b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
---- 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/telnet/patches/netkit-telnet-0.17-reallynodns.patch b/telnet/patches/netkit-telnet-0.17-reallynodns.patch
deleted file mode 100644 (file)
index 32f7af5..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
---- 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/telnet/patches/telnet-0.17-8bit.patch b/telnet/patches/telnet-0.17-8bit.patch
deleted file mode 100644 (file)
index 89818b5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-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/telnet/patches/telnet-0.17-CAN-2005-468_469.patch b/telnet/patches/telnet-0.17-CAN-2005-468_469.patch
deleted file mode 100644 (file)
index 57e1372..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
---- 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/telnet/patches/telnet-0.17-argv.patch b/telnet/patches/telnet-0.17-argv.patch
deleted file mode 100644 (file)
index 6f71bed..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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/telnet/patches/telnet-0.17-cleanup_race.patch b/telnet/patches/telnet-0.17-cleanup_race.patch
deleted file mode 100644 (file)
index bc3c0f5..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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/telnet/patches/telnet-0.17-conf.patch b/telnet/patches/telnet-0.17-conf.patch
deleted file mode 100644 (file)
index 512f104..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
---- 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/telnet/patches/telnet-0.17-env.patch b/telnet/patches/telnet-0.17-env.patch
deleted file mode 100644 (file)
index 88e7c01..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
---- 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/telnet/patches/telnet-0.17-errno_test_sys_bsd.patch b/telnet/patches/telnet-0.17-errno_test_sys_bsd.patch
deleted file mode 100644 (file)
index 9a4fcba..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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/telnet/patches/telnet-0.17-issue.patch b/telnet/patches/telnet-0.17-issue.patch
deleted file mode 100644 (file)
index c00df43..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
---- 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/telnet/patches/telnet-0.17-pek.patch0 b/telnet/patches/telnet-0.17-pek.patch0
deleted file mode 100644 (file)
index 0f4c400..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-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/telnet/patches/telnet-0.17-sa-01-49.patch b/telnet/patches/telnet-0.17-sa-01-49.patch
deleted file mode 100644 (file)
index 64ed23c..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-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/telnet/patches/telnet-client-cvs.patch0 b/telnet/patches/telnet-client-cvs.patch0
deleted file mode 100644 (file)
index 5fc57a7..0000000
+++ /dev/null
@@ -1,1721 +0,0 @@
-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/telnet/patches/telnet-gethostbyname.patch b/telnet/patches/telnet-gethostbyname.patch
deleted file mode 100644 (file)
index e1c1976..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
---- 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);
diff --git a/telnet/patches/telnetd-0.17-pty_read.patch0 b/telnet/patches/telnetd-0.17-pty_read.patch0
deleted file mode 100644 (file)
index 1760ddd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
---- telnetd/telnetd.c  2005-01-19 14:37:25.000000000 +0000
-+++ telnetd/telnetd.c.new      2005-01-19 14:48:12.000000000 +0000
-@@ -697,6 +697,7 @@
-     int on = 1;
-     char *HE;
-     const char *IM;
-+    int pty_read_ok = 0; /* track whether the pty read has worked yet */
-     /*
-      * Initialize the slc mapping table.
-@@ -1016,12 +1017,13 @@
-            * off the master side before the slave side is
-            * opened, we get EIO.
-            */
--          if (pcc < 0 && (errno == EWOULDBLOCK || errno == EIO)) {
-+          if (pcc < 0 && (errno == EWOULDBLOCK || (errno == EIO && pty_read_ok == 0))) {
-               pcc = 0;
-           } 
-           else {
-               if (pcc <= 0)
-                   break;
-+              pty_read_ok = 1;        /* mark connection up for read */
- #ifdef        LINEMODE
-                               /*
-                                * If ioctl from pty, pass it through net
diff --git a/telnet/patches/telnetd-0.17.patch0 b/telnet/patches/telnetd-0.17.patch0
deleted file mode 100644 (file)
index 469b35a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- telnetd/defs.h     Mon Aug  2 06:14:03 1999
-+++ telnetd.new/defs.h Sun Mar 11 03:28:13 2001
-@@ -56,6 +56,7 @@
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <sys/time.h>
-+#include <time.h>
- #include <sys/ioctl.h>
- #include <netinet/in.h>
- #include <arpa/telnet.h>
diff --git a/telnet/patches/use-cmake-as-buildsystem.patch b/telnet/patches/use-cmake-as-buildsystem.patch
new file mode 100644 (file)
index 0000000..19a2897
--- /dev/null
@@ -0,0 +1,137 @@
+Description: Use cmake as build system
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
+Bug-Debian: https://bugs.debian.org/912131
+Last-Update: 2019-02-24
+
+--- /dev/null
++++ b/CMakeLists.txt
+@@ -0,0 +1,27 @@
++cmake_minimum_required(VERSION 3.7)
++project(netkit-telnet)
++
++set(BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin")
++set(SBIN_DIR "${CMAKE_INSTALL_PREFIX}/sbin")
++set(MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man")
++
++set(USE_GLIBC 1)
++
++set(
++    CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
++    -D_GNU_SOURCE \
++    -DACCEPT_USERVAR \
++    -Wall \
++    -Wno-trigraphs \
++")
++set(
++    CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
++    -D_GNU_SOURCE \
++    -DACCEPT_USERVAR \
++    -Wall \
++    -Wno-trigraphs \
++")
++
++add_subdirectory(telnet)
++add_subdirectory(telnetd)
++add_subdirectory(telnetlogin)
+--- /dev/null
++++ b/telnet/CMakeLists.txt
+@@ -0,0 +1,31 @@
++
++set(
++    CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
++    -DUSE_TERMIO \
++    -DKLUDGELINEMODE \
++")
++
++add_executable(
++    telnet
++    commands.cc
++    environ.cc
++    genget.cc
++    main.cc
++    netlink.cc
++    network.cc
++    ring.cc
++    sys_bsd.cc
++    telnet.cc
++    terminal.cc
++    tn3270.cc
++    utilities.cc
++)
++install(
++    TARGETS telnet
++    DESTINATION ${BIN_DIR}
++)
++
++install(
++    FILES telnet.1
++    DESTINATION ${MAN_DIR}/man1/
++)
+--- /dev/null
++++ b/telnetd/CMakeLists.txt
+@@ -0,0 +1,43 @@
++
++set(CMAKE_C_FLAGS "\
++    ${CMAKE_C_FLAGS} \
++    -DISSUE_FILE='\"/etc/issue.net\"' \
++    -DPARANOID_TTYS \
++    -DNO_REVOKE \
++    -DKLUDGELINEMODE \
++    -DDIAGNOSTICS \
++    -DLOGIN_WRAPPER='\"/usr/lib/telnetlogin\"' \
++")
++
++add_executable(
++    in.telnetd
++    global.c
++    setproctitle.c
++    slc.c
++    state.c
++    sys_term.c
++    telnetd.c
++    termstat.c
++    utility.c
++)
++target_link_libraries(
++    in.telnetd
++    ncurses
++    util
++)
++install(
++    TARGETS in.telnetd
++    DESTINATION ${SBIN_DIR}
++)
++
++install(
++    FILES telnetd.8
++    DESTINATION ${MAN_DIR}/man8/
++    RENAME in.telnetd.8
++)
++install(
++    CODE "execute_process( \
++        COMMAND ${CMAKE_COMMAND} -E create_symlink \
++        telnetd.8 \$ENV{DESTDIR}${MAN_DIR}/man8/in.telnetd.8 \
++    )"
++)
+--- /dev/null
++++ b/telnetlogin/CMakeLists.txt
+@@ -0,0 +1,19 @@
++
++add_executable(
++    telnetlogin
++    telnetlogin.c
++)
++install(
++    TARGETS telnetlogin
++    DESTINATION ${SBIN_DIR}
++    PERMISSIONS
++        SETUID
++        OWNER_WRITE OWNER_READ OWNER_EXECUTE
++        GROUP_READ GROUP_EXECUTE
++
++)
++
++install(
++    FILES telnetlogin.8
++    DESTINATION ${MAN_DIR}/man8/
++)
index a660f1c236681a1f8990dffbf6b70dd55dc640ff..6927acffc4d99456158f48a67f28b2f017f356d4 100644 (file)
@@ -5,7 +5,7 @@
 
 name       = telnet
 version    = 0.17
-release    = 3
+release    = 4
 
 groups     = Applications/Internet
 url        = http://www.ibiblio.org/pub/Linux/system/network/netkit/
@@ -20,75 +20,33 @@ end
 
 source_dl  = http://www.ibiblio.org/pub/Linux/system/network/netkit/
 sources    = netkit-%{thisapp}.tar.gz
-sources   += telnet-client.tar.gz
-
-# Apply patches in a special order
-patches    = \
-       telnet-client-cvs.patch0 \
-       telnetd-0.17.patch0 \
-       telnet-0.17-env.patch \
-       telnet-0.17-pek.patch0 \
-       telnet-0.17-issue.patch \
-       telnet-0.17-sa-01-49.patch \
-       telnet-0.17-8bit.patch \
-       telnet-0.17-argv.patch \
-       telnet-0.17-conf.patch \
-       telnet-0.17-cleanup_race.patch \
-       telnetd-0.17-pty_read.patch0 \
-       telnet-0.17-CAN-2005-468_469.patch \
-       telnet-gethostbyname.patch \
-       netkit-telnet-0.17-ipv6.diff \
-       netkit-telnet-0.17-nodns.patch \
-       telnet-0.17-errno_test_sys_bsd.patch \
-       netkit-telnet-0.17-reallynodns.patch
 
 build
        requires
+               cmake
                gcc-c++
                ncurses-devel
        end
 
        DIR_APP = %{DIR_SRC}/netkit-%{thisapp}
 
-       # Overwite configure options, because configure script
-       # doesn't accept flags for used compiler or host definition
-       configure_options = \
-               --prefix=/usr
-
-       # For the telnet client we have to extract a second tarball into the source
-       # directory of the main tarball.
-       prepare
-               cd %{DIR_SRC} && %{MACRO_EXTRACT} %{DIR_DL}/netkit-%{thisapp}.tar.gz
-               cd %{DIR_APP} && mv telnet telnet-netkit
-               cd %{DIR_APP} && %{MACRO_EXTRACT} %{DIR_DL}/telnet-client.tar.gz
+       build
+               %{cmake}
 
-               %{MACRO_PATCHES}
-
-               sed -i configure \
-                       -e "s/LDFLAGS=/LDFLAGS=\"%{LDFLAGS}\"/"
+               make %{PARALLELISMFLAGS}
        end
 
-       install
-               # We have to create the directories on our own
-               mkdir -pv %{BUILDROOT}/usr/man/man{1,5,8}
-               mkdir -pv %{BUILDROOT}/usr/{,s}bin
-
-               make install INSTALLROOT=%{BUILDROOT}
-
-               # Move manpages to correct place
-               mkdir -pv %{BUILDROOT}/usr/share
-               mv %{BUILDROOT}/usr/man %{BUILDROOT}/usr/share/man
-
+       install_cmds
                # Remove telnetd, we don't want it
-               rm -rf %{BUILDROOT}/usr/sbin
-               rm -rf %{BUILDROOT}/usr/share/man/man8
-               rm -rf %{BUILDROOT}/usr/share/man/man5
+               rm -rvf %{BUILDROOT}%{sbindir}/*telnetd*
+               rm -rvf %{BUILDROOT}%{sbindir}/telnetlogin
+               rm -rvf %{BUILDROOT}%{mandir}/man8/*telnetd*
+               rm -rvf %{BUILDROOT}%{mandir}/man8/telnetlogin*
        end
 end
 
 packages
        package %{name}
-       end
 
        package %{name}-debuginfo
                template DEBUGINFO