Commit b74c8f42 authored by runge's avatar runge

Improvements to demo scripts. Alias -coe for -connect_or_exit. Fix HAVE_V4L2....

Improvements to demo scripts. Alias -coe for -connect_or_exit.  Fix HAVE_V4L2. Warn no Xvfb, Xdummy, or Xvnc. Xinerama screens.
parent 2a8ba97e
2010-04-18 Karl Runge <runge@karlrunge.com>
* x11vnc/misc: improvements to demo scripts
* x11vnc: Alias -coe for -connect_or_exit. more accurate
dotted_ip() and -listen6. Improvements to ipv6 mode.
http interface for X11VNC_HTTP_LISTEN_LOCALHOST. Print
warning about missing Xvfb, Xdummy, or Xvnc in -create.
Fix __LINUX_VIDEODEV2_H / HAVE_V4L2. Always print out info
about Xinerama screens.
2010-04-09 Karl Runge <runge@karlrunge.com>
* classes/ssl: debugging and workarounds for java viewer
* x11vnc/misc: sync ssvnc, improve util scripts.
......
This diff is collapsed.
......@@ -1925,7 +1925,7 @@ int appshare_main(int argc, char *argv[]) {
id_opt = "-sid";
if (end) exiter("no -sid value supplied\n", 1);
app_str = strdup(argv[++i]);
} else if (!strcmp(s, "-connect") || !strcmp(s, "-connect_or_exit")) {
} else if (!strcmp(s, "-connect") || !strcmp(s, "-connect_or_exit") || !strcmp(s, "-coe")) {
if (end) exiter("no -connect value supplied\n", 1);
connect_to = strdup(argv[++i]);
} else if (!strcmp(s, "-control")) {
......
......@@ -308,7 +308,7 @@ static rfbClientPtr *client_match(char *str) {
}
if (ipv6_ip(str)) {
;
} else if (! dotted_ip(str)) {
} else if (! dotted_ip(str, 0)) {
char *orig = rstr;
rstr = host2ip(rstr);
free(orig);
......@@ -385,7 +385,7 @@ void set_client_input(char *str) {
return;
}
p = strchr(str, ':');
p = strrchr(str, ':');
if (! p) {
return;
}
......@@ -1067,7 +1067,7 @@ int check_access(char *addr) {
}
if (ipv6_ip(p)) {
chk = p;
} else if (! dotted_ip(p)) {
} else if (! dotted_ip(p, 1)) {
r = host2ip(p);
if (r == NULL || *r == '\0') {
rfbLog("check_access: bad lookup \"%s\"\n", p);
......@@ -1837,9 +1837,8 @@ void check_ipv6_listen(long usec) {
screen->httpListenSock = save;
}
}
#else
if (usec) {}
#endif
if (usec) {}
}
/*
......
This diff is collapsed.
......@@ -45,7 +45,7 @@ char *raw2host(char *raw, int len);
char *raw2ip(char *raw);
char *ip2host(char *ip);
int ipv6_ip(char *host);
int dotted_ip(char *host);
int dotted_ip(char *host, int partial);
int get_remote_port(int sock);
int get_local_port(int sock);
char *get_remote_host(int sock);
......@@ -143,8 +143,8 @@ int ipv6_ip(char *host_in) {
host = host_in;
}
if (strstr(host, "::ffff:") == host) {
return dotted_ip(host + strlen("::ffff:"));
if (strstr(host, "::ffff:") == host || strstr(host, "::FFFF:") == host) {
return dotted_ip(host + strlen("::ffff:"), 0);
}
a[1] = '\0';
......@@ -170,15 +170,34 @@ int ipv6_ip(char *host_in) {
}
}
int dotted_ip(char *host) {
int dotted_ip(char *host, int partial) {
int len, dots = 0;
char *p = host;
if (!host) {
return 0;
}
if (!isdigit((unsigned char) host[0])) {
return 0;
}
len = strlen(host);
if (!partial && !isdigit((unsigned char) host[len-1])) {
return 0;
}
while (*p != '\0') {
if (*p == '.') dots++;
if (*p == '.' || isdigit((unsigned char) (*p))) {
p++;
continue;
}
return 0;
}
if (!partial && dots != 3) {
return 0;
}
return 1;
}
......@@ -253,7 +272,6 @@ char *ident_username(rfbClientPtr client) {
user = cd->username;
}
if (!user || *user == '\0') {
char msg[128];
int n, sock, ok = 0;
int block = 0;
int refused = 0;
......@@ -310,6 +328,7 @@ char *ident_username(rfbClientPtr client) {
rfbLog("ident_username: could not connect to ident: %s:%d\n",
client->host, 113);
} else {
char msg[128];
int ret;
fd_set rfds;
struct timeval tv;
......@@ -321,14 +340,14 @@ char *ident_username(rfbClientPtr client) {
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
tv.tv_sec = 4;
tv.tv_sec = 3;
tv.tv_usec = 0;
ret = select(sock+1, &rfds, NULL, NULL, &tv);
if (ret > 0) {
int i;
char *q, *p;
for (i=0; i<128; i++) {
for (i=0; i < sizeof(msg); i++) {
msg[i] = '\0';
}
usleep(250*1000);
......@@ -504,7 +523,7 @@ char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen) {
}
char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen) {
#if X11VNC_IPV6
#if X11VNC_IPV6 && defined(NI_NUMERICHOST)
char name[200];
if (noipv6) {
return strdup("unknown");
......@@ -524,22 +543,27 @@ int listen6(int port) {
if (noipv6) {
return -1;
}
if (port <= 0 || 65535 < port) {
/* for us, invalid port means do not listen. */
return -1;
}
fd = socket(AF_INET6, SOCK_STREAM, 0);
if (fd < 0) {
rfbLogPerror("listen6: socket");
rfbLog("(Ignore the above error if this system is IPv4-only.)\n");
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
rfbLogPerror("listen6: setsockopt1");
rfbLogPerror("listen6: setsockopt SO_REUSEADDR");
close(fd);
return -1;
}
#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
rfbLogPerror("listen6: setsockopt2");
rfbLogPerror("listen6: setsockopt IPV6_V6ONLY");
close(fd);
return -1;
}
......@@ -551,19 +575,57 @@ int listen6(int port) {
sin.sin6_addr = in6addr_any;
if (listen_str6) {
if (!strcmp(listen_str6, "localhost")) {
if (!strcmp(listen_str6, "localhost") || !strcmp(listen_str6, "::1")) {
sin.sin6_addr = in6addr_loopback;
} else if (ipv6_ip(listen_str6)) {
int err = inet_pton(AF_INET6, listen_str6, &(sin.sin6_addr));
if (err <= 0) {
rfbLog("inet_pton[%d] failed -listen6 %s\n", err, listen_str6);
} else {
int err;
struct addrinfo *ai;
struct addrinfo hints;
char service[32];
memset(&hints, 0, sizeof(hints));
sprintf(service, "%d", port);
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
#ifdef AI_NUMERICHOST
if(ipv6_ip(listen_str6)) {
hints.ai_flags |= AI_NUMERICHOST;
}
#endif
#ifdef AI_NUMERICSERV
hints.ai_flags |= AI_NUMERICSERV;
#endif
err = getaddrinfo(listen_str6, service, &hints, &ai);
if (err == 0) {
struct addrinfo *ap = ai;
err = 1;
while (ap != NULL) {
char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen);
if (!s) s = strdup("unknown");
rfbLog("listen6: checking: %s family: %d\n", s, ap->ai_family);
if (ap->ai_family == AF_INET6) {
memcpy((char *)&sin, ap->ai_addr, sizeof(sin));
rfbLog("listen6: using: %s scope_id: %d\n", s, sin.sin6_scope_id);
err = 0;
free(s);
break;
}
free(s);
ap = ap->ai_next;
}
freeaddrinfo(ai);
}
if (err != 0) {
rfbLog("Invalid or Unsupported -listen6 string: %s\n", listen_str6);
close(fd);
return -1;
}
} else {
rfbLog("Unsupported -listen6 string: %s\n", listen_str6);
close(fd);
return -1;
}
} else if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
sin.sin6_addr = in6addr_loopback;
......@@ -625,7 +687,7 @@ int connect_tcp(char *host, int port) {
}
if (fd < 0 && !noipv6) {
#if X11VNC_IPV6 && defined(AI_ADDRCONFIG)
#if X11VNC_IPV6
int err;
struct addrinfo *ai;
struct addrinfo hints;
......@@ -638,13 +700,13 @@ int connect_tcp(char *host, int port) {
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_ADDRCONFIG;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
if(ipv6_ip(host)) {
#ifdef AI_NUMERICHOST
rfbLog("connect_tcp[ipv6]: setting AI_NUMERICHOST for %s\n", host);
hints.ai_flags |= AI_NUMERICHOST;
#else
rfbLog("connect_tcp[ipv6]: no AI_NUMERICHOST for %s\n", host);
#endif
}
#ifdef AI_NUMERICSERV
......@@ -662,7 +724,6 @@ int connect_tcp(char *host, int port) {
if (q) {
*q = '\0';
}
err = getaddrinfo(host2, service, &hints, &ai);
if (err != 0) {
......@@ -677,14 +738,53 @@ int connect_tcp(char *host, int port) {
} else {
struct addrinfo *ap = ai;
while (ap != NULL) {
int sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
int sock;
if (fail4) {
struct sockaddr_in6 *s6ptr;
if (ap->ai_family != AF_INET6) {
rfbLog("connect_tcp[ipv6]: skipping AF_INET address under -noipv4\n");
ap = ap->ai_next;
continue;
}
#ifdef IN6_IS_ADDR_V4MAPPED
s6ptr = (struct sockaddr_in6 *) ap->ai_addr;
if (IN6_IS_ADDR_V4MAPPED(&(s6ptr->sin6_addr))) {
rfbLog("connect_tcp[ipv6]: skipping V4MAPPED address under -noipv4\n");
ap = ap->ai_next;
continue;
}
#endif
}
sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
if (sock == -1) {
rfbLogPerror("connect_tcp[ipv6]: socket");
if (0) rfbLog("(Ignore the above error if this system is IPv4-only.)\n");
} else {
int res = -1, dmsg = 0;
char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen);
if (!s) s = strdup("unknown");
rfbLog("connect_tcp[ipv6]: trying sock=%d using %s\n", sock, s);
if (connect(sock, ap->ai_addr, ap->ai_addrlen) == 0) {
rfbLog("connect_tcp[ipv6]: trying sock=%d fam=%d proto=%d using %s\n",
sock, ap->ai_family, ap->ai_protocol, s);
res = connect(sock, ap->ai_addr, ap->ai_addrlen);
#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
if (res != 0) {
int zero = 0;
rfbLogPerror("connect_tcp[ipv6]: connect");
dmsg = 1;
if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) {
rfbLog("connect_tcp[ipv6]: trying again with IPV6_V6ONLY=0\n");
res = connect(sock, ap->ai_addr, ap->ai_addrlen);
dmsg = 0;
} else {
rfbLogPerror("connect_tcp[ipv6]: setsockopt IPV6_V6ONLY");
}
}
#endif
if (res == 0) {
rfbLog("connect_tcp[ipv6]: connect OK\n");
fd = sock;
if (!ipv6_client_ip_str) {
......@@ -693,8 +793,8 @@ int connect_tcp(char *host, int port) {
free(s);
break;
} else {
if (!dmsg) rfbLogPerror("connect_tcp[ipv6]: connect");
close(sock);
rfbLogPerror("connect_tcp[ipv6]: connect");
}
free(s);
}
......@@ -704,6 +804,30 @@ int connect_tcp(char *host, int port) {
}
#endif
}
if (fd < 0 && !fail4) {
/* this is a kludge for IPv4-only machines getting v4mapped string. */
char *q, *host2;
if (host[0] == '[') {
host2 = strdup(host+1);
} else {
host2 = strdup(host);
}
q = strrchr(host2, ']');
if (q) {
*q = '\0';
}
if (strstr(host2, "::ffff:") == host2 || strstr(host2, "::FFFF:") == host2) {
char *host3 = host2 + strlen("::ffff:");
if (dotted_ip(host3, 0)) {
rfbLog("connect_tcp[ipv4]: trying fallback to IPv4 for %s\n", host2);
fd = rfbConnectToTcpAddr(host3, port);
if (fd < 0) {
rfbLogPerror("connect_tcp[ipv4]: connection failed");
}
}
}
free(host2);
}
return fd;
}
......@@ -714,6 +838,11 @@ int listen_tcp(int port, in_addr_t iface, int try6) {
fail4 = 2;
}
if (port <= 0 || 65535 < port) {
/* for us, invalid port means do not listen. */
return -1;
}
if (fail4) {
if (fail4 > 1) {
rfbLog("TESTING: IPV4_FAILS for listen_tcp: port=%d try6=%d\n", port, try6);
......@@ -742,8 +871,6 @@ int listen_tcp(int port, in_addr_t iface, int try6) {
fd = listen6(port);
}
listen_str6 = save;
#else
if (try6) {}
#endif
}
return fd;
......
......@@ -40,7 +40,7 @@ extern char *raw2host(char *raw, int len);
extern char *raw2ip(char *raw);
extern char *ip2host(char *ip);
extern int ipv6_ip(char *host);
extern int dotted_ip(char *host);
extern int dotted_ip(char *host, int partial);
extern int get_remote_port(int sock);
extern int get_local_port(int sock);
extern char *get_remote_host(int sock);
......
......@@ -231,7 +231,11 @@ if (exists $ENV{CONNECT_SWITCH_LISTEN}) {
#
# E.g. CONNECT_SWITCH_LISTEN=192.168.0.32:443
#
($listen_host, $listen_port) = split(/:/, $ENV{CONNECT_SWITCH_LISTEN});
$listen_host = '';
$listen_port = '';
if ($ENV{CONNECT_SWITCH_LISTEN} =~ /^(.*):(\d+)$/) {
($listen_host, $listen_port) = ($1, $2);
}
}
my $httpd_host = 'localhost';
......@@ -241,7 +245,11 @@ if (exists $ENV{CONNECT_SWITCH_HTTPD}) {
#
# E.g. CONNECT_SWITCH_HTTPD=127.0.0.1:443
#
($httpd_host, $httpd_port) = split(/:/, $ENV{CONNECT_SWITCH_HTTPD});
$httpd_host = '';
$httpd_port = '';
if ($ENV{CONNECT_SWITCH_HTTPD} =~ /^(.*):(\d+)$/) {
($httpd_host, $httpd_port) = ($1, $2);
}
}
my $bufsize = 8192;
......@@ -353,6 +361,12 @@ use IO::Socket::INET;
use strict;
use warnings;
# Test for INET6 support:
#
my $have_inet6 = 0;
eval "use IO::Socket::INET6;";
$have_inet6 = 1 if $@ eq "";
my $killpid = 1;
setpgrp(0, 0);
......@@ -360,14 +374,13 @@ setpgrp(0, 0);
if (exists $ENV{CONNECT_SWITCH_LISTEN_IPV6}) {
# note we leave out LocalAddr.
my $cmd = '
use IO::Socket::INET6;
$listen_sock = IO::Socket::INET6->new(
Listen => 10,
LocalPort => $listen_port,
ReuseAddr => 1,
Domain => AF_INET6,
Proto => "tcp"
);
$listen_sock = IO::Socket::INET6->new(
Listen => 10,
LocalPort => $listen_port,
ReuseAddr => 1,
Domain => AF_INET6,
Proto => "tcp"
);
';
eval $cmd;
die "$@\n" if $@;
......@@ -493,8 +506,12 @@ sub handle_conn {
if ($str =~ /^CONNECT\s+(\S+)\s+HTTP\/(\S+)/) {
$hostport = $1;
$http_vers = $2;
my $h = '';
my $p = '';
my ($h, $p) = split(/:/, $hostport);
if ($hostport =~ /^(.*):(\d+)$/) {
($h, $p) = ($1, $2);
}
if ($p =~ /^\d+$/) {
# check allowed host list:
foreach my $hp (@allow) {
......@@ -532,7 +549,12 @@ sub handle_conn {
exit 0;
}
my ($host, $port) = split(/:/, $hostport);
my $host = '';
my $port = '';
if ($hostport =~ /^(.*):(\d+)$/) {
($host, $port) = ($1, $2);
}
print STDERR "connecting to: $host:$port\n" if $verbose;
......@@ -541,6 +563,15 @@ sub handle_conn {
PeerPort => $port,
Proto => "tcp"
);
print STDERR "connect to host='$host' port='$port' failed: $!\n" if !$sock;
if (! $sock && $have_inet6) {
eval {$sock = IO::Socket::INET6->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);};
print STDERR "connect to host='$host' port='$port' failed: $! (ipv6)\n" if !$sock;
}
my $msg;
# send the connect proxy reply:
......@@ -561,6 +592,13 @@ sub handle_conn {
PeerPort => $httpd_port,
Proto => "tcp"
);
if (! $sock && $have_inet6) {
eval {$sock = IO::Socket::INET6->new(
PeerAddr => $httpd_host,
PeerPort => $httpd_port,
Proto => "tcp"
);};
}
}
if (! $sock) {
......
......@@ -218,6 +218,11 @@
use strict;
use IO::Socket::INET;
# Test for INET6 support:
#
my $have_inet6 = 0;
eval "use IO::Socket::INET6;";
$have_inet6 = 1 if $@ eq "";
##########################################################################
# Path to the x11vnc program:
......@@ -261,6 +266,10 @@ my $find_free_port = 0;
#
my $starting_port = 7000;
# Listen on AF_INET6 if IO::Socket::INET6 is available.
#
my $listen_on_ipv6 = 0;
##########################################################################
# Port redirection mode:
......@@ -978,12 +987,24 @@ sub auto_select_port {
# Now try to find a free one:
#
for (my $p = $pmin; $p <= $pmax; $p++) {
my $sock = IO::Socket::INET->new(
Listen => 1,
LocalPort => $p,
ReuseAddr => 1,
Proto => "tcp"
);
my $sock = '';
if ($have_inet6 && $listen_on_ipv6) {
eval {$sock = IO::Socket::INET6->new(
Listen => 1,
LocalPort => $p,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::",
Proto => "tcp"
);};
} else {
$sock = IO::Socket::INET->new(
Listen => 1,
LocalPort => $p,
ReuseAddr => 1,
Proto => "tcp"
);
}
if ($sock) {
# we will keep this open until we call x11vnc:
$find_free_port = $sock;
......@@ -1159,12 +1180,23 @@ sub lock_fixed_port {
$reason = 'locked';
} else {
# unlocked, try to listen on port:
$sock = IO::Socket::INET->new(
Listen => 1,
LocalPort => $vnc_port,
ReuseAddr => 1,
Proto => "tcp"
);
if ($have_inet6 && $listen_on_ipv6) {
eval {$sock = IO::Socket::INET6->new(
Listen => 1,
LocalPort => $vnc_port,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::",
Proto => "tcp"
);};
} else {
$sock = IO::Socket::INET->new(
Listen => 1,
LocalPort => $vnc_port,
ReuseAddr => 1,
Proto => "tcp"
);
}
if ($sock) {
# we got it, now try to lock:
my $str = "$$:" . time();
......@@ -1266,12 +1298,23 @@ sub port_redir {
$rmlock = lock_fixed_port(90, 60);
} elsif ($find_free_port eq '0') {
$find_free_port = IO::Socket::INET->new(
Listen => 1,
LocalPort => $vnc_port,
ReuseAddr => 1,
Proto => "tcp"
);
if ($have_inet6 && $listen_on_ipv6) {
eval {$find_free_port = IO::Socket::INET6->new(
Listen => 1,
LocalPort => $vnc_port,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::",
Proto => "tcp"
);};
} else {
$find_free_port = IO::Socket::INET->new(
Listen => 1,
LocalPort => $vnc_port,
ReuseAddr => 1,
Proto => "tcp"
);
}
}
# In all cases, at this point $find_free_port is the listening
# socket.
......@@ -1409,13 +1452,24 @@ sub handle_conn {
exit 1;
}
my ($host, $port) = split(/:/, $redirect_host);
my $host = '';
my $port = '';
if ($redirect_host =~ /^(.*):(\d+)$/) {
($host, $port) = ($1, $2);
}
my $sock = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);
if (! $sock && $have_inet6) {
eval {$sock = IO::Socket::INET6->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);};
}
if (! $sock) {
close $client;
......
......@@ -28,17 +28,19 @@ protocol: Listen on one port for vnc clients (default 5900.)
Read 250 bytes from connecting vnc client or server.
Accept ID:<string> from clients and servers, connect them
together once both are present.
The string "RFB 000.000\n" is sent to the client (the client
must understand this means send ID:... or host:port.)
Also accept <host>:<port> from clients and make the
connection to the vnc server immediately.
Note there is no authentication or security WRT ID names or
identities; it us up to the client and server to manage that
and whether to encrypt the session, etc.
identities; it is up to the client and server to completely
manage that aspect and whether to encrypt the session, etc.
usage: ultravnc_repeater.pl [-r] [client_port [server_port]]
Use -r to refuse new server/client connections with an existing
Use -r to refuse new server/client connections when there is an existing
server/client ID. The default is to close the previous one.
To write to a log file set the env. var ULTRAVNC_REPEATER_LOGFILE.
......@@ -175,11 +177,18 @@ use warnings;
use IO::Socket::INET;
use IO::Select;
# Test for INET6 support:
#
my $have_inet6 = 0;
eval "use IO::Socket::INET6;";
$have_inet6 = 1 if $@ eq "";
print "perl module IO::Socket::INET6 not available: no IPv6 support.\n" if ! $have_inet6;
my $prog = 'ultravnc_repeater.pl';
my %ID;
my $refuse = 0;
my $init_timeout = 3;
my $init_timeout = 5;
if (@ARGV && $ARGV[0] =~ /-h/) {
print $usage;
......@@ -187,6 +196,7 @@ if (@ARGV && $ARGV[0] =~ /-h/) {
}
if (@ARGV && $ARGV[0] eq '-r') {
$refuse = 1;
print "enabling refuse mode (-r).\n";
shift;
}
......@@ -196,6 +206,7 @@ my $server_port = shift;
$client_port = 5900 unless $client_port;
$server_port = 5500 unless $server_port;
my $uname = `uname`;
my $repeater_bufsize = 250;
$repeater_bufsize = $ENV{BUFSIZE} if exists $ENV{BUFSIZE};
......@@ -208,9 +219,25 @@ my $client_listen = IO::Socket::INET->new(
ReuseAddr => 1,
Proto => "tcp"
);
if (! $client_listen) {
my $err1 = $!;
my $err2 = '';
$client_listen = '' if ! $client_listen;
my $client_listen6 = '';
if ($have_inet6) {
eval {$client_listen6 = IO::Socket::INET6->new(
Listen => 10,
LocalPort => $client_port,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::",
Proto => "tcp"
);};
$err2 = $!;
}
if (! $client_listen && ! $client_listen6) {
cleanup();
die "$prog: error: client listen on port $client_port: $!\n";
die "$prog: error: client listen on port $client_port: $err1 - $err2\n";
}
my $server_listen = IO::Socket::INET->new(
......@@ -219,9 +246,25 @@ my $server_listen = IO::Socket::INET->new(
ReuseAddr => 1,
Proto => "tcp"
);
if (! $server_listen) {
$err1 = $!;
$err2 = '';
$server_listen = '' if ! $server_listen;
my $server_listen6 = '';
if ($have_inet6) {
eval {$server_listen6 = IO::Socket::INET6->new(
Listen => 10,
LocalPort => $server_port,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::",
Proto => "tcp"
);};
$err2 = $!;
}
if (! $server_listen && ! $server_listen6) {
cleanup();
die "$prog: error: server listen on port $server_port: $!\n";
die "$prog: error: server listen on port $server_port: $err1 - $err2\n";
}
my $select = new IO::Select();
......@@ -230,8 +273,10 @@ if (! $select) {
die "$prog: select $!\n";
}
$select->add($client_listen);
$select->add($server_listen);
$select->add($client_listen) if $client_listen;
$select->add($client_listen6) if $client_listen6;
$select->add($server_listen) if $server_listen;
$select->add($server_listen6) if $server_listen6;
$SIG{INT} = sub {cleanup(); exit;};
$SIG{TERM} = sub {cleanup(); exit;};
......@@ -240,7 +285,10 @@ my $SOCK1 = '';
my $SOCK2 = '';
my $CURR = '';
print "watching for connections on ports $server_port/server and $client_port/client\n";
print "watching for IPv4 connections on $client_port/client\n" if $client_listen;
print "watching for IPv4 connections on $server_port/server\n" if $server_listen;
print "watching for IPv6 connections on $client_port/client\n" if $client_listen6;
print "watching for IPv6 connections on $server_port/server\n" if $server_listen6;
my $alarm_sock = '';
my $got_alarm = 0;
......@@ -255,9 +303,9 @@ sub alarm_handler {
while (my @ready = $select->can_read()) {
foreach my $fh (@ready) {
if ($fh == $client_listen) {
if ($fh == $client_listen || $fh == $client_listen6) {
print "new vnc client connecting at ", scalar(localtime), "\n";
} elsif ($fh == $server_listen) {
} elsif ($fh == $server_listen || $fh == $server_listen6) {
print "new vnc server connecting at ", scalar(localtime), "\n";
}
my $sock = $fh->accept();
......@@ -266,7 +314,7 @@ while (my @ready = $select->can_read()) {
next;
}
if ($fh == $client_listen) {
if ($fh == $client_listen || $fh == $client_listen6) {
my $str = "RFB 000.000\n";
my $len = length $str;
my $n = syswrite($sock, $str, $len, 0);
......@@ -294,9 +342,9 @@ while (my @ready = $select->can_read()) {
} elsif ($repeater_bufsize > 0 && $n != $size) {
print "$prog: short read $n != $size $!\n";
close $sock;
} elsif ($fh == $client_listen) {
} elsif ($fh == $client_listen || $fh == $client_listen6) {
do_new_client($sock, $buf);
} elsif ($fh == $server_listen) {
} elsif ($fh == $server_listen || $fh == $server_listen6) {
do_new_server($sock, $buf);
}
}
......@@ -309,10 +357,12 @@ sub do_new_client {
my $id = $1;
if (exists $ID{$id}) {
if ($ID{$id}{client}) {
print "refusing extra vnc client for ID:$id\n";
close $sock;
return;
if ($refuse) {
my $ref = $refuse;
if ($ref && !established($ID{$id}{sock})) {
print "socket for ID:$id is no longer established, closing it.\n";
$ref = 0;
}
if ($ref) {
print "refusing extra vnc client for ID:$id\n";
close $sock;
return;
......@@ -337,9 +387,11 @@ sub do_new_client {
}
} else {
my $str = sprintf("%s", $buf);
$str =~ s/\s*$//g;
$str =~ s/\0*$//g;
my $host = '';
my $port = '';
if ($str =~ /^(.+):(\d+)/) {
if ($str =~ /^(.+):(\d+)$/) {
$host = $1;
$port = $2;
} else {
......@@ -355,12 +407,23 @@ sub do_new_client {
print "resetting port from $port to $pnew\n";
$port = $pnew;
}
print "making vnc client connection directly to vnc server $host:$port\n";
print "making vnc client connection directly to vnc server host='$host' port='$port'\n";
my $sock2 = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);
if (! $sock2 && $have_inet6) {
print "IPv4 connect error: $!, trying IPv6 ...\n";
eval{$sock2 = IO::Socket::INET6->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);};
print "IPv6 connect error: $!\n" if !$sock2;
} else {
print "IPv4 connect error: $!\n" if !$sock2;
}
if (!$sock2) {
print "failed to connect to $host:$port\n";
close $sock;
......@@ -378,7 +441,12 @@ sub do_new_server {
my $store = 1;
if (exists $ID{$id}) {
if (! $ID{$id}{client}) {
if ($refuse) {
my $ref = $refuse;
if ($ref && !established($ID{$id}{sock})) {
print "socket for ID:$id is no longer established, closing it.\n";
$ref = 0;
}
if ($ref) {
print "refusing extra vnc server for ID:$id\n";
close $sock;
return;
......@@ -408,6 +476,78 @@ sub do_new_server {
}
}
sub established {
# hack for Linux to see if remote side has gone away:
my $fh = shift;
# if we can't figure things out, we return true.
if ($uname !~ /Linux/) {
return 1;
}
my @proc_net_tcp = ();
if (-e "/proc/net/tcp") {
push @proc_net_tcp, "/proc/net/tcp";
}
if (-e "/proc/net/tcp6") {
push @proc_net_tcp, "/proc/net/tcp6";
}
if (! @proc_net_tcp) {
return 1;
}
my $n = fileno($fh);
if (!defined($n)) {
return 1;
}
my $proc_fd = "/proc/$$/fd/$n";
if (! -e $proc_fd) {
return 1;
}
my $val = readlink($proc_fd);
if (! defined $val || $val !~ /socket:\[(\d+)\]/) {
return 1;
}
my $num = $1;
my $st = '';
foreach my $tcp (@proc_net_tcp) {
if (! open(TCP, "<$tcp")) {
next;
}
while (<TCP>) {
next if /^\s*[A-z]/;
chomp;
# sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
# 170: 0102000A:170C FE02000A:87FA 01 00000000:00000000 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1
# 172: 0102000A:170C FE02000A:87FA 08 00000000:00000001 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1
my @items = split(' ', $_);
my $state = $items[3];
my $inode = $items[9];
if (!defined $state || $state !~ /^\d+$/) {
next;
}
if (!defined $inode || $inode !~ /^\d+$/) {
next;
}
if ($inode == $num) {
$st = $state;
last;
}
}
close TCP;
last if $st ne '';
}
if ($st ne '' && $st != 1) {
return 0;
}
return 1;
}
sub handler {
print STDERR "$prog\[$$/$CURR]: got SIGTERM.\n";
close $SOCK1 if $SOCK1;
......@@ -535,8 +675,10 @@ sub xfer_both {
}
sub cleanup {
close $client_listen if defined $client_listen;
close $server_listen if defined $server_listen;
close $client_listen if $client_listen;
close $client_listen6 if $client_listen6;
close $server_listen if $server_listen;
close $server_listen6 if $server_listen6;
foreach my $id (keys %ID) {
close $ID{$id}{sock};
}
......
......@@ -134,10 +134,12 @@ int no_external_cmds = 1; /* cannot be turned back on. */
char *allowed_external_cmds = NULL;
int started_as_root = 0;
int host_lookup = 1;
#ifndef X11VNC_LISTEN6
int ipv6_listen = 0; /* -6 */
#if X11VNC_LISTEN6
int ipv6_listen = 1; /* -6 / -no6 */
int got_ipv6_listen = 1;
#else
int ipv6_listen = 1;
int ipv6_listen = 0; /* -6 / -no6 */
int got_ipv6_listen = 0;
#endif
int ipv6_listen_fd = -1;
int ipv6_http_fd = -1;
......
......@@ -116,6 +116,7 @@ extern char *allowed_external_cmds;
extern int started_as_root;
extern int host_lookup;
extern int ipv6_listen;
extern int got_ipv6_listen;
extern int ipv6_listen_fd;
extern int ipv6_http_fd;
extern int noipv6;
......
......@@ -516,8 +516,16 @@ void http_connections(int on) {
screen->httpInitDone = FALSE;
if (check_httpdir()) {
int fd6 = -1;
char *save = listen_str6;
screen->httpDir = http_dir;
rfb_http_init_sockets();
if (getenv("X11VNC_HTTP_LISTEN_LOCALHOST")) {
listen_str6 = "localhost";
}
if (screen->httpPort != 0 && screen->httpListenSock < 0) {
rfbLog("http_connections: failed to listen on http port: %d\n", screen->httpPort);
if (ipv6_listen) {
......@@ -534,11 +542,12 @@ void http_connections(int on) {
}
ipv6_http_fd = fd6;
if (ipv6_http_fd >= 0) {
rfbLog("http_connections: %s listening on IPv6 port=%d sock=%d\n",
screen->httpListenSock < 0 ? "Only" : "Also",
rfbLog("http_connections: Listening %s on IPv6 port %d (socket %d)\n",
screen->httpListenSock < 0 ? "only" : "also",
screen->httpPort, ipv6_http_fd);
}
}
listen_str6 = save;
}
} else {
rfbLog("http_connections: turning off http service.\n");
......
......@@ -3631,9 +3631,10 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
fd = listen6(screen->port);
if (fd < 0) {
ipv6_listen = 0;
rfbLog("Not listening on IPv6 interface.\n");
} else {
rfbLog("%slistening on IPv6 port=%d sock=%d\n",
screen->listenSock < 0 ? "Only " : "Also ",
rfbLog("Listening %s on IPv6 port %d (socket %d)\n",
screen->listenSock < 0 ? "only" : "also",
screen->port, fd);
ipv6_listen_fd = fd;
}
......
......@@ -2749,7 +2749,7 @@ void openssl_port(int restart) {
if (port < 0) {
rfbLog("openssl_port: could not obtain listening port %d\n", port);
if (!got_rfbport && !ipv6_listen) {
if (!got_rfbport && !got_ipv6_listen) {
rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
}
clean_up_exit(1);
......@@ -2760,8 +2760,10 @@ void openssl_port(int restart) {
sock = listen_tcp(port, iface, 0);
if (ipv6_listen) {
fd6 = listen6(port);
} else if (!got_rfbport) {
rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
} else if (!got_rfbport && !got_ipv6_listen) {
if (sock < 0) {
rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
}
}
if (sock < 0) {
if (fd6 < 0) {
......@@ -2770,7 +2772,7 @@ void openssl_port(int restart) {
clean_up_exit(1);
}
} else {
rfbLog("openssl_port: Info: only listening on IPv6\n");
rfbLog("openssl_port: Info: listening on IPv6 only.\n");
}
}
}
......
......@@ -1801,6 +1801,13 @@ char create_display[] =
" echo \"$tf\"\n"
"}\n"
"\n"
"missing_mesg() {\n"
" echo \"\" 1>&2\n"
" echo \"The program \\\"$1\\\" could not be found in PATH and standard locations.\" 1>&2\n"
" echo \"You probably need to install a package that provides the \\\"$1\\\" program.\" 1>&2\n"
" echo \"\" 1>&2\n"
"}\n"
"\n"
"server() {\n"
" authfile=`auth`\n"
" sess=`findsession`\n"
......@@ -2010,6 +2017,7 @@ char create_display[] =
"\n"
"try_Xvnc() {\n"
" if [ \"X$have_Xvnc\" = \"X\" ]; then\n"
" missing_mesg Xvnc\n"
" return\n"
" fi\n"
"\n"
......@@ -2078,6 +2086,7 @@ char create_display[] =
"\n"
"try_Xvfb() {\n"
" if [ \"X$have_Xvfb\" = \"X\" ]; then\n"
" missing_mesg Xvfb\n"
" return\n"
" fi\n"
"\n"
......@@ -2110,6 +2119,7 @@ char create_display[] =
"\n"
"try_Xdummy() {\n"
" if [ \"X$have_Xdummy\" = \"X\" ]; then\n"
" missing_mesg Xdummy\n"
" return\n"
" fi\n"
" if [ \"X$FD_XDUMMY_RUN_AS_ROOT\" != \"X\" -a \"X$have_root\" = \"X\" ]; then\n"
......
......@@ -2417,6 +2417,46 @@ static void do_try_switch(char *usslpeer, char *users_list_save) {
}
}
static void path_lookup(char *prog) {
/* see create_display script */
char *create_display_extra = "/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde4/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin:/usr/local/bin";
char *path, *try, *p;
int found = 0, len = strlen(create_display_extra);
if (getenv("PATH")) {
len += strlen(getenv("PATH")) + 1;
path = (char *) malloc((len+1) * sizeof(char));
sprintf(path, "%s:%s", getenv("PATH"), create_display_extra);
} else {
path = (char *) malloc((len+1) * sizeof(char));
sprintf(path, "%s", create_display_extra);
}
try = (char *) malloc((len+2+strlen(prog)) * sizeof(char));
p = strtok(path, ":");
while (p) {
struct stat sbuf;
sprintf(try, "%s/%s", p, prog);
if (stat(try, &sbuf) == 0) {
found = 1;
break;
}
p = strtok(NULL, ":");
}
free(path);
free(try);
if (!found) {
fprintf(stderr, "\n");
fprintf(stderr, "The program \"%s\" could not be found in PATH and standard locations.\n", prog);
fprintf(stderr, "You probably need to install a package that provides the \"%s\" program.\n", prog);
fprintf(stderr, "Without it FINDCREATEDISPLAY mode may not be able to create an X display.\n");
fprintf(stderr, "\n");
}
}
static int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int created_disp, int db) {
char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
char line1[1024], line2[16384];
......@@ -2497,6 +2537,18 @@ static int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int cr
rfbLog("wait_for_client: running: %s\n", cmd);
if (create_cmd != NULL) {
if (strstr(create_cmd, "Xvfb")) {
path_lookup("Xvfb");
}
if (strstr(create_cmd, "Xvnc")) {
path_lookup("Xvnc");
}
if (strstr(create_cmd, "Xdummy")) {
path_lookup("Xdummy");
}
}
if (unixpw && !unixpw_nis) {
int res = 0, k, j, i;
char line[18000];
......@@ -2996,11 +3048,11 @@ int wait_for_client(int *argc, char** argv, int http) {
if (got_rfbport && got_rfbport_val == 0) {
;
} else if (ipv6_listen && ipv6_listen_fd >= 0) {
rfbLog("Info: listening only on IPv6 interface.\n");
rfbLog("Info: listening on IPv6 interface only. (wait for client)\n");
} else {
rfbLogEnable(1);
rfbLog("Error: could not obtain listening port.\n");
if (!got_rfbport) {
rfbLog("Error: could not obtain listening port. (wait for client)\n");
if (!got_rfbport && !got_ipv6_listen) {
rfbLog("If this system is IPv6-only, use the -6 option.\n");
}
clean_up_exit(1);
......
......@@ -36,6 +36,7 @@ so, delete this exception statement from your version.
#include "cleanup.h"
#include "win_utils.h"
#include "unixpw.h"
#include "connections.h"
struct timeval _mysleep;
......
......@@ -46,6 +46,11 @@ so, delete this exception statement from your version.
#include <sys/ioctl.h>
#define CONFIG_VIDEO_V4L1_COMPAT
#include <linux/videodev.h>
#ifdef __LINUX_VIDEODEV2_H
# ifndef HAVE_V4L2
# define HAVE_V4L2 1
# endif
#endif
#define V4L_OK
#endif
#endif
......
......@@ -2,7 +2,7 @@
.TH X11VNC "1" "April 2010" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.9.10, lastmod: 2010-04-08
version: 0.9.10, lastmod: 2010-04-18
.SH SYNOPSIS
.B x11vnc
[OPTION]...
......@@ -105,7 +105,7 @@ stay away from other VNC servers near 5900.
.PP
\fB-rfbport\fR \fIstr\fR
.IP
The VNC port to listen on (a libvncserver option), e.g.
The VNC port to listen on (a LibVNCServer option), e.g.
5900, 5901, etc. If specified as "\fB-rfbport\fR \fIPROMPT\fR"
then the x11vnc \fB-gui\fR is used to prompt the user to
enter the port number.
......@@ -114,19 +114,32 @@ enter the port number.
.IP
IPv6 listening support. In addition to IPv4, the
IPv6 address is listened on for incoming connections.
The same port as IPv4 is used to listen. If you have
trouble compiling for this mode, set \fB-DX11VNC_IPV6=0\fR
in CPPFLAGS when configuring.
The same port as IPv4 is used.
.IP
Currently, the machine may need to have some IPv4
support, at the least for the loopback interface, for
everything to work correctly. However for most usage
modes IPv4 support is not required.
NOTE: This x11vnc binary was compiled to have the
"-6" IPv6 listening mode ENABLED by default (CPPFLAGS
\fB-DX11VNC_LISTEN6=1).\fR So to disable IPv6 listening mode
you MUST supply the "\fB-no6\fR" option (see below.)
.IP
The -6 mode works for both normal connections and
The "-6" mode works for both normal connections and
\fB-ssl\fR encrypted ones. Nearly everything is supported
for the IPv6 case, but there are a few exceptions.
See \fB-stunnel\fR for its IPv6 support.
.IP
Currently, for absolutely everything to work correctly
the machine may need to have some IPv4 support, at the
least for the loopback interface. However, for nearly
all usage modes no IPv4 support is required. See \fB-nopiv4.\fR
.IP
If you have trouble compiling or running in IPv6 mode,
set \fB-DX11VNC_IPV6=0\fR in CPPFLAGS when configuring to
disable IPv6 support.
.PP
\fB-no6\fR
.IP
Disable IPv6 listening support (only useful if the
"-6" mode is compiled in to be the default; see the
X11VNC_LISTEN6 description above under "-6".)
.PP
\fB-noipv6\fR
.IP
......@@ -562,7 +575,7 @@ Also, tightfilexfer is disabled in \fB-unixpw\fR mode.
\fB-ultrafilexfer\fR
.IP
Note: to enable UltraVNC filetransfer and to get it to
work you probably need to supply these libvncserver
work you probably need to supply these LibVNCServer
options: "\fB-rfbversion\fR \fI3.6 \fB-permitfiletransfer\fR"\fR
"\fB-ultrafilexfer\fR" is an alias for this combination.
.IP
......@@ -696,6 +709,8 @@ included inet6to4 script or the \fB-proxy\fR option.
As with \fB-connect,\fR except if none of the reverse
connections succeed, then x11vnc shuts down immediately
.IP
An easier to type alias for this option is '-coe'
.IP
By the way, if you do not want x11vnc to listen on
ANY interface use \fB-rfbport\fR 0 which is handy for the
\fB-connect_or_exit\fR mode.
......@@ -796,7 +811,7 @@ Only allow client connections from hosts matching
the comma separated list of hostnames or IP addresses.
Can also be a numerical IP prefix, e.g. "192.168.100."
to match a simple subnet, for more control build
libvncserver with libwrap support (See the FAQ). If the
LibVNCServer with libwrap support (See the FAQ). If the
list contains a "/" it instead is a interpreted
as a file containing addresses or prefixes that is
re-read each time a new client connects. Lines can be
......@@ -833,10 +848,11 @@ implies the IPv6 loopback address '::1' as well.
.PP
\fB-listen6\fR \fIstr\fR
.IP
When in IPv6 listen mode "-6", only listen on the
network interface with address \fIstr\fR. It currently
does not work for link scope addresses or non-numeric
hostname strings.
When in IPv6 listen mode "-6", listen only on the
network interface with address \fIstr\fR. It also works
for link scope addresses (fe80::219:dbff:fee5:3f92%eth0)
and IPv6 hostname strings (e.g. ipv6.google.com.)
Use LibVNCServer \fB-listen\fR option for the IPv4 interface.
.PP
\fB-nolookup\fR
.IP
......@@ -905,7 +921,7 @@ Supply a 2nd password for view-only logins. The \fB-passwd\fR
.PP
\fB-passwdfile\fR \fIfilename\fR
.IP
Specify the libvncserver password via the first line
Specify the LibVNCServer password via the first line
of the file \fIfilename\fR (instead of via \fB-passwd\fR on
the command line where others might see it via
.IR ps (1)
......@@ -2735,10 +2751,10 @@ If you do not want to expose the non-SSL HTTP port to
the network (i.e. you just want the single VNC/HTTPS
port, e.g. 5900, open for connections) then specify the
option \fB-env\fR X11VNC_HTTP_LISTEN_LOCALHOST=1 This way
the connection to the libvncserver httpd server will
the connection to the LibVNCServer httpd server will
only be available on localhost (note that in \fB-ssl\fR mode,
HTTPS requests are redirected from SSL to the non-SSL
libvncserver HTTP server.)
LibVNCServer HTTP server.)
.PP
\fB-http_oneport\fR
.IP
......@@ -2774,7 +2790,7 @@ port redirections.
.IP
Note that the \fB-env\fR X11VNC_HTTP_LISTEN_LOCALHOST=1
option described above under \fB-httpsredir\fR applies for
the libvncserver httpd server in all cases (ssl or not.)
the LibVNCServer httpd server in all cases (ssl or not.)
.PP
\fB-ssh\fR \fIuser@host:disp\fR
.IP
......@@ -2791,7 +2807,7 @@ viewer. "user@" is not needed unless the remote unix
username differs from the current one.
.IP
By default the remote sshd is usually configured to
only listen on localhost for rport, so the viewer may
listen only on localhost for rport, so the viewer may
need to ssh \fB-L\fR redir to "host" as well (See SSVNC to
automate this). The sshd setting GatewayPorts enables
listening on all interfaces for rport; viewers can
......@@ -3188,7 +3204,7 @@ screen PDA or laptop, or using a XRANDR-aware Desktop
where you resize often. It is best to be viewing with a
vncviewer that supports the NewFBSize encoding, since it
knows how to react to screen size changes. Otherwise,
libvncserver tries to do so something reasonable for
LibVNCServer tries to do so something reasonable for
viewers that cannot do this (portions of the screen
may be clipped, unused, etc).
.IP
......@@ -3747,7 +3763,7 @@ cursors).
\fB-noalphablend\fR
.IP
In XFIXES mode do not send cursor alpha channel data
to libvncserver. The default is to send it. The
to LibVNCServer. The default is to send it. The
alphablend effect will only be visible in \fB-nocursorshape\fR
mode or for clients with cursorshapeupdates turned
off. (However there is a hack for 32bpp with depth 24,
......@@ -4518,9 +4534,9 @@ for about 1.5 secs). Use 0 to disable. Default: 60
.PP
\fB-readtimeout\fR \fIn\fR
.IP
Set libvncserver rfbMaxClientWait to n seconds. On
Set LibVNCServer rfbMaxClientWait to n seconds. On
slow links that take a long time to paint the first
screen libvncserver may hit the timeout and drop the
screen LibVNCServer may hit the timeout and drop the
connection. Default: 20 seconds.
.PP
\fB-ping\fR \fIn\fR
......@@ -4608,7 +4624,7 @@ skip powering off the monitor.
\fB-noultraext\fR
.IP
Disable the following UltraVNC extensions: SingleWindow
and ServerInput. The others managed by libvncserver
and ServerInput. The others managed by LibVNCServer
(textchat, 1/n scaling, rfbEncodingUltra) are not.
.PP
\fB-chatwindow\fR
......@@ -4673,12 +4689,12 @@ there are problems or decrease it to live on the edge
\fB-sigpipe\fR \fIstring\fR
.IP
Broken pipe (SIGPIPE) handling. \fIstring\fR can be
"ignore" or "exit". For "ignore" libvncserver
"ignore" or "exit". For "ignore" LibVNCServer
will handle the abrupt loss of a client and continue,
for "exit" x11vnc will cleanup and exit at the 1st
broken connection.
.IP
This option is not really needed since libvncserver
This option is not really needed since LibVNCServer
is doing the correct thing now for quite some time.
However, for convenience you can use it to ignore other
signals, e.g. "\fB-sigpipe\fR \fIignore:HUP,INT,TERM\fR" in case
......@@ -4690,7 +4706,7 @@ for this option if you don't like the 'pipe'. Example:
.PP
\fB-threads,\fR \fB-nothreads\fR
.IP
Whether or not to use the threaded libvncserver
Whether or not to use the threaded LibVNCServer
algorithm [rfbRunEventLoop] if libpthread is available.
In this mode new threads (one for input and one
for output) are created to handle each new client.
......@@ -4985,7 +5001,7 @@ LINUX CONSOLE: The following describes some ways to
view and possibly interact with the Linux text/graphics
console (i.e. not X11 XFree86/Xorg)
.IP
Note: If the libvncserver LinuxVNC program is on your
Note: If the LibVNCServer LinuxVNC program is on your
system you may want to use that instead of the following
method because it will be faster and more accurate
for the Linux text console and includes mouse support.
......@@ -6082,7 +6098,7 @@ uinput_reset:n set uinput_reset to n ms.
.IP
uinput_always:n set uinput_always to 1/0.
.IP
progressive:n set libvncserver \fB-progressive\fR slice
progressive:n set LibVNCServer \fB-progressive\fR slice
height parameter to n.
.IP
desktop:str set \fB-desktop\fR name to str for new clients.
......@@ -6546,7 +6562,7 @@ For use with \fB-remote\fR nodeny: start out denying all
incoming clients until "\fB-remote\fR \fInodeny\fR" is used to
let them in.
.PP
These options are passed to libvncserver:
These options are passed to LibVNCServer:
.PP
\fB-rfbport\fR \fIport\fR
.IP
......
......@@ -2364,8 +2364,8 @@ int main(int argc, char* argv[]) {
overlay_cursor = 2;
continue;
}
#if !SKIP_8TO24
if (!strcmp(arg, "-8to24")) {
#if !SKIP_8TO24
cmap8to24 = 1;
if (i < argc-1) {
char *s = argv[i+1];
......@@ -2374,9 +2374,9 @@ int main(int argc, char* argv[]) {
i++;
}
}
#endif
continue;
}
#endif
if (!strcmp(arg, "-24to32")) {
xform24to32 = 1;
continue;
......@@ -2481,10 +2481,13 @@ int main(int argc, char* argv[]) {
continue;
}
if (!strcmp(arg, "-connect") ||
!strcmp(arg, "-connect_or_exit")) {
!strcmp(arg, "-connect_or_exit") ||
!strcmp(arg, "-coe")) {
CHECK_ARGC
if (!strcmp(arg, "-connect_or_exit")) {
connect_or_exit = 1;
} else if (!strcmp(arg, "-coe")) {
connect_or_exit = 1;
}
if (strchr(argv[++i], '/') && !strstr(argv[i], "repeater://")) {
struct stat sb;
......@@ -2522,20 +2525,27 @@ int main(int argc, char* argv[]) {
continue;
}
if (!strcmp(arg, "-listen6")) {
#if X11VNC_IPV6
listen_str6 = strdup(argv[++i]);
#endif
continue;
}
if (!strcmp(arg, "-nolookup")) {
host_lookup = 0;
continue;
}
#if X11VNC_IPV6
if (!strcmp(arg, "-6")) {
#if X11VNC_IPV6
ipv6_listen = 1;
got_ipv6_listen = 1;
#endif
continue;
}
if (!strcmp(arg, "-no6")) {
#if X11VNC_IPV6
ipv6_listen = 0;
got_ipv6_listen = 0;
#endif
continue;
}
if (!strcmp(arg, "-noipv6")) {
......@@ -2546,7 +2556,7 @@ int main(int argc, char* argv[]) {
noipv4 = 1;
continue;
}
#endif
if (!strcmp(arg, "-input")) {
CHECK_ARGC
allowed_input_str = strdup(argv[++i]);
......@@ -5785,7 +5795,7 @@ int main(int argc, char* argv[]) {
} else {
rfbLogEnable(1);
rfbLog("Error: could not obtain listening port.\n");
if (!got_rfbport) {
if (!got_rfbport && !got_ipv6_listen) {
rfbLog("If this system is IPv6-only, use the -6 option.\n");
}
clean_up_exit(1);
......
......@@ -316,14 +316,35 @@ extern int h_errno;
#include <arpa/inet.h>
#endif
#ifndef SOL_IPV6
#ifdef IPPROTO_IPV6
#define SOL_IPV6 IPPROTO_IPV6
#endif
#endif
#ifndef IPV6_V6ONLY
#ifdef IPV6_BINDV6ONLY
#define IPV6_V6ONLY IPV6_BINDV6ONLY
#endif
#endif
#ifndef X11VNC_IPV6
#if defined(AF_INET6) || defined(PF_INET6)
#if defined(AF_INET6)
#define X11VNC_IPV6 1
#else
#define X11VNC_IPV6 0
#endif
#endif
#ifndef X11VNC_LISTEN6
#define X11VNC_LISTEN6 1
#endif
#if !X11VNC_IPV6
#undef X11VNC_LISTEN6
#define X11VNC_LISTEN6 0
#endif
#if LIBVNCSERVER_HAVE_PWD_H
#include <pwd.h>
#include <grp.h>
......
......@@ -47,7 +47,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.10 lastmod: 2010-04-08";
char lastmod[] = "0.9.10 lastmod: 2010-04-18";
/* X display info */
......
......@@ -372,9 +372,7 @@ static void initialize_xinerama (void) {
/* n.b. change to XineramaGetData() someday */
xineramas = XineramaQueryScreens(dpy, &n);
if (verbose) {
rfbLog("Xinerama: number of sub-screens: %d\n", n);
}
rfbLog("Xinerama: number of sub-screens: %d\n", n);
if (! use_xwarppointer && ! got_noxwarppointer && n > 1) {
rfbLog("Xinerama: enabling -xwarppointer mode to try to correct\n");
......@@ -384,11 +382,8 @@ static void initialize_xinerama (void) {
}
if (n == 1) {
if (verbose) {
rfbLog("Xinerama: no blackouts needed (only one"
" sub-screen)\n");
rfbLog("\n");
}
rfbLog("Xinerama: no blackouts needed (only one sub-screen)\n");
rfbLog("\n");
XFree_wr(xineramas);
X_UNLOCK;
return; /* must be OK w/o change */
......@@ -405,6 +400,8 @@ static void initialize_xinerama (void) {
w = sc->width;
h = sc->height;
rfbLog("Xinerama: sub-screen[%d] %dx%d+%d+%d\n", i, w, h, x, y);
tmp_region = sraRgnCreateRect(x, y, x + w, y + h);
sraRgnSubtract(black_region, tmp_region);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment