diff -up screen/src/doc/screen.1.ipv6 screen/src/doc/screen.1 --- screen/src/doc/screen.1.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/doc/screen.1 2011-02-03 16:05:35.957087079 +0100 @@ -398,6 +398,12 @@ Send the specified command to a running the \fB-d\fP or \fB-r\fP option to tell screen to look only for attached or detached screen sessions. Note that this command doesn't work if the session is password protected. +.TP 5 +.B \-4 +Resolve hostnames only to IPv4 addresses. +.TP 5 +.B \-6 +Resolve hostnames only to IPv6 addresses. .SH "DEFAULT KEY BINDINGS" .ta 12n 26n diff -up screen/src/extern.h.ipv6 screen/src/extern.h --- screen/src/extern.h.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/extern.h 2011-02-03 16:04:35.995743620 +0100 @@ -455,8 +455,7 @@ extern void ExitOverlayPage __P((void)) /* teln.c */ #ifdef BUILTIN_TELNET -extern int TelOpen __P((char **)); -extern int TelConnect __P((struct win *)); +extern int TelOpenAndConnect __P((struct win *)); extern int TelIsline __P((struct win *p)); extern void TelProcessLine __P((char **, int *)); extern int DoTelnet __P((char *, int *, int)); diff -up screen/src/help.c.ipv6 screen/src/help.c --- screen/src/help.c.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/help.c 2011-02-03 16:04:35.992744154 +0100 @@ -66,6 +66,10 @@ char *myname, *message, *arg; { printf("Use: %s [-opts] [cmd [args]]\n", myname); printf(" or: %s -r [host.tty]\n\nOptions:\n", myname); +#ifdef BUILTIN_TELNET + printf("-4 Resolve hostnames only to IPv4 addresses.\n"); + printf("-6 Resolve hostnames only to IPv6 addresses.\n"); +#endif printf("-a Force all capabilities into each window's termcap.\n"); printf("-A -[r|R] Adapt all windows to the new display width & height.\n"); printf("-c file Read configuration file instead of '.screenrc'.\n"); diff -up screen/src/screen.c.ipv6 screen/src/screen.c --- screen/src/screen.c.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/screen.c 2011-02-03 16:04:35.994743798 +0100 @@ -248,8 +248,9 @@ struct layer *flayer; struct win *fore; struct win *windows; struct win *console_window; - - +#ifdef BUILTIN_TELNET +int af; +#endif /* * Do this last @@ -507,6 +508,9 @@ char **av; nwin = nwin_undef; nwin_options = nwin_undef; strcpy(screenterm, "screen"); +#ifdef BUILTIN_TELNET + af = AF_UNSPEC; +#endif logreopen_register(lf_secreopen); @@ -541,6 +545,14 @@ char **av; { switch (*ap) { +#ifdef BUILTIN_TELNET + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; +#endif case 'a': nwin_options.aflag = 1; break; diff -up screen/src/teln.c.ipv6 screen/src/teln.c --- screen/src/teln.c.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/teln.c 2011-02-03 16:04:35.992744154 +0100 @@ -30,6 +30,7 @@ #include #include #include +#include #include "config.h" @@ -42,12 +43,13 @@ extern struct win *fore; extern struct layer *flayer; extern int visual_bell; extern char screenterm[]; +extern int af; static void TelReply __P((struct win *, char *, int)); static void TelDocmd __P((struct win *, int, int)); static void TelDosub __P((struct win *)); - -#define TEL_DEFPORT 23 +// why TEL_DEFPORT has " +#define TEL_DEFPORT "23" #define TEL_CONNECTING (-2) #define TC_IAC 255 @@ -105,86 +107,78 @@ char *data; } int -TelOpen(args) -char **args; -{ - int fd; - int on = 1; - - if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) - { - Msg(errno, "TelOpen: socket"); - return -1; - } - if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))) - Msg(errno, "TelOpen: setsockopt SO_OOBINLINE"); - return fd; -} - -int -TelConnect(p) -struct win *p; -{ - int port = TEL_DEFPORT; - struct hostent *hp; - char **args; +TelOpenAndConnect(struct win *p) { + int fd, on = 1; char buf[256]; - args = p->w_cmdargs + 1; - - if (!*args) - { - Msg(0, "Usage: screen //telnet host [port]"); - return -1; - } - if (args[1]) - port = atoi(args[1]); - p->w_telsa.sin_family = AF_INET; - if((p->w_telsa.sin_addr.s_addr = inet_addr(*args)) == -1) - { - if ((hp = gethostbyname(*args)) == NULL) - { - Msg(0, "unknown host: %s", *args); - return -1; - } - if (hp->h_length != sizeof(p->w_telsa.sin_addr.s_addr) || hp->h_addrtype != AF_INET) - { - Msg(0, "Bad address type for %s", hp->h_name); - return -1; - } - bcopy((char *)hp->h_addr,(char *)&p->w_telsa.sin_addr.s_addr, hp->h_length); - p->w_telsa.sin_family = hp->h_addrtype; - } - p->w_telsa.sin_port = htons(port); - if (port != TEL_DEFPORT) - sprintf(buf, "Trying %s %d...", inet_ntoa(p->w_telsa.sin_addr), port); - else - sprintf(buf, "Trying %s...", inet_ntoa(p->w_telsa.sin_addr)); - WriteString(p, buf, strlen(buf)); - if (connect(p->w_ptyfd, (struct sockaddr *)&p->w_telsa, sizeof(p->w_telsa))) - { - if (errno == EINPROGRESS) - { - p->w_telstate = TEL_CONNECTING; - p->w_telconnev.fd = p->w_ptyfd; - p->w_telconnev.handler = tel_connev_fn; - p->w_telconnev.data = (char *)p; - p->w_telconnev.type = EV_WRITE; - p->w_telconnev.pri = 1; - debug("telnet connect in progress...\n"); - evenq(&p->w_telconnev); - } - else - { - Msg(errno, "TelOpen: connect"); - return -1; - } - } - else - WriteString(p, "connected.\r\n", 12); - if (port == TEL_DEFPORT) - TelReply(p, (char *)tn_init, sizeof(tn_init)); - return 0; + struct addrinfo hints, *res0, *res; + + if (!(p->w_cmdargs[1])) { + Msg(0, "Usage: screen //telnet host [port]"); + return -1; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if(getaddrinfo(p->w_cmdargs[1], p->w_cmdargs[2] ? p->w_cmdargs[2] : TEL_DEFPORT, + &hints, &res0)) { + Msg(0, "unknown host: %s", p->w_cmdargs[1]); + return -1; + } + + for(res = res0; res; res = res->ai_next) { + if((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { + if(res->ai_next) + continue; + else { + Msg(errno, "TelOpenAndConnect: socket"); + freeaddrinfo(res0); + return -1; + } + } + + if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))) + Msg(errno, "TelOpenAndConnect: setsockopt SO_OOBINLINE"); + + if (p->w_cmdargs[2] && strcmp(p->w_cmdargs[2], TEL_DEFPORT)) + snprintf(buf, 256, "Trying %s %s...", p->w_cmdargs[1], p->w_cmdargs[2]); + else + snprintf(buf, 256, "Trying %s...", p->w_cmdargs[1]); + WriteString(p, buf, strlen(buf)); + if (connect(fd, res->ai_addr, res->ai_addrlen)) { + if (errno == EINPROGRESS) { + p->w_telstate = TEL_CONNECTING; + p->w_telconnev.fd = fd; + p->w_telconnev.handler = tel_connev_fn; + p->w_telconnev.data = (char *)p; + p->w_telconnev.type = EV_WRITE; + p->w_telconnev.pri = 1; + debug("telnet connect in progress...\n"); + evenq(&p->w_telconnev); + } + else { + close(fd); + if(res->ai_next) + continue; + else { + Msg(errno, "TelOpenAndConnect: connect"); + freeaddrinfo(res0); + return -1; + } + } + } + else + WriteString(p, "connected.\r\n", 12); + if (!(p->w_cmdargs[2] && strcmp(p->w_cmdargs[2], TEL_DEFPORT))) + TelReply(p, (char *)tn_init, sizeof(tn_init)); + p->w_ptyfd = fd; + memcpy(&p->w_telsa, &res->ai_addr, sizeof(res->ai_addr)); + freeaddrinfo(res0); + return 0; + } + return -1; } int diff -up screen/src/window.c.ipv6 screen/src/window.c --- screen/src/window.c.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/window.c 2011-02-03 16:30:56.900750293 +0100 @@ -605,6 +605,13 @@ struct NewWindow *newwin; n = pp - wtab; debug1("Makewin creating %d\n", n); +#ifdef BUILTIN_TELNET + if(!strcmp(nwin.args[0], "//telnet")) { + type = W_TYPE_TELNET; + TtyName = "telnet"; + } + else +#endif if ((f = OpenDevice(nwin.args, nwin.lflag, &type, &TtyName)) < 0) return -1; if (type == W_TYPE_GROUP) @@ -766,7 +773,7 @@ struct NewWindow *newwin; #ifdef BUILTIN_TELNET if (type == W_TYPE_TELNET) { - if (TelConnect(p)) + if (TelOpenAndConnect(p)) { FreeWindow(p); return -1; @@ -878,6 +885,13 @@ struct win *p; int lflag, f; lflag = nwin_default.lflag; +#ifdef BUILTIN_TELNET + if(!strcmp(p->w_cmdargs[0], "//telnet")) { + p->w_type = W_TYPE_TELNET; + TtyName = "telnet"; + } + else +#endif if ((f = OpenDevice(p->w_cmdargs, lflag, &p->w_type, &TtyName)) < 0) return -1; @@ -909,7 +923,7 @@ struct win *p; #ifdef BUILTIN_TELNET if (p->w_type == W_TYPE_TELNET) { - if (TelConnect(p)) + if (TelOpenAndConnect(p)) return -1; } else @@ -1068,16 +1082,6 @@ char **namep; *namep = "telnet"; return 0; } -#ifdef BUILTIN_TELNET - if (strcmp(arg, "//telnet") == 0) - { - f = TelOpen(args + 1); - lflag = 0; - *typep = W_TYPE_TELNET; - *namep = "telnet"; - } - else -#endif if (strncmp(arg, "//", 2) == 0) { Msg(0, "Invalid argument '%s'", arg); diff -up screen/src/window.h.ipv6 screen/src/window.h --- screen/src/window.h.ipv6 2010-11-11 03:47:46.000000000 +0100 +++ screen/src/window.h 2011-02-03 16:04:35.989744687 +0100 @@ -268,7 +268,7 @@ struct win struct display *w_zdisplay; #endif #ifdef BUILTIN_TELNET - struct sockaddr_in w_telsa; + struct sockaddr_storage w_telsa; char w_telbuf[IOSIZE]; int w_telbufl; char w_telmopts[256];