summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Naumov <posix.ru@gmail.com>2015-06-10 13:06:07 +0200
committerAlexander Naumov <posix.ru@gmail.com>2015-06-10 13:06:07 +0200
commit6795815fe1a9d7a12c4fbe3d407ed06377377b14 (patch)
treed2bfda03ea1bbc95966191dfe5ea3a626d5ebad9
parent5ac6a9498ce80003718fdb3e17a079eea82e9a65 (diff)
downloadscreen-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.16
-rw-r--r--src/extern.h3
-rw-r--r--src/help.c4
-rw-r--r--src/screen.c16
-rw-r--r--src/teln.c148
-rw-r--r--src/window.c28
-rw-r--r--src/window.h2
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));
diff --git a/src/help.c b/src/help.c
index 8446f34..a2b8614 100644
--- a/src/help.c
+++ b/src/help.c
@@ -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;
diff --git a/src/teln.c b/src/teln.c
index 1764dbc..0546c35 100644
--- a/src/teln.c
+++ b/src/teln.c
@@ -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];