diff options
author | Alexander Naumov <posix.ru@gmail.com> | 2015-06-10 13:06:07 +0200 |
---|---|---|
committer | Alexander Naumov <posix.ru@gmail.com> | 2015-06-10 13:06:07 +0200 |
commit | 6795815fe1a9d7a12c4fbe3d407ed06377377b14 (patch) | |
tree | d2bfda03ea1bbc95966191dfe5ea3a626d5ebad9 | |
parent | 5ac6a9498ce80003718fdb3e17a079eea82e9a65 (diff) | |
download | screen-6795815fe1a9d7a12c4fbe3d407ed06377377b14.tar.gz |
I'd like to upstream the ipv6.patch.
Some distributions downstream supply it for years:
http://pkgs.fedoraproject.org/cgit/screen.git/tree/screen-ipv6.patch
https://sources.debian.net/src/screen/4.2.1-3/debian/patches/48screen-ipv6.patch/
https://build.opensuse.org/package/view_file/openSUSE:Factory/screen/screen-4.0.3-ipv6.patch
Signed-off-by: Alexander Naumov <alexander_naumov@opensuse.org>
-rw-r--r-- | src/doc/screen.1 | 6 | ||||
-rw-r--r-- | src/extern.h | 3 | ||||
-rw-r--r-- | src/help.c | 4 | ||||
-rw-r--r-- | src/screen.c | 16 | ||||
-rw-r--r-- | src/teln.c | 148 | ||||
-rw-r--r-- | src/window.c | 28 | ||||
-rw-r--r-- | src/window.h | 2 |
7 files changed, 115 insertions, 92 deletions
diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 8a0d51f..abb19ad 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -409,6 +409,12 @@ several screen sessions running. You can use the \fB-d\fP 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 As mentioned, each diff --git a/src/extern.h b/src/extern.h index a3e3ca2..9b564e6 100644 --- a/src/extern.h +++ b/src/extern.h @@ -459,8 +459,7 @@ extern void LayProcessMouseSwitch __P((struct layer *, int)); /* 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)); @@ -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 --git a/src/screen.c b/src/screen.c index ad798c5..6008039 100644 --- a/src/screen.c +++ b/src/screen.c @@ -243,13 +243,14 @@ int nethackflag = 0; #endif int maxwin; - 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; @@ -30,6 +30,7 @@ #include <sys/socket.h> #include <fcntl.h> #include <netdb.h> +#include <stdio.h> #include "config.h" @@ -42,12 +43,14 @@ 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 +108,81 @@ char *data; } int -TelOpen(args) -char **args; -{ - int fd; - int on = 1; +TelOpenAndConnect(struct win *p) { + int fd, on = 1; + char buf[256]; - 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; -} + struct addrinfo hints, *res0, *res; -int -TelConnect(p) -struct win *p; -{ - int port = TEL_DEFPORT; - struct hostent *hp; - char **args; - char buf[256]; + if (!(p->w_cmdargs[1])) { + Msg(0, "Usage: screen //telnet host [port]"); + return -1; + } - args = p->w_cmdargs + 1; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; - 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); + 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; } - else - { - Msg(errno, "TelOpen: connect"); - 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; } - } - else - WriteString(p, "connected.\r\n", 12); - if (port == TEL_DEFPORT) - TelReply(p, (char *)tn_init, sizeof(tn_init)); - return 0; + return -1; } int diff --git a/src/window.c b/src/window.c index f39f419..53cffcd 100644 --- a/src/window.c +++ b/src/window.c @@ -614,6 +614,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) @@ -775,7 +782,7 @@ struct NewWindow *newwin; #ifdef BUILTIN_TELNET if (type == W_TYPE_TELNET) { - if (TelConnect(p)) + if (TelOpenAndConnect(p)) { FreeWindow(p); return -1; @@ -895,6 +902,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; @@ -928,7 +942,7 @@ struct win *p; #ifdef BUILTIN_TELNET if (p->w_type == W_TYPE_TELNET) { - if (TelConnect(p)) + if (TelOpenAndConnect(p)) return -1; } else @@ -1088,16 +1102,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 --git a/src/window.h b/src/window.h index 380d3e9..f14ed04 100644 --- a/src/window.h +++ b/src/window.h @@ -271,7 +271,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]; |