x11vnc: fix wireframe crash under -clip. Add -redirect for

VNC redir.  -rawfb nullbig, randbig, solid, swirl, etc.
          FD_XDM mode to find_display.  -listdpy.  Add enlightenment.
          Xvnc.redirect FINDDISPLAY-vnc_redirect. -xvnc, -xvnc_redirect,
          -svc_xvnc. AUTO_PORT.
pull/1/head
runge 17 years ago
parent 6a6d26a747
commit 115e935f72

@ -1,10 +1,17 @@
2007-09-11 Karl Runge <runge@karlrunge.com>
* x11vnc: fix wireframe crash under -clip. Add -redirect for
VNC redir. -rawfb nullbig, randbig, solid, swirl, etc.
FD_XDM mode to find_display. -listdpy. Add enlightenment.
Xvnc.redirect FINDDISPLAY-vnc_redirect. -xvnc, -xvnc_redirect,
-svc_xvnc. AUTO_PORT.
2007-09-04 Karl Runge <runge@karlrunge.com> 2007-09-04 Karl Runge <runge@karlrunge.com>
* x11vnc: Add -autoport and -finddpy utils. -xdummy creation. * x11vnc: Add -autoport and -finddpy utils. -xdummy creation.
tweak xkb tiebreaking again. Shut off -ncache in dev mode. tweak xkb tiebreaking again. Shut off -ncache in dev mode.
watch for xrandr events even if no -xrandr. Tips for types watch for xrandr events even if no -xrandr. Tips for types
of URLs for java viewers. Add check_redir_services() to of URLs for java viewers. Add check_redir_services() to
create_display and tsdo() redir helper utility (-tsd). create_display and tsdo() redir helper utility (-tsd).
Improvements to Xdummy. Improvements to Xdummy. Prevent dcop XAUTHORITY=''
2007-08-19 Karl Runge <runge@karlrunge.com> 2007-08-19 Karl Runge <runge@karlrunge.com>
* x11vnc: better -xkb tie-breaking for up keystrokes. Add * x11vnc: better -xkb tie-breaking for up keystrokes. Add

File diff suppressed because it is too large Load Diff

@ -89,7 +89,7 @@ void clean_shm(int quick) {
break; break;
} }
} }
if (!quiet) { if (!quiet && cnt > 0) {
rfbLog("deleted %d tile_row polling images.\n", cnt); rfbLog("deleted %d tile_row polling images.\n", cnt);
} }
} }

@ -372,12 +372,13 @@ int cmd_ok(char *cmd) {
int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input, int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
int len, FILE *output) { int len, FILE *output) {
char *old_display = NULL; char *old_display = NULL;
char *addr = client->host; char *addr = NULL;
char str[100]; char str[100];
int rc, ok; int rc, ok;
ClientData *cd = NULL; ClientData *cd = NULL;
if (client != NULL) { if (client != NULL) {
cd = (ClientData *) client->clientData; cd = (ClientData *) client->clientData;
addr = client->host;
} }
if (addr == NULL || addr[0] == '\0') { if (addr == NULL || addr[0] == '\0') {
@ -400,7 +401,9 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
sprintf(str, "%d", (int) getpid()); sprintf(str, "%d", (int) getpid());
set_env("RFB_X11VNC_PID", str); set_env("RFB_X11VNC_PID", str);
if (client->state == RFB_PROTOCOL_VERSION) { if (client == NULL) {
;
} else if (client->state == RFB_PROTOCOL_VERSION) {
set_env("RFB_STATE", "PROTOCOL_VERSION"); set_env("RFB_STATE", "PROTOCOL_VERSION");
} else if (client->state == RFB_SECURITY_TYPE) { } else if (client->state == RFB_SECURITY_TYPE) {
set_env("RFB_STATE", "SECURITY_TYPE"); set_env("RFB_STATE", "SECURITY_TYPE");
@ -422,7 +425,7 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
/* set RFB_CLIENT_PORT to peer port for command to use */ /* set RFB_CLIENT_PORT to peer port for command to use */
if (cd && cd->client_port > 0) { if (cd && cd->client_port > 0) {
sprintf(str, "%d", cd->client_port); sprintf(str, "%d", cd->client_port);
} else { } else if (client) {
sprintf(str, "%d", get_remote_port(client->sock)); sprintf(str, "%d", get_remote_port(client->sock));
} }
set_env("RFB_CLIENT_PORT", str); set_env("RFB_CLIENT_PORT", str);
@ -437,7 +440,7 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
*/ */
if (cd && cd->server_ip) { if (cd && cd->server_ip) {
set_env("RFB_SERVER_IP", cd->server_ip); set_env("RFB_SERVER_IP", cd->server_ip);
} else { } else if (client) {
char *sip = get_local_host(client->sock); char *sip = get_local_host(client->sock);
set_env("RFB_SERVER_IP", sip); set_env("RFB_SERVER_IP", sip);
if (sip) free(sip); if (sip) free(sip);
@ -445,7 +448,7 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
if (cd && cd->server_port > 0) { if (cd && cd->server_port > 0) {
sprintf(str, "%d", cd->server_port); sprintf(str, "%d", cd->server_port);
} else { } else if (client) {
sprintf(str, "%d", get_local_port(client->sock)); sprintf(str, "%d", get_local_port(client->sock));
} }
set_env("RFB_SERVER_PORT", str); set_env("RFB_SERVER_PORT", str);

@ -1790,6 +1790,13 @@ void cursor_position(int x, int y) {
y = nfix(y, scaled_y); y = nfix(y, scaled_y);
} }
if (clipshift) {
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x >= dpy_x) x = dpy_x-1;
if (y >= dpy_y) y = dpy_y-1;
}
if (x == screen->cursorX && y == screen->cursorY) { if (x == screen->cursorX && y == screen->cursorY) {
return; return;
} }
@ -1940,6 +1947,18 @@ if (0) fprintf(stderr, "check_x11_pointer %d %d\n", root_x, root_y);
x = root_x - off_x - coff_x; x = root_x - off_x - coff_x;
y = root_y - off_y - coff_y; y = root_y - off_y - coff_y;
if (clipshift) {
static int cnt = 0;
if (x < 0 || y < 0 || x >= dpy_x || y >= dpy_y) {
if (cnt++ % 4 != 0) {
if (debug_pointer) {
rfbLog("Skipping cursor_position() outside our clipshift\n");
}
return 0;
}
}
}
/* record the cursor position in the rfb screen */ /* record the cursor position in the rfb screen */
cursor_position(x, y); cursor_position(x, y);

@ -762,17 +762,30 @@ void print_help(int mode) {
" in addition to this option.\n" " in addition to this option.\n"
"\n" "\n"
#endif #endif
"-find Find the user's display using FINDDISPLAY. It is\n" "-find Find the user's display using FINDDISPLAY. This is an\n"
" an alias for \"-display WAIT:cmd=FINDDISPLAY\".\n" " alias for \"-display WAIT:cmd=FINDDISPLAY\".\n"
" Use -finddpy to run the FINDDISPLAY program and exit.\n" "\n"
" For this and the next few options see -display WAIT:...\n"
" below for all of the details.\n"
"\n"
"-finddpy Run the FINDDISPLAY program, print out the found\n"
" display (if any) and exit. Output is like: DISPLAY=:0.0\n"
" DISPLAY=:0.0,XPID=12345 or DISPLAY=:0.0,VT=7. XPID is\n"
" the process ID of the found X server. VT is the Linux\n"
" virtual terminal of the X server.\n"
"-listdpy Have the FINDDISPLAY program list all of your displays\n"
" (i.e. all the X displays on the local machine that you\n"
" have access rights to).\n"
"\n" "\n"
"-create First try to find the user's display using FINDDISPLAY,\n" "-create First try to find the user's display using FINDDISPLAY,\n"
" if that doesn't work create an X session via the\n" " if that doesn't succeed create an X session via the\n"
" FINDCREATEDISPLAY method. This is an alias for\n" " FINDCREATEDISPLAY method. This is an alias for\n"
" \"-display WAIT:cmd=FINDCREATEDISPLAY-Xvfb\".\n" " \"-display WAIT:cmd=FINDCREATEDISPLAY-Xvfb\".\n"
"\n" "\n"
"-xdummy As -create except Xdummy instead of Xvfb. Implies\n" "-xdummy As in -create, except Xdummy instead of Xvfb. Implies\n"
" FD_XDUMMY_NOROOT=1.\n" " FD_XDUMMY_NOROOT=1.\n"
"-xvnc As in -create, except Xvnc instead of Xvfb.\n"
"-xvnc_redirect As in -create, except Xvnc.redirect instead of Xvfb.\n"
"\n" "\n"
"-svc Terminal services mode. Also \"-service\". Alias for\n" "-svc Terminal services mode. Also \"-service\". Alias for\n"
" -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb -unixpw\n" " -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb -unixpw\n"
@ -780,11 +793,30 @@ void print_help(int mode) {
"\n" "\n"
"-svc_xdummy As -svc except Xdummy instead of Xvfb. Implies\n" "-svc_xdummy As -svc except Xdummy instead of Xvfb. Implies\n"
" FD_XDUMMY_NOROOT=1.\n" " FD_XDUMMY_NOROOT=1.\n"
"-svc_xvnc As -svc except Xvnc instead of Xvfb.\n"
"\n" "\n"
"-xdmsvc Terminal services mode. Also \"-xdm_service\". Alias for\n" "-xdmsvc Terminal services mode. Also \"-xdm_service\". Alias for\n"
" -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw\n" " -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw\n"
" -users unixpw= -ssl SAVE\n" " -users unixpw= -ssl SAVE\n"
"\n" "\n"
"-redirect port As in FINDCREATEDISPLAY-Xvnc.redirect mode except\n"
" redirect immediately (i.e. without X session finding\n"
" or creation) to a VNC server listening on port. You\n"
" can also supply host:port to redirect to a different\n"
" machine.\n"
"\n"
" If 0 <= port < 200 it is taken as a VNC display (5900 is\n"
" added to get the actual port), if port < 0 then -port\n"
" is used.\n"
"\n"
" Probably the only reason to use the -redirect option is\n"
" in conjunction with SSL support, e.g. -ssl, -ssl SAVE.\n"
" This provides an easy way to add SSL encryption to a VNC\n"
" server that does not support SSL (e.g. Xvnc or vnc.so)\n"
" In fact, the protocol does not even need to be VNC,\n"
" and so \"-ssl SAVE -redirect host:port\" can act as a\n"
" replacement for stunnel(1).\n"
"\n"
"-display WAIT:... A special usage mode for the normal -display option.\n" "-display WAIT:... A special usage mode for the normal -display option.\n"
" Useful with -unixpw, but can be used independently\n" " Useful with -unixpw, but can be used independently\n"
" of it. If the display string begins with WAIT: then\n" " of it. If the display string begins with WAIT: then\n"
@ -845,15 +877,16 @@ void print_help(int mode) {
" your long \"login:\" line press the Up arrow once\n" " your long \"login:\" line press the Up arrow once\n"
" (before typing anything else).\n" " (before typing anything else).\n"
"\n" "\n"
" Another option is \"geom=WxH\" or \"geom=WxHxD\" (or\n" " Another option is \"geom=WxH\" or \"geom=WxHxD\"\n"
" ge=). This only has an effect in FINDCREATEDISPLAY\n" " (or ge=). This only has an effect in FINDCREATEDISPLAY\n"
" mode when a virtual X server such as Xvfb is going\n" " mode when a virtual X server such as Xvfb is going to\n"
" to be created. It sets the width and height of\n" " be created. It sets the width and height of the new\n"
" the new display, and optionally the color depth as\n" " display, and optionally the color depth as well. You\n"
" well. You can also supply \"gnome\", \"kde\", \"twm\",\n" " can also supply \"gnome\", \"kde\", \"twm\", \"fvwm\",\n"
" \"fvwm\", \"mwm\", \"dtwm\", \"wmaker\", \"Xsession\",\n" " \"mwm\", \"dtwm\", \"wmaker\", \"enlightenment\",\n"
" or \"failsafe\" (same as \"xterm\") to have the created\n" " \"Xsession\", or \"failsafe\" (same as \"xterm\")\n"
" display use that mode for the user session.\n" " to have the created display use that mode for the\n"
" user session.\n"
"\n" "\n"
" To disable the option setting set the environment\n" " To disable the option setting set the environment\n"
" variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc.\n" " variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc.\n"
@ -885,7 +918,9 @@ void print_help(int mode) {
" DISPLAY variable and xauthority data (see who(1)).\n" " DISPLAY variable and xauthority data (see who(1)).\n"
"\n" "\n"
" To have this default script printed to stdout (e.g. for\n" " To have this default script printed to stdout (e.g. for\n"
" customization) run with WAIT:cmd=FINDDISPLAY-print\n" " customization) run with WAIT:cmd=FINDDISPLAY-print To\n"
" have the script run to print what display it would find\n"
" use \"-finddpy\" or WAIT:cmd=FINDDISPLAY-run\n"
"\n" "\n"
" As another special case, WAIT:cmd=HTTPONCE will allow\n" " As another special case, WAIT:cmd=HTTPONCE will allow\n"
" x11vnc to service one http request and then exit.\n" " x11vnc to service one http request and then exit.\n"
@ -998,6 +1033,25 @@ void print_help(int mode) {
" If you set the env. var WAITBG=1 x11vnc will go into\n" " If you set the env. var WAITBG=1 x11vnc will go into\n"
" the background once listening in wait mode.\n" " the background once listening in wait mode.\n"
"\n" "\n"
" Another special mode is FINDCREATEDISPLAY-Xvnc.redirect,\n"
" (or FINDDISPLAY-Xvnc.redirect). In this case it will\n"
" start up Xvnc as above if needed, but instead of\n"
" polling it in its normal way, it simply does a socket\n"
" redirection of the connected VNC viewer to the Xvnc.\n"
"\n"
" So in Xvnc.redirect x11vnc does no VNC but merely\n"
" transfers the data back and forth. This should be\n"
" faster then x11vnc's polling method, but not as fast\n"
" as connecting directly to the Xvnc with the VNC Viewer.\n"
" The idea here is to take advantage of x11vnc's display\n"
" finding/creating scheme, SSL, and perhaps a few others.\n"
" Most of x11vnc's options do not apply in this mode.\n"
"\n"
" Xvnc.redirect should also work for the vnc.so X server\n"
" module for the h/w display however it will work only\n"
" for finding the display and the user must already be\n"
" logged into the X console.\n"
"\n"
#ifndef NO_SSL_OR_UNIXPW #ifndef NO_SSL_OR_UNIXPW
"-nossl Disable the -ssl option (see below). Since -ssl is off\n" "-nossl Disable the -ssl option (see below). Since -ssl is off\n"
" by default -nossl would only be used on the commandline\n" " by default -nossl would only be used on the commandline\n"

@ -120,6 +120,8 @@ int launch_gui = 0; /* -gui */
#define AVAHI 0 #define AVAHI 0
#endif #endif
int avahi = AVAHI; /* -avahi, -mdns */ int avahi = AVAHI; /* -avahi, -mdns */
int vnc_redirect = 0;
int vnc_redirect_sock = -1;
int use_modifier_tweak = 1; /* use the shift/altgr modifier tweak */ int use_modifier_tweak = 1; /* use the shift/altgr modifier tweak */
int watch_capslock = 0; /* -capslock */ int watch_capslock = 0; /* -capslock */

@ -92,6 +92,8 @@ extern int xform24to32;
extern int launch_gui; extern int launch_gui;
extern int avahi; extern int avahi;
extern int vnc_redirect;
extern int vnc_redirect_sock;
extern int use_modifier_tweak; extern int use_modifier_tweak;
extern int watch_capslock; extern int watch_capslock;

@ -24,6 +24,7 @@
#include "macosx.h" #include "macosx.h"
#include "macosxCG.h" #include "macosxCG.h"
#include "avahi.h" #include "avahi.h"
#include "solid.h"
#include <rfb/rfbclient.h> #include <rfb/rfbclient.h>
@ -1141,6 +1142,7 @@ XImage *initialize_raw_fb(int reset) {
int closedpy = 1, i, m, db = 0; int closedpy = 1, i, m, db = 0;
int do_macosx = 0; int do_macosx = 0;
int do_reflect = 0; int do_reflect = 0;
char *unlink_me = NULL;
static char *last_file = NULL; static char *last_file = NULL;
static int last_mode = 0; static int last_mode = 0;
@ -1218,14 +1220,75 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
if (! raw_fb_str) { if (! raw_fb_str) {
return NULL; return NULL;
} }
/* testing aliases */
if (!strcasecmp(raw_fb_str, "NULL") || !strcasecmp(raw_fb_str, "ZERO") if (!strcasecmp(raw_fb_str, "NULL") || !strcasecmp(raw_fb_str, "ZERO")
|| !strcasecmp(raw_fb_str, "NONE")) { || !strcasecmp(raw_fb_str, "NONE")) {
raw_fb_str = strdup("map:/dev/zero@640x480x32"); raw_fb_str = strdup("map:/dev/zero@640x480x32");
} else if (!strcasecmp(raw_fb_str, "NULLBIG") || !strcasecmp(raw_fb_str, "NONEBIG")) {
raw_fb_str = strdup("map:/dev/zero@1024x768x32");
} }
if (!strcasecmp(raw_fb_str, "RAND")) { if (!strcasecmp(raw_fb_str, "RAND")) {
raw_fb_str = strdup("file:/dev/urandom@128x128x16"); raw_fb_str = strdup("file:/dev/urandom@128x128x16");
} else if (!strcasecmp(raw_fb_str, "RANDBIG")) {
raw_fb_str = strdup("file:/dev/urandom@640x480x16");
} else if (!strcasecmp(raw_fb_str, "RANDHUGE")) {
raw_fb_str = strdup("file:/dev/urandom@1024x768x16");
}
if (strstr(raw_fb_str, "solid=") == raw_fb_str) {
char *n = raw_fb_str + strlen("solid=");
char tmp[] = "/tmp/solid.XXXXXX";
char str[100];
unsigned int vals[1024], val;
int x, y, fd, w = 1024, h = 768;
if (strstr(n, "0x")) {
if (sscanf(n, "0x%lx", &val) != 1) {
val = 0;
}
}
if (val == 0) {
val = get_pixel(n);
}
if (val == 0) {
val = 0xFF00FF;
}
fd = mkstemp(tmp);
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
vals[x] = val;
}
write(fd, (char *)vals, 4 * w);
}
close(fd);
fd = open(tmp, O_WRONLY);
unlink_me = strdup(tmp);
sprintf(str, "map:%s@%dx%dx32", tmp, w, h);
raw_fb_str = strdup(str);
} else if (strstr(raw_fb_str, "swirl") == raw_fb_str) {
char tmp[] = "/tmp/solid.XXXXXX";
char str[100];
unsigned int val[1024];
unsigned int c1, c2, c3, c4;
int x, y, fd, w = 1024, h = 768;
fd = mkstemp(tmp);
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
c1 = 0;
c2 = ((x+y)*128)/(w+h);
c3 = (x*128)/w;
c4 = (y*256)/h;
val[x] = (c1 << 24) | (c2 << 16) | (c3 << 8) | (c4 << 0);
}
write(fd, (char *)val, 4 * w);
}
close(fd);
fd = open(tmp, O_WRONLY);
unlink_me = strdup(tmp);
sprintf(str, "map:%s@%dx%dx32", tmp, w, h);
raw_fb_str = strdup(str);
} }
if ( (q = strstr(raw_fb_str, "setup:")) == raw_fb_str) { if ( (q = strstr(raw_fb_str, "setup:")) == raw_fb_str) {
FILE *pipe; FILE *pipe;
char line[1024], *t; char line[1024], *t;
@ -1578,6 +1641,10 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
clean_up_exit(1); clean_up_exit(1);
} }
if (unlink_me) {
unlink(unlink_me);
}
if (! raw_fb_image) { if (! raw_fb_image) {
raw_fb_image = &ximage_struct; raw_fb_image = &ximage_struct;
} }
@ -2866,7 +2933,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen->inetdSock = fd; screen->inetdSock = fd;
screen->port = 0; screen->port = 0;
} else if (auto_port > 0) { } else if (! got_rfbport && auto_port > 0) {
int lport = find_free_port(auto_port, auto_port+200); int lport = find_free_port(auto_port, auto_port+200);
screen->autoPort = FALSE; screen->autoPort = FALSE;
screen->port = lport; screen->port = lport;

@ -933,7 +933,9 @@ void openssl_port(void) {
clean_up_exit(1); clean_up_exit(1);
} }
rfbLog("openssl_port: listen on port/sock %d/%d\n", port, sock); rfbLog("openssl_port: listen on port/sock %d/%d\n", port, sock);
if (!quiet) {
announce(port, 1, NULL); announce(port, 1, NULL);
}
openssl_sock = sock; openssl_sock = sock;
openssl_port_num = port; openssl_port_num = port;
@ -1971,6 +1973,12 @@ if (db) fprintf(stderr, "iface: %s\n", iface);
openssl_last_helper_pid = pid; openssl_last_helper_pid = pid;
ssl_helper_pid(pid, vsock); ssl_helper_pid(pid, vsock);
if (vnc_redirect) {
vnc_redirect_sock = vsock;
openssl_last_helper_pid = 0;
return;
}
client = rfbNewClient(screen, vsock); client = rfbNewClient(screen, vsock);
openssl_last_helper_pid = 0; openssl_last_helper_pid = 0;
@ -2630,12 +2638,18 @@ static void init_prng(void) {
#endif /* LIBVNCSERVER_HAVE_LIBSSL */ #endif /* LIBVNCSERVER_HAVE_LIBSSL */
void raw_xfer(int csock, int s_in, int s_out) { void raw_xfer(int csock, int s_in, int s_out) {
char buf[8192]; char buf0[8192];
int sz = 8192, n, m, status, db = 1; int sz = 8192, n, m, status, db = 1;
char *buf;
#ifdef FORK_OK #ifdef FORK_OK
pid_t par = getpid(); pid_t par = getpid();
pid_t pid = fork(); pid_t pid = fork();
buf = buf0;
if (vnc_redirect) {
/* change buf size some direction. */
}
/* this is for testing, no SSL just socket redir */ /* this is for testing, no SSL just socket redir */
if (pid < 0) { if (pid < 0) {
exit(1); exit(1);

@ -744,12 +744,104 @@ char find_display[] =
" exit 1\n" " exit 1\n"
"fi\n" "fi\n"
"\n" "\n"
"prdpy () {\n"
" d1=$1\n"
" chvt0=\"\"\n"
" if [ \"X$uname\" = \"XLinux\" ]; then\n"
" d2=$d1\n"
" d3=`echo \"$d2\" | sed -e 's/^.*:/:/' -e 's/\\..*$//'`\n"
" d4=\"($d2|$d3)\"\n"
" vt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | egrep ' vt([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -n 1`\n"
" if [ \"X$vt\" != \"X\" ]; then\n"
" vt=`echo \"$vt\" | sed -e 's/^.* vt\\([0-9][0-9]*\\) .*$/\\1/'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt0=\",VT=$vt\"\n"
" fi\n"
" else\n"
" vt=`ps wwwwwaux | grep X | egrep \" $d4 \" | egrep ' tty([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -n 1`\n"
" if [ \"X$vt\" != \"X\" ]; then\n"
" vt=`echo \"$vt\" | sed -e 's/^.* tty\\([0-9][0-9]*\\) .*$/\\1/'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt0=\",VT=$vt\"\n"
" fi\n"
" else\n"
" pvt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | head -n 1 | awk '{print $2}'`\n"
" if [ \"X$pvt\" != \"X\" ]; then\n"
" vt=`lsof -p \"$pvt\" 2>/dev/null | egrep '/dev/tty([789]|[1-9][0-9][0-9]*)$' | grep -v grep | head -n 1 | awk '{print $NF}' | sed -e 's,/dev/tty,,'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt0=\",VT=$vt\"\n"
" else\n"
" chvt0=\",XPID=$pvt\"\n"
" fi\n"
" fi\n"
" fi\n"
" fi\n"
" fi\n"
" echo \"$d1$chvt0\"\n"
"}\n"
"\n"
"uname=`uname`\n"
"nsout=`netstat -an`\n"
"if [ \"X$uname\" = \"XDarwin\" ]; then\n"
" psout=`ps aux 2>/dev/null | grep -wv PID | grep -v grep`\n"
" pslist=`echo \"$psout\" | awk '{print $2}'`\n"
"else\n"
" psout=`ps -ef 2>/dev/null | grep -wv PID | grep -v grep`\n"
" pslist=`echo \"$psout\" | awk '{print $2}'`\n"
"fi\n"
"\n"
"if [ \"X$FD_XDM\" != \"X\" ]; then\n"
" list=\"\"\n"
" for pair in `echo \"$psout\" | grep '/X.* :[0-9][0-9]* .*-auth' | egrep -v 'startx|xinit' | sed -e 's,^.*/X.* \\(:[0-9][0-9]*\\) .* -auth \\([^ ][^ ]*\\).*$,\\1\\,\\2,' | sort -u`\n"
" do\n"
" da=`echo \"$pair\" | awk -F, '{print $1}'`\n"
" xa=`echo \"$pair\" | awk -F, '{print $2}'`\n"
" if [ -f $xa -a -r $xa ]; then\n"
" env XAUTHORITY=\"$xa\" xdpyinfo -display \"$da\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n"
" env XAUTHORITY=/dev/null xdpyinfo -display \"$da\" >/dev/null 2>&1\n"
" if [ $? != 0 ]; then\n"
" y=`prdpy $da`\n"
" echo \"DISPLAY=$y\"\n"
" if [ \"X$showxauth\" != \"X\" ]; then\n"
" cook=`xauth -f \"$xa\" list | head -n 1 | awk '{print $NF}'`\n"
" tf=$HOME/.xat.$$\n"
" rm -f $tf\n"
" if [ -f $tf ]; then\n"
" exit 1\n"
" fi\n"
" touch $tf 2>/dev/null\n"
" chmod 600 $tf 2>/dev/null\n"
" if [ ! -f $tf ]; then\n"
" tf=/tmp/.xat.$$\n"
" rm -f $tf\n"
" if [ -f $tf ]; then\n"
" exit 1\n"
" fi\n"
" touch $tf 2>/dev/null\n"
" chmod 600 $tf 2>/dev/null\n"
" if [ ! -f $tf ]; then\n"
" exit 1\n"
" fi\n"
" fi\n"
" xauth -f $tf add \"$da\" . $cook\n"
" xauth -f $tf extract - \"$da\" 2>/dev/null\n"
" rm -f $tf\n"
" fi\n"
" exit 0\n"
" fi\n"
" fi\n"
" fi\n"
" done\n"
" exit 1\n"
"fi\n"
"\n"
"# Now try to match X DISPLAY to user:\n" "# Now try to match X DISPLAY to user:\n"
"\n" "\n"
"# who(1) output column 2:\n" "# who(1) output column 2:\n"
"#gone=`last $user | grep 'gone.*no.logout' | awk '{print $2}' | grep '^:' | sed -e 's,/.*,,' | tr '\\n' '|'`\n" "#gone=`last $user | grep 'gone.*no.logout' | awk '{print $2}' | grep '^:' | sed -e 's,/.*,,' | tr '\\n' '|'`\n"
"#gone=\"${gone}__quite_impossible__\"\n" "#gone=\"${gone}__quite_impossible__\"\n"
"#display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | egrep -v \" ($gone)\\>\" | head -1 \\\n" "#display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | egrep -v \" ($gone)\\>\" | head -n 1 \\\n"
"# | awk '{print $2}' | sed -e 's,/.*$,,'`\n" "# | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
"poss=\"\"\n" "poss=\"\"\n"
"list=`who | grep \"^${user}[ ][ ]*:[0-9]\" | awk '{print $2}' | sed -e 's,/.*$,,'`\n" "list=`who | grep \"^${user}[ ][ ]*:[0-9]\" | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
@ -759,12 +851,11 @@ char find_display[] =
"if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" = \"X\" ]; then\n" "if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" = \"X\" ]; then\n"
" list=\"$list \"`xauth list | awk '{print $1}' | grep /unix | grep \"^${host}\" | sed -e 's/^.*:/:/' | sort -n | uniq`\n" " list=\"$list \"`xauth list | awk '{print $1}' | grep /unix | grep \"^${host}\" | sed -e 's/^.*:/:/' | sort -n | uniq`\n"
"fi\n" "fi\n"
"uname=`uname`\n" "\n"
"nsout=`netstat -an`\n"
"psout=`ps -ef`\n"
"for p in $list\n" "for p in $list\n"
"do\n" "do\n"
" d=`echo \"$p\" | sed -e 's/://' -e 's/\\..*$//'`\n" " xa=`echo \"$p\" | awk -F, '{print $2}'`\n"
" d=`echo \"$p\" | sed -e 's/,.*$//' -e 's/://' -e 's/\\..*$//'`\n"
" ok=\"\"\n" " ok=\"\"\n"
" if [ \"X$X11VNC_SKIP_DISPLAY\" != \"X\" ]; then\n" " if [ \"X$X11VNC_SKIP_DISPLAY\" != \"X\" ]; then\n"
" mat=\"\"\n" " mat=\"\"\n"
@ -799,7 +890,7 @@ char find_display[] =
" if [ -d \"/proc/$pid\" ]; then\n" " if [ -d \"/proc/$pid\" ]; then\n"
" ok=1\n" " ok=1\n"
" fi\n" " fi\n"
" elif echo \"$psout\" | awk '{print $2}' | grep -w \"$pid\" > /dev/null; then\n" " elif echo \"$pslist\" | grep -w \"$pid\" > /dev/null; then\n"
" ok=1\n" " ok=1\n"
" fi\n" " fi\n"
" fi\n" " fi\n"
@ -810,14 +901,57 @@ char find_display[] =
" fi\n" " fi\n"
"done\n" "done\n"
"\n" "\n"
"seenvalues=\"\"\n"
"\n"
"seen() {\n"
" v=$1\n"
" if [ \"X$seenvalues\" != \"X\" ]; then\n"
" for v2 in $seenvalues\n"
" do\n"
" if [ \"X$v\" = \"X$v2\" ]; then\n"
" seenret=1\n"
" return\n"
" fi\n"
" done\n"
" fi\n"
" if [ \"X$seenvalues\" = \"X\" ]; then\n"
" seenvalues=\"$v\"\n"
" else\n"
" seenvalues=\"$seenvalues $v\"\n"
" fi\n"
" seenret=0\n"
"}\n"
"\n"
"poss=`echo \"$poss\" | sed -e 's/^ *//' -e 's/ *$//'`\n" "poss=`echo \"$poss\" | sed -e 's/^ *//' -e 's/ *$//'`\n"
"\n" "\n"
"if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" != \"X\" ]; then\n" "if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" != \"X\" ]; then\n"
" display=`echo \"$poss\" | tr ' ' '\\n' | head -1`\n" " if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
" for p in $poss\n"
" do\n"
" if [ \"X$p\" = \"X\" ]; then\n"
" continue\n"
" fi\n"
" seen \"$p\"\n"
" if [ \"X$seenret\" = \"X1\" ]; then\n"
" continue\n"
" fi\n"
" y=`prdpy $p`\n"
" echo $y\n"
" done\n"
" exit 0\n"
" fi\n"
" display=`echo \"$poss\" | tr ' ' '\\n' | head -n 1`\n"
"else\n" "else\n"
" freebie=\"\"\n" " freebie=\"\"\n"
" for p in $poss\n" " for p in $poss\n"
" do\n" " do\n"
" if [ \"X$p\" = \"X\" ]; then\n"
" continue\n"
" fi\n"
" seen \"$p\"\n"
" if [ \"X$seenret\" = \"X1\" ]; then\n"
" continue\n"
" fi\n"
" xdpyinfo -display \"$p\" >/dev/null 2>&1\n" " xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n" " if [ $? = 0 ]; then\n"
" if [ \"X$FD_TAG\" != \"X\" ]; then\n" " if [ \"X$FD_TAG\" != \"X\" ]; then\n"
@ -834,8 +968,18 @@ char find_display[] =
" if [ $? != 0 ]; then\n" " if [ $? != 0 ]; then\n"
" # keep it\n" " # keep it\n"
" display=\"$p\"\n" " display=\"$p\"\n"
" if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
" y=`prdpy $p`\n"
" echo \"DISPLAY=$y\"\n"
" continue\n"
" fi\n"
" break\n" " break\n"
" else\n" " else\n"
" if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
" y=`prdpy $p`\n"
" echo \"$y,NOXAUTH\"\n"
" continue\n"
" fi\n"
" if [ \"X$freebie\" = \"X\" ]; then\n" " if [ \"X$freebie\" = \"X\" ]; then\n"
" freebie=\"$p\"\n" " freebie=\"$p\"\n"
" fi\n" " fi\n"
@ -847,44 +991,17 @@ char find_display[] =
" fi\n" " fi\n"
"fi\n" "fi\n"
"\n" "\n"
"if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
" exit\n"
"fi\n"
"if [ \"X$display\" = \"X\" ]; then\n" "if [ \"X$display\" = \"X\" ]; then\n"
" echo \"\" # failure\n" " echo \"\" # failure\n"
" exit 1\n" " exit 1\n"
"fi\n" "fi\n"
"\n" "\n"
"chvt=\"\"\n" "dpy2=`prdpy \"$display\"`\n"
"if [ \"X$uname\" = \"XLinux\" ]; then\n"
" d2=$display\n"
" d3=`echo \"$d2\" | sed -e 's/^.*:/:/' -e 's/\\..*$//'`\n"
" d4=\"($d2|$d3)\"\n"
" vt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | egrep ' vt([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
" if [ \"X$vt\" != \"X\" ]; then\n"
" vt=`echo \"$vt\" | sed -e 's/^.* vt\\([0-9][0-9]*\\) .*$/\\1/'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt=\",VT=$vt\"\n"
" fi\n"
" else\n"
" vt=`ps wwwwwaux | grep X | egrep \" $d4 \" | egrep ' tty([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
" if [ \"X$vt\" != \"X\" ]; then\n"
" vt=`echo \"$vt\" | sed -e 's/^.* tty\\([0-9][0-9]*\\) .*$/\\1/'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt=\",VT=$vt\"\n"
" fi\n"
" else\n"
" pvt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | head -1 | awk '{print $2}'`\n"
" if [ \"X$pvt\" != \"X\" ]; then\n"
" vt=`lsof -p \"$pvt\" | egrep '/dev/tty([789]|[1-9][0-9][0-9]*)$' | grep -v grep | head -1 | awk '{print $NF}' | sed -e 's,/dev/tty,,'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt=\",VT=$vt\"\n"
" else\n"
" chvt=\",XPID=$pvt\"\n"
" fi\n"
" fi\n"
" fi\n"
" fi\n"
"fi\n"
"\n" "\n"
"echo \"DISPLAY=$display$chvt\"\n" "echo \"DISPLAY=$dpy2\"\n"
"if [ \"X$showxauth\" != \"X\" ]; then\n" "if [ \"X$showxauth\" != \"X\" ]; then\n"
" xauth extract - \"$display\" 2>/dev/null\n" " xauth extract - \"$display\" 2>/dev/null\n"
"fi\n" "fi\n"
@ -959,7 +1076,7 @@ char create_display[] =
" if echo \"$r1\" | grep '^[0-9][0-9]*$' > /dev/null; then\n" " if echo \"$r1\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" echo \"$r1\"\n" " echo \"$r1\"\n"
" else\n" " else\n"
" r2=`sh -c 'echo $$; date; ps -elf' 2>/dev/null | sum -r 2>/dev/null | awk '{print $1}'`\n" " r2=`sh -c 'echo $$; date; ps -elf' 2>&1 | sum -r 2>/dev/null | awk '{print $1}'`\n"
" if echo \"$r2\" | grep '^[0-9][0-9]*$' > /dev/null; then\n" " if echo \"$r2\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" echo \"$r2\"\n" " echo \"$r2\"\n"
" else\n" " else\n"
@ -999,6 +1116,9 @@ char create_display[] =
" elif [ \"X$have_wmaker\" != \"X\" -a \"X$FD_SESS\" = \"Xwmaker\" ]; then\n" " elif [ \"X$have_wmaker\" != \"X\" -a \"X$FD_SESS\" = \"Xwmaker\" ]; then\n"
" echo \"$have_wmaker\"\n" " echo \"$have_wmaker\"\n"
" return\n" " return\n"
" elif [ \"X$have_enlightenment\" != \"X\" -a \"X$FD_SESS\" = \"Xenlightenment\" ]; then\n"
" echo \"$have_enlightenment\"\n"
" return\n"
" elif [ \"X$have_Xsession\" != \"X\" -a \"X$FD_SESS\" = \"XXsession\" ]; then\n" " elif [ \"X$have_Xsession\" != \"X\" -a \"X$FD_SESS\" = \"XXsession\" ]; then\n"
" echo \"$have_Xsession\"\n" " echo \"$have_Xsession\"\n"
" return\n" " return\n"
@ -1046,7 +1166,7 @@ char create_display[] =
" return\n" " return\n"
" fi\n" " fi\n"
" fi\n" " fi\n"
" for wm in blackbox fvwm icewm wmw openbox twm mwm windowmaker metacity\n" " for wm in blackbox fvwm icewm wmw openbox twm mwm windowmaker enlightenment metacity\n"
" do\n" " do\n"
" eval \"have=\\$have_$wm\"\n" " eval \"have=\\$have_$wm\"\n"
" if [ \"X$have\" = \"X\" ]; then\n" " if [ \"X$have\" = \"X\" ]; then\n"
@ -1106,7 +1226,6 @@ char create_display[] =
" dport=`freeport $dport`\n" " dport=`freeport $dport`\n"
" FD_CUPS=$dport\n" " FD_CUPS=$dport\n"
" redir_daemon=\"$redir_daemon,TS_CUPS_REDIR:$dport:$rport\"\n" " redir_daemon=\"$redir_daemon,TS_CUPS_REDIR:$dport:$rport\"\n"
"#echo \"redir_daemon=$redir_daemon\" 1>&2\n"
" fi\n" " fi\n"
" if echo \"$FD_CUPS\" | grep ':' > /dev/null; then\n" " if echo \"$FD_CUPS\" | grep ':' > /dev/null; then\n"
" :\n" " :\n"
@ -1426,7 +1545,7 @@ char create_display[] =
" cookie=`(echo $r; date; uptime; ps -ealf 2>&1) | md5sum | awk '{print $1}'`\n" " cookie=`(echo $r; date; uptime; ps -ealf 2>&1) | md5sum | awk '{print $1}'`\n"
" fi\n" " fi\n"
" elif [ \"X$have_xauth\" != \"X\" ]; then\n" " elif [ \"X$have_xauth\" != \"X\" ]; then\n"
" cookie=`$have_xauth list | awk '{print $NF}' | tail -1`\n" " cookie=`$have_xauth list | awk '{print $NF}' | tail -n 1`\n"
" fi\n" " fi\n"
" if [ \"X$cookie\" = \"X\" ]; then\n" " if [ \"X$cookie\" = \"X\" ]; then\n"
" # oh well..\n" " # oh well..\n"
@ -1518,8 +1637,8 @@ char create_display[] =
" fi\n" " fi\n"
"fi\n" "fi\n"
"\n" "\n"
"depth=`echo \"$depth\" | head -1`\n" "depth=`echo \"$depth\" | head -n 1`\n"
"geom=`echo \"$geom\" | head -1`\n" "geom=`echo \"$geom\" | head -n 1`\n"
"\n" "\n"
"if echo \"$depth\" | grep '^[0-9][0-9]*$' > /dev/null; then\n" "if echo \"$depth\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" :\n" " :\n"
@ -1552,7 +1671,7 @@ char create_display[] =
" p_ok=1\n" " p_ok=1\n"
"fi\n" "fi\n"
"\n" "\n"
"for prog in startx xinit xdm gdm kdm xterm Xdummy Xvfb Xvnc xauth mcookie md5sum xmodmap startkde gnome-session blackbox fvwm2 mwm openbox twm windowmaker wmaker metacity X Xorg XFree86 Xsun Xsession dtwm netstat nohup esddsp konsole gnome-terminal\n" "for prog in startx xinit xdm gdm kdm xterm Xdummy Xvfb Xvnc xauth mcookie md5sum xmodmap startkde gnome-session blackbox fvwm2 mwm openbox twm windowmaker wmaker enlightenment metacity X Xorg XFree86 Xsun Xsession dtwm netstat nohup esddsp konsole gnome-terminal\n"
"do\n" "do\n"
" p2=`echo \"$prog\" | sed -e 's/-/_/g'`\n" " p2=`echo \"$prog\" | sed -e 's/-/_/g'`\n"
" eval \"have_$p2=''\"\n" " eval \"have_$p2=''\"\n"
@ -1605,6 +1724,7 @@ char create_display[] =
" use_xdmcp_query=1\n" " use_xdmcp_query=1\n"
" fi\n" " fi\n"
" curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]xdmcp//'`\n" " curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]xdmcp//'`\n"
" curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]redirect//'`\n"
" \n" " \n"
" if echo \"$curr_try\" | grep -iw \"^Xdummy\" > /dev/null; then\n" " if echo \"$curr_try\" | grep -iw \"^Xdummy\" > /dev/null; then\n"
" try_Xdummy\n" " try_Xdummy\n"

@ -1312,6 +1312,11 @@ void user_supplied_opts(char *opts) {
free(str); free(str);
} }
static void vnc_redirect_timeout (int sig) {
write(2, "timeout: no clients connected.\n", 31);
exit(0);
}
extern char find_display[]; extern char find_display[];
extern char create_display[]; extern char create_display[];
static XImage ximage_struct; static XImage ximage_struct;
@ -1330,6 +1335,13 @@ int wait_for_client(int *argc, char** argv, int http) {
int ncache_save; int ncache_save;
int did_client_connect = 0; int did_client_connect = 0;
int loop = 0; int loop = 0;
time_t start;
char *vnc_redirect_host = "localhost";
int vnc_redirect_port = -1;
int vnc_redirect_cnt = 0;
char vnc_redirect_test[10];
vnc_redirect = 0;
if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) { if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
return 0; return 0;
@ -1345,6 +1357,9 @@ int wait_for_client(int *argc, char** argv, int http) {
} }
if (db) fprintf(stderr, "args %d %s\n", i, argv[i]); if (db) fprintf(stderr, "args %d %s\n", i, argv[i]);
} }
if (!quiet && !strstr(use_dpy, "FINDDISPLAY-run")) {
rfbLog("wait_for_client: %s\n", use_dpy);
}
str = strdup(use_dpy); str = strdup(use_dpy);
str += strlen("WAIT"); str += strlen("WAIT");
@ -1408,6 +1423,34 @@ int wait_for_client(int *argc, char** argv, int http) {
clean_up_exit(0); clean_up_exit(0);
} }
if (db) fprintf(stderr, "cmd: %s\n", cmd); if (db) fprintf(stderr, "cmd: %s\n", cmd);
if (strstr(str, "FINDCREATEDISPLAY") || strstr(str, "FINDDISPLAY")) {
if (strstr(str, "Xvnc.redirect") || strstr(str, "X.redirect")) {
vnc_redirect = 1;
}
}
if (strstr(cmd, "FINDDISPLAY-vnc_redirect") == cmd) {
int p;
char h[256];
if (strlen(cmd) >= 256) {
rfbLog("wait_for_client string too long: %s\n", str);
clean_up_exit(1);
}
h[0] = '\0';
if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%d", &p) == 1) {
;
} else if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%s %d", h, &p) == 2) {
;
} else {
rfbLog("wait_for_client bad string: %s\n", cmd);
clean_up_exit(1);
}
vnc_redirect_port = p;
if (strcmp(h, "")) {
vnc_redirect_host = strdup(h);
}
vnc_redirect = 2;
rfbLog("wait_for_client: vnc_redirect: %s:%d\n", vnc_redirect_host, vnc_redirect_port);
}
} }
if (fake_fb) { if (fake_fb) {
@ -1542,6 +1585,86 @@ int wait_for_client(int *argc, char** argv, int http) {
#endif #endif
} }
if (vnc_redirect) {
if (unixpw) {
rfbLog("wait_for_client: -unixpw and Xvnc.redirect not allowed\n");
clean_up_exit(1);
}
if (client_connect) {
rfbLog("wait_for_client: -connect and Xvnc.redirect not allowed\n");
clean_up_exit(1);
}
if (inetd) {
if (use_openssl) {
accept_openssl(OPENSSL_INETD, -1);
}
} else {
int gotone = 0;
if (first_conn_timeout) {
if (first_conn_timeout < 0) {
first_conn_timeout = -first_conn_timeout;
}
signal(SIGALRM, vnc_redirect_timeout);
alarm(first_conn_timeout);
}
if (use_openssl) {
accept_openssl(OPENSSL_VNC, -1);
} else {
struct sockaddr_in addr;
#ifdef __hpux
int addrlen = sizeof(addr);
#else
socklen_t addrlen = sizeof(addr);
#endif
if (screen->listenSock < 0) {
rfbLog("wait_for_client: Xvnc.redirect not listening... sock=%d port=%d\n", screen->listenSock, screen->port);
clean_up_exit(1);
}
vnc_redirect_sock = accept(screen->listenSock, (struct sockaddr *)&addr, &addrlen);
}
if (first_conn_timeout) {
alarm(0);
}
}
if (vnc_redirect_sock < 0) {
rfbLog("wait_for_client: vnc_redirect failed.\n");
clean_up_exit(1);
}
if (!inetd && use_openssl) {
/* check for Fetch Cert closing */
fd_set rfds;
struct timeval tv;
int nfds;
usleep(300*1000);
FD_ZERO(&rfds);
FD_SET(vnc_redirect_sock, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 200000;
nfds = select(vnc_redirect_sock+1, &rfds, NULL, NULL, &tv);
rfbLog("wait_for_client: vnc_redirect nfds: %d\n", nfds);
if (nfds > 0) {
int n;
n = read(vnc_redirect_sock, vnc_redirect_test, 1);
if (n <= 0) {
close(vnc_redirect_sock);
vnc_redirect_sock = -1;
rfbLog("wait_for_client: waiting for 2nd connection (Fetch Cert?)\n");
accept_openssl(OPENSSL_VNC, -1);
if (vnc_redirect_sock < 0) {
rfbLog("wait_for_client: vnc_redirect failed.\n");
clean_up_exit(1);
}
} else {
vnc_redirect_cnt = n;
}
}
}
goto vnc_redirect_place;
}
if (inetd && use_openssl) { if (inetd && use_openssl) {
accept_openssl(OPENSSL_INETD, -1); accept_openssl(OPENSSL_INETD, -1);
@ -1580,8 +1703,17 @@ int wait_for_client(int *argc, char** argv, int http) {
} }
} }
if (first_conn_timeout < 0) {
first_conn_timeout = -first_conn_timeout;
}
start = time(NULL);
while (1) { while (1) {
loop++; loop++;
if (first_conn_timeout && time(NULL) > start + first_conn_timeout) {
rfbLog("no client connect after %d seconds.\n", first_conn_timeout);
shut_down = 1;
}
if (shut_down) { if (shut_down) {
clean_up_exit(0); clean_up_exit(0);
} }
@ -1693,7 +1825,11 @@ int wait_for_client(int *argc, char** argv, int http) {
if (0) db = 1; if (0) db = 1;
if (cmd) { vnc_redirect_place:
if (vnc_redirect == 2) {
;
} else if (cmd) {
char line1[1024]; char line1[1024];
char line2[16384]; char line2[16384];
char *q; char *q;
@ -1852,6 +1988,8 @@ if (0) db = 1;
sprintf(fdsess, "xterm"); sprintf(fdsess, "xterm");
} else if (strstr(t, "wmaker")) { } else if (strstr(t, "wmaker")) {
sprintf(fdsess, "wmaker"); sprintf(fdsess, "wmaker");
} else if (strstr(t, "enlightenment")) {
sprintf(fdsess, "enlightenment");
} else if (strstr(t, "Xsession")) { } else if (strstr(t, "Xsession")) {
sprintf(fdsess, "Xsession"); sprintf(fdsess, "Xsession");
} else if (strstr(t, "failsafe")) { } else if (strstr(t, "failsafe")) {
@ -2382,6 +2520,64 @@ fprintf(stderr, "\n");}
free(create_cmd); free(create_cmd);
} }
if (vnc_redirect) {
char *q = strchr(use_dpy, ':');
int vdpy = -1, sock = -1;
int s_in, s_out, i;
if (vnc_redirect == 2) {
char num[32];
sprintf(num, ":%d", vnc_redirect_port);
q = num;
}
if (!q) {
rfbLog("wait_for_client: can't find number in X display: %s\n", use_dpy);
clean_up_exit(1);
}
if (sscanf(q+1, "%d", &vdpy) != 1) {
rfbLog("wait_for_client: can't find number in X display: %s\n", q);
clean_up_exit(1);
}
if (vdpy == -1 && vnc_redirect != 2) {
rfbLog("wait_for_client: can't find number in X display: %s\n", q);
clean_up_exit(1);
}
if (vnc_redirect == 2) {
if (vdpy < 0) {
vdpy = -vdpy;
} else if (vdpy < 200) {
vdpy += 5900;
}
} else {
vdpy += 5900;
}
if (created_disp) {
usleep(1000*1000);
}
for (i=0; i < 20; i++) {
sock = rfbConnectToTcpAddr(vnc_redirect_host, vdpy);
if (sock >= 0) {
break;
}
rfbLog("wait_for_client: ...\n");
usleep(500*1000);
}
if (sock < 0) {
rfbLog("wait_for_client: could not connect to a VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
clean_up_exit(1);
}
if (inetd) {
s_in = fileno(stdin);
s_out = fileno(stdout);
} else {
s_in = s_out = vnc_redirect_sock;
}
if (vnc_redirect_cnt > 0) {
write(vnc_redirect_sock, vnc_redirect_test, vnc_redirect_cnt);
}
rfbLog("wait_for_client: switching control to VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
raw_xfer(sock, s_in, s_out);
clean_up_exit(0);
}
return 1; return 1;
} }

@ -4385,6 +4385,19 @@ if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr
if (! try_it && wireframe_mod_state()) { if (! try_it && wireframe_mod_state()) {
try_it = 1; try_it = 1;
} }
if (try_it && clipshift) {
sraRegionPtr r1, r2;
int xc = off_x + coff_x;
int yc = off_y + coff_y;
r1 = sraRgnCreateRect(x, y, x+w, y+h);
r2 = sraRgnCreateRect(xc, yc, xc+dpy_x, yc+dpy_y);
if (!sraRgnAnd(r1, r2)) {
if (db) fprintf(stderr, "OUTSIDE CLIPSHIFT\n");
try_it = 0;
}
sraRgnDestroy(r1);
sraRgnDestroy(r2);
}
if (! try_it) { if (! try_it) {
if (db) fprintf(stderr, "INTERIOR\n"); if (db) fprintf(stderr, "INTERIOR\n");
#ifdef MACOSX #ifdef MACOSX

@ -2,7 +2,7 @@
.TH X11VNC "1" "September 2007" "x11vnc " "User Commands" .TH X11VNC "1" "September 2007" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.9.3, lastmod: 2007-09-04 version: 0.9.3, lastmod: 2007-09-10
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -904,22 +904,46 @@ in addition to this option.
.PP .PP
\fB-find\fR \fB-find\fR
.IP .IP
Find the user's display using FINDDISPLAY. It is Find the user's display using FINDDISPLAY. This is an
an alias for "\fB-display\fR \fIWAIT:cmd=FINDDISPLAY\fR". alias for "\fB-display\fR \fIWAIT:cmd=FINDDISPLAY\fR".
Use \fB-finddpy\fR to run the FINDDISPLAY program and exit. .IP
For this and the next few options see \fB-display\fR WAIT:...
below for all of the details.
.PP
\fB-finddpy\fR
.IP
Run the FINDDISPLAY program, print out the found
display (if any) and exit. Output is like: DISPLAY=:0.0
DISPLAY=:0.0,XPID=12345 or DISPLAY=:0.0,VT=7. XPID is
the process ID of the found X server. VT is the Linux
virtual terminal of the X server.
.PP
\fB-listdpy\fR
.IP
Have the FINDDISPLAY program list all of your displays
(i.e. all the X displays on the local machine that you
have access rights to).
.PP .PP
\fB-create\fR \fB-create\fR
.IP .IP
First try to find the user's display using FINDDISPLAY, First try to find the user's display using FINDDISPLAY,
if that doesn't work create an X session via the if that doesn't succeed create an X session via the
FINDCREATEDISPLAY method. This is an alias for FINDCREATEDISPLAY method. This is an alias for
"\fB-display\fR \fIWAIT:cmd=FINDCREATEDISPLAY-Xvfb\fR". "\fB-display\fR \fIWAIT:cmd=FINDCREATEDISPLAY-Xvfb\fR".
.PP .PP
\fB-xdummy\fR \fB-xdummy\fR
.IP .IP
As \fB-create\fR except Xdummy instead of Xvfb. Implies As in \fB-create,\fR except Xdummy instead of Xvfb. Implies
FD_XDUMMY_NOROOT=1. FD_XDUMMY_NOROOT=1.
.PP .PP
\fB-xvnc\fR
.IP
As in \fB-create,\fR except Xvnc instead of Xvfb.
.PP
\fB-xvnc_redirect\fR
.IP
As in \fB-create,\fR except Xvnc.redirect instead of Xvfb.
.PP
\fB-svc\fR \fB-svc\fR
.IP .IP
Terminal services mode. Also "\fB-service\fR". Alias for Terminal services mode. Also "\fB-service\fR". Alias for
@ -931,12 +955,37 @@ Terminal services mode. Also "\fB-service\fR". Alias for
As \fB-svc\fR except Xdummy instead of Xvfb. Implies As \fB-svc\fR except Xdummy instead of Xvfb. Implies
FD_XDUMMY_NOROOT=1. FD_XDUMMY_NOROOT=1.
.PP .PP
\fB-svc_xvnc\fR
.IP
As \fB-svc\fR except Xvnc instead of Xvfb.
.PP
\fB-xdmsvc\fR \fB-xdmsvc\fR
.IP .IP
Terminal services mode. Also "\fB-xdm_service\fR". Alias for Terminal services mode. Also "\fB-xdm_service\fR". Alias for
\fB-display\fR WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp \fB-unixpw\fR \fB-display\fR WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp \fB-unixpw\fR
\fB-users\fR unixpw= \fB-ssl\fR SAVE \fB-users\fR unixpw= \fB-ssl\fR SAVE
.PP .PP
\fB-redirect\fR \fIport\fR
.IP
As in FINDCREATEDISPLAY-Xvnc.redirect mode except
redirect immediately (i.e. without X session finding
or creation) to a VNC server listening on port. You
can also supply host:port to redirect to a different
machine.
.IP
If 0 <= port < 200 it is taken as a VNC display (5900 is
added to get the actual port), if port < 0 then \fB-port\fR
is used.
.IP
Probably the only reason to use the \fB-redirect\fR option is
in conjunction with SSL support, e.g. \fB-ssl,\fR \fB-ssl\fR SAVE.
This provides an easy way to add SSL encryption to a VNC
server that does not support SSL (e.g. Xvnc or vnc.so)
In fact, the protocol does not even need to be VNC,
and so "\fB-ssl\fR \fISAVE \fB-redirect\fR host:port\fR" can act as a
replacement for
.IR stunnel (1).
.PP
\fB-display\fR \fIWAIT:...\fR \fB-display\fR \fIWAIT:...\fR
.IP .IP
A special usage mode for the normal \fB-display\fR option. A special usage mode for the normal \fB-display\fR option.
@ -1000,15 +1049,16 @@ type and enter your password incorrectly, to retrieve
your long "login:" line press the Up arrow once your long "login:" line press the Up arrow once
(before typing anything else). (before typing anything else).
.IP .IP
Another option is "geom=WxH" or "geom=WxHxD" (or Another option is "geom=WxH" or "geom=WxHxD"
ge=). This only has an effect in FINDCREATEDISPLAY (or ge=). This only has an effect in FINDCREATEDISPLAY
mode when a virtual X server such as Xvfb is going mode when a virtual X server such as Xvfb is going to
to be created. It sets the width and height of be created. It sets the width and height of the new
the new display, and optionally the color depth as display, and optionally the color depth as well. You
well. You can also supply "gnome", "kde", "twm", can also supply "gnome", "kde", "twm", "fvwm",
"fvwm", "mwm", "dtwm", "wmaker", "Xsession", "mwm", "dtwm", "wmaker", "enlightenment",
or "failsafe" (same as "xterm") to have the created "Xsession", or "failsafe" (same as "xterm")
display use that mode for the user session. to have the created display use that mode for the
user session.
.IP .IP
To disable the option setting set the environment To disable the option setting set the environment
variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc. variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc.
@ -1042,7 +1092,9 @@ DISPLAY variable and xauthority data (see
). ).
.IP .IP
To have this default script printed to stdout (e.g. for To have this default script printed to stdout (e.g. for
customization) run with WAIT:cmd=FINDDISPLAY-print customization) run with WAIT:cmd=FINDDISPLAY-print To
have the script run to print what display it would find
use "\fB-finddpy\fR" or WAIT:cmd=FINDDISPLAY-run
.IP .IP
As another special case, WAIT:cmd=HTTPONCE will allow As another special case, WAIT:cmd=HTTPONCE will allow
x11vnc to service one http request and then exit. x11vnc to service one http request and then exit.
@ -1162,6 +1214,25 @@ that specify the above options for some useful cases.
.IP .IP
If you set the env. var WAITBG=1 x11vnc will go into If you set the env. var WAITBG=1 x11vnc will go into
the background once listening in wait mode. the background once listening in wait mode.
.IP
Another special mode is FINDCREATEDISPLAY-Xvnc.redirect,
(or FINDDISPLAY-Xvnc.redirect). In this case it will
start up Xvnc as above if needed, but instead of
polling it in its normal way, it simply does a socket
redirection of the connected VNC viewer to the Xvnc.
.IP
So in Xvnc.redirect x11vnc does no VNC but merely
transfers the data back and forth. This should be
faster then x11vnc's polling method, but not as fast
as connecting directly to the Xvnc with the VNC Viewer.
The idea here is to take advantage of x11vnc's display
finding/creating scheme, SSL, and perhaps a few others.
Most of x11vnc's options do not apply in this mode.
.IP
Xvnc.redirect should also work for the vnc.so X server
module for the h/w display however it will work only
for finding the display and the user must already be
logged into the X console.
.PP .PP
\fB-nossl\fR \fB-nossl\fR
.IP .IP

@ -2299,20 +2299,34 @@ int main(int argc, char* argv[]) {
} }
} else if (!strcmp(arg, "-find")) { } else if (!strcmp(arg, "-find")) {
use_dpy = strdup("WAIT:cmd=FINDDISPLAY"); use_dpy = strdup("WAIT:cmd=FINDDISPLAY");
} else if (!strcmp(arg, "-finddpy")) { } else if (!strcmp(arg, "-finddpy") || strstr(arg, "-listdpy") == arg) {
int ic = 0; int ic = 0;
use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run"); use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run");
if (argc > i+1) { if (argc > i+1) {
set_env("X11VNC_USER", argv[i+1]); set_env("X11VNC_USER", argv[i+1]);
fprintf(stdout, "X11VNC_USER=%s\n", getenv("X11VNC_USER")); fprintf(stdout, "X11VNC_USER=%s\n", getenv("X11VNC_USER"));
} }
if (strstr(arg, "-listdpy") == arg) {
set_env("FIND_DISPLAY_ALL", "1");
}
wait_for_client(&ic, NULL, 0); wait_for_client(&ic, NULL, 0);
exit(0); exit(0);
} else if (!strcmp(arg, "-create")) { } else if (!strcmp(arg, "-create")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb"); use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb");
} else if (!strcmp(arg, "-xdummy")) { } else if (!strcmp(arg, "-xdummy")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy"); use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
set_env("FD_XDUMMY_NOROOT", "1"); } else if (!strcmp(arg, "-xvnc")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc");
} else if (!strcmp(arg, "-xvnc_redirect")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect");
} else if (!strcmp(arg, "-redirect")) {
char *q, *t, *t0 = "WAIT:cmd=FINDDISPLAY-vnc_redirect";
CHECK_ARGC
t = (char *) malloc(strlen(t0) + strlen(argv[++i]) + 2);
q = strrchr(argv[i], ':');
if (q) *q = ' ';
sprintf(t, "%s=%s", t0, argv[i]);
use_dpy = t;
} else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) { } else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
CHECK_ARGC CHECK_ARGC
auth_file = strdup(argv[++i]); auth_file = strdup(argv[++i]);
@ -2492,6 +2506,12 @@ int main(int argc, char* argv[]) {
use_openssl = 1; use_openssl = 1;
openssl_pem = strdup("SAVE"); openssl_pem = strdup("SAVE");
set_env("FD_XDUMMY_NOROOT", "1"); set_env("FD_XDUMMY_NOROOT", "1");
} else if (!strcmp(arg, "-svc_xvnc")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc");
unixpw = 1;
users_list = strdup("unixpw=");
use_openssl = 1;
openssl_pem = strdup("SAVE");
} else if (!strcmp(arg, "-xdmsvc") || !strcmp(arg, "-xdm_service")) { } else if (!strcmp(arg, "-xdmsvc") || !strcmp(arg, "-xdm_service")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp"); use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp");
unixpw = 1; unixpw = 1;
@ -3295,6 +3315,10 @@ int main(int argc, char* argv[]) {
orig_use_xdamage = use_xdamage; orig_use_xdamage = use_xdamage;
if (!auto_port && getenv("AUTO_PORT")) {
auto_port = atoi(getenv("AUTO_PORT"));
}
if (getenv("X11VNC_LOOP_MODE")) { if (getenv("X11VNC_LOOP_MODE")) {
if (bg && !getenv("X11VNC_LOOP_MODE_BG")) { if (bg && !getenv("X11VNC_LOOP_MODE_BG")) {
if (! quiet) { if (! quiet) {
@ -3856,6 +3880,7 @@ int main(int argc, char* argv[]) {
/* open the X display: */ /* open the X display: */
if (auth_file) { if (auth_file) {
set_env("XAUTHORITY", auth_file); set_env("XAUTHORITY", auth_file);
fprintf(stderr, "XA: %s\n", getenv("XAUTHORITY"));
} }
#if LIBVNCSERVER_HAVE_XKEYBOARD #if LIBVNCSERVER_HAVE_XKEYBOARD
/* /*

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.3 lastmod: 2007-09-04"; char lastmod[] = "0.9.3 lastmod: 2007-09-10";
/* X display info */ /* X display info */

@ -189,10 +189,16 @@ void initialize_xrecord(void) {
rdpy_ctrl = NULL; rdpy_ctrl = NULL;
} }
rdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy)); rdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy));
if (!rdpy_ctrl) {
fprintf(stderr, "rdpy_ctrl open failed: %s / %s / %s / %s\n", getenv("DISPLAY"), DisplayString(dpy), getenv("XAUTHORITY"), getenv("XAUTHORIT_"));
}
XSync(dpy, True); XSync(dpy, True);
XSync(rdpy_ctrl, True); XSync(rdpy_ctrl, True);
/* open datalink connection to DISPLAY: */ /* open datalink connection to DISPLAY: */
rdpy_data = XOpenDisplay_wr(DisplayString(dpy)); rdpy_data = XOpenDisplay_wr(DisplayString(dpy));
if (!rdpy_data) {
fprintf(stderr, "rdpy_data open failed\n");
}
if (!rdpy_ctrl || ! rdpy_data) { if (!rdpy_ctrl || ! rdpy_data) {
X_UNLOCK; X_UNLOCK;
return; return;
@ -218,9 +224,15 @@ void initialize_xrecord(void) {
xserver_grabbed = 0; xserver_grabbed = 0;
gdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy)); gdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy));
if (!gdpy_ctrl) {
fprintf(stderr, "gdpy_ctrl open failed\n");
}
XSync(dpy, True); XSync(dpy, True);
XSync(gdpy_ctrl, True); XSync(gdpy_ctrl, True);
gdpy_data = XOpenDisplay_wr(DisplayString(dpy)); gdpy_data = XOpenDisplay_wr(DisplayString(dpy));
if (!gdpy_data) {
fprintf(stderr, "gdpy_data open failed\n");
}
if (gdpy_ctrl && gdpy_data) { if (gdpy_ctrl && gdpy_data) {
disable_grabserver(gdpy_ctrl, 0); disable_grabserver(gdpy_ctrl, 0);
disable_grabserver(gdpy_data, 0); disable_grabserver(gdpy_data, 0);

@ -1055,15 +1055,15 @@ int xauth_raw(int on) {
} }
return 1; return 1;
} else { } else {
if (old_xauthority && strcmp(old_xauthority, "")) { if (old_xauthority) {
set_env("XAUTHORITY", old_xauthority); if (!strcmp(old_xauthority, "")) {
} else {
char *xauth = getenv("XAUTHORITY"); char *xauth = getenv("XAUTHORITY");
if (xauth) { if (xauth) {
*(xauth-2) = '_'; /* yow */ *(xauth-2) = '_'; /* yow */
} }
} else {
set_env("XAUTHORITY", old_xauthority);
} }
if (old_xauthority) {
free(old_xauthority); free(old_xauthority);
old_xauthority = NULL; old_xauthority = NULL;
} }

Loading…
Cancel
Save