diff options
| author | Holger Hans Peter Freyther <zecke@selfish.org> | 2008-11-23 22:48:56 +0100 |
|---|---|---|
| committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2008-11-23 23:25:14 +0100 |
| commit | 269716a27d3334806c3d44365b4aae4f29c79c48 (patch) | |
| tree | 7a9a6dc300bd2ef72aabf4daec5f58fbb03f20e2 | |
| parent | 59f5a9c741bba79e6ebf8e6527142aeeb8ea9236 (diff) | |
netkit-telnet: Add a telnet package...
telnetd does not compile with the debian patch, telnet compiles
let us use that. This is not using update-alternatives as I think
it is not necessary as this is the only telnet provider we have.
The "buildsystem" is horrible... kick the configure to not run
tests...
| -rw-r--r-- | conf/checksums.ini | 4 | ||||
| -rw-r--r-- | packages/netkit-telnet/files/cross-compile.patch | 40 | ||||
| -rw-r--r-- | packages/netkit-telnet/files/netkit-telnet-debian_0.17-36.diff | 3443 | ||||
| -rw-r--r-- | packages/netkit-telnet/netkit-telnet_0.17.bb | 27 |
4 files changed, 3514 insertions, 0 deletions
diff --git a/conf/checksums.ini b/conf/checksums.ini index a35f763b55..015e7a0c12 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -14454,6 +14454,10 @@ sha256=61c913299b81a4671ff089aac821329f7db9bc111aa812993dd585798b700349 md5=67212720482ea1aea9182a98653a9642 sha256=421d63b414162237a72867061f1bd3e3752a0d962cd5d30b5e933ddad8a14d3b +[ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/netkit-telnet-0.17.tar.gz] +md5=d6beabaaf53fe6e382c42ce3faa05a36 +sha256=9c80d5c7838361a328fb6b60016d503def9ce53ad3c589f3b08ff71a2bb88e00 + [ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/netkit-tftp-0.17.tar.gz] md5=b7262c798e2ff50e29c2ff50dfd8d6a8 sha256=3a43c0010d4e61f412563fd83769d4667d8b8e82903526d21cb9205fe55ad14d diff --git a/packages/netkit-telnet/files/cross-compile.patch b/packages/netkit-telnet/files/cross-compile.patch new file mode 100644 index 0000000000..7bb8156153 --- /dev/null +++ b/packages/netkit-telnet/files/cross-compile.patch @@ -0,0 +1,40 @@ +Index: netkit-telnet-0.17/configure +=================================================================== +--- netkit-telnet-0.17.orig/configure 2008-11-23 22:01:26.000000000 +0100 ++++ netkit-telnet-0.17/configure 2008-11-23 22:05:00.000000000 +0100 +@@ -94,7 +94,7 @@ + echo -n 'Checking if C compiler works... ' + if ( + $CC __conftest.c -o __conftest || exit 1 +- ./__conftest || exit 1 ++ # Idiots belong shot! ./__conftest || exit 1 + ) >/dev/null 2>&1; then + echo 'yes' + else +@@ -141,7 +141,7 @@ + echo -n 'Checking if C++ compiler works... ' + if ( + $CXX __conftest.cc -o __conftest || exit 1 +- ./__conftest || exit 1 ++ # Iditios belong shot! ./__conftest || exit 1 + ) >/dev/null 2>&1; then + echo 'yes' + else +@@ -284,7 +284,7 @@ + else + if ( + $CXX $CXXFLAGS -D__USE_BSD_SIGNAL __conftest.cc -o __conftest || exit 1 +- ./__conftest || exit 1 ++ # running still does not work./__conftest || exit 1 + ) >/dev/null 2>&1; then + echo '-D__USE_BSD_SIGNAL' + CFLAGS="$CFLAGS -D__USE_BSD_SIGNAL" +@@ -501,7 +501,7 @@ + EOF + if ( + $CXX $CXXFLAGS __conftest.cc $LIBBSD -o __conftest || exit 1 +- ./__conftest || exit 1 ++ # argh! morons!./__conftest || exit 1 + ) >/dev/null 2>&1; then + echo 'ok' + else diff --git a/packages/netkit-telnet/files/netkit-telnet-debian_0.17-36.diff b/packages/netkit-telnet/files/netkit-telnet-debian_0.17-36.diff new file mode 100644 index 0000000000..961fc036b6 --- /dev/null +++ b/packages/netkit-telnet/files/netkit-telnet-debian_0.17-36.diff @@ -0,0 +1,3443 @@ +--- netkit-telnet-0.17.orig/Makefile ++++ netkit-telnet-0.17/Makefile +@@ -1,8 +1,7 @@ + # You can do "make SUB=blah" to make only a few, or edit here, or both + # You can also run make directly in the subdirs you want. + +-SUB = telnet telnetd +-# not yet: telnetlogin ++SUB = telnet telnetd telnetlogin + + %.build: + (cd $(patsubst %.build, %, $@) && $(MAKE)) +--- netkit-telnet-0.17.orig/configure ++++ netkit-telnet-0.17/configure +@@ -67,7 +67,7 @@ + + ################################################## + +-WARNINGS='-Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline ' ++WARNINGS='-Wall -Wno-trigraphs ' + + cat << EOF > __conftest.c + int main() { int class=0; return class; } +@@ -117,7 +117,7 @@ + + cat << EOF > __conftest.cc + template <class T> class fnord { public: T x; fnord(T y) { x=y; }}; +- int main() { fnord<int> a(0); return a.x; } ++ int main() { fnord<int> *a = new fnord<int>(0); return a->x; } + EOF + + if [ x"$CXX" = x ]; then +--- netkit-telnet-0.17.orig/telnet/defines.h ++++ netkit-telnet-0.17/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 */ +--- netkit-telnet-0.17.orig/telnet/main.cc ++++ netkit-telnet-0.17/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] [ -b addr ]", + #ifdef TN3270 ++ "\n\t" + "[-noasynch] [-noasynctty] [-noasyncnet] [-r] [-t transcom]\n\t", + #else +- "[-r] ", ++ " [-r] ", + #endif + "[host-name [port]]" + ); +@@ -102,7 +106,8 @@ + extern char *optarg; + extern int optind; + int ch; +- char *user; ++ char *user, *srcaddr; ++ int family; + + tninit(); /* Clear out things */ + #if defined(CRAY) && !defined(__STDC__) +@@ -110,21 +115,38 @@ + #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, "8EKLS: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; ++ break; ++ case '6': ++#ifdef AF_INET6 ++ family = AF_INET6; ++#else ++ 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; +@@ -133,23 +155,26 @@ + //autologin = 0; + break; + case 'L': +- eight |= 2; /* binary output only */ ++ binary |= 2; /* binary output only */ + 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': +@@ -210,6 +235,9 @@ + "%s: -x ignored, no encryption support.\n", + prompt); + break; ++ case 'b': ++ srcaddr = optarg; ++ break; + case '?': + default: + usage(); +@@ -233,6 +261,13 @@ + *argp++ = "-l"; + *argp++ = user; + } ++ if (srcaddr) { ++ *argp++ = "-b"; ++ *argp++ = srcaddr; ++ } ++ if (family) { ++ *argp++ = family == AF_INET ? "-4" : "-6"; ++ } + *argp++ = argv[0]; /* host */ + if (argc > 1) + *argp++ = argv[1]; /* port */ +--- netkit-telnet-0.17.orig/telnet/netlink.cc ++++ netkit-telnet-0.17/telnet/netlink.cc +@@ -79,22 +79,61 @@ + shutdown(net, 2); + } + ::close(net); ++ net = -1; + } + +-int netlink::connect(int debug, struct hostent *host, +- struct sockaddr_in *sn, +- char *srcroute, int srlen, int tos) ++int netlink::bind(struct addrinfo *addr) + { +- int on=1; ++ 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); + +- net = socket(AF_INET, SOCK_STREAM, 0); + if (net < 0) { +- perror("telnet: socket"); +- return 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; ++ ++ res = socket(addr->ai_family); ++ if (res < 2) ++ return res; ++ + #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 +147,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 +155,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; + } +--- netkit-telnet-0.17.orig/telnet/netlink.h ++++ netkit-telnet-0.17/telnet/netlink.h +@@ -1,13 +1,16 @@ + + class netlink { ++ private: ++ int family; + protected: + int net; + public: + netlink(); + ~netlink(); + +- int connect(int debug, struct hostent *host, +- struct sockaddr_in *sin, ++ int bind(struct addrinfo *hostaddr); ++ int socket(int family); ++ int connect(int debug, struct addrinfo *hostaddr, + char *srcroute, int srlen, + int tos); + void close(int doshutdown); +--- netkit-telnet-0.17.orig/telnet/network.cc ++++ netkit-telnet-0.17/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> + +--- netkit-telnet-0.17.orig/telnet/proto.h ++++ netkit-telnet-0.17/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); +--- netkit-telnet-0.17.orig/telnet/ring.cc ++++ netkit-telnet-0.17/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); +--- netkit-telnet-0.17.orig/telnet/ring.h ++++ netkit-telnet-0.17/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 +--- netkit-telnet-0.17.orig/telnet/sys_bsd.cc ++++ netkit-telnet-0.17/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 +--- netkit-telnet-0.17.orig/telnet/telnet.1 ++++ netkit-telnet-0.17/telnet/telnet.1 +@@ -42,8 +42,9 @@ + protocol + .Sh SYNOPSIS + .Nm telnet +-.Op Fl 8ELadr ++.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 +@@ -68,6 +69,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 +@@ -89,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 +@@ -474,17 +481,29 @@ + 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. 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 +@@ -1184,9 +1203,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 +1256,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 +--- netkit-telnet-0.17.orig/telnet/terminal.cc ++++ netkit-telnet-0.17/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" +@@ -155,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; + +@@ -449,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); +@@ -468,7 +475,7 @@ + + #ifdef SIGINFO + signal(SIGINFO, ayt); +-#endif SIGINFO ++#endif /* SIGINFO */ + + #if defined(NOKERNINFO) + tmp_tc.c_lflag |= NOKERNINFO; +@@ -504,7 +511,7 @@ + + #ifdef SIGINFO + signal(SIGINFO, ayt_status); +-#endif SIGINFO ++#endif /* SIGINFO */ + + #ifdef SIGTSTP + signal(SIGTSTP, SIG_DFL); +--- netkit-telnet-0.17.orig/telnet/utilities.cc ++++ netkit-telnet-0.17/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" +--- netkit-telnet-0.17.orig/telnet/commands.cc ++++ netkit-telnet-0.17/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) { +@@ -480,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; +@@ -506,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; + } + +@@ -689,9 +693,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 +1619,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; +- +- const char *cmd, *volatile user = 0; ++ int family = 0; ++ const char *cmd, *volatile user = 0, *srchostp = 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 +1641,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) "); +@@ -1657,11 +1670,33 @@ + --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; + 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 +1715,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 +1733,122 @@ + } 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 ++ } 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; ++ 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 { +- 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; ++ ++ 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); ++ 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); +- cmdrc(hostp, hostname); ++ 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, portp); ++ freeaddrinfo(hostaddr); + if (autologin && user == NULL) { + struct passwd *pw; + +@@ -2013,30 +2094,21 @@ + 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 *port, ++ const char *rcname) ++{ + FILE *rcfile; + int gotmachine = 0; + int l1 = strlen(m1); + int l2 = strlen(m2); +- char m1save[64]; +- +- if (skiprc) return; ++ int lport = strlen(port); ++ char m1save[l1 + 1]; ++ char portsave[lport + 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; +- } ++ strcpy(portsave, port); ++ port = portsave; + + rcfile = fopen(rcname, "r"); + if (!rcfile) return; +@@ -2061,6 +2133,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; +@@ -2073,6 +2152,21 @@ + fclose(rcfile); + } + ++void cmdrc(const char *m1, const char *m2, const char *port) { ++ char *rcname = NULL; ++ ++ if (skiprc) return; ++ ++ readrc(m1, m2, port, "/etc/telnetrc"); ++ 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) + + /* +--- netkit-telnet-0.17.orig/telnet/externs.h ++++ netkit-telnet-0.17/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] +--- netkit-telnet-0.17.orig/telnet/telnet.cc ++++ netkit-telnet-0.17/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, +@@ -639,14 +640,14 @@ + 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"; + } + mklist(termbuf, tname, termtypes); + next = 0; + } +- if (next==termtypes.num()) next = 0; ++ if (next==termtypes.num()-1) next = 0; + return termtypes[next++]; + } + /* +@@ -681,7 +682,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 +694,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 +781,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 +799,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 +816,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 +839,7 @@ + k |= MODE_ACK; + } + |
