x11vnc: -autoport, -finddpy, -xdummy. watch xrandr events. check_redir_services() utilities for Terminal services. Improve Xdummy.

pull/1/head
runge 17 years ago
parent e305525129
commit 6a6d26a747

@ -1,3 +1,11 @@
2007-09-04 Karl Runge <runge@karlrunge.com>
* x11vnc: Add -autoport and -finddpy utils. -xdummy creation.
tweak xkb tiebreaking again. Shut off -ncache in dev mode.
watch for xrandr events even if no -xrandr. Tips for types
of URLs for java viewers. Add check_redir_services() to
create_display and tsdo() redir helper utility (-tsd).
Improvements to Xdummy.
2007-08-19 Karl Runge <runge@karlrunge.com>
* x11vnc: better -xkb tie-breaking for up keystrokes. Add
Xsrv/FD_XSRV custom server to FINDCREATEDISPLAY list.

File diff suppressed because it is too large Load Diff

@ -87,6 +87,10 @@ void print_help(int mode) {
" to 5900+N. The program will exit immediately if that\n"
" port is not available.\n"
"\n"
"-autoport n Automatically probe for a free VNC port starting at n.\n"
" The default is to start probing at 5900. Use this to\n"
" stay away from other VNC servers near 5900.\n"
"\n"
"-reflect host:N Instead of connecting to and polling an X display,\n"
" connect to the remote VNC server host:N and be a\n"
" reflector/repeater for it. This is useful for trying\n"
@ -758,18 +762,25 @@ void print_help(int mode) {
" in addition to this option.\n"
"\n"
#endif
"-find Find the user's display using FINDDISPLAY. It is an\n"
" alias for \"-display WAIT:cmd=FINDDISPLAY\".\n"
"-find Find the user's display using FINDDISPLAY. It is\n"
" an alias for \"-display WAIT:cmd=FINDDISPLAY\".\n"
" Use -finddpy to run the FINDDISPLAY program and exit.\n"
"\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"
" FINDCREATEDISPLAY method. This is an alias for\n"
" \"-display WAIT:cmd=FINDCREATEDISPLAY-Xvfb\".\n"
"\n"
"-xdummy As -create except Xdummy instead of Xvfb. Implies\n"
" FD_XDUMMY_NOROOT=1.\n"
"\n"
"-svc Terminal services mode. Also \"-service\". Alias for\n"
" -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb -unixpw\n"
" -users unixpw= -ssl SAVE\n"
"\n"
"-svc_xdummy As -svc except Xdummy instead of Xvfb. Implies\n"
" FD_XDUMMY_NOROOT=1.\n"
"\n"
"-xdmsvc Terminal services mode. Also \"-xdm_service\". Alias for\n"
" -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw\n"
" -users unixpw= -ssl SAVE\n"
@ -901,13 +912,15 @@ void print_help(int mode) {
" for the user. This is the only time x11vnc tries to\n"
" actually start up an X server.\n"
"\n"
" By default FINDCREATEDISPLAY will try Xdummy and\n"
" then Xvfb. The Xdummy wrapper is part of the x11vnc\n"
" source code (x11vnc/misc/Xdummy) It should be available\n"
" in PATH and have run \"Xdummy -install\" once to create\n"
" the shared library. Xdummy requires root permission\n"
" and only works on Linux. Xvfb is available on most\n"
" platforms and does not require root.\n"
" By default FINDCREATEDISPLAY will try Xdummy and then\n"
" Xvfb. The Xdummy wrapper is part of the x11vnc source\n"
" code (x11vnc/misc/Xdummy) It should be available in\n"
" PATH and have run \"Xdummy -install\" once to create\n"
" the shared library. Xdummy requires root permission and\n"
" only works on Linux. (Note: specify FD_XDUMMY_NOROOT=1\n"
" to skip a check for the root id; evidently your sudo(1)\n"
" will take care of everything). Xvfb is available on\n"
" most platforms and does not require root.\n"
"\n"
" When x11vnc exits (i.e. user disconnects) the X\n"
" server session stays running in the background.\n"
@ -959,6 +972,13 @@ void print_help(int mode) {
" the X server. You can also set FD_PROG to be the full\n"
" path to the session/windowmanager program.\n"
"\n"
" More FD tricks: FD_CUPS=port or FD_CUPS=host:port\n"
" will set the cups printing environment. Similarly\n"
" for FD_ESD=port or FD_ESD=host:port for esddsp sound\n"
" redirection. FD_XDUMMY_NOROOT means the Xdummy server\n"
" does not need to be started as root (e.g. it will sudo\n"
" automatically)\n"
"\n"
" If you want the FINDCREATEDISPLAY session to contact an\n"
" XDMCP login manager (xdm/gdm/kdm) on the same machine,\n"
" then use \"Xvfb.xdmcp\" instead of \"Xvfb\", etc.\n"
@ -1504,9 +1524,9 @@ void print_help(int mode) {
" -httpdir option. If not supplied it will try to guess\n"
" the directory as though the -http option was supplied.\n"
"\n"
"-httpsredir [port] In -ssl mode with the Java applet retrieved via HTTPS:\n"
"-httpsredir [port] In -ssl mode with the Java applet retrieved via HTTPS,\n"
" when the HTML file containing applet parameters\n"
" ('index.vnc' or 'proxy.vnc') is sent do not set the\n"
" ('index.vnc' or 'proxy.vnc') is sent do NOT set the\n"
" applet PORT parameter to the actual VNC port but set it\n"
" to \"port\" instead. If \"port\" is not supplied, then\n"
" the port number is guessed from the Host: HTTP header.\n"
@ -1520,9 +1540,12 @@ void print_help(int mode) {
" redir from mygateway.com:443 to workstation:5900.\n"
"\n"
" This spares the user from having to type in\n"
" https://mygateway.com/?PORT=443 into their web browser\n"
" (note 443 is the default https port; other ports must\n"
" be explicity indicated: https://mygateway.com:8000/...)\n"
" https://mygateway.com/?PORT=443 into their web\n"
" browser. Note taht port 443 is the default https port;\n"
" other ports must be explicity indicated, for example:\n"
" https://mygateway.com:8000/?PORT=8000. To avoid having\n"
" to include the PORT= in the browser URL, simply supply\n"
" \"-httpsredir\" to x11vnc.\n"
"\n"
#endif
"-usepw If no other password method was supplied on the command\n"
@ -1826,6 +1849,12 @@ void print_help(int mode) {
" viewers that cannot do this (portions of the screen\n"
" may be clipped, unused, etc).\n"
"\n"
" Note: the default now is to check for XRANDR events, but\n"
" do not trap every X call that may fail due to resize.\n"
" If a resize event is received, the full -xrandr mode\n"
" is enabled. To disable even checking for events supply:\n"
" -noxrandr.\n"
"\n"
" \"mode\" defaults to \"resize\", which means create a\n"
" new, resized, framebuffer and hope all viewers can cope\n"
" with the change. \"newfbsize\" means first disconnect\n"
@ -3712,7 +3741,7 @@ void print_help(int mode) {
" noncache_no_dtchange disable ncache_no_dtchange mode.\n"
" ncache_no_rootpixmap enable ncache_no_rootpixmap.\n"
" noncache_no_rootpixmap disable ncache_no_rootpixmap.\n"
" ncache_reset_rootpixmap recheck the root pixmap\n"
" ncache_reset_rootpixmap recheck the root pixmap, ncrp\n"
" ncache_keep_anims enable ncache_keep_anims.\n"
" noncache_keep_anims disable ncache_keep_anims.\n"
" wireframe enable -wireframe mode. same as \"wf\"\n"

@ -1490,6 +1490,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
static int Kc_last_down[KLAST];
static KeySym Ks_last_down[KLAST];
static int klast = 0, khints = 1, anydown = 1;
static int cnt = 0;
if (!client || !down || !keysym) {} /* unused vars warning: */
@ -1529,6 +1530,15 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
}
}
}
cnt++;
if (cnt % 100 && khints && score_hint != NULL) {
int i, j;
for (i=0; i<0x100; i++) {
for (j=0; j<0x100; j++) {
score_hint[i][j] = -1;
}
}
}
if (debug_keyboard) {
char *str = XKeysymToString(keysym);
@ -1807,7 +1817,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
}
}
/* next just check for any one that is down */
/* next just check for "best" one that is down */
if (Kc_f == -1 && anydown) {
int l;
int best = -1, lbest;
@ -1824,7 +1834,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
int key = (int) kc_f[l];
int j, jmatch = -1;
if (keycode_state[key]) {
if (! keycode_state[key]) {
continue;
}
/* break ties based on lowest XKeycodeToKeysym index */
@ -1851,12 +1861,27 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
}
}
/* next, use the first one found that is down */
if (Kc_f == -1) {
int l;
for (l=0; l < found; l++) {
int key = (int) kc_f[l];
if (keycode_state[key]) {
Kc_f = kc_f[l];
break;
}
}
if (debug_keyboard && Kc_f != -1) {
fprintf(stderr, " UP: set to first one down, kc_f[%d]!!\n", l);
}
}
/* last, use the first one found */
if (Kc_f == -1) {
/* hope for the best... XXX check mods */
Kc_f = kc_f[0];
if (debug_keyboard && Kc_f != -1) {
fprintf(stderr, " UP: set to first one, kc_f[0]!!\n");
fprintf(stderr, " UP: set to first one at all, kc_f[0]!!\n");
}
}
}

@ -22,7 +22,7 @@ export PATH
program=`basename "$0"`
help () {
cat << END
${PAGER:-more} << END
$program: a hack to run a stock XFree86(1) or Xorg(1) server with the
"dummy" video driver such that it AVOIDS the Linux VT switching, keyboard
@ -87,6 +87,43 @@ gdm/kdm example:
TBD.
Root permission and x11vnc:
This program needs to be run as root. One could run x11vnc as
root with -unixpw (it switches to the user that logs in) and
that may be OK, some other ideas:
- add this to sudo via visudo:
ALL ALL = NOPASSWD: /usr/local/bin/Xdummy
- use this little suid wrapper:
/*
* xdummy.c
*
cc -o ./xdummy xdummy.c
sudo cp ./xdummy /usr/local/bin/xdummy
sudo chown root:root /usr/local/bin/xdummy
sudo chmod u+s /usr/local/bin/xdummy
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
int main (int argc, char *argv[]) {
extern char **environ;
char str[100];
sprintf(str, "XDUMMY_UID=%d", (int) getuid());
putenv(str);
setuid(0);
setgid(0);
execv("/usr/local/bin/Xdummy", argv);
exit(1);
return 1;
}
Options:
@ -124,6 +161,9 @@ Options:
-nonroot Try to run in non-root mode (XXX NOT yet working).
-nosudo Do not try to use sudo(1) when re-running as root,
use su(1) instead.
-xserver path Specify the path to the Xserver to use. Default
is to try "Xorg" first and then "XFree86". If
those are not in \$PATH, use these locations:
@ -192,17 +232,35 @@ END
warn() {
echo "$*" 1>&2
}
#set -xv
if [ "X$XDUMMY_UID" = "X" ]; then
XDUMMY_UID=`id -u`
export XDUMMY_UID
fi
if [ "X$XDUMMY_UID" = "X0" ]; then
if [ "X$SUDO_UID" != "X" ]; then
XDUMMY_UID=$SUDO_UID
export XDUMMY_UID
fi
fi
#warn "id: `id -u`"
# See if it needs to be run as root:
if [ "X$XDUMMY_SU_EXEC" = "X" -a "X`id -u`" != "X0" ]; then
dosu=1
nosudo=""
XDUMMY_SU_EXEC=1
export XDUMMY_SU_EXEC
for arg in $*
do
#echo "arg=$arg"
if [ "X$arg" = "X-nonroot" ]; then
dosu=""
elif [ "X$arg" = "X-noroot" ]; then
dosu=""
elif [ "X$arg" = "X-nosudo" ]; then
nosudo="1"
elif [ "X$arg" = "X-help" ]; then
dosu=""
elif [ "X$arg" = "X-h" ]; then
@ -221,8 +279,26 @@ if [ "X$XDUMMY_SU_EXEC" = "X" -a "X`id -u`" != "X0" ]; then
done
if [ $dosu ]; then
warn "$program: currently needs to be run as root to work."
warn "$program: supply the root password to restart as root:"
exec su -c "$0 $*"
if type sudo > /dev/null 2>&1; then
:
else
nosudo=1
fi
if [ "X$nosudo" = "X" ]; then
warn "$program: supply the sudo password to restart as root:"
if [ "X$XDUMMY_UID" != "X" ]; then
exec sudo $0 -uid $XDUMMY_UID "$@"
else
exec sudo $0 "$@"
fi
else
warn "$program: supply the root password to restart as root:"
if [ "X$XDUMMY_UID" != "X" ]; then
exec su -c "$0 -uid $XDUMMY_UID $*"
else
exec su -c "$0 $*"
fi
fi
exit
fi
fi
@ -241,8 +317,15 @@ do
;;
"-nonroot") root=""
;;
"-noroot") root=""
;;
"-nosudo") nosudo=1
;;
"-xserver") xserver="$2"; shift
;;
"-uid") XDUMMY_UID="$2"; shift
export XDUMMY_UID
;;
"-geom"*) geom="$2"; shift
;;
"-tmpdir") XDUMMY_TMPDIR="$2"; shift
@ -285,12 +368,19 @@ if [ "X$user" = "X" ]; then
user=`whoami 2>/dev/null`
fi
if [ "X$user" = "X" ]; then
user=`basename $HOME`
user=`basename "$HOME"`
fi
if [ "X$user" = "X" -o "X$user" = "X." ]; then
user="u$$"
fi
if [ "X$debug" = "X1" ]; then
echo ""
echo "/usr/bin/env:"
env
echo ""
fi
# Function to compile the LD_PRELOAD shared object:
make_so() {
@ -409,6 +499,8 @@ if [ "X$xserver" = "X" ]; then
xserver="XFree86"
elif -x /usr/X11R6/bin/Xorg; then
xserver="/usr/X11R6/bin/Xorg"
elif -x /usr/bin/Xorg; then
xserver="/usr/bin/Xorg"
elif -x /usr/X11R6/bin/XFree86; then
xserver="/usr/X11R6/bin/XFree86"
fi
@ -425,14 +517,21 @@ if [ -e "$xserver_path" -a "X$root" = "X" -a "X$runit" != "X" ]; then
if [ ! -r $xserver_path -o -u $xserver_path ]; then
# XXX not quite correct with rm -rf $XDUMMY_TMPDIR ...
base=`basename "$xserver_path"`
new="$tdir/$base.$user"
#new="$tdir/$base.$user"
new="/tmp/$base.$user"
if [ ! -e $new ]; then
warn "need to copy $xserver_path to $new as root:"
warn "NEED TO COPY UNREADABLE $xserver_path to $new as root:"
warn ""
ls -l $xserver_path 1>&2
warn "please supply root passwd to 'su -c'"
warn ""
warn "This only needs to be done once."
warn "Please supply root passwd to 'su -c'"
touch $new || exit 1
chmod 700 $new || exit 1
su -c "cat $xserver_path > $new"
ls -l $new
warn "Please restart."
exit 0
elif [ ! -O $new ]; then
warn "file \"$new\" not owned by us!"
ls -l $new
@ -830,6 +929,13 @@ static char str2[1024];
static char devs[256][1024];
static int debug = -1;
static int root = -1;
static int changed_uid = 0;
static int saw_fonts = 0;
#if 0
typedef long time_t;
#endif
static time_t start = 0;
void check_debug(void) {
if (debug < 0) {
@ -850,8 +956,29 @@ void check_root(void) {
}
}
}
void check_uid(void) {
if (start == 0) {
start = time(NULL);
if (debug) fprintf(stderr, "START: %d\n", start);
return;
} else if (changed_uid == 0) {
if (saw_fonts || time(NULL) > start + 20) {
if (getenv("XDUMMY_UID")) {
int uid = atoi(getenv("XDUMMY_UID"));
if (debug) fprintf(stderr, "SETREUID: %d\n", uid);
if (uid >= 0) {
setreuid(uid, -1);
}
}
changed_uid = 1;
}
}
}
#define CHECKIT if (debug < 0) check_debug(); \
if (root < 0) check_root();
if (root < 0) check_root(); \
check_uid();
static void set_tmpdir(void) {
char *s;
@ -904,7 +1031,7 @@ int open(const char *pathname, int flags, unsigned short mode) {
} else if (strstr(pathname, "/dev") == pathname) {
store_dev = strdup(pathname);
pathname = tmpdir_path(pathname);
if (debug) fprintf(stderr, "OPEN: -> %s\n", pathname, mode);
if (debug) fprintf(stderr, "OPEN: -> %s\n", pathname);
fd = real_open(pathname, O_WRONLY|O_CREAT, 0777);
close(fd);
}
@ -941,6 +1068,16 @@ FILE *fopen(const char *pathname, const char *mode) {
static FILE* (*real_fopen)(const char *, const char *) = NULL;
char *str;
if (! saw_fonts) {
if (strstr(pathname, "/fonts/")) {
if (strstr(pathname, "fonts.dir")) {
saw_fonts = 1;
} else if (strstr(pathname, "fonts.alias")) {
saw_fonts = 1;
}
}
}
CHECKIT
if (! real_fopen) {
real_fopen = (FILE* (*)(const char *, const char *))
@ -955,7 +1092,7 @@ FILE *fopen(const char *pathname, const char *mode) {
str = (char *) pathname;
if (strstr(pathname, "/var/log") == pathname) {
str = tmpdir_path(pathname);
if (debug) fprintf(stderr, "FOPEN: -> %s\n", str, mode);
if (debug) fprintf(stderr, "FOPEN: -> %s\n", str);
}
}
@ -1051,6 +1188,38 @@ int close(int fd) {
return(real_close(fd));
}
struct stat {
int foo;
};
int stat(const char *path, struct stat *buf) {
static int (*real_stat)(const char *, struct stat *) = NULL;
CHECKIT
if (! real_stat) {
real_stat = (int (*)(const char *, struct stat *))
dlsym(RTLD_NEXT, "stat");
}
if (debug) fprintf(stderr, "STAT: %s\n", path);
return(real_stat(path, buf));
}
int stat64(const char *path, struct stat *buf) {
static int (*real_stat64)(const char *, struct stat *) = NULL;
CHECKIT
if (! real_stat64) {
real_stat64 = (int (*)(const char *, struct stat *))
dlsym(RTLD_NEXT, "stat64");
}
if (debug) fprintf(stderr, "STAT64: %s\n", path);
return(real_stat64(path, buf));
}
/*
* Note: the following just call the real function if root is
* true. They will be used if -nonroot is ever figured out.
@ -1203,5 +1372,24 @@ gid_t getegid32(void) {
return 0;
}
#if 0
int xf86PathIsSafe(char *path) {
fprintf(stderr, "xf86pathIsSafe: %s\n", path);
return 1;
}
#endif
#if 0
int strcmp(const char *s1, const char *s2) {
static int (*real_strcmp)(const char *, const char *) = NULL;
CHECKIT
if (! real_strcmp) {
real_strcmp = (int (*)(const char *, const char *)) dlsym(RTLD_NEXT, "strcmp");
}
if (debug) fprintf(stderr, "STRCMP: '%s' '%s'\n", s1, s2);
return(real_strcmp(s1, s2));
}
#endif
#code_end
}

@ -10,6 +10,7 @@ int debug = 0;
char *use_dpy = NULL; /* -display */
int display_N = 0;
int auto_port = 0;
char *auth_file = NULL; /* -auth/-xauth */
char *visual_str = NULL; /* -visual */
int set_visual_str_to_something = 0;
@ -160,6 +161,7 @@ int debug_sel = 0;
int xtrap_input = 0; /* -xtrap for user input insertion */
int xinerama = XINERAMA; /* -xinerama */
int xrandr = 0; /* -xrandr */
int xrandr_maybe = 1; /* check for events, but don't trap all calls */
char *xrandr_mode = NULL;
char *pad_geometry = NULL;
time_t pad_geometry_time = 0;
@ -206,8 +208,8 @@ int wireframe_local = 1;
#ifdef NO_NCACHE
#define NCACHE 0
#else
#define NCACHE -12
#define xxNCACHE -1
#define xxNCACHE -12
#define NCACHE -1
#endif
#endif

@ -10,6 +10,7 @@ extern int debug;
extern char *use_dpy;
extern int display_N;
extern int auto_port;
extern char *auth_file;
extern char *visual_str;
extern int set_visual_str_to_something;
@ -132,6 +133,7 @@ extern int debug_sel;
extern int xtrap_input;
extern int xinerama;
extern int xrandr;
extern int xrandr_maybe;
extern char *xrandr_mode;
extern char *pad_geometry;
extern time_t pad_geometry_time;

@ -1937,6 +1937,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "ans=%s:%d", p, !xrandr); goto qry;
}
xrandr = 0;
xrandr_maybe = 0;
if (xrandr_present) {
rfbLog("remote_cmd: disable xrandr mode.\n");
if (orig != xrandr) {
@ -1956,6 +1957,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
p += strlen("xrandr_mode:");
if (!strcmp("none", p)) {
xrandr = 0;
xrandr_maybe = 0;
} else {
if (known_xrandr_mode(p)) {
if (xrandr_mode) free(xrandr_mode);
@ -2866,7 +2868,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
do_new_fb(1);
}
} else if (!strcmp(p, "ncache_reset_rootpixmap")) {
} else if (!strcmp(p, "ncache_reset_rootpixmap") || !strcmp(p, "ncrp")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !ncache_xrootpmap);
goto qry;

@ -530,7 +530,7 @@ static char *raw_fb_orig_dpy = NULL;
void set_raw_fb_params(int restore) {
static int first = 1;
static int vo0, us0, sm0, ws0, wp0, wc0, wb0, na0, tn0;
static int xr0, sb0, re0;
static int xr0, xrm0, sb0, re0;
static char *mc0;
/*
@ -552,6 +552,7 @@ void set_raw_fb_params(int restore) {
sm0 = using_shm;
tn0 = take_naps;
xr0 = xrandr;
xrm0 = xrandr_maybe;
re0 = noxrecord;
mc0 = multiple_cursors_mode;
@ -571,6 +572,7 @@ void set_raw_fb_params(int restore) {
using_shm = sm0;
take_naps = tn0;
xrandr = xr0;
xrandr_maybe = xrm0;
noxrecord = re0;
multiple_cursors_mode = mc0;
@ -665,6 +667,10 @@ void set_raw_fb_params(int restore) {
if (verbose) rfbLog(" rawfb: turning off xrandr\n");
xrandr = 0;
}
if (xrandr_maybe) {
if (verbose) rfbLog(" rawfb: turning off xrandr_maybe\n");
xrandr_maybe = 0;
}
if (! noxrecord) {
if (verbose) rfbLog(" rawfb: turning off xrecord\n");
noxrecord = 1;
@ -2860,6 +2866,10 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen->inetdSock = fd;
screen->port = 0;
} else if (auto_port > 0) {
int lport = find_free_port(auto_port, auto_port+200);
screen->autoPort = FALSE;
screen->port = lport;
} else if (! got_rfbport) {
screen->autoPort = TRUE;
} else if (got_rfbport && got_rfbport_val == 0) {
@ -2984,6 +2994,23 @@ void set_vnc_desktop_name(void) {
if (screen->port) {
if (! quiet) {
if (screen->httpListenSock > -1 && screen->httpPort) {
rfbLog("\n");
rfbLog("The URLs printed out below ('Java ... viewer URL') can\n");
rfbLog("be used for Java enabled Web browser connections.\n");
if (use_openssl || stunnel_port) {
rfbLog("Here are some additional possibilities:\n");
rfbLog("\n");
rfbLog("https://host:port/proxy.vnc (MUST be used if Web Proxy used)\n");
rfbLog("\n");
rfbLog("https://host:port/ultra.vnc (Use UltraVNC Java Viewer)\n");
rfbLog("https://host:port/ultraproxy.vnc (Web Proxy with UltraVNC)\n");
rfbLog("https://host:port/ultrasigned.vnc (Signed UltraVNC Filexfer)\n");
rfbLog("\n");
rfbLog("Where you replace \"host:port\" with that printed below, or\n");
rfbLog("whatever is needed to reach the host e.g. Internet IP number\n");
}
}
rfbLog("\n");
}

@ -883,10 +883,10 @@ void kde_no_animate(int restore) {
cmd = (char *) malloc(len);
sprintf(cmd, kwin_reconfigure, user, sess);
len = 1 + strlen(kwinrc_off) + 2 + strlen(cmd) + 2 + strlen("sleep 5") + 2 + strlen(kwinrc_on) + 3 + 1;
len = 1 + strlen("sleep 10") + 2 + strlen(kwinrc_off) + 2 + strlen(cmd) + 2 + strlen("sleep 5") + 2 + strlen(kwinrc_on) + 3 + 1;
cmd2 = (char *) malloc(len);
sprintf(cmd2, "(%s; %s; sleep 5; %s) &", kwinrc_off, cmd, kwinrc_on);
sprintf(cmd2, "(sleep 10; %s; %s; sleep 5; %s) &", kwinrc_off, cmd, kwinrc_on);
dt_cmd(cmd2);
free(cmd);

@ -1875,6 +1875,14 @@ if (db) fprintf(stderr, "iface: %s\n", iface);
strncpy(last_get, rcookie, 100);
if (db) fprintf(stderr, "last_get: '%s'\n", last_get);
}
if (rcookie && strstr(rcookie, "VncViewer.class")) {
rfbLog("\n");
rfbLog("***********************************************************\n");
rfbLog("SSL: WARNING CLIENT ASKED FOR NONEXISTENT 'VncViewer.class'\n");
rfbLog("SSL: USER NEEDS TO **RESTART** HIS WEB BROWSER.\n");
rfbLog("***********************************************************\n");
rfbLog("\n");
}
ssl_helper_pid(pid, -2);
if (https_port_redir) {
@ -2625,6 +2633,7 @@ void raw_xfer(int csock, int s_in, int s_out) {
char buf[8192];
int sz = 8192, n, m, status, db = 1;
#ifdef FORK_OK
pid_t par = getpid();
pid_t pid = fork();
/* this is for testing, no SSL just socket redir */
@ -2657,6 +2666,7 @@ if (db) fprintf(stderr, "raw_xfer bad write: %d -> %d | %d/%d errno=%d\n", cso
}
}
}
usleep(250*1000);
kill(pid, SIGTERM);
waitpid(pid, &status, WNOHANG);
if (db) fprintf(stderr, "raw_xfer done: %d -> %d\n", csock, s_out);
@ -2687,8 +2697,10 @@ if (db) fprintf(stderr, "raw_xfer bad write: %d -> %d | %d/%d errno=%d\n", cso
}
}
}
usleep(250*1000);
kill(par, SIGTERM);
waitpid(par, &status, WNOHANG);
if (db) fprintf(stderr, "raw_xfer done: %d <- %d\n", csock, s_in);
}
close(csock);
close(s_in);

@ -799,7 +799,7 @@ char find_display[] =
" if [ -d \"/proc/$pid\" ]; then\n"
" ok=1\n"
" fi\n"
" elif echo \"$ps_out\" | awk '{print $2}' | grep -w \"$pid\" > /dev/null; then\n"
" elif echo \"$psout\" | awk '{print $2}' | grep -w \"$pid\" > /dev/null; then\n"
" ok=1\n"
" fi\n"
" fi\n"
@ -820,6 +820,14 @@ char find_display[] =
" do\n"
" xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n"
" if [ \"X$FD_TAG\" != \"X\" ]; then\n"
" if xprop -display \"$p\" -root -len 128 FD_TAG | grep -iv no.such.atom \\\n"
" | grep \"=[ ][ ]*\\\"$FD_TAG\\\"\" > /dev/null; then\n"
" :\n"
" else\n"
" continue\n"
" fi\n"
" fi\n"
" # try again with no authority:\n"
" env XAUTHORITY=/dev/null xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
" # 0 means got in for free... skip it.\n"
@ -1004,7 +1012,15 @@ char create_display[] =
" echo \"$have_xterm\"\n"
" return\n"
" fi\n"
" home=`csh -f -c \"echo ~$USER\"`\n"
" if type csh > /dev/null 2>&1; then\n"
" home=`csh -f -c \"echo ~$USER\"`\n"
" elif type tcsh > /dev/null 2>&1; then\n"
" home=`tcsh -f -c \"echo ~$USER\"`\n"
" elif type bash > /dev/null 2>&1; then\n"
" home=`bash -c \"echo ~$USER\"`\n"
" else\n"
" home=\"\"\n"
" fi\n"
" if [ \"X$home\" = \"X\" -o ! -d \"$home\" ]; then\n"
" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
" home=`su - $USER -c 'echo $HOME'`\n"
@ -1058,6 +1074,101 @@ char create_display[] =
" fi\n"
"}\n"
"\n"
"check_redir_services() {\n"
" redir_daemon=\"\"\n"
" need_env=\"\"\n"
" if echo \"$sess\" | grep '^env ' > /dev/null; then\n"
" sess=`echo \"$sess\" | sed -e 's/^env //'`\n"
" need_env=1\n"
" fi\n"
" if [ \"X$FD_ESD\" != \"X\" -a \"X$have_esddsp\" != \"X\" ]; then\n"
" if echo \"$FD_ESD\" | grep '^DAEMON-' > /dev/null; then\n"
" FD_ESD=`echo \"$FD_ESD\" | sed -e 's/DAEMON-//'`\n"
" rport=`echo \"$FD_ESD\" | sed -e 's/^.*://'`\n"
" dport=`expr $rport + 1`\n"
" dport=`freeport $dport`\n"
" FD_ESD=$dport\n"
" redir_daemon=\"$redir_daemon,TS_ESD_REDIR:$dport:$rport\"\n"
" fi\n"
" if echo \"$FD_ESD\" | grep ':' > /dev/null; then\n"
" :\n"
" else\n"
" FD_ESD=\"localhost:$FD_ESD\"\n"
" fi\n"
" sess=\"ESPEAKER=$FD_ESD $have_esddsp -s $FD_ESD $sess\"\n"
" need_env=1\n"
" fi\n"
" if [ \"X$FD_CUPS\" != \"X\" ]; then\n"
" if echo \"$FD_CUPS\" | grep '^DAEMON-' > /dev/null; then\n"
" FD_CUPS=`echo \"$FD_CUPS\" | sed -e 's/DAEMON-//'`\n"
" rport=`echo \"$FD_CUPS\" | sed -e 's/^.*://'`\n"
" dport=`expr $rport + 1`\n"
" dport=`freeport $dport`\n"
" FD_CUPS=$dport\n"
" redir_daemon=\"$redir_daemon,TS_CUPS_REDIR:$dport:$rport\"\n"
"#echo \"redir_daemon=$redir_daemon\" 1>&2\n"
" fi\n"
" if echo \"$FD_CUPS\" | grep ':' > /dev/null; then\n"
" :\n"
" else\n"
" FD_CUPS=\"localhost:$FD_CUPS\"\n"
" fi\n"
" csr=`echo \"$FD_CUPS\" | awk -F: '{print $1}'`\n"
" ipp=`echo \"$FD_CUPS\" | awk -F: '{print $2}'`\n"
" old=`strings -a /usr/sbin/cupsd 2>/dev/null | grep 'CUPS.v1\\.[01]'`\n"
" if [ \"X$old\" != \"X\" ]; then\n"
" FD_CUPS=`echo \"$FD_CUPS\" | sed -e 's/:.*$//'`\n"
" fi\n"
" sess=\"CUPS_SERVER=$FD_CUPS IPP_PORT=$ipp $sess\"\n"
" need_env=1\n"
" fi\n"
"\n"
" if [ \"X$FD_SMB\" != \"X\" ]; then\n"
" if echo \"$FD_SMB\" | grep '^DAEMON-' > /dev/null; then\n"
" FD_SMB=`echo \"$FD_SMB\" | sed -e 's/DAEMON-//'`\n"
" rport=`echo \"$FD_SMB\" | sed -e 's/^.*://'`\n"
" dport=`expr $rport + 1`\n"
" dport=`freeport $dport`\n"
" FD_SMB=$dport\n"
" redir_daemon=\"$redir_daemon,TS_SMB_REDIR:$dport:$rport\"\n"
" fi\n"
" if echo \"$FD_SMB\" | grep ':' > /dev/null; then\n"
" :\n"
" else\n"
" FD_SMB=\"localhost:$FD_SMB\"\n"
" fi\n"
" smh=`echo \"$FD_SMB\" | awk -F: '{print $1}'`\n"
" smp=`echo \"$FD_SMB\" | awk -F: '{print $2}'`\n"
" if [ \"X$smh\" = \"X\" ]; then\n"
" smh=localhost\n"
" fi\n"
" sess=\"SMB_SERVER=$FD_SMB SMB_HOST=$smh SMB_PORT=$smp $sess\"\n"
" need_env=1\n"
" fi\n"
"\n"
" if [ \"X$FD_NAS\" != \"X\" ]; then\n"
" if echo \"$FD_NAS\" | grep '^DAEMON-' > /dev/null; then\n"
" FD_NAS=`echo \"$FD_NAS\" | sed -e 's/DAEMON-//'`\n"
" rport=`echo \"$FD_NAS\" | sed -e 's/^.*://'`\n"
" dport=`expr $rport + 1`\n"
" dport=`freeport $dport`\n"
" FD_NAS=$dport\n"
" redir_daemon=\"$redir_daemon,TS_NAS_REDIR:$dport:$rport\"\n"
" fi\n"
" if echo \"$FD_NAS\" | grep ':' > /dev/null; then\n"
" :\n"
" else\n"
" FD_NAS=\"tcp/localhost:$FD_NAS\"\n"
" fi\n"
" sess=\"AUDIOSERVER=$FD_NAS $sess\"\n"
" need_env=1\n"
" fi\n"
" if [ \"X$need_env\" != \"X\" ]; then\n"
" sess=\"env $sess\"\n"
" fi\n"
" redir_daemon=`echo \"$redir_daemon\" | sed -e 's/^,*//'`\n"
"}\n"
"\n"
"server() {\n"
" authfile=`auth`\n"
" sess=`findsession`\n"
@ -1067,6 +1178,10 @@ char create_display[] =
" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
" sess=\"env DISPLAY=:$N $sess\"\n"
" fi\n"
"\n"
" redir_daemon=\"\"\n"
" check_redir_services\n"
"\n"
" rmf=\"/nosuch\"\n"
" if echo \"$sess\" | grep '[ ]' > /dev/null; then\n"
" stmp=/tmp/.cd$$`random`\n"
@ -1163,6 +1278,15 @@ char create_display[] =
" else\n"
" $have_nohup sh -c \"(sleep 60; rm -f $rmf $authfile)\" 1>&2 &\n"
" fi\n"
"\n"
" if [ \"X$redir_daemon\" != \"X\" -a \"X$result\" = \"X1\" ]; then\n"
" redir_daemon=`echo \"$redir_daemon\" | sed -e 's|[^A-z0-9:,/]||g'`\n"
" xprog=$X11VNC_PROG\n"
" if [ \"X$xprog\" = \"X\"]; then\n"
" xprog=x11vnc\n"
" fi\n"
" $have_nohup sh -c \"$xprog -sleepin 10 -auth $authfile -tsd $redir_daemon\" 2>.tsd.log.$USER 1>&2 &\n"
" fi\n"
"}\n"
"\n"
"try_X() {\n"
@ -1190,14 +1314,13 @@ char create_display[] =
" if [ \"X$have_Xdummy\" = \"X\" ]; then\n"
" return\n"
" fi\n"
" if [ \"X$have_root\" = \"X\" ]; then\n"
" if [ \"X$FD_XDUMMY_NOROOT\" != \"X\" ]; then\n"
" :\n"
" elif [ \"X$have_root\" = \"X\" ]; then\n"
" return\n"
" fi\n"
"\n"
" #save_have_startx=$have_startx\n"
" #have_startx=\"\"\n"
" server $have_Xdummy :$N -geom $geom -depth $depth\n"
" #have_startx=$save_have_startx\n"
" server $have_Xdummy :$N -geometry $geom -depth $depth\n"
"}\n"
"\n"
"try_Xvnc() {\n"
@ -1336,6 +1459,46 @@ char create_display[] =
" echo \"$tmp\"\n"
"}\n"
"\n"
"freeport() {\n"
" base=$1\n"
" if [ \"X$have_uname\" != \"X\" -a \"X$have_netstat\" != \"X\" ]; then\n"
" inuse=\"\"\n"
" if $have_uname | grep Linux > /dev/null; then\n"
" inuse=`$have_netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'`\n"
" elif $have_uname | grep SunOS > /dev/null; then\n"
" inuse=`$have_netstat -an -f inet -P tcp | grep LISTEN | awk '{print $1}' | sed 's/^.*\\.//'`\n"
" elif $have_uname | grep -i bsd > /dev/null; then\n"
" inuse=`$have_netstat -ant -f inet | grep LISTEN | awk '{print $4}' | sed 's/^.*\\.//'`\n"
" # add others...\n"
" fi\n"
" fi\n"
" i=0\n"
" ok=\"\"\n"
" while [ $i -lt 500 ]\n"
" do\n"
" tryp=`expr $base + $i`\n"
" if echo \"$inuse\" | grep -w \"$tryp\" > /dev/null; then\n"
" :\n"
" elif echo \"$palloc\" | tr ' ' '\\n' | grep -w \"$tryp\" > /dev/null; then\n"
" :\n"
" else\n"
" ok=$tryp\n"
" break\n"
" fi\n"
" i=`expr $i + 1`\n"
" done\n"
" if [ \"X$ok\" != \"X\" ]; then\n"
" base=$ok\n"
" fi\n"
" if [ \"X$palloc\" = \"X\" ]; then\n"
" palloc=\"$base\"\n"
" else\n"
" palloc=\"$palloc $base\"\n"
" fi\n"
" echo \"$base\"\n"
"}\n"
"\n"
"\n"
"depth=${depth:-16}\n"
"geom=${geom:-1280x1024}\n"
"\n"
@ -1389,7 +1552,7 @@ char create_display[] =
" p_ok=1\n"
"fi\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\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"
"do\n"
" p2=`echo \"$prog\" | sed -e 's/-/_/g'`\n"
" eval \"have_$p2=''\"\n"
@ -1406,6 +1569,13 @@ char create_display[] =
" eval \"have_$p2=$bpath\"\n"
" fi\n"
"done\n"
"if [ \"X$have_xterm\" = \"X\" ]; then\n"
" if [ \"X$have_konsole\" != \"X\" ]; then\n"
" have_xterm=$have_konsole\n"
" elif [ \"X$have_gnome_terminal\" != \"X\" ]; then\n"
" have_xterm=$have_gnome_terminal\n"
" fi\n"
"fi\n"
"\n"
"if [ \"X$have_nohup\" = \"X\" ]; then\n"
" have_nohup=\"nohup\"\n"

@ -1386,10 +1386,23 @@ int wait_for_client(int *argc, char** argv, int http) {
}
cmd = str + strlen("cmd=");
if (!strcmp(str, "FINDDISPLAY-print")) {
if (!strcmp(cmd, "FINDDISPLAY-print")) {
fprintf(stdout, "%s", find_display);
clean_up_exit(0);
}
if (!strcmp(cmd, "FINDDISPLAY-run")) {
char tmp[] = "/tmp/fd.XXXXXX";
char com[100];
int fd = mkstemp(tmp);
if (fd >= 0) {
write(fd, find_display, strlen(find_display));
close(fd);
sprintf(com, "/bin/sh %s -n; rm -f %s", tmp, tmp);
system(com);
}
unlink(tmp);
exit(0);
}
if (!strcmp(str, "FINDCREATEDISPLAY-print")) {
fprintf(stdout, "%s", create_display);
clean_up_exit(0);
@ -1767,6 +1780,12 @@ if (0) db = 1;
/* only sets environment variables: */
run_user_command("", latest_client, "env", NULL, 0, NULL);
if (program_name) {
set_env("X11VNC_PROG", program_name);
} else {
set_env("X11VNC_PROG", "x11vnc");
}
if (!strcmp(cmd, "FINDDISPLAY") ||
strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
char *nd = "";
@ -1789,7 +1808,9 @@ if (0) db = 1;
if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
char *opts = strchr(cmd, '-');
char st[] = "";
char geom[128], xsess[128], fdopts[128], fdprog[128], fdxsrv[128];
char fdgeom[128], fdsess[128], fdopts[128], fdprog[128];
char fdxsrv[128], fdxdum[128], fdcups[128], fdesd[128];
char fdnas[128], fdsmb[128], fdtag[128];
if (opts) {
opts++;
if (strstr(opts, "xdmcp")) {
@ -1798,43 +1819,43 @@ if (0) db = 1;
} else {
opts = st;
}
sprintf(geom, "NONE");
xsess[0] = '\0';
geom[0] = '\0';
sprintf(fdgeom, "NONE");
fdsess[0] = '\0';
fdgeom[0] = '\0';
fdopts[0] = '\0';
fdprog[0] = '\0';
fdxsrv[0] = '\0';
#if 0
if (!keep_unixpw_opts) {
fprintf(stderr, "no keep_unixpw_opts\n");
} else {
fprintf(stderr, "keep_unixpw_opts: %s\n", keep_unixpw_opts);
}
#endif
fdxdum[0] = '\0';
fdcups[0] = '\0';
fdesd[0] = '\0';
fdnas[0] = '\0';
fdsmb[0] = '\0';
fdtag[0] = '\0';
if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
char *q, *p, *t = strdup(keep_unixpw_opts);
if (strstr(t, "gnome")) {
sprintf(xsess, "gnome");
sprintf(fdsess, "gnome");
} else if (strstr(t, "kde")) {
sprintf(xsess, "kde");
sprintf(fdsess, "kde");
} else if (strstr(t, "twm")) {
sprintf(xsess, "twm");
sprintf(fdsess, "twm");
} else if (strstr(t, "fvwm")) {
sprintf(xsess, "fvwm");
sprintf(fdsess, "fvwm");
} else if (strstr(t, "mwm")) {
sprintf(xsess, "mwm");
sprintf(fdsess, "mwm");
} else if (strstr(t, "cde")) {
sprintf(xsess, "cde");
sprintf(fdsess, "cde");
} else if (strstr(t, "dtwm")) {
sprintf(xsess, "dtwm");
sprintf(fdsess, "dtwm");
} else if (strstr(t, "xterm")) {
sprintf(xsess, "xterm");
sprintf(fdsess, "xterm");
} else if (strstr(t, "wmaker")) {
sprintf(xsess, "wmaker");
sprintf(fdsess, "wmaker");
} else if (strstr(t, "Xsession")) {
sprintf(xsess, "Xsession");
sprintf(fdsess, "Xsession");
} else if (strstr(t, "failsafe")) {
sprintf(xsess, "failsafe");
sprintf(fdsess, "failsafe");
}
q = strstr(t, "ge=");
@ -1859,19 +1880,33 @@ if (!keep_unixpw_opts) {
p++;
}
if (ok && strlen(q) < 32) {
sprintf(geom, q);
sprintf(fdgeom, q);
if (!quiet) {
rfbLog("set create display geom: %s\n", geom);
rfbLog("set create display geom: %s\n", fdgeom);
}
}
}
q = strstr(t, "cups=");
if (q) {
int p;
if (sscanf(q, "cups=%d", &p) == 1) {
sprintf(fdcups, "%d", p);
}
}
q = strstr(t, "esd=");
if (q) {
int p;
if (sscanf(q, "esd=%d", &p) == 1) {
sprintf(fdesd, "%d", p);
}
}
free(t);
}
if (geom[0] == '\0' && getenv("FD_GEOM")) {
snprintf(geom, 120, "%s", getenv("FD_GEOM"));
if (fdgeom[0] == '\0' && getenv("FD_GEOM")) {
snprintf(fdgeom, 120, "%s", getenv("FD_GEOM"));
}
if (xsess[0] == '\0' && getenv("FD_SESS")) {
snprintf(xsess, 120, "%s", getenv("FD_SESS"));
if (fdsess[0] == '\0' && getenv("FD_SESS")) {
snprintf(fdsess, 120, "%s", getenv("FD_SESS"));
}
if (fdopts[0] == '\0' && getenv("FD_OPTS")) {
snprintf(fdopts, 120, "%s", getenv("FD_OPTS"));
@ -1882,12 +1917,36 @@ if (!keep_unixpw_opts) {
if (fdxsrv[0] == '\0' && getenv("FD_XSRV")) {
snprintf(fdxsrv, 120, "%s", getenv("FD_XSRV"));
}
if (fdcups[0] == '\0' && getenv("FD_CUPS")) {
snprintf(fdcups, 120, "%s", getenv("FD_CUPS"));
}
if (fdesd[0] == '\0' && getenv("FD_ESD")) {
snprintf(fdesd, 120, "%s", getenv("FD_ESD"));
}
if (fdnas[0] == '\0' && getenv("FD_NAS")) {
snprintf(fdnas, 120, "%s", getenv("FD_NAS"));
}
if (fdsmb[0] == '\0' && getenv("FD_SMB")) {
snprintf(fdsmb, 120, "%s", getenv("FD_SMB"));
}
if (fdtag[0] == '\0' && getenv("FD_TAG")) {
snprintf(fdtag, 120, "%s", getenv("FD_TAG"));
}
if (fdxdum[0] == '\0' && getenv("FD_XDUMMY_NOROOT")) {
snprintf(fdxdum, 120, "%s", getenv("FD_XDUMMY_NOROOT"));
}
set_env("FD_GEOM", geom);
set_env("FD_SESS", xsess);
set_env("FD_GEOM", fdgeom);
set_env("FD_OPTS", fdopts);
set_env("FD_PROG", fdprog);
set_env("FD_XSRV", fdxsrv);
set_env("FD_CUPS", fdcups);
set_env("FD_ESD", fdesd);
set_env("FD_NAS", fdnas);
set_env("FD_SMB", fdsmb);
set_env("FD_TAG", fdtag);
set_env("FD_XDUMMY_NOROOT", fdxdum);
set_env("FD_SESS", fdsess);
if (usslpeer || (unixpw && keep_unixpw_user)) {
char *uu = usslpeer;
@ -1900,16 +1959,32 @@ if (!keep_unixpw_opts) {
+ strlen("FD_OPTS='' ")
+ strlen("FD_PROG='' ")
+ strlen("FD_XSRV='' ")
+ strlen("FD_CUPS='' ")
+ strlen("FD_ESD='' ")
+ strlen("FD_NAS='' ")
+ strlen("FD_SMB='' ")
+ strlen("FD_TAG='' ")
+ strlen("FD_XDUMMY_NOROOT='' ")
+ strlen("FD_SESS='' /bin/sh ")
+ strlen(uu) + 1
+ strlen(geom) + 1
+ strlen(xsess) + 1
+ strlen(fdgeom) + 1
+ strlen(fdopts) + 1
+ strlen(fdprog) + 1
+ strlen(fdxsrv) + 1
+ strlen(fdcups) + 1
+ strlen(fdesd) + 1
+ strlen(fdnas) + 1
+ strlen(fdsmb) + 1
+ strlen(fdtag) + 1
+ strlen(fdxdum) + 1
+ strlen(fdsess) + 1
+ strlen(opts) + 1);
sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' FD_OPTS='%s' FD_PROG='%s' FD_XSRV='%s' /bin/sh %s %s",
uu, geom, xsess, fdopts, fdprog, fdxsrv, tmp, opts);
sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' "
"FD_OPTS='%s' FD_PROG='%s' FD_XSRV='%s' FD_CUPS='%s' "
"FD_ESD='%s' FD_NAS='%s' FD_SMB='%s' FD_TAG='%s' "
"FD_XDUMMY_NOROOT='%s' /bin/sh %s %s",
uu, fdgeom, fdsess, fdopts, fdprog, fdxsrv,
fdcups, fdesd, fdnas, fdsmb, fdtag, fdxdum, tmp, opts);
} else {
create_cmd = (char *) malloc(strlen(tmp)
+ strlen("/bin/sh ") + 1 + strlen(opts) + 1);
@ -2161,7 +2236,7 @@ if (db) fprintf(stderr, "line1=%s\n", line1);
char *t = strstr(line1, ",VT=");
vt = atoi(t + strlen(",VT="));
*t = '\0';
if (7 <= vt && vt <= 128) {
if (7 <= vt && vt <= 15) {
char chvt[100];
sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
rfbLog("running: %s\n", chvt);

@ -1954,7 +1954,7 @@ if (0) fprintf(stderr, "sa.. %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy)
sy1 = sy2;
sy2 = t;
}
if (1) fprintf(stderr, "sb.. %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy);
if (0) fprintf(stderr, "sb.. %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy);
if (mode == DCR_Direct) {
rfbClientIteratorPtr i;
@ -3619,7 +3619,7 @@ void clear_win_events(Window win, int vis) {
/* XXX Y */
if (vis) {
while (XCheckTypedWindowEvent(dpy, win, VisibilityNotify, &ev)) {
fprintf(stderr, "+");
if (ncdb) fprintf(stderr, "+");
if (trapped_xerror) {
break;
}
@ -7692,7 +7692,7 @@ int try_to_fix_resize_su(Window orig_frame, int orig_x, int orig_y, int orig_w,
if (orig_w >= w && orig_h >= h) {
fprintf(stderr, "Shrinking resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
if (0) fprintf(stderr, "Shrinking resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
r3 = sraRgnCreateRgn(r1);
sraRgnSubtract(r3, r2);
@ -7739,7 +7739,7 @@ fprintf(stderr, "Shrinking resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w
/* XXX Y */
if (0) cache_list[idx].su_time = dnow();
} else {
fprintf(stderr, "Growing resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
if (0) fprintf(stderr, "Growing resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
sx1 = cache_list[idx].su_x;
sy1 = cache_list[idx].su_y;

@ -1,8 +1,8 @@
.\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "August 2007" "x11vnc " "User Commands"
.TH X11VNC "1" "September 2007" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.9.3, lastmod: 2007-08-19
version: 0.9.3, lastmod: 2007-09-04
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -84,6 +84,12 @@ to also be :N This just sets the \fB-rfbport\fR option
to 5900+N. The program will exit immediately if that
port is not available.
.PP
\fB-autoport\fR \fIn\fR
.IP
Automatically probe for a free VNC port starting at n.
The default is to start probing at 5900. Use this to
stay away from other VNC servers near 5900.
.PP
\fB-reflect\fR \fIhost:N\fR
.IP
Instead of connecting to and polling an X display,
@ -898,8 +904,9 @@ in addition to this option.
.PP
\fB-find\fR
.IP
Find the user's display using FINDDISPLAY. It is an
alias for "\fB-display\fR \fIWAIT:cmd=FINDDISPLAY\fR".
Find the user's display using FINDDISPLAY. It is
an alias for "\fB-display\fR \fIWAIT:cmd=FINDDISPLAY\fR".
Use \fB-finddpy\fR to run the FINDDISPLAY program and exit.
.PP
\fB-create\fR
.IP
@ -908,12 +915,22 @@ if that doesn't work create an X session via the
FINDCREATEDISPLAY method. This is an alias for
"\fB-display\fR \fIWAIT:cmd=FINDCREATEDISPLAY-Xvfb\fR".
.PP
\fB-xdummy\fR
.IP
As \fB-create\fR except Xdummy instead of Xvfb. Implies
FD_XDUMMY_NOROOT=1.
.PP
\fB-svc\fR
.IP
Terminal services mode. Also "\fB-service\fR". Alias for
\fB-display\fR WAIT:cmd=FINDCREATEDISPLAY-Xvfb \fB-unixpw\fR
\fB-users\fR unixpw= \fB-ssl\fR SAVE
.PP
\fB-svc_xdummy\fR
.IP
As \fB-svc\fR except Xdummy instead of Xvfb. Implies
FD_XDUMMY_NOROOT=1.
.PP
\fB-xdmsvc\fR
.IP
Terminal services mode. Also "\fB-xdm_service\fR". Alias for
@ -1052,13 +1069,16 @@ find one it will try to *start* up an X server session
for the user. This is the only time x11vnc tries to
actually start up an X server.
.IP
By default FINDCREATEDISPLAY will try Xdummy and
then Xvfb. The Xdummy wrapper is part of the x11vnc
source code (x11vnc/misc/Xdummy) It should be available
in PATH and have run "Xdummy \fB-install"\fR once to create
the shared library. Xdummy requires root permission
and only works on Linux. Xvfb is available on most
platforms and does not require root.
By default FINDCREATEDISPLAY will try Xdummy and then
Xvfb. The Xdummy wrapper is part of the x11vnc source
code (x11vnc/misc/Xdummy) It should be available in
PATH and have run "Xdummy \fB-install"\fR once to create
the shared library. Xdummy requires root permission and
only works on Linux. (Note: specify FD_XDUMMY_NOROOT=1
to skip a check for the root id; evidently your
.IR sudo (1)
will take care of everything). Xvfb is available on
most platforms and does not require root.
.IP
When x11vnc exits (i.e. user disconnects) the X
server session stays running in the background.
@ -1117,6 +1137,13 @@ failsafe, etc.). FD_OPTS as extra options to pass to
the X server. You can also set FD_PROG to be the full
path to the session/windowmanager program.
.IP
More FD tricks: FD_CUPS=port or FD_CUPS=host:port
will set the cups printing environment. Similarly
for FD_ESD=port or FD_ESD=host:port for esddsp sound
redirection. FD_XDUMMY_NOROOT means the Xdummy server
does not need to be started as root (e.g. it will sudo
automatically)
.IP
If you want the FINDCREATEDISPLAY session to contact an
XDMCP login manager (xdm/gdm/kdm) on the same machine,
then use "Xvfb.xdmcp" instead of "Xvfb", etc.
@ -1700,9 +1727,9 @@ the directory as though the \fB-http\fR option was supplied.
.PP
\fB-httpsredir\fR \fI[port]\fR
.IP
In \fB-ssl\fR mode with the Java applet retrieved via HTTPS:
In \fB-ssl\fR mode with the Java applet retrieved via HTTPS,
when the HTML file containing applet parameters
('index.vnc' or 'proxy.vnc') is sent do not set the
('index.vnc' or 'proxy.vnc') is sent do NOT set the
applet PORT parameter to the actual VNC port but set it
to "port" instead. If "port" is not supplied, then
the port number is guessed from the Host: HTTP header.
@ -1716,9 +1743,12 @@ on the internal workstation. For example, one could
redir from mygateway.com:443 to workstation:5900.
.IP
This spares the user from having to type in
https://mygateway.com/?PORT=443 into their web browser
(note 443 is the default https port; other ports must
be explicity indicated: https://mygateway.com:8000/...)
https://mygateway.com/?PORT=443 into their web
browser. Note taht port 443 is the default https port;
other ports must be explicity indicated, for example:
https://mygateway.com:8000/?PORT=8000. To avoid having
to include the PORT= in the browser URL, simply supply
"\fB-httpsredir\fR" to x11vnc.
.PP
\fB-usepw\fR
.IP
@ -2084,6 +2114,12 @@ libvncserver tries to do so something reasonable for
viewers that cannot do this (portions of the screen
may be clipped, unused, etc).
.IP
Note: the default now is to check for XRANDR events, but
do not trap every X call that may fail due to resize.
If a resize event is received, the full \fB-xrandr\fR mode
is enabled. To disable even checking for events supply:
\fB-noxrandr.\fR
.IP
"mode" defaults to "resize", which means create a
new, resized, framebuffer and hope all viewers can cope
with the change. "newfbsize" means first disconnect
@ -4446,7 +4482,7 @@ ncache_no_rootpixmap enable ncache_no_rootpixmap.
.IP
noncache_no_rootpixmap disable ncache_no_rootpixmap.
.IP
ncache_reset_rootpixmap recheck the root pixmap
ncache_reset_rootpixmap recheck the root pixmap, ncrp
.IP
ncache_keep_anims enable ncache_keep_anims.
.IP

@ -394,6 +394,574 @@ if (0 && dt > 0.0) fprintf(stderr, "dt: %.5f %.4f\n", dt, dnowx());
return msec;
}
static int tsdo_timeout_flag;
static void tsdo_timeout (int sig) {
tsdo_timeout_flag = 1;
}
#define TASKMAX 32
static pid_t ts_tasks[TASKMAX];
static int ts_taskn = -1;
int tsdo(int port, int lsock, int *conn) {
int csock, rsock, i, db = 1;
pid_t pid;
struct sockaddr_in addr;
#ifdef __hpux
int addrlen = sizeof(addr);
#else
socklen_t addrlen = sizeof(addr);
#endif
if (*conn < 0) {
signal(SIGALRM, tsdo_timeout);
tsdo_timeout_flag = 0;
alarm(10);
csock = accept(lsock, (struct sockaddr *)&addr, &addrlen);
alarm(0);
if (db) rfbLog("tsdo: accept: lsock: %d, csock: %d, port: %d\n", lsock, csock, port);
if (tsdo_timeout_flag > 0 || csock < 0) {
close(csock);
*conn = -1;
return 1;
}
*conn = csock;
} else {
csock = *conn;
if (db) rfbLog("tsdo: using exiting csock: %d, port: %d\n", csock, port);
}
rsock = rfbConnectToTcpAddr("127.0.0.1", port);
if (rsock < 0) {
if (db) rfbLog("tsdo: rfbConnectToTcpAddr(port=%d) failed.\n", port);
return 2;
}
pid = fork();
if (pid < 0) {
close(rsock);
return 3;
}
if (pid > 0) {
ts_taskn = (ts_taskn+1) % TASKMAX;
ts_tasks[ts_taskn] = pid;
close(csock);
*conn = -1;
close(rsock);
return 0;
}
if (pid == 0) {
for (i=0; i<255; i++) {
if (i != csock && i != rsock && i != 2) {
close(i);
}
}
#if LIBVNCSERVER_HAVE_SETSID
if (setsid() == -1) {
perror("setsid");
exit(1);
}
#else
if (setpgrp() == -1) {
perror("setpgrp");
exit(1);
}
#endif /* SETSID */
raw_xfer(rsock, csock, csock);
exit(0);
}
}
void set_redir_properties(void);
#define TSMAX 32
#define TSSTK 16
void terminal_services(char *list) {
int i, j, n = 0, db = 1;
char *p, *q, *r, *str = strdup(list);
#if !NO_X11
char *tag[TSMAX];
int listen[TSMAX], redir[TSMAX][TSSTK], socks[TSMAX], tstk[TSSTK];
Atom at, atom[TSMAX];
fd_set rd;
Window rwin;
XErrorHandler old_handler1;
XIOErrorHandler old_handler2;
char num[32];
time_t last_clean = time(NULL);
if (! dpy) {
return;
}
rwin = RootWindow(dpy, DefaultScreen(dpy));
at = XInternAtom(dpy, "TS_REDIR_LIST", False);
if (at != None) {
XChangeProperty(dpy, rwin, at, XA_STRING, 8,
PropModeReplace, (unsigned char *)list, strlen(list));
XSync(dpy, False);
}
for (i=0; i<TASKMAX; i++) {
ts_tasks[i] = 0;
}
for (i=0; i<TSMAX; i++) {
for (j=0; j<TSSTK; j++) {
redir[i][j] = 0;
}
}
p = strtok(str, ",");
while (p) {
int m1, m2;
if (db) fprintf(stderr, "item: %s\n", p);
q = strrchr(p, ':');
if (!q) {
p = strtok(NULL, ",");
continue;
}
r = strchr(p, ':');
if (!r || r == q) {
p = strtok(NULL, ",");
continue;
}
m1 = atoi(q+1);
*q = '\0';
m2 = atoi(r+1);
*r = '\0';
if (m1 <= 0 || m2 <= 0 || m1 >= 0xffff || m2 >= 0xffff) {
p = strtok(NULL, ",");
continue;
}
redir[n][0] = m1;
listen[n] = m2;
tag[n] = strdup(p);
if (db) fprintf(stderr, " %d %d %s\n", redir[n][0], listen[n], tag[n]);
*r = ':';
*q = ':';
n++;
if (n >= TSMAX) {
break;
}
p = strtok(NULL, ",");
}
free(str);
if (n==0) {
return;
}
at = XInternAtom(dpy, "TS_REDIR_PID", False);
if (at != None) {
sprintf(num, "%d", getpid());
XChangeProperty(dpy, rwin, at, XA_STRING, 8,
PropModeReplace, (unsigned char *)num, strlen(num));
XSync(dpy, False);
}
for (i=0; i<n; i++) {
atom[i] = XInternAtom(dpy, tag[i], False);
if (db) fprintf(stderr, "tag: %s atom: %d\n", tag[i], atom[i]);
if (atom[i] == None) {
continue;
}
sprintf(num, "%d", redir[i][0]);
if (db) fprintf(stderr, " listen: %d redir: %s\n", listen[i], num);
XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
PropModeReplace, (unsigned char *)num, strlen(num));
XSync(dpy, False);
socks[i] = rfbListenOnTCPPort(listen[i], htonl(INADDR_LOOPBACK));
}
if (getenv("TSD_RESTART")) {
if (!strcmp(getenv("TSD_RESTART"), "1")) {
set_redir_properties();
}
}
while (1) {
struct timeval tv;
int nfd;
int fmax = -1;
tv.tv_sec = 3;
tv.tv_usec = 0;
FD_ZERO(&rd);
for (i=0; i<n; i++) {
if (socks[i] >= 0) {
FD_SET(socks[i], &rd);
if (socks[i] > fmax) {
fmax = socks[i];
}
}
}
nfd = select(fmax+1, &rd, NULL, NULL, &tv);
if (db && 0) fprintf(stderr, "nfd=%d\n", nfd);
if (nfd < 0 && errno == EINTR) {
XSync(dpy, True);
continue;
}
if (nfd > 0) {
for(i=0; i<n; i++) {
int k = 0;
for (j = 0; j < TSSTK; j++) {
tstk[j] = 0;
}
for (j = 0; j < TSSTK; j++) {
if (redir[i][j] != 0) {
tstk[k++] = redir[i][j];
}
}
for (j = 0; j < TSSTK; j++) {
redir[i][j] = tstk[j];
if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], tag[i]);
}
}
for(i=0; i<n; i++) {
int s = socks[i];
if (s < 0) {
continue;
}
if (FD_ISSET(s, &rd)) {
int p0, p, found = -1, jzero = -1;
int conn = -1;
get_prop(num, 32, atom[i]);
p0 = atoi(num);
for (j = TSSTK-1; j >= 0; j--) {
if (redir[i][j] == 0) {
jzero = j;
continue;
}
if (p0 > 0 && p0 < 0xffff) {
if (redir[i][j] == p0) {
found = j;
break;
}
}
}
if (jzero < 0) {
jzero = TSSTK-1;
}
if (found < 0) {
if (p0 > 0 && p0 < 0xffff) {
redir[i][jzero] = p0;
}
}
for (j = TSSTK-1; j >= 0; j--) {
int rc;
p = redir[i][j];
if (p <= 0 || p >= 0xffff) {
redir[i][j] = 0;
continue;
}
rc = tsdo(p, s, &conn);
if (rc == 0) {
/* AOK */
if (db) fprintf(stderr, "tsdo[%d] OK: %d\n", i, p);
if (p != p0) {
sprintf(num, "%d", p);
XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
PropModeReplace, (unsigned char *)num, strlen(num));
XSync(dpy, False);
}
break;
} else if (rc == 1) {
/* accept failed */
if (db) fprintf(stderr, "tsdo[%d] accept failed: %d\n", i, p);
break;
} else if (rc == 2) {
/* connect failed */
if (db) fprintf(stderr, "tsdo[%d] connect failed: %d\n", i, p);
redir[i][j] = 0;
continue;
} else if (rc == 3) {
/* fork failed */
usleep(250*1000);
break;
}
}
for (j = 0; j < TSSTK; j++) {
if (redir[i][j] != 0) fprintf(stderr, "A redir[%d][%d] = %d %s\n", i, j, redir[i][j], tag[i]);
}
}
}
}
for (i=0; i<TASKMAX; i++) {
pid_t p = ts_tasks[i];
if (p > 0) {
int status;
pid_t p2 = waitpid(p, &status, WNOHANG);
if (p2 == p) {
ts_tasks[i] = 0;
}
}
}
/* this is to drop events and exit when X server is gone. */
old_handler1 = XSetErrorHandler(trap_xerror);
old_handler2 = XSetIOErrorHandler(trap_xioerror);
trapped_xerror = 0;
trapped_xioerror = 0;
XSync(dpy, True);
sprintf(num, "%d", (int) time(NULL));
at = XInternAtom(dpy, "TS_REDIR", False);
if (at != None) {
XChangeProperty(dpy, rwin, at, XA_STRING, 8,
PropModeReplace, (unsigned char *)num, strlen(num));
XSync(dpy, False);
}
if (time(NULL) > last_clean + 20 * 60) {
int i, j;
for(i=0; i<n; i++) {
int first = 1;
for (j = TSSTK-1; j >= 0; j--) {
int s, p = redir[i][j];
if (p <= 0 || p >= 0xffff) {
redir[i][j] = 0;
continue;
}
s = rfbConnectToTcpAddr("127.0.0.1", p);
if (s < 0) {
redir[i][j] = 0;
if (db) fprintf(stderr, "tsdo[%d][%d] clean: connect failed: %d\n", i, j, p);
} else {
close(s);
if (first) {
sprintf(num, "%d", p);
XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
PropModeReplace, (unsigned char *)num, strlen(num));
XSync(dpy, False);
}
first = 0;
}
usleep(500*1000);
}
}
last_clean = time(NULL);
}
if (trapped_xerror || trapped_xioerror) {
if (db) fprintf(stderr, "Xerror: %d/%d\n", trapped_xerror, trapped_xioerror);
exit(0);
}
XSetErrorHandler(old_handler1);
XSetIOErrorHandler(old_handler2);
}
#endif
}
char *ts_services[][2] = {
{"FD_CUPS", "TS_CUPS_REDIR"},
{"FD_SMB", "TS_SMB_REDIR"},
{"FD_ESD", "TS_ESD_REDIR"},
{"FD_NAS", "TS_NAS_REDIR"},
{NULL, NULL}
};
void do_tsd(void) {
#if !NO_X11
Atom a;
char prop[513];
pid_t pid;
char *cmd;
int n, sz = 0;
char *disp = DisplayString(dpy);
prop[0] = '\0';
a = XInternAtom(dpy, "TS_REDIR_LIST", False);
if (a != None) {
get_prop(prop, 512, a);
}
if (prop[0] == '\0') {
return;
}
if (! program_name) {
program_name = "x11vnc";
}
sz += strlen(program_name) + 1;
sz += strlen("-display") + 1;
sz += strlen(disp) + 1;
sz += strlen("-tsd") + 1;
sz += 1 + strlen(prop) + 1 + 1;
sz += strlen("-env TSD_RESTART=1") + 1;
sz += strlen("</dev/null 1>/dev/null 2>&1") + 1;
sz += strlen(" &") + 1;
cmd = (char *) malloc(sz);
if (getenv("XAUTHORITY")) {
char *xauth = getenv("XAUTHORITY");
if (!strcmp(xauth, "") || access(xauth, R_OK) != 0) {
*(xauth-2) = '_'; /* yow */
}
}
sprintf(cmd, "%s -display %s -tsd '%s' -env TSD_RESTART=1 </dev/null 1>/dev/null 2>&1 &", program_name, disp, prop);
rfbLog("running: %s\n", cmd);
#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
/* fork into the background now */
if ((pid = fork()) > 0) {
pid_t pidw;
int status;
double s = dnow();
while (dnow() < s + 1.5) {
pidw = waitpid(pid, &status, WNOHANG);
if (pidw == pid) {
break;
}
usleep(100*1000);
}
return;
} else if (pid == -1) {
system(cmd);
} else {
setsid();
/* adjust our stdio */
n = open("/dev/null", O_RDONLY);
dup2(n, 0);
dup2(n, 1);
dup2(n, 2);
if (n > 2) {
close(n);
}
system(cmd);
exit(0);
}
#else
system(cmd);
#endif
#endif
}
void set_redir_properties(void) {
#if !NO_X11
char *e, *f, *t;
Atom a;
char num[32];
int i, p;
if (! dpy) {
return;
}
i = 0;
while (ts_services[i][0] != NULL) {
f = ts_services[i][0];
t = ts_services[i][1];
e = getenv(f);
if (!e || strstr(e, "DAEMON-") != e) {
i++;
continue;
}
p = atoi(e + strlen("DAEMON-"));
if (p <= 0) {
i++;
continue;
}
sprintf(num, "%d", p);
a = XInternAtom(dpy, t, False);
if (a != None) {
Window rwin = RootWindow(dpy, DefaultScreen(dpy));
fprintf(stderr, "Set: %s %s %s -> %s\n", f, t, e, num);
XChangeProperty(dpy, rwin, a, XA_STRING, 8,
PropModeReplace, (unsigned char *) num, strlen(num));
XSync(dpy, False);
}
i++;
}
#endif
}
void check_redir_services(void) {
#if !NO_X11
Atom a;
char prop[513];
time_t tsd_last;
int i, restart = 0;
pid_t pid = 0;
if (! dpy) {
return;
}
a = XInternAtom(dpy, "TS_REDIR_PID", False);
if (a != None) {
prop[0] = '\0';
get_prop(prop, 512, a);
if (prop[0] != '\0') {
pid = (pid_t) atoi(prop);
}
}
if (getenv("FD_TAG")) {
a = XInternAtom(dpy, "FD_TAG", False);
if (a != None) {
Window rwin = RootWindow(dpy, DefaultScreen(dpy));
char *tag = getenv("FD_TAG");
XChangeProperty(dpy, rwin, a, XA_STRING, 8,
PropModeReplace, (unsigned char *)tag, strlen(tag));
XSync(dpy, False);
}
}
prop[0] = '\0';
a = XInternAtom(dpy, "TS_REDIR", False);
if (a != None) {
get_prop(prop, 512, a);
}
if (prop[0] == '\0') {
rfbLog("TS_REDIR is empty, restarting...\n");
restart = 1;
} else {
tsd_last = (time_t) atoi(prop);
if (time(NULL) > tsd_last + 30) {
rfbLog("TS_REDIR seems dead for: %d sec, restarting...\n",
time(NULL) - tsd_last);
restart = 1;
} else if (pid > 0 && time(NULL) > tsd_last + 6) {
if (kill(pid, 0) != 0) {
rfbLog("TS_REDIR seems dead via kill(%d, 0), restarting...\n",
pid);
restart = 1;
}
}
}
if (restart) {
if (pid > 1) {
rfbLog("killing TS_REDIR_PID: %d\n", pid);
kill(pid, SIGTERM);
usleep(500*1000);
kill(pid, SIGKILL);
}
do_tsd();
return;
}
set_redir_properties();
#endif
}
void check_filexfer(void) {
static time_t last_check = 0;
rfbClientIteratorPtr iter;
@ -646,6 +1214,27 @@ static void watch_loop(void) {
vnc_reflect_process_client();
}
dtime0(&tm);
#if !NO_X11
if (xrandr_present && !xrandr && xrandr_maybe) {
int delay = 180;
/* there may be xrandr right after xsession start */
if (tm < x11vnc_start + delay || tm < last_client + delay) {
int tw = 20;
if (auth_file != NULL) {
tw = 120;
}
X_LOCK;
if (tm < x11vnc_start + tw || tm < last_client + tw) {
XSync(dpy, False);
} else {
XFlush_wr(dpy);
}
X_UNLOCK;
}
check_xrandr_event("before-scan");
}
#endif
if (use_snapfb) {
int t, tries = 3;
copy_snap();
@ -1562,7 +2151,7 @@ char msg2[] =
#define SHOW_NO_PASSWORD_WARNING \
(!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list) \
&& !query_cmd && !remote_cmd && !unixpw && !got_gui_pw \
&& ! ssl_verify && !inetd)
&& ! ssl_verify && !inetd && !terminal_services_daemon)
extern int dragum(void);
@ -1710,18 +2299,36 @@ int main(int argc, char* argv[]) {
}
} else if (!strcmp(arg, "-find")) {
use_dpy = strdup("WAIT:cmd=FINDDISPLAY");
} else if (!strcmp(arg, "-finddpy")) {
int ic = 0;
use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run");
if (argc > i+1) {
set_env("X11VNC_USER", argv[i+1]);
fprintf(stdout, "X11VNC_USER=%s\n", getenv("X11VNC_USER"));
}
wait_for_client(&ic, NULL, 0);
exit(0);
} else if (!strcmp(arg, "-create")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb");
} else if (!strcmp(arg, "-xdummy")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
set_env("FD_XDUMMY_NOROOT", "1");
} else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
CHECK_ARGC
auth_file = strdup(argv[++i]);
} else if (!strcmp(arg, "-N")) {
display_N = 1;
} else if (!strcmp(arg, "-autoport")) {
CHECK_ARGC
auto_port = atoi(argv[++i]);
} else if (!strcmp(arg, "-reflect")) {
CHECK_ARGC
raw_fb_str = (char *) malloc(4 + strlen(argv[i]) + 1);
sprintf(raw_fb_str, "vnc:%s", argv[++i]);
shared = 1;
} else if (!strcmp(arg, "-tsd")) {
CHECK_ARGC
terminal_services_daemon = strdup(argv[++i]);
} else if (!strcmp(arg, "-id") || !strcmp(arg, "-sid")) {
CHECK_ARGC
if (!strcmp(arg, "-sid")) {
@ -1878,6 +2485,13 @@ int main(int argc, char* argv[]) {
users_list = strdup("unixpw=");
use_openssl = 1;
openssl_pem = strdup("SAVE");
} else if (!strcmp(arg, "-svc_xdummy")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
unixpw = 1;
users_list = strdup("unixpw=");
use_openssl = 1;
openssl_pem = strdup("SAVE");
set_env("FD_XDUMMY_NOROOT", "1");
} else if (!strcmp(arg, "-xdmsvc") || !strcmp(arg, "-xdm_service")) {
use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp");
unixpw = 1;
@ -2095,6 +2709,9 @@ int main(int argc, char* argv[]) {
i++;
}
}
} else if (!strcmp(arg, "-noxrandr")) {
xrandr = 0;
xrandr_maybe = 0;
} else if (!strcmp(arg, "-rotate")) {
CHECK_ARGC
rotating_str = strdup(argv[++i]);
@ -3328,6 +3945,11 @@ int main(int argc, char* argv[]) {
dpy = XOpenDisplay_wr("");
}
if (terminal_services_daemon != NULL) {
terminal_services(terminal_services_daemon);
exit(0);
}
#ifdef MACOSX
if (! dpy && ! raw_fb_str) {
raw_fb_str = strdup("console");
@ -3744,6 +4366,7 @@ int main(int argc, char* argv[]) {
}
xrandr_base_event_type = 0;
xrandr = 0;
xrandr_maybe = 0;
xrandr_present = 0;
} else {
xrandr_present = 1;
@ -3905,7 +4528,8 @@ int main(int argc, char* argv[]) {
}
free(xdmcp_insert);
#endif
}
}
check_redir_services();
}

@ -485,6 +485,7 @@ extern rfbClientPtr latest_client;
extern int waited_for_client;
extern int findcreatedisplay;
extern char *terminal_services_daemon;
extern int client_count;
extern int clients_served;

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.3 lastmod: 2007-08-19";
char lastmod[] = "0.9.3 lastmod: 2007-09-04";
/* X display info */
@ -148,6 +148,7 @@ rfbClientPtr latest_client = NULL;
int waited_for_client = 0;
int findcreatedisplay = 0;
char *terminal_services_daemon = NULL;
int client_count = 0;
int clients_served = 0;

@ -43,10 +43,10 @@ void set_server_input(rfbClientPtr cl, int s);
void set_text_chat(rfbClientPtr cl, int l, char *t);
int get_keyboard_led_state_hook(rfbScreenInfoPtr s);
int get_file_transfer_permitted(rfbClientPtr cl);
void get_prop(char *str, int len, Atom prop);
static void initialize_xevents(int reset);
static void print_xevent_bases(void);
static void get_prop(char *str, int len, Atom prop);
static void bust_grab(int reset);
static int process_watch(char *str, int parent, int db);
static void grab_buster_watch(int parent, char *dstr);
@ -135,7 +135,7 @@ static void initialize_xevents(int reset) {
did_xcreate_simple_window = 1;
}
if (xrandr && !did_xrandr) {
if ((xrandr || xrandr_maybe) && !did_xrandr) {
initialize_xrandr();
did_xrandr = 1;
}
@ -178,7 +178,7 @@ static void print_xevent_bases(void) {
fprintf(stderr, " SelClear=%d, Expose=%d\n", SelectionClear, Expose);
}
static void get_prop(char *str, int len, Atom prop) {
void get_prop(char *str, int len, Atom prop) {
int i;
#if !NO_X11
Atom type;
@ -949,7 +949,7 @@ void check_xevents(int reset) {
}
#if LIBVNCSERVER_HAVE_LIBXRANDR
if (xrandr) {
if (xrandr || xrandr_maybe) {
check_xrandr_event("check_xevents");
}
#endif

@ -26,6 +26,7 @@ extern void set_server_input(rfbClientPtr cl, int s);
extern void set_text_chat(rfbClientPtr cl, int l, char *t);
extern int get_keyboard_led_state_hook(rfbScreenInfoPtr s);
extern int get_file_transfer_permitted(rfbClientPtr cl);
extern void get_prop(char *str, int len, Atom prop);
#endif /* _X11VNC_XEVENTS_H */

@ -36,7 +36,7 @@ void initialize_xrandr(void) {
xrandr_height = XDisplayHeight(dpy, scr);
XRRRotations(dpy, scr, &rot);
xrandr_rotation = (int) rot;
if (xrandr) {
if (xrandr || xrandr_maybe) {
XRRSelectInput(dpy, rootwin, RRScreenChangeNotifyMask);
} else {
XRRSelectInput(dpy, rootwin, 0);
@ -156,36 +156,58 @@ int check_xrandr_event(char *msg) {
return handle_subwin_resize(msg);
}
#if LIBVNCSERVER_HAVE_LIBXRANDR
if (! xrandr || ! xrandr_present) {
if (! xrandr_present) {
return 0;
}
if (! xrandr && ! xrandr_maybe) {
return 0;
}
if (xrandr_base_event_type && XCheckTypedEvent(dpy,
xrandr_base_event_type + RRScreenChangeNotify, &xev)) {
int do_change;
int do_change, qout = 0;
static int first = 1;
XRRScreenChangeNotifyEvent *rev;
rev = (XRRScreenChangeNotifyEvent *) &xev;
if (first && ! xrandr) {
fprintf(stderr, "\n");
qout = 1;
}
first = 0;
rfbLog("check_xrandr_event():\n");
rfbLog("Detected XRANDR event at location '%s':\n", msg);
rfbLog(" serial: %d\n", (int) rev->serial);
rfbLog(" timestamp: %d\n", (int) rev->timestamp);
rfbLog(" cfg_timestamp: %d\n", (int) rev->config_timestamp);
rfbLog(" size_id: %d\n", (int) rev->size_index);
rfbLog(" sub_pixel: %d\n", (int) rev->subpixel_order);
rfbLog(" rotation: %d\n", (int) rev->rotation);
rfbLog(" width: %d\n", (int) rev->width);
rfbLog(" height: %d\n", (int) rev->height);
rfbLog(" mwidth: %d mm\n", (int) rev->mwidth);
rfbLog(" mheight: %d mm\n", (int) rev->mheight);
rfbLog("\n");
rfbLog("check_xrandr_event: previous WxH: %dx%d\n",
wdpy_x, wdpy_y);
if (qout) {
;
} else {
rfbLog(" serial: %d\n", (int) rev->serial);
rfbLog(" timestamp: %d\n", (int) rev->timestamp);
rfbLog(" cfg_timestamp: %d\n", (int) rev->config_timestamp);
rfbLog(" size_id: %d\n", (int) rev->size_index);
rfbLog(" sub_pixel: %d\n", (int) rev->subpixel_order);
rfbLog(" rotation: %d\n", (int) rev->rotation);
rfbLog(" width: %d\n", (int) rev->width);
rfbLog(" height: %d\n", (int) rev->height);
rfbLog(" mwidth: %d mm\n", (int) rev->mwidth);
rfbLog(" mheight: %d mm\n", (int) rev->mheight);
rfbLog("\n");
rfbLog("check_xrandr_event: previous WxH: %dx%d\n",
wdpy_x, wdpy_y);
}
if (wdpy_x == rev->width && wdpy_y == rev->height &&
xrandr_rotation == (int) rev->rotation) {
rfbLog("check_xrandr_event: no change detected.\n");
do_change = 0;
} else {
do_change = 1;
if (! xrandr) {
rfbLog("check_xrandr_event: Resize; "
"enabling full XRANDR trapping.\n");
xrandr = 1;
}
}
xrandr_width = rev->width;
@ -194,13 +216,16 @@ int check_xrandr_event(char *msg) {
xrandr_cfg_time = rev->config_timestamp;
xrandr_rotation = (int) rev->rotation;
rfbLog("check_xrandr_event: updating config...\n");
if (! qout) rfbLog("check_xrandr_event: updating config...\n");
XRRUpdateConfiguration(&xev);
if (do_change) {
X_UNLOCK;
handle_xrandr_change(rev->width, rev->height);
}
if (qout) {
return do_change;
}
rfbLog("check_xrandr_event: current WxH: %dx%d\n",
XDisplayWidth(dpy, scr), XDisplayHeight(dpy, scr));
rfbLog("check_xrandr_event(): returning control to"

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

Loading…
Cancel
Save