/* -- remote.c -- */ #include "x11vnc.h" #include "inet.h" #include "xwrappers.h" #include "xevents.h" #include "xinerama.h" #include "xrandr.h" #include "xdamage.h" #include "xrecord.h" #include "xkb_bell.h" #include "win_utils.h" #include "screen.h" #include "cleanup.h" #include "gui.h" #include "solid.h" #include "user.h" #include "rates.h" #include "scan.h" #include "connections.h" #include "pointer.h" #include "cursor.h" #include "userinput.h" #include "keyboard.h" #include "selection.h" #include "unixpw.h" #include "uinput.h" int send_remote_cmd(char *cmd, int query, int wait); int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync, int qdefault); void check_black_fb(void); int check_httpdir(void); void http_connections(int on); int remote_control_access_ok(void); char *process_remote_cmd(char *cmd, int stringonly); static char *add_item(char *instr, char *item); static char *delete_item(char *instr, char *item); static void if_8bpp_do_new_fb(void); static void reset_httpport(int old, int new); static void reset_rfbport(int old, int new) ; /* * for the wild-n-crazy -remote/-R interface. */ int send_remote_cmd(char *cmd, int query, int wait) { FILE *in = NULL; if (client_connect_file) { in = fopen(client_connect_file, "w"); if (in == NULL) { fprintf(stderr, "send_remote_cmd: could not open " "connect file \"%s\" for writing\n", client_connect_file); perror("fopen"); return 1; } } else if (x11vnc_remote_prop == None) { initialize_x11vnc_remote_prop(); if (x11vnc_remote_prop == None) { fprintf(stderr, "send_remote_cmd: could not obtain " "X11VNC_REMOTE X property\n"); return 1; } } if (in != NULL) { fprintf(stderr, ">>> sending remote command: \"%s\"\n via" " connect file: %s\n", cmd, client_connect_file); fprintf(in, "%s\n", cmd); fclose(in); } else { fprintf(stderr, ">>> sending remote command: \"%s\" via" " X11VNC_REMOTE X property.\n", cmd); set_x11vnc_remote_prop(cmd); if (dpy) { XFlush_wr(dpy); } } if (query || wait) { char line[X11VNC_REMOTE_MAX]; int rc=1, i=0, max=70, ms_sl=50; if (!strcmp(cmd, "cmd=stop")) { max = 20; } for (i=0; ihttpPort == 0) { int port = find_free_port(5800, 5850); if (port) { screen->httpPort = port; } } } screen->httpInitDone = FALSE; if (check_httpdir()) { screen->httpDir = http_dir; rfbHttpInitSockets(screen); } } else { rfbLog("http_connections: turning off http service.\n"); if (screen->httpListenSock > -1) { close(screen->httpListenSock); } screen->httpListenSock = -1; screen->httpDir = NULL; } } static void reset_httpport(int old, int new) { int hp = new; if (hp < 0) { rfbLog("reset_httpport: invalid httpport: %d\n", hp); } else if (hp == old) { rfbLog("reset_httpport: unchanged httpport: %d\n", hp); } else if (inetd) { rfbLog("reset_httpport: cannot set httpport: %d" " in inetd.\n", hp); } else if (screen) { screen->httpPort = hp; screen->httpInitDone = FALSE; if (screen->httpListenSock > -1) { close(screen->httpListenSock); } rfbLog("reset_httpport: setting httpport %d -> %d.\n", old == -1 ? hp : old, hp); rfbHttpInitSockets(screen); } } static void reset_rfbport(int old, int new) { int rp = new; if (rp < 0) { rfbLog("reset_rfbport: invalid rfbport: %d\n", rp); } else if (rp == old) { rfbLog("reset_rfbport: unchanged rfbport: %d\n", rp); } else if (inetd) { rfbLog("reset_rfbport: cannot set rfbport: %d" " in inetd.\n", rp); } else if (screen) { rfbClientIteratorPtr iter; rfbClientPtr cl; int maxfd; if (rp == 0) { screen->autoPort = TRUE; } else { screen->autoPort = FALSE; } screen->port = rp; screen->socketState = RFB_SOCKET_INIT; if (screen->listenSock > -1) { close(screen->listenSock); } rfbLog("reset_rfbport: setting rfbport %d -> %d.\n", old == -1 ? rp : old, rp); rfbInitSockets(screen); maxfd = screen->maxFd; if (screen->udpSock > 0 && screen->udpSock > maxfd) { maxfd = screen->udpSock; } iter = rfbGetClientIterator(screen); while( (cl = rfbClientIteratorNext(iter)) ) { if (cl->sock > -1) { FD_SET(cl->sock, &(screen->allFds)); if (cl->sock > maxfd) { maxfd = cl->sock; } } } rfbReleaseClientIterator(iter); screen->maxFd = maxfd; set_vnc_desktop_name(); } } /* * Do some sanity checking of the permissions on the XAUTHORITY and the * -connect file. This is -privremote. What should be done is check * for an empty host access list, currently we lazily do not bring in * libXau yet. */ int remote_control_access_ok(void) { struct stat sbuf; #if NO_X11 return 0; #else if (client_connect_file) { if (stat(client_connect_file, &sbuf) == 0) { if (sbuf.st_mode & S_IWOTH) { rfbLog("connect file is writable by others.\n"); rfbLog(" %s\n", client_connect_file); return 0; } if (sbuf.st_mode & S_IWGRP) { rfbLog("connect file is writable by group.\n"); rfbLog(" %s\n", client_connect_file); return 0; } } } if (dpy) { char tmp[1000]; char *home, *xauth; char *dpy_str = DisplayString(dpy); Display *dpy2; XHostAddress *xha; Bool enabled; int n; home = get_home_dir(); if (getenv("XAUTHORITY") != NULL) { xauth = getenv("XAUTHORITY"); } else if (home) { int len = 1000 - strlen("/.Xauthority") - 1; strncpy(tmp, home, len); strcat(tmp, "/.Xauthority"); xauth = tmp; } else { rfbLog("cannot determine default XAUTHORITY.\n"); return 0; } if (home) { free(home); } if (stat(xauth, &sbuf) == 0) { if (sbuf.st_mode & S_IWOTH) { rfbLog("XAUTHORITY is writable by others!!\n"); rfbLog(" %s\n", xauth); return 0; } if (sbuf.st_mode & S_IWGRP) { rfbLog("XAUTHORITY is writable by group!!\n"); rfbLog(" %s\n", xauth); return 0; } if (sbuf.st_mode & S_IROTH) { rfbLog("XAUTHORITY is readable by others.\n"); rfbLog(" %s\n", xauth); return 0; } if (sbuf.st_mode & S_IRGRP) { rfbLog("XAUTHORITY is readable by group.\n"); rfbLog(" %s\n", xauth); return 0; } } xha = XListHosts(dpy, &n, &enabled); if (! enabled) { rfbLog("X access control is disabled, X clients can\n"); rfbLog(" connect from any host. Run 'xhost -'\n"); return 0; } if (xha) { int i; rfbLog("The following hosts can connect w/o X11 " "auth:\n"); for (i=0; i= X11VNC_REMOTE_MAX - 1) { rfbLog("overflow in process_remote_cmd:" " %s -- %s\n", buf, res); free(res); break; } if (res) { strcat(buf, res); free(res); } if (k < n - 1) { strcat(buf, ","); } } for (k=0; kalwaysShared = TRUE; screen->neverShared = FALSE; } } else if (!strcmp(p, "noshared")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !shared); goto qry; } rfbLog("remote_cmd: disable sharing.\n"); shared = 0; if (screen) { screen->alwaysShared = FALSE; screen->neverShared = TRUE; } } else if (!strcmp(p, "forever")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, 1-connect_once); goto qry; } rfbLog("remote_cmd: enable -forever mode.\n"); connect_once = 0; } else if (!strcmp(p, "noforever") || !strcmp(p, "once")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, connect_once); goto qry; } rfbLog("remote_cmd: disable -forever mode.\n"); connect_once = 1; } else if (strstr(p, "timeout") == p) { int to; COLON_CHECK("timeout:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, first_conn_timeout); goto qry; } p += strlen("timeout:"); to = atoi(p); if (to > 0 ) { to = -to; } first_conn_timeout = to; rfbLog("remote_cmd: set -timeout to %d\n", -to); } else if (!strcmp(p, "filexfer")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, filexfer); goto qry; } #ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER if (! filexfer) { rfbLog("remote_cmd: enabling -filexfer for new clients.\n"); filexfer = 1; rfbRegisterTightVNCFileTransferExtension(); } #else rfbLog("remote_cmd: -filexfer not supported in this binary.\n"); #endif } else if (!strcmp(p, "nofilexfer")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !filexfer); goto qry; } #ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER if (filexfer) { rfbLog("remote_cmd: disabling -filexfer for new clients.\n"); filexfer = 0; rfbUnregisterTightVNCFileTransferExtension(); } #else rfbLog("remote_cmd: -filexfer not supported in this binary.\n"); #endif } else if (!strcmp(p, "deny") || !strcmp(p, "lock")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, deny_all); goto qry; } rfbLog("remote_cmd: denying new connections.\n"); deny_all = 1; } else if (!strcmp(p, "nodeny") || !strcmp(p, "unlock")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !deny_all); goto qry; } rfbLog("remote_cmd: allowing new connections.\n"); deny_all = 0; } else if (strstr(p, "connect") == p) { NOTAPP COLON_CHECK("connect:") p += strlen("connect:"); /* this is a reverse connection */ reverse_connect(p); } else if (strstr(p, "allowonce") == p) { COLON_CHECK("allowonce:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(allow_once)); goto qry; } p += strlen("allowonce:"); allow_once = strdup(p); rfbLog("remote_cmd: set allow_once %s\n", allow_once); } else if (strstr(p, "allow") == p) { char *before, *old; COLON_CHECK("allow:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(allow_list)); goto qry; } if (unixpw) { rfbLog("remote_cmd: cannot change allow in -unixpw\n"); goto done; } p += strlen("allow:"); if (allow_list && strchr(allow_list, '/')) { rfbLog("remote_cmd: cannot use allow:host\n"); rfbLog("in '-allow %s' mode.\n", allow_list); goto done; } if (allow_list) { before = strdup(allow_list); } else { before = strdup(""); } old = allow_list; if (*p == '+') { p++; allow_list = add_item(allow_list, p); } else if (*p == '-') { p++; allow_list = delete_item(allow_list, p); } else { allow_list = strdup(p); } if (strcmp(before, allow_list)) { rfbLog("remote_cmd: modified allow_list:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", allow_list); } if (old) free(old); free(before); } else if (!strcmp(p, "localhost")) { char *before, *old; if (query) { int state = 0; char *s = allow_list; if (s && (!strcmp(s, "127.0.0.1") || !strcmp(s, "localhost"))) { state = 1; } snprintf(buf, bufn, "ans=%s:%d", p, state); goto qry; } if (allow_list) { before = strdup(allow_list); } else { before = strdup(""); } old = allow_list; allow_list = strdup("127.0.0.1"); if (strcmp(before, allow_list)) { rfbLog("remote_cmd: modified allow_list:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", allow_list); } if (old) free(old); free(before); if (listen_str) { free(listen_str); } listen_str = strdup("localhost"); screen->listenInterface = htonl(INADDR_LOOPBACK); rfbLog("listening on loopback network only.\n"); rfbLog("allow list is: '%s'\n", NONUL(allow_list)); reset_rfbport(-1, screen->port); if (screen->httpListenSock > -1) { reset_httpport(-1, screen->httpPort); } } else if (!strcmp(p, "nolocalhost")) { char *before, *old; if (query) { int state = 0; char *s = allow_list; if (s && (!strcmp(s, "127.0.0.1") || !strcmp(s, "localhost"))) { state = 1; } snprintf(buf, bufn, "ans=%s:%d", p, !state); goto qry; } if (unixpw) { rfbLog("remote_cmd: cannot change localhost in -unixpw\n"); goto done; } if (allow_list) { before = strdup(allow_list); } else { before = strdup(""); } old = allow_list; allow_list = strdup(""); if (strcmp(before, allow_list)) { rfbLog("remote_cmd: modified allow_list:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", allow_list); } if (old) free(old); free(before); if (listen_str) { free(listen_str); } listen_str = NULL; screen->listenInterface = htonl(INADDR_ANY); rfbLog("listening on ALL network interfaces.\n"); rfbLog("allow list is: '%s'\n", NONUL(allow_list)); reset_rfbport(-1, screen->port); if (screen->httpListenSock > -1) { reset_httpport(-1, screen->httpPort); } } else if (strstr(p, "listen") == p) { char *before; int ok, mod = 0; COLON_CHECK("listen:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(listen_str)); goto qry; } if (unixpw) { rfbLog("remote_cmd: cannot change listen in -unixpw\n"); goto done; } if (listen_str) { before = strdup(listen_str); } else { before = strdup(""); } p += strlen("listen:"); listen_str = strdup(p); if (strcmp(before, listen_str)) { rfbLog("remote_cmd: modified listen_str:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", listen_str); mod = 1; } ok = 1; if (listen_str == NULL || *listen_str == '\0' || !strcmp(listen_str, "any")) { screen->listenInterface = htonl(INADDR_ANY); } else if (!strcmp(listen_str, "localhost")) { screen->listenInterface = htonl(INADDR_LOOPBACK); } else { struct hostent *hp; in_addr_t iface = inet_addr(listen_str); if (iface == htonl(INADDR_NONE)) { if (!host_lookup) { ok = 0; } else if (!(hp = gethostbyname(listen_str))) { ok = 0; } else { iface = *(unsigned long *)hp->h_addr; } } if (ok) { screen->listenInterface = iface; } } if (ok && mod) { int is_loopback = 0; in_addr_t iface = screen->listenInterface; if (allow_list) { if (!strcmp(allow_list, "127.0.0.1") || !strcmp(allow_list, "localhost")) { is_loopback = 1; } } if (iface != htonl(INADDR_LOOPBACK)) { if (is_loopback) { rfbLog("re-setting -allow list to all " "hosts for non-loopback listening.\n"); if (allow_list) { free(allow_list); } allow_list = NULL; } } else { if (!is_loopback) { if (allow_list) { free(allow_list); } rfbLog("setting -allow list to 127.0.0.1\n"); allow_list = strdup("127.0.0.1"); } } } if (ok) { rfbLog("allow list is: '%s'\n", NONUL(allow_list)); reset_rfbport(-1, screen->port); if (screen->httpListenSock > -1) { reset_httpport(-1, screen->httpPort); } free(before); } else { rfbLog("invalid listen string: %s\n", listen_str); free(listen_str); listen_str = before; } } else if (!strcmp(p, "lookup")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, host_lookup); goto qry; } rfbLog("remote_cmd: enabling hostname lookup.\n"); host_lookup = 1; } else if (!strcmp(p, "nolookup")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !host_lookup); goto qry; } rfbLog("remote_cmd: disabling hostname lookup.\n"); host_lookup = 0; } else if (strstr(p, "accept") == p) { int doit = 1, safe = 0; COLON_CHECK("accept:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(accept_cmd)); goto qry; } p += strlen("accept:"); if (!strcmp(p, "") || strstr(p, "popup") == p) { /* skip-cmd-list */ safe = 1; } if (safe_remote_only && ! safe) { rfbLog("unsafe: %s\n", p); doit = 0; } if (doit) { if (accept_cmd) free(accept_cmd); accept_cmd = strdup(p); } } else if (strstr(p, "afteraccept") == p) { int safe = 0; COLON_CHECK("afteraccept:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(afteraccept_cmd)); goto qry; } p += strlen("afteraccept:"); if (!strcmp(p, "")) { /* skip-cmd-list */ safe = 1; } if (safe_remote_only && ! safe) { rfbLog("unsafe: %s\n", p); } else { if (afteraccept_cmd) free(afteraccept_cmd); afteraccept_cmd = strdup(p); } } else if (strstr(p, "gone") == p) { int safe = 0; COLON_CHECK("gone:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(gone_cmd)); goto qry; } p += strlen("gone:"); if (!strcmp(p, "") || strstr(p, "popup") == p) { /* skip-cmd-list */ safe = 1; } if (safe_remote_only && ! safe) { rfbLog("unsafe: %s\n", p); } else { if (gone_cmd) free(gone_cmd); gone_cmd = strdup(p); } } else if (!strcmp(p, "shm")) { int orig = using_shm; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, using_shm); goto qry; } rfbLog("remote_cmd: turning off noshm mode.\n"); using_shm = 1; if (raw_fb) set_raw_fb_params(0); if (orig != using_shm) { do_new_fb(1); } else { rfbLog(" already in shm mode.\n"); } } else if (!strcmp(p, "noshm")) { int orig = using_shm; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !using_shm); goto qry; } rfbLog("remote_cmd: turning on noshm mode.\n"); using_shm = 0; if (orig != using_shm) { do_new_fb(1); } else { rfbLog(" already in noshm mode.\n"); } } else if (!strcmp(p, "flipbyteorder")) { int orig = flip_byte_order; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, flip_byte_order); goto qry; } rfbLog("remote_cmd: turning on flipbyteorder mode.\n"); flip_byte_order = 1; if (orig != flip_byte_order) { if (! using_shm || xform24to32) { do_new_fb(1); } else { rfbLog(" using shm, not resetting fb\n"); } } } else if (!strcmp(p, "noflipbyteorder")) { int orig = flip_byte_order; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !flip_byte_order); goto qry; } rfbLog("remote_cmd: turning off flipbyteorder mode.\n"); flip_byte_order = 0; if (orig != flip_byte_order) { if (! using_shm || xform24to32) { do_new_fb(1); } else { rfbLog(" using shm, not resetting fb\n"); } } } else if (!strcmp(p, "onetile")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, single_copytile); goto qry; } rfbLog("remote_cmd: enable -onetile mode.\n"); single_copytile = 1; } else if (!strcmp(p, "noonetile")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !single_copytile); goto qry; } rfbLog("remote_cmd: disable -onetile mode.\n"); if (tile_shm_count < ntiles_x) { rfbLog(" this has no effect: tile_shm_count=%d" " ntiles_x=%d\n", tile_shm_count, ntiles_x); } single_copytile = 0; } else if (strstr(p, "solid_color") == p) { /* * n.b. this solid stuff perhaps should reflect * safe_remote_only but at least the command names * are fixed. */ char *new; int doit = 1; COLON_CHECK("solid_color:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(solid_str)); goto qry; } p += strlen("solid_color:"); if (*p != '\0') { new = strdup(p); } else { new = strdup(solid_default); } rfbLog("remote_cmd: solid %s -> %s\n", NONUL(solid_str), new); if (solid_str) { if (!strcmp(solid_str, new)) { doit = 0; } free(solid_str); } solid_str = new; use_solid_bg = 1; if (raw_fb) set_raw_fb_params(0); if (doit && client_count) { solid_bg(0); } } else if (!strcmp(p, "solid")) { int orig = use_solid_bg; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, use_solid_bg); goto qry; } rfbLog("remote_cmd: enable -solid mode\n"); if (! solid_str) { solid_str = strdup(solid_default); } use_solid_bg = 1; if (raw_fb) set_raw_fb_params(0); if (client_count && !orig) { solid_bg(0); } } else if (!strcmp(p, "nosolid")) { int orig = use_solid_bg; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !use_solid_bg); goto qry; } rfbLog("remote_cmd: disable -solid mode\n"); use_solid_bg = 0; if (client_count && orig) { solid_bg(1); } } else if (strstr(p, "blackout") == p) { char *before, *old; COLON_CHECK("blackout:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(blackout_str)); goto qry; } p += strlen("blackout:"); if (blackout_str) { before = strdup(blackout_str); } else { before = strdup(""); } old = blackout_str; if (*p == '+') { p++; blackout_str = add_item(blackout_str, p); } else if (*p == '-') { p++; blackout_str = delete_item(blackout_str, p); } else { blackout_str = strdup(p); } if (strcmp(before, blackout_str)) { rfbLog("remote_cmd: changing -blackout\n"); rfbLog(" from: %s\n", before); rfbLog(" to: %s\n", blackout_str); if (0 && !strcmp(blackout_str, "") && single_copytile_orig != single_copytile) { rfbLog("resetting single_copytile to: %d\n", single_copytile_orig); single_copytile = single_copytile_orig; } initialize_blackouts_and_xinerama(); } if (old) free(old); free(before); } else if (!strcmp(p, "xinerama")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, xinerama); goto qry; } rfbLog("remote_cmd: enable xinerama mode. (if applicable).\n"); xinerama = 1; initialize_blackouts_and_xinerama(); } else if (!strcmp(p, "noxinerama")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !xinerama); goto qry; } rfbLog("remote_cmd: disable xinerama mode. (if applicable).\n"); xinerama = 0; initialize_blackouts_and_xinerama(); } else if (!strcmp(p, "xtrap")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, xtrap_input); goto qry; } rfbLog("remote_cmd: enable xtrap input mode." "(if applicable).\n"); if (! xtrap_input) { xtrap_input = 1; disable_grabserver(dpy, 1); } } else if (!strcmp(p, "noxtrap")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !xtrap_input); goto qry; } rfbLog("remote_cmd: disable xtrap input mode." "(if applicable).\n"); if (xtrap_input) { xtrap_input = 0; disable_grabserver(dpy, 1); } } else if (!strcmp(p, "xrandr")) { int orig = xrandr; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, xrandr); goto qry; } if (xrandr_present) { rfbLog("remote_cmd: enable xrandr mode.\n"); xrandr = 1; if (raw_fb) set_raw_fb_params(0); if (! xrandr_mode) { xrandr_mode = strdup("default"); } if (orig != xrandr) { initialize_xrandr(); } } else { rfbLog("remote_cmd: XRANDR ext. not present.\n"); } } else if (!strcmp(p, "noxrandr")) { int orig = xrandr; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !xrandr); goto qry; } xrandr = 0; if (xrandr_present) { rfbLog("remote_cmd: disable xrandr mode.\n"); if (orig != xrandr) { initialize_xrandr(); } } else { rfbLog("remote_cmd: XRANDR ext. not present.\n"); } } else if (strstr(p, "xrandr_mode") == p) { int orig = xrandr; COLON_CHECK("xrandr_mode:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(xrandr_mode)); goto qry; } p += strlen("xrandr_mode:"); if (!strcmp("none", p)) { xrandr = 0; } else { if (known_xrandr_mode(p)) { if (xrandr_mode) free(xrandr_mode); xrandr_mode = strdup(p); } else { rfbLog("skipping unknown xrandr mode: %s\n", p); goto done; } xrandr = 1; } if (xrandr_present) { if (xrandr) { rfbLog("remote_cmd: enable xrandr mode.\n"); } else { rfbLog("remote_cmd: disable xrandr mode.\n"); } if (! xrandr_mode) { xrandr_mode = strdup("default"); } if (orig != xrandr) { initialize_xrandr(); } } else { rfbLog("remote_cmd: XRANDR ext. not present.\n"); } } else if (strstr(p, "padgeom") == p) { COLON_CHECK("padgeom:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(pad_geometry)); goto qry; } p += strlen("padgeom:"); if (!strcmp("force", p) || !strcmp("do",p) || !strcmp("go",p)) { rfbLog("remote_cmd: invoking install_padded_fb()\n"); install_padded_fb(pad_geometry); } else { if (pad_geometry) free(pad_geometry); pad_geometry = strdup(p); rfbLog("remote_cmd: set padgeom to: %s\n", pad_geometry); } } else if (!strcmp(p, "quiet") || !strcmp(p, "q")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, quiet); goto qry; } rfbLog("remote_cmd: turning on quiet mode.\n"); quiet = 1; } else if (!strcmp(p, "noquiet")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !quiet); goto qry; } rfbLog("remote_cmd: turning off quiet mode.\n"); quiet = 0; } else if (!strcmp(p, "modtweak")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, use_modifier_tweak); goto qry; } rfbLog("remote_cmd: enabling -modtweak mode.\n"); if (! use_modifier_tweak) { use_modifier_tweak = 1; initialize_modtweak(); } use_modifier_tweak = 1; } else if (!strcmp(p, "nomodtweak")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !use_modifier_tweak); goto qry; } rfbLog("remote_cmd: enabling -nomodtweak mode.\n"); got_nomodtweak = 1; use_modifier_tweak = 0; } else if (!strcmp(p, "xkb")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, use_xkb_modtweak); goto qry; } if (! xkb_present) { rfbLog("remote_cmd: cannot enable -xkb " "modtweak mode (not supported on X display)\n"); goto done; } rfbLog("remote_cmd: enabling -xkb modtweak mode" " (if supported).\n"); if (! use_modifier_tweak || ! use_xkb_modtweak) { use_modifier_tweak = 1; use_xkb_modtweak = 1; initialize_modtweak(); } use_modifier_tweak = 1; use_xkb_modtweak = 1; } else if (!strcmp(p, "noxkb")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !use_xkb_modtweak); goto qry; } if (! xkb_present) { rfbLog("remote_cmd: cannot disable -xkb " "modtweak mode (not supported on X display)\n"); goto done; } rfbLog("remote_cmd: disabling -xkb modtweak mode.\n"); use_xkb_modtweak = 0; got_noxkb = 1; initialize_modtweak(); } else if (!strcmp(p, "capslock")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, watch_capslock); goto qry; } rfbLog("remote_cmd: enabling -capslock mode\n"); watch_capslock = 1; } else if (!strcmp(p, "nocapslock")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_capslock); goto qry; } rfbLog("remote_cmd: disabling -capslock mode\n"); watch_capslock = 0; } else if (!strcmp(p, "skip_lockkeys")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, skip_lockkeys); goto qry; } rfbLog("remote_cmd: enabling -skip_lockkeys mode\n"); skip_lockkeys = 1; } else if (!strcmp(p, "noskip_lockkeys")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !skip_lockkeys); goto qry; } rfbLog("remote_cmd: disabling -skip_lockkeys mode\n"); skip_lockkeys = 0; } else if (strstr(p, "skip_keycodes") == p) { COLON_CHECK("skip_keycodes:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(skip_keycodes)); goto qry; } p += strlen("skip_keycodes:"); rfbLog("remote_cmd: setting xkb -skip_keycodes" " to:\n\t'%s'\n", p); if (! xkb_present) { rfbLog("remote_cmd: warning xkb not present\n"); } else if (! use_xkb_modtweak) { rfbLog("remote_cmd: turning on xkb.\n"); use_xkb_modtweak = 1; if (! use_modifier_tweak) { rfbLog("remote_cmd: turning on modtweak.\n"); use_modifier_tweak = 1; } } if (skip_keycodes) free(skip_keycodes); skip_keycodes = strdup(p); initialize_modtweak(); } else if (!strcmp(p, "sloppy_keys")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, sloppy_keys); goto qry; } sloppy_keys += 1; rfbLog("remote_cmd: set sloppy_keys to: %d\n", sloppy_keys); } else if (!strcmp(p, "nosloppy_keys")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !sloppy_keys); goto qry; } sloppy_keys = 0; rfbLog("remote_cmd: set sloppy_keys to: %d\n", sloppy_keys); } else if (!strcmp(p, "skip_dups")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, skip_duplicate_key_events); goto qry; } rfbLog("remote_cmd: enabling -skip_dups mode\n"); skip_duplicate_key_events = 1; } else if (!strcmp(p, "noskip_dups")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !skip_duplicate_key_events); goto qry; } rfbLog("remote_cmd: disabling -skip_dups mode\n"); skip_duplicate_key_events = 0; } else if (!strcmp(p, "add_keysyms")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, add_keysyms); goto qry; } rfbLog("remote_cmd: enabling -add_keysyms mode.\n"); add_keysyms = 1; } else if (!strcmp(p, "noadd_keysyms")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !add_keysyms); goto qry; } rfbLog("remote_cmd: disabling -add_keysyms mode.\n"); add_keysyms = 0; } else if (!strcmp(p, "clear_mods")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 1); goto qry; } rfbLog("remote_cmd: enabling -clear_mods mode.\n"); clear_mods = 1; clear_modifiers(0); } else if (!strcmp(p, "noclear_mods")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !(clear_mods == 1)); goto qry; } rfbLog("remote_cmd: disabling -clear_mods mode.\n"); clear_mods = 0; } else if (!strcmp(p, "clear_keys")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 2); goto qry; } rfbLog("remote_cmd: enabling -clear_keys mode.\n"); clear_mods = 2; clear_keys(); } else if (!strcmp(p, "noclear_keys")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !(clear_mods == 2)); goto qry; } rfbLog("remote_cmd: disabling -clear_keys mode.\n"); clear_mods = 0; } else if (strstr(p, "remap") == p) { char *before, *old; COLON_CHECK("remap:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(remap_file)); goto qry; } p += strlen("remap:"); if ((*p == '+' || *p == '-') && remap_file && strchr(remap_file, '/')) { rfbLog("remote_cmd: cannot use remap:+/-\n"); rfbLog("in '-remap %s' mode.\n", remap_file); goto done; } if (remap_file) { before = strdup(remap_file); } else { before = strdup(""); } old = remap_file; if (*p == '+') { p++; remap_file = add_item(remap_file, p); } else if (*p == '-') { p++; remap_file = delete_item(remap_file, p); if (! strchr(remap_file, '-')) { *remap_file = '\0'; } } else { remap_file = strdup(p); } if (strcmp(before, remap_file)) { rfbLog("remote_cmd: changed -remap\n"); rfbLog(" from: %s\n", before); rfbLog(" to: %s\n", remap_file); initialize_remap(remap_file); } if (old) free(old); free(before); } else if (!strcmp(p, "repeat")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !no_autorepeat); goto qry; } rfbLog("remote_cmd: enabling -repeat mode.\n"); autorepeat(1, 0); /* restore initial setting */ no_autorepeat = 0; } else if (!strcmp(p, "norepeat")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, no_autorepeat); goto qry; } rfbLog("remote_cmd: enabling -norepeat mode.\n"); no_autorepeat = 1; if (no_repeat_countdown >= 0) { no_repeat_countdown = 2; } if (client_count && ! view_only) { autorepeat(0, 0); /* disable if any clients */ } } else if (!strcmp(p, "fb")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !nofb); goto qry; } if (nofb) { rfbLog("remote_cmd: disabling nofb mode.\n"); rfbLog(" you may need to these turn back on:\n"); rfbLog(" xfixes, xdamage, solid, flashcmap\n"); rfbLog(" overlay, shm, noonetile, nap, cursor\n"); rfbLog(" cursorpos, cursorshape, bell.\n"); nofb = 0; set_nofb_params(1); do_new_fb(1); } } else if (!strcmp(p, "nofb")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, nofb); goto qry; } if (!nofb) { rfbLog("remote_cmd: enabling nofb mode.\n"); if (main_fb) { push_black_screen(4); } nofb = 1; sound_bell = 0; initialize_watch_bell(); set_nofb_params(0); do_new_fb(1); } } else if (!strcmp(p, "bell")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, sound_bell); goto qry; } rfbLog("remote_cmd: enabling bell (if supported).\n"); initialize_watch_bell(); sound_bell = 1; } else if (!strcmp(p, "nobell")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !sound_bell); goto qry; } rfbLog("remote_cmd: disabling bell.\n"); initialize_watch_bell(); sound_bell = 0; } else if (!strcmp(p, "sel")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, watch_selection); goto qry; } rfbLog("remote_cmd: enabling watch selection+primary.\n"); watch_selection = 1; watch_primary = 1; watch_clipboard = 1; } else if (!strcmp(p, "nosel")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_selection); goto qry; } rfbLog("remote_cmd: disabling watch selection+primary.\n"); watch_selection = 0; watch_primary = 0; watch_clipboard = 0; } else if (!strcmp(p, "primary")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, watch_primary); goto qry; } rfbLog("remote_cmd: enabling watch_primary.\n"); watch_primary = 1; } else if (!strcmp(p, "noprimary")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_primary); goto qry; } rfbLog("remote_cmd: disabling watch_primary.\n"); watch_primary = 0; } else if (!strcmp(p, "setprimary")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, set_primary); goto qry; } rfbLog("remote_cmd: enabling set_primary.\n"); set_primary = 1; } else if (!strcmp(p, "nosetprimary")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !set_primary); goto qry; } rfbLog("remote_cmd: disabling set_primary.\n"); set_primary = 0; } else if (!strcmp(p, "clipboard")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, watch_clipboard); goto qry; } rfbLog("remote_cmd: enabling watch_clipboard.\n"); watch_clipboard = 1; } else if (!strcmp(p, "noclipboard")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_clipboard); goto qry; } rfbLog("remote_cmd: disabling watch_clipboard.\n"); watch_clipboard = 0; } else if (!strcmp(p, "setclipboard")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, set_clipboard); goto qry; } rfbLog("remote_cmd: enabling set_clipboard.\n"); set_clipboard = 1; } else if (!strcmp(p, "nosetclipboard")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !set_clipboard); goto qry; } rfbLog("remote_cmd: disabling set_clipboard.\n"); set_clipboard = 0; } else if (strstr(p, "seldir") == p) { COLON_CHECK("seldir:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(sel_direction)); goto qry; } p += strlen("seldir:"); rfbLog("remote_cmd: setting -seldir to %s\n", p); if (sel_direction) free(sel_direction); sel_direction = strdup(p); } else if (!strcmp(p, "set_no_cursor")) { /* skip-cmd-list */ rfbLog("remote_cmd: calling set_no_cursor()\n"); set_no_cursor(); } else if (!strcmp(p, "cursorshape")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, cursor_shape_updates); goto qry; } rfbLog("remote_cmd: turning on cursorshape mode.\n"); set_no_cursor(); cursor_shape_updates = 1; restore_cursor_shape_updates(screen); first_cursor(); } else if (!strcmp(p, "nocursorshape")) { int i, max = 5; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !cursor_shape_updates); goto qry; } rfbLog("remote_cmd: turning off cursorshape mode.\n"); set_no_cursor(); for (i=0; i= 0) { rfbLog("remote_cmd: setting xdamage_max_area " "%d -> %d.\n", xdamage_max_area, a); xdamage_max_area = a; } } else if (strstr(p, "xd_mem") == p) { double a; COLON_CHECK("xd_mem:") if (query) { snprintf(buf, bufn, "ans=%s%s%.3f", p, co, xdamage_memory); goto qry; } p += strlen("xd_mem:"); a = atof(p); if (a >= 0.0) { rfbLog("remote_cmd: setting xdamage_memory " "%.3f -> %.3f.\n", xdamage_memory, a); xdamage_memory = a; } } else if (strstr(p, "alphacut") == p) { int a; COLON_CHECK("alphacut:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, alpha_threshold); goto qry; } p += strlen("alphacut:"); a = atoi(p); if (a < 0) a = 0; if (a > 256) a = 256; /* allow 256 for testing. */ if (alpha_threshold != a) { rfbLog("remote_cmd: setting alphacut " "%d -> %d.\n", alpha_threshold, a); if (a == 256) { rfbLog("note: alphacut=256 leads to completely" " transparent cursors.\n"); } alpha_threshold = a; setup_cursors_and_push(); } } else if (strstr(p, "alphafrac") == p) { double a; COLON_CHECK("alphafrac:") if (query) { snprintf(buf, bufn, "ans=%s%s%f", p, co, alpha_frac); goto qry; } p += strlen("alphafrac:"); a = atof(p); if (a < 0.0) a = 0.0; if (a > 1.0) a = 1.0; if (alpha_frac != a) { rfbLog("remote_cmd: setting alphafrac " "%f -> %f.\n", alpha_frac, a); alpha_frac = a; setup_cursors_and_push(); } } else if (strstr(p, "alpharemove") == p) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, alpha_remove); goto qry; } if (!alpha_remove) { rfbLog("remote_cmd: enable alpharemove\n"); alpha_remove = 1; setup_cursors_and_push(); } } else if (strstr(p, "noalpharemove") == p) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !alpha_remove); goto qry; } if (alpha_remove) { rfbLog("remote_cmd: disable alpharemove\n"); alpha_remove = 0; setup_cursors_and_push(); } } else if (strstr(p, "alphablend") == p) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, alpha_blend); goto qry; } if (!alpha_blend) { rfbLog("remote_cmd: enable alphablend\n"); alpha_remove = 0; alpha_blend = 1; setup_cursors_and_push(); } } else if (strstr(p, "noalphablend") == p) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !alpha_blend); goto qry; } if (alpha_blend) { rfbLog("remote_cmd: disable alphablend\n"); alpha_blend = 0; setup_cursors_and_push(); } } else if (strstr(p, "xwarppointer") == p || strstr(p, "xwarp") == p) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, use_xwarppointer); goto qry; } rfbLog("remote_cmd: turning on xwarppointer mode.\n"); use_xwarppointer = 1; } else if (strstr(p, "noxwarppointer") == p || strstr(p, "noxwarp") == p) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !use_xwarppointer); goto qry; } rfbLog("remote_cmd: turning off xwarppointer mode.\n"); use_xwarppointer = 0; } else if (strstr(p, "buttonmap") == p) { COLON_CHECK("buttonmap:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(pointer_remap)); goto qry; } p += strlen("buttonmap:"); if (pointer_remap) free(pointer_remap); pointer_remap = strdup(p); rfbLog("remote_cmd: setting -buttonmap to:\n\t'%s'\n", p); initialize_pointer_map(p); } else if (!strcmp(p, "dragging")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, show_dragging); goto qry; } rfbLog("remote_cmd: enabling mouse dragging mode.\n"); show_dragging = 1; } else if (!strcmp(p, "nodragging")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !show_dragging); goto qry; } rfbLog("remote_cmd: enabling mouse nodragging mode.\n"); show_dragging = 0; } else if (strstr(p, "wireframe_mode") == p) { COLON_CHECK("wireframe_mode:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, wireframe_str ? wireframe_str : WIREFRAME_PARMS); goto qry; } p += strlen("wireframe_mode:"); if (*p) { if (wireframe_str) { free(wireframe_str); } wireframe_str = strdup(p); parse_wireframe(); } rfbLog("remote_cmd: enabling -wireframe mode.\n"); wireframe = 1; } else if (strstr(p, "wireframe:") == p) { /* skip-cmd-list */ COLON_CHECK("wireframe:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, wireframe); goto qry; } p += strlen("wireframe:"); if (*p) { if (wireframe_str) { free(wireframe_str); } wireframe_str = strdup(p); parse_wireframe(); } rfbLog("remote_cmd: enabling -wireframe mode.\n"); wireframe = 1; } else if (strstr(p, "wf:") == p) { /* skip-cmd-list */ COLON_CHECK("wf:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, wireframe); goto qry; } p += strlen("wf:"); if (*p) { if (wireframe_str) { free(wireframe_str); } wireframe_str = strdup(p); parse_wireframe(); } rfbLog("remote_cmd: enabling -wireframe mode.\n"); wireframe = 1; } else if (!strcmp(p, "wireframe") || !strcmp(p, "wf")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, wireframe); goto qry; } rfbLog("remote_cmd: enabling -wireframe mode.\n"); wireframe = 1; } else if (!strcmp(p, "nowireframe") || !strcmp(p, "nowf")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !wireframe); goto qry; } rfbLog("remote_cmd: enabling -nowireframe mode.\n"); wireframe = 0; } else if (strstr(p, "wirecopyrect") == p) { COLON_CHECK("wirecopyrect:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(wireframe_copyrect)); goto qry; } p += strlen("wirecopyrect:"); set_wirecopyrect_mode(p); rfbLog("remote_cmd: changed -wirecopyrect mode " "to: %s\n", NONUL(wireframe_copyrect)); got_wirecopyrect = 1; } else if (strstr(p, "wcr") == p) { COLON_CHECK("wcr:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(wireframe_copyrect)); goto qry; } p += strlen("wcr:"); set_wirecopyrect_mode(p); rfbLog("remote_cmd: changed -wirecopyrect mode " "to: %s\n", NONUL(wireframe_copyrect)); got_wirecopyrect = 1; } else if (!strcmp(p, "nowirecopyrect") || !strcmp(p, "nowcr")) { if (query) { snprintf(buf, bufn, "ans=%s:%s", p, NONUL(wireframe_copyrect)); goto qry; } set_wirecopyrect_mode("never"); rfbLog("remote_cmd: changed -wirecopyrect mode " "to: %s\n", NONUL(wireframe_copyrect)); } else if (strstr(p, "scr_area") == p) { COLON_CHECK("scr_area:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, scrollcopyrect_min_area); goto qry; } p += strlen("scr_area:"); scrollcopyrect_min_area = atoi(p); rfbLog("remote_cmd: changed -scr_area to: %d\n", scrollcopyrect_min_area); } else if (strstr(p, "scr_skip") == p) { char *s = scroll_skip_str; COLON_CHECK("scr_skip:") if (!s || *s == '\0') s = scroll_skip_str0; if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s)); goto qry; } p += strlen("scr_skip:"); if (scroll_skip_str) { free(scroll_skip_str); } scroll_skip_str = strdup(p); rfbLog("remote_cmd: changed -scr_skip to: %s\n", scroll_skip_str); initialize_scroll_matches(); } else if (strstr(p, "scr_inc") == p) { char *s = scroll_good_str; if (!s || *s == '\0') s = scroll_good_str0; COLON_CHECK("scr_inc:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s)); goto qry; } p += strlen("scr_inc:"); if (scroll_good_str) { free(scroll_good_str); } scroll_good_str = strdup(p); rfbLog("remote_cmd: changed -scr_inc to: %s\n", scroll_good_str); initialize_scroll_matches(); } else if (strstr(p, "scr_keys") == p) { COLON_CHECK("scr_keys:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(scroll_key_list_str)); goto qry; } p += strlen("scr_keys:"); if (scroll_key_list_str) { free(scroll_key_list_str); } scroll_key_list_str = strdup(p); rfbLog("remote_cmd: changed -scr_keys to: %s\n", scroll_key_list_str); initialize_scroll_keys(); } else if (strstr(p, "scr_term") == p) { char *s = scroll_term_str; if (!s || *s == '\0') s = scroll_term_str0; COLON_CHECK("scr_term:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s)); goto qry; } p += strlen("scr_term:"); if (scroll_term_str) { free(scroll_term_str); } scroll_term_str = strdup(p); rfbLog("remote_cmd: changed -scr_term to: %s\n", scroll_term_str); initialize_scroll_term(); } else if (strstr(p, "scr_keyrepeat") == p) { char *s = max_keyrepeat_str; if (!s || *s == '\0') s = max_keyrepeat_str0; COLON_CHECK("scr_keyrepeat:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s)); goto qry; } p += strlen("scr_keyrepeat:"); if (max_keyrepeat_str) { free(max_keyrepeat_str); } max_keyrepeat_str = strdup(p); rfbLog("remote_cmd: changed -scr_keyrepeat to: %s\n", max_keyrepeat_str); initialize_max_keyrepeat(); } else if (strstr(p, "scr_parms") == p) { COLON_CHECK("scr_parms:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, scroll_copyrect_str ? scroll_copyrect_str : SCROLL_COPYRECT_PARMS); goto qry; } p += strlen("scr_parms:"); if (*p) { if (scroll_copyrect_str) { free(scroll_copyrect_str); } set_scrollcopyrect_mode("always"); scroll_copyrect_str = strdup(p); parse_scroll_copyrect(); } rfbLog("remote_cmd: set -scr_parms %s.\n", NONUL(scroll_copyrect_str)); got_scrollcopyrect = 1; } else if (strstr(p, "scrollcopyrect") == p) { COLON_CHECK("scrollcopyrect:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(scroll_copyrect)); goto qry; } p += strlen("scrollcopyrect:"); set_scrollcopyrect_mode(p); rfbLog("remote_cmd: changed -scrollcopyrect mode " "to: %s\n", NONUL(scroll_copyrect)); got_scrollcopyrect = 1; } else if (!strcmp(p, "scr") || strstr(p, "scr:") == p) { /* skip-cmd-list */ COLON_CHECK("scr:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(scroll_copyrect)); goto qry; } p += strlen("scr:"); set_scrollcopyrect_mode(p); rfbLog("remote_cmd: changed -scrollcopyrect mode " "to: %s\n", NONUL(scroll_copyrect)); got_scrollcopyrect = 1; } else if (!strcmp(p, "noscrollcopyrect") || !strcmp(p, "noscr")) { if (query) { snprintf(buf, bufn, "ans=%s:%s", p, NONUL(scroll_copyrect)); goto qry; } set_scrollcopyrect_mode("never"); rfbLog("remote_cmd: changed -scrollcopyrect mode " "to: %s\n", NONUL(scroll_copyrect)); } else if (strstr(p, "fixscreen") == p) { COLON_CHECK("fixscreen:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(screen_fixup_str)); goto qry; } p += strlen("fixscreen:"); if (screen_fixup_str) { free(screen_fixup_str); } screen_fixup_str = strdup(p); parse_fixscreen(); rfbLog("remote_cmd: set -fixscreen %s.\n", NONUL(screen_fixup_str)); } else if (!strcmp(p, "noxrecord")) { int orig = noxrecord; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, noxrecord); goto qry; } noxrecord = 1; rfbLog("set noxrecord to: %d\n", noxrecord); if (orig != noxrecord) { shutdown_xrecord(); } } else if (!strcmp(p, "xrecord")) { int orig = noxrecord; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !noxrecord); goto qry; } noxrecord = 0; rfbLog("set noxrecord to: %d\n", noxrecord); if (orig != noxrecord) { initialize_xrecord(); } } else if (!strcmp(p, "reset_record")) { NOTAPP if (use_xrecord) { rfbLog("resetting RECORD\n"); check_xrecord_reset(1); } else { rfbLog("RECORD is disabled, not resetting.\n"); } } else if (strstr(p, "pointer_mode") == p) { int pm; COLON_CHECK("pointer_mode:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode); goto qry; } p += strlen("pointer_mode:"); pm = atoi(p); if (pm < 0 || pm > pointer_mode_max) { rfbLog("remote_cmd: pointer_mode out of range:" " 1-%d: %d\n", pointer_mode_max, pm); } else { rfbLog("remote_cmd: setting pointer_mode %d\n", pm); pointer_mode = pm; } } else if (strstr(p, "pm") == p) { int pm; COLON_CHECK("pm:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode); goto qry; } p += strlen("pm:"); pm = atoi(p); if (pm < 0 || pm > pointer_mode_max) { rfbLog("remote_cmd: pointer_mode out of range:" " 1-%d: %d\n", pointer_mode_max, pm); } else { rfbLog("remote_cmd: setting pointer_mode %d\n", pm); pointer_mode = pm; } } else if (strstr(p, "input_skip") == p) { int is; COLON_CHECK("input_skip:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, ui_skip); goto qry; } p += strlen("input_skip:"); is = atoi(p); rfbLog("remote_cmd: setting input_skip %d\n", is); ui_skip = is; } else if (!strcmp(p, "allinput")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, all_input); goto qry; } all_input = 1; rfbLog("enabled allinput\n"); } else if (!strcmp(p, "noallinput")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !all_input); goto qry; } all_input = 0; rfbLog("disabled allinput\n"); } else if (strstr(p, "input") == p) { int doit = 1; COLON_CHECK("input:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(allowed_input_str)); goto qry; } p += strlen("input:"); if (allowed_input_str && !strcmp(p, allowed_input_str)) { doit = 0; } rfbLog("remote_cmd: setting input %s\n", p); if (allowed_input_str) free(allowed_input_str); if (*p == '\0') { allowed_input_str = NULL; } else { allowed_input_str = strdup(p); } if (doit) { initialize_allowed_input(); } } else if (!strcmp(p, "grabkbd")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, grab_kbd); goto qry; } grab_kbd = 1; rfbLog("enabled grab_kbd\n"); } else if (!strcmp(p, "nograbkbd")) { int orig = grab_kbd; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !grab_kbd); goto qry; } grab_kbd = 0; if (orig && dpy) { #if !NO_X11 X_LOCK; XUngrabKeyboard(dpy, CurrentTime); X_UNLOCK; #endif } rfbLog("disabled grab_kbd\n"); } else if (!strcmp(p, "grabptr")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, grab_ptr); goto qry; } grab_ptr = 1; rfbLog("enabled grab_ptr\n"); } else if (!strcmp(p, "nograbptr")) { int orig = grab_ptr; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !grab_ptr); goto qry; } grab_ptr = 0; if (orig && dpy) { #if !NO_X11 X_LOCK; XUngrabPointer(dpy, CurrentTime); X_UNLOCK; #endif } rfbLog("disabled grab_ptr\n"); } else if (strstr(p, "client_input") == p) { NOTAPP COLON_CHECK("client_input:") p += strlen("client_input:"); set_client_input(p); } else if (strstr(p, "speeds") == p) { COLON_CHECK("speeds:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(speeds_str)); goto qry; } p += strlen("speeds:"); if (speeds_str) free(speeds_str); speeds_str = strdup(p); rfbLog("remote_cmd: setting -speeds to:\n\t'%s'\n", p); initialize_speeds(); } else if (strstr(p, "wmdt") == p) { COLON_CHECK("wmdt:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(wmdt_str)); goto qry; } p += strlen("wmdt:"); if (wmdt_str) free(wmdt_str); wmdt_str = strdup(p); rfbLog("remote_cmd: setting -wmdt to: %s\n", p); } else if (!strcmp(p, "debug_pointer") || !strcmp(p, "dp")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_pointer); goto qry; } rfbLog("remote_cmd: turning on debug_pointer.\n"); debug_pointer = 1; } else if (!strcmp(p, "nodebug_pointer") || !strcmp(p, "nodp")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_pointer); goto qry; } rfbLog("remote_cmd: turning off debug_pointer.\n"); debug_pointer = 0; } else if (!strcmp(p, "debug_keyboard") || !strcmp(p, "dk")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_keyboard); goto qry; } rfbLog("remote_cmd: turning on debug_keyboard.\n"); debug_keyboard = 1; } else if (!strcmp(p, "nodebug_keyboard") || !strcmp(p, "nodk")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_keyboard); goto qry; } rfbLog("remote_cmd: turning off debug_keyboard.\n"); debug_keyboard = 0; } else if (strstr(p, "deferupdate") == p) { int d; COLON_CHECK("deferupdate:") if (query) { if (!screen) { d = defer_update; } else { d = screen->deferUpdateTime; } snprintf(buf, bufn, "ans=%s%s%d", p, co, d); goto qry; } p += strlen("deferupdate:"); d = atoi(p); if (d < 0) d = 0; rfbLog("remote_cmd: setting defer to %d ms.\n", d); screen->deferUpdateTime = d; got_defer = 1; } else if (strstr(p, "defer") == p) { int d; COLON_CHECK("defer:") if (query) { if (!screen) { d = defer_update; } else { d = screen->deferUpdateTime; } snprintf(buf, bufn, "ans=%s%s%d", p, co, d); goto qry; } p += strlen("defer:"); d = atoi(p); if (d < 0) d = 0; rfbLog("remote_cmd: setting defer to %d ms.\n", d); screen->deferUpdateTime = d; got_defer = 1; } else if (strstr(p, "wait_ui") == p) { double w; COLON_CHECK("wait_ui:") if (query) { snprintf(buf, bufn, "ans=%s%s%.2f", p, co, wait_ui); goto qry; } p += strlen("wait_ui:"); w = atof(p); if (w <= 0) w = 1.0; rfbLog("remote_cmd: setting wait_ui factor %.2f -> %.2f\n", wait_ui, w); wait_ui = w; } else if (!strcmp(p, "wait_bog")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, wait_bog); goto qry; } wait_bog = 1; rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog); } else if (!strcmp(p, "nowait_bog")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !wait_bog); goto qry; } wait_bog = 0; rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog); } else if (strstr(p, "slow_fb") == p) { double w; COLON_CHECK("slow_fb:") if (query) { snprintf(buf, bufn, "ans=%s%s%.2f", p, co, slow_fb); goto qry; } p += strlen("slow_fb:"); w = atof(p); if (w <= 0) w = 0.0; rfbLog("remote_cmd: setting slow_fb factor %.2f -> %.2f\n", slow_fb, w); slow_fb = w; } else if (strstr(p, "wait") == p) { int w; COLON_CHECK("wait:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, waitms); goto qry; } p += strlen("wait:"); w = atoi(p); if (w < 0) w = 0; rfbLog("remote_cmd: setting wait %d -> %d ms.\n", waitms, w); waitms = w; } else if (strstr(p, "readtimeout") == p) { int w, orig = rfbMaxClientWait; COLON_CHECK("readtimeout:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, rfbMaxClientWait/1000); goto qry; } p += strlen("readtimeout:"); w = atoi(p) * 1000; if (w <= 0) w = 0; rfbLog("remote_cmd: setting rfbMaxClientWait %d -> " "%d msec.\n", orig, w); rfbMaxClientWait = w; } else if (!strcmp(p, "nap")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, take_naps); goto qry; } rfbLog("remote_cmd: turning on nap mode.\n"); take_naps = 1; } else if (!strcmp(p, "nonap")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !take_naps); goto qry; } rfbLog("remote_cmd: turning off nap mode.\n"); take_naps = 0; } else if (strstr(p, "sb") == p) { int w; COLON_CHECK("sb:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank); goto qry; } p += strlen("sb:"); w = atoi(p); if (w < 0) w = 0; rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n", screen_blank, w); screen_blank = w; } else if (strstr(p, "screen_blank") == p) { int w; COLON_CHECK("screen_blank:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank); goto qry; } p += strlen("screen_blank:"); w = atoi(p); if (w < 0) w = 0; rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n", screen_blank, w); screen_blank = w; } else if (!strcmp(p, "fbpm")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_fbpm); goto qry; } rfbLog("remote_cmd: turning off -nofbpm mode.\n"); watch_fbpm = 0; } else if (!strcmp(p, "nofbpm")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, watch_fbpm); goto qry; } rfbLog("remote_cmd: turning on -nofbpm mode.\n"); watch_fbpm = 1; } else if (strstr(p, "fs") == p) { COLON_CHECK("fs:") if (query) { snprintf(buf, bufn, "ans=%s%s%f", p, co, fs_frac); goto qry; } p += strlen("fs:"); fs_frac = atof(p); rfbLog("remote_cmd: setting -fs frac to %f\n", fs_frac); } else if (strstr(p, "gaps") == p) { int g; COLON_CHECK("gaps:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, gaps_fill); goto qry; } p += strlen("gaps:"); g = atoi(p); if (g < 0) g = 0; rfbLog("remote_cmd: setting gaps_fill %d -> %d.\n", gaps_fill, g); gaps_fill = g; } else if (strstr(p, "grow") == p) { int g; COLON_CHECK("grow:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, grow_fill); goto qry; } p += strlen("grow:"); g = atoi(p); if (g < 0) g = 0; rfbLog("remote_cmd: setting grow_fill %d -> %d.\n", grow_fill, g); grow_fill = g; } else if (strstr(p, "fuzz") == p) { int f; COLON_CHECK("fuzz:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, tile_fuzz); goto qry; } p += strlen("fuzz:"); f = atoi(p); if (f < 0) f = 0; rfbLog("remote_cmd: setting tile_fuzz %d -> %d.\n", tile_fuzz, f); grow_fill = f; } else if (!strcmp(p, "snapfb")) { int orig = use_snapfb; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, use_snapfb); goto qry; } rfbLog("remote_cmd: turning on snapfb mode.\n"); use_snapfb = 1; if (orig != use_snapfb) { do_new_fb(1); } } else if (!strcmp(p, "nosnapfb")) { int orig = use_snapfb; if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !use_snapfb); goto qry; } rfbLog("remote_cmd: turning off snapfb mode.\n"); use_snapfb = 0; if (orig != use_snapfb) { do_new_fb(1); } } else if (strstr(p, "rawfb") == p) { COLON_CHECK("rawfb:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(raw_fb_str)); goto qry; } p += strlen("rawfb:"); if (raw_fb_str) free(raw_fb_str); raw_fb_str = strdup(p); if (safe_remote_only && strstr(p, "setup:") == p) { /* skip-cmd-list */ /* n.b. we still allow filename, shm, of rawfb */ fprintf(stderr, "unsafe rawfb setup: %s\n", p); exit(1); } rfbLog("remote_cmd: setting -rawfb to:\n\t'%s'\n", p); if (*raw_fb_str == '\0') { free(raw_fb_str); raw_fb_str = NULL; if (raw_fb_mmap) { munmap(raw_fb_addr, raw_fb_mmap); } if (raw_fb_fd >= 0) { close(raw_fb_fd); } raw_fb_fd = -1; raw_fb = NULL; raw_fb_addr = NULL; raw_fb_offset = 0; raw_fb_shm = 0; raw_fb_mmap = 0; raw_fb_seek = 0; rfbLog("restoring per-rawfb settings...\n"); set_raw_fb_params(1); } rfbLog("hang on tight, here we go...\n"); raw_fb_back_to_X = 1; do_new_fb(1); raw_fb_back_to_X = 0; } else if (strstr(p, "uinput_accel") == p) { COLON_CHECK("uinput_accel:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(get_uinput_accel())); goto qry; } p += strlen("uinput_accel:"); rfbLog("set_uinput_accel: %s\n", p); set_uinput_accel(p); } else if (strstr(p, "uinput_thresh") == p) { COLON_CHECK("uinput_thresh:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(get_uinput_thresh())); goto qry; } p += strlen("uinput_thresh:"); rfbLog("set_uinput_thresh: %s\n", p); set_uinput_thresh(p); } else if (strstr(p, "uinput_reset") == p) { COLON_CHECK("uinput_reset:") p += strlen("uinput_reset:"); if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, get_uinput_reset()); goto qry; } rfbLog("set_uinput_reset: %s\n", p); set_uinput_reset(atoi(p)); } else if (strstr(p, "uinput_always") == p) { COLON_CHECK("uinput_always:") p += strlen("uinput_always:"); if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, get_uinput_always()); goto qry; } rfbLog("set_uinput_always: %s\n", p); set_uinput_always(atoi(p)); } else if (strstr(p, "progressive") == p) { int f; COLON_CHECK("progressive:") if (query) { if (!screen) { f = 0; } else { f = screen->progressiveSliceHeight; } snprintf(buf, bufn, "ans=%s%s%d", p, co, f); goto qry; } p += strlen("progressive:"); f = atoi(p); if (f < 0) f = 0; rfbLog("remote_cmd: setting progressive %d -> %d.\n", screen->progressiveSliceHeight, f); screen->progressiveSliceHeight = f; } else if (strstr(p, "rfbport") == p) { int rp, orig = screen ? screen->port : 5900; COLON_CHECK("rfbport:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, orig); goto qry; } p += strlen("rfbport:"); rp = atoi(p); reset_rfbport(orig, rp); } else if (!strcmp(p, "http")) { if (query) { int ls = screen ? screen->httpListenSock : -1; snprintf(buf, bufn, "ans=%s:%d", p, (ls > -1)); goto qry; } if (screen->httpListenSock > -1) { rfbLog("already listening for http connections.\n"); } else { rfbLog("turning on listening for http connections.\n"); if (check_httpdir()) { http_connections(1); } } } else if (!strcmp(p, "nohttp")) { if (query) { int ls = screen ? screen->httpListenSock : -1; snprintf(buf, bufn, "ans=%s:%d", p, !(ls > -1)); goto qry; } if (screen->httpListenSock < 0) { rfbLog("already not listening for http connections.\n"); } else { rfbLog("turning off listening for http connections.\n"); if (check_httpdir()) { http_connections(0); } } } else if (strstr(p, "httpport") == p) { int hp, orig = screen ? screen->httpPort : 0; COLON_CHECK("httpport:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, orig); goto qry; } p += strlen("httpport:"); hp = atoi(p); reset_httpport(orig, hp); } else if (strstr(p, "httpdir") == p) { COLON_CHECK("httpdir:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(http_dir)); goto qry; } p += strlen("httpdir:"); if (http_dir && !strcmp(http_dir, p)) { rfbLog("no change in httpdir: %s\n", http_dir); } else { if (http_dir) { free(http_dir); } http_dir = strdup(p); http_connections(0); if (*p != '\0') { http_connections(1); } } } else if (!strcmp(p, "enablehttpproxy")) { if (query) { int ht = screen ? screen->httpEnableProxyConnect : 0; snprintf(buf, bufn, "ans=%s:%d", p, ht != 0); goto qry; } rfbLog("turning on enablehttpproxy.\n"); screen->httpEnableProxyConnect = 1; } else if (!strcmp(p, "noenablehttpproxy")) { if (query) { int ht = screen ? screen->httpEnableProxyConnect : 0; snprintf(buf, bufn, "ans=%s:%d", p, ht == 0); goto qry; } rfbLog("turning off enablehttpproxy.\n"); screen->httpEnableProxyConnect = 0; } else if (!strcmp(p, "alwaysshared")) { if (query) { int t = screen ? screen->alwaysShared : 0; snprintf(buf, bufn, "ans=%s:%d", p, t != 0); goto qry; } rfbLog("turning on alwaysshared.\n"); screen->alwaysShared = 1; } else if (!strcmp(p, "noalwaysshared")) { if (query) { int t = screen ? screen->alwaysShared : 0; snprintf(buf, bufn, "ans=%s:%d", p, t == 0); goto qry; } rfbLog("turning off alwaysshared.\n"); screen->alwaysShared = 0; } else if (!strcmp(p, "nevershared")) { if (query) { int t = screen ? screen->neverShared : 1; snprintf(buf, bufn, "ans=%s:%d", p, t != 0); goto qry; } rfbLog("turning on nevershared.\n"); screen->neverShared = 1; } else if (!strcmp(p, "noalwaysshared")) { if (query) { int t = screen ? screen->neverShared : 1; snprintf(buf, bufn, "ans=%s:%d", p, t == 0); goto qry; } rfbLog("turning off nevershared.\n"); screen->neverShared = 0; } else if (!strcmp(p, "dontdisconnect")) { if (query) { int t = screen ? screen->dontDisconnect : 1; snprintf(buf, bufn, "ans=%s:%d", p, t != 0); goto qry; } rfbLog("turning on dontdisconnect.\n"); screen->dontDisconnect = 1; } else if (!strcmp(p, "nodontdisconnect")) { if (query) { int t = screen ? screen->dontDisconnect : 1; snprintf(buf, bufn, "ans=%s:%d", p, t == 0); goto qry; } rfbLog("turning off dontdisconnect.\n"); screen->dontDisconnect = 0; } else if (!strcmp(p, "desktop") || strstr(p, "desktop:") == p) { /* skip-cmd-list */ COLON_CHECK("desktop:") if (query) { snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(rfb_desktop_name)); goto qry; } p += strlen("desktop:"); if (rfb_desktop_name) { free(rfb_desktop_name); } rfb_desktop_name = strdup(p); screen->desktopName = rfb_desktop_name; rfbLog("remote_cmd: setting desktop name to %s\n", rfb_desktop_name); } else if (!strcmp(p, "debug_xevents")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_xevents); goto qry; } debug_xevents = 1; rfbLog("set debug_xevents to: %d\n", debug_xevents); } else if (!strcmp(p, "nodebug_xevents")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_xevents); goto qry; } debug_xevents = 0; rfbLog("set debug_xevents to: %d\n", debug_xevents); } else if (strstr(p, "debug_xevents") == p) { COLON_CHECK("debug_xevents:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xevents); goto qry; } p += strlen("debug_xevents:"); debug_xevents = atoi(p); rfbLog("set debug_xevents to: %d\n", debug_xevents); } else if (!strcmp(p, "debug_xdamage")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_xdamage); goto qry; } debug_xdamage = 1; rfbLog("set debug_xdamage to: %d\n", debug_xdamage); } else if (!strcmp(p, "nodebug_xdamage")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_xdamage); goto qry; } debug_xdamage = 0; rfbLog("set debug_xdamage to: %d\n", debug_xdamage); } else if (strstr(p, "debug_xdamage") == p) { COLON_CHECK("debug_xdamage:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xdamage); goto qry; } p += strlen("debug_xdamage:"); debug_xdamage = atoi(p); rfbLog("set debug_xdamage to: %d\n", debug_xdamage); } else if (!strcmp(p, "debug_wireframe")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_wireframe); goto qry; } debug_wireframe = 1; rfbLog("set debug_wireframe to: %d\n", debug_wireframe); } else if (!strcmp(p, "nodebug_wireframe")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_wireframe); goto qry; } debug_wireframe = 0; rfbLog("set debug_wireframe to: %d\n", debug_wireframe); } else if (strstr(p, "debug_wireframe") == p) { COLON_CHECK("debug_wireframe:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_wireframe); goto qry; } p += strlen("debug_wireframe:"); debug_wireframe = atoi(p); rfbLog("set debug_wireframe to: %d\n", debug_wireframe); } else if (!strcmp(p, "debug_scroll")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_scroll); goto qry; } debug_scroll = 1; rfbLog("set debug_scroll to: %d\n", debug_scroll); } else if (!strcmp(p, "nodebug_scroll")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_scroll); goto qry; } debug_scroll = 0; rfbLog("set debug_scroll to: %d\n", debug_scroll); } else if (strstr(p, "debug_scroll") == p) { COLON_CHECK("debug_scroll:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_scroll); goto qry; } p += strlen("debug_scroll:"); debug_scroll = atoi(p); rfbLog("set debug_scroll to: %d\n", debug_scroll); } else if (!strcmp(p, "debug_tiles") || !strcmp(p, "dbt")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_tiles); goto qry; } debug_tiles = 1; rfbLog("set debug_tiles to: %d\n", debug_tiles); } else if (!strcmp(p, "nodebug_tiles") || !strcmp(p, "nodbt")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_tiles); goto qry; } debug_tiles = 0; rfbLog("set debug_tiles to: %d\n", debug_tiles); } else if (strstr(p, "debug_tiles") == p) { COLON_CHECK("debug_tiles:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_tiles); goto qry; } p += strlen("debug_tiles:"); debug_tiles = atoi(p); rfbLog("set debug_tiles to: %d\n", debug_tiles); } else if (!strcmp(p, "debug_grabs")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_grabs); goto qry; } debug_grabs = 1; rfbLog("set debug_grabs to: %d\n", debug_grabs); } else if (!strcmp(p, "nodebug_grabs")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_grabs); goto qry; } debug_grabs = 0; rfbLog("set debug_grabs to: %d\n", debug_grabs); } else if (!strcmp(p, "debug_sel")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, debug_sel); goto qry; } debug_sel = 1; rfbLog("set debug_sel to: %d\n", debug_sel); } else if (!strcmp(p, "nodebug_sel")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_sel); goto qry; } debug_sel = 0; rfbLog("set debug_sel to: %d\n", debug_sel); } else if (!strcmp(p, "dbg")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, crash_debug); goto qry; } crash_debug = 1; rfbLog("set crash_debug to: %d\n", crash_debug); } else if (!strcmp(p, "nodbg")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !crash_debug); goto qry; } crash_debug = 0; rfbLog("set crash_debug to: %d\n", crash_debug); } else if (strstr(p, "hack") == p) { /* skip-cmd-list */ COLON_CHECK("hack:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, hack_val); goto qry; } p += strlen("hack:"); hack_val = atoi(p); rfbLog("set hack_val to: %d\n", hack_val); } else if (!strcmp(p, "noremote")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !accept_remote_cmds); goto qry; } rfbLog("remote_cmd: disabling remote commands.\n"); accept_remote_cmds = 0; /* cannot be turned back on. */ } else if (strstr(p, "client_info_sock") == p) { /* skip-cmd-list */ NOTAPP p += strlen("client_info_sock:"); if (*p != '\0') { start_client_info_sock(p); } } else if (strstr(p, "noop") == p) { NOTAPP rfbLog("remote_cmd: noop\n"); } else if (icon_mode && !query && strstr(p, "passwd") == p) { /* skip-cmd-list */ char **passwds_new = (char **) malloc(3*sizeof(char *)); char **passwds_old = (char **) screen->authPasswdData; COLON_CHECK("passwd:") p += strlen("passwd:"); passwds_new[0] = strdup(p); if (screen->authPasswdData && screen->passwordCheck == rfbCheckPasswordByList) { passwds_new[1] = passwds_old[1]; } else { passwds_new[1] = NULL; screen->passwordCheck = rfbCheckPasswordByList; } passwds_new[2] = NULL; screen->authPasswdData = (void*) passwds_new; if (*p == '\0') { screen->authPasswdData = (void*) NULL; } rfbLog("remote_cmd: changed full access passwd.\n"); } else if (icon_mode && !query && strstr(p, "viewpasswd") == p) { /* skip-cmd-list */ char **passwds_new = (char **) malloc(3*sizeof(char *)); char **passwds_old = (char **) screen->authPasswdData; COLON_CHECK("viewpasswd:") p += strlen("viewpasswd:"); passwds_new[1] = strdup(p); if (screen->authPasswdData && screen->passwordCheck == rfbCheckPasswordByList) { passwds_new[0] = passwds_old[0]; } else { char *tmp = (char *) malloc(4 + CHALLENGESIZE); rfbRandomBytes((unsigned char*)tmp); passwds_new[0] = tmp; screen->passwordCheck = rfbCheckPasswordByList; } passwds_new[2] = NULL; if (*p == '\0') { passwds_new[1] = NULL; } screen->authPasswdData = (void*) passwds_new; rfbLog("remote_cmd: changed view only passwd.\n"); } else if (strstr(p, "trayembed") == p) { /* skip-cmd-list */ unsigned long id; NOTAPP COLON_CHECK("trayembed:") p += strlen("trayembed:"); if (scan_hexdec(p, &id)) { tray_request = (Window) id; tray_unembed = 0; rfbLog("remote_cmd: will try to embed 0x%x in" " the system tray.\n", id); } } else if (strstr(p, "trayunembed") == p) { /* skip-cmd-list */ unsigned long id; NOTAPP COLON_CHECK("trayunembed:") p += strlen("trayunembed:"); if (scan_hexdec(p, &id)) { tray_request = (Window) id; tray_unembed = 1; rfbLog("remote_cmd: will try to unembed 0x%x out" " of the system tray.\n", id); } } else if (query) { /* read-only variables that can only be queried: */ if (!strcmp(p, "display")) { if (raw_fb) { snprintf(buf, bufn, "aro=%s:rawfb:%p", p, raw_fb_addr); } else if (! dpy) { snprintf(buf, bufn, "aro=%s:", p); } else { char *d; d = DisplayString(dpy); if (! d) d = "unknown"; if (*d == ':') { snprintf(buf, bufn, "aro=%s:%s%s", p, this_host(), d); } else { snprintf(buf, bufn, "aro=%s:%s", p, d); } } } else if (!strcmp(p, "vncdisplay")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(vnc_desktop_name)); } else if (!strcmp(p, "desktopname")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(rfb_desktop_name)); } else if (!strcmp(p, "guess_desktop")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(guess_desktop())); } else if (!strcmp(p, "http_url")) { if (!screen) { snprintf(buf, bufn, "aro=%s:", p); } else if (screen->httpListenSock > -1) { snprintf(buf, bufn, "aro=%s:http://%s:%d", p, NONUL(screen->thisHost), screen->httpPort); } else { snprintf(buf, bufn, "aro=%s:%s", p, "http_not_active"); } } else if (!strcmp(p, "auth") || !strcmp(p, "xauth")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(auth_file)); } else if (!strcmp(p, "users")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(users_list)); } else if (!strcmp(p, "rootshift")) { snprintf(buf, bufn, "aro=%s:%d", p, rootshift); } else if (!strcmp(p, "clipshift")) { snprintf(buf, bufn, "aro=%s:%d", p, clipshift); } else if (!strcmp(p, "scale_str")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(scale_str)); } else if (!strcmp(p, "scaled_x")) { snprintf(buf, bufn, "aro=%s:%d", p, scaled_x); } else if (!strcmp(p, "scaled_y")) { snprintf(buf, bufn, "aro=%s:%d", p, scaled_y); } else if (!strcmp(p, "scale_numer")) { snprintf(buf, bufn, "aro=%s:%d", p, scale_numer); } else if (!strcmp(p, "scale_denom")) { snprintf(buf, bufn, "aro=%s:%d", p, scale_denom); } else if (!strcmp(p, "scale_fac")) { snprintf(buf, bufn, "aro=%s:%f", p, scale_fac); } else if (!strcmp(p, "scaling_blend")) { snprintf(buf, bufn, "aro=%s:%d", p, scaling_blend); } else if (!strcmp(p, "scaling_nomult4")) { snprintf(buf, bufn, "aro=%s:%d", p, scaling_nomult4); } else if (!strcmp(p, "scaling_pad")) { snprintf(buf, bufn, "aro=%s:%d", p, scaling_pad); } else if (!strcmp(p, "scaling_interpolate")) { snprintf(buf, bufn, "aro=%s:%d", p, scaling_interpolate); } else if (!strcmp(p, "inetd")) { snprintf(buf, bufn, "aro=%s:%d", p, inetd); } else if (!strcmp(p, "privremote")) { snprintf(buf, bufn, "aro=%s:%d", p, priv_remote); } else if (!strcmp(p, "unsafe")) { snprintf(buf, bufn, "aro=%s:%d", p, !safe_remote_only); } else if (!strcmp(p, "safer")) { snprintf(buf, bufn, "aro=%s:%d", p, more_safe); } else if (!strcmp(p, "nocmds")) { snprintf(buf, bufn, "aro=%s:%d", p, no_external_cmds); } else if (!strcmp(p, "passwdfile")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(passwdfile)); #ifndef REL8x } else if (!strcmp(p, "unixpw")) { snprintf(buf, bufn, "aro=%s:%d", p, unixpw); } else if (!strcmp(p, "unixpw_nis")) { snprintf(buf, bufn, "aro=%s:%d", p, unixpw_nis); } else if (!strcmp(p, "unixpw_list")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(unixpw_list)); } else if (!strcmp(p, "ssl")) { snprintf(buf, bufn, "aro=%s:%d", p, use_openssl); } else if (!strcmp(p, "ssl_pem")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(openssl_pem)); } else if (!strcmp(p, "sslverify")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(ssl_verify)); } else if (!strcmp(p, "stunnel")) { snprintf(buf, bufn, "aro=%s:%d", p, use_stunnel); } else if (!strcmp(p, "stunnel_pem")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(stunnel_pem)); } else if (!strcmp(p, "https")) { snprintf(buf, bufn, "aro=%s:%d", p, https_port_num); #endif } else if (!strcmp(p, "usepw")) { snprintf(buf, bufn, "aro=%s:%d", p, usepw); } else if (!strcmp(p, "using_shm")) { snprintf(buf, bufn, "aro=%s:%d", p, !using_shm); } else if (!strcmp(p, "logfile") || !strcmp(p, "o")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(logfile)); } else if (!strcmp(p, "flag")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(flagfile)); } else if (!strcmp(p, "rc")) { char *s = rc_rcfile; if (rc_rcfile_default) { s = NULL; } snprintf(buf, bufn, "aro=%s:%s", p, NONUL(s)); } else if (!strcmp(p, "norc")) { snprintf(buf, bufn, "aro=%s:%d", p, got_norc); } else if (!strcmp(p, "h") || !strcmp(p, "help") || !strcmp(p, "V") || !strcmp(p, "version") || !strcmp(p, "lastmod")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(lastmod)); } else if (!strcmp(p, "bg")) { snprintf(buf, bufn, "aro=%s:%d", p, opts_bg); } else if (!strcmp(p, "sigpipe")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(sigpipe)); } else if (!strcmp(p, "threads")) { snprintf(buf, bufn, "aro=%s:%d", p, use_threads); } else if (!strcmp(p, "readrate")) { snprintf(buf, bufn, "aro=%s:%d", p, get_read_rate()); } else if (!strcmp(p, "netrate")) { snprintf(buf, bufn, "aro=%s:%d", p, get_net_rate()); } else if (!strcmp(p, "netlatency")) { snprintf(buf, bufn, "aro=%s:%d", p, get_net_latency()); } else if (!strcmp(p, "pipeinput")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(pipeinput_str)); } else if (!strcmp(p, "clients")) { char *str = list_clients(); snprintf(buf, bufn, "aro=%s:%s", p, str); free(str); } else if (!strcmp(p, "client_count")) { snprintf(buf, bufn, "aro=%s:%d", p, client_count); } else if (!strcmp(p, "pid")) { snprintf(buf, bufn, "aro=%s:%d", p, (int) getpid()); } else if (!strcmp(p, "ext_xtest")) { snprintf(buf, bufn, "aro=%s:%d", p, xtest_present); } else if (!strcmp(p, "ext_xtrap")) { snprintf(buf, bufn, "aro=%s:%d", p, xtrap_present); } else if (!strcmp(p, "ext_xrecord")) { snprintf(buf, bufn, "aro=%s:%d", p, xrecord_present); } else if (!strcmp(p, "ext_xkb")) { snprintf(buf, bufn, "aro=%s:%d", p, xkb_present); } else if (!strcmp(p, "ext_xshm")) { snprintf(buf, bufn, "aro=%s:%d", p, xshm_present); } else if (!strcmp(p, "ext_xinerama")) { snprintf(buf, bufn, "aro=%s:%d", p, xinerama_present); } else if (!strcmp(p, "ext_overlay")) { snprintf(buf, bufn, "aro=%s:%d", p, overlay_present); } else if (!strcmp(p, "ext_xfixes")) { snprintf(buf, bufn, "aro=%s:%d", p, xfixes_present); } else if (!strcmp(p, "ext_xdamage")) { snprintf(buf, bufn, "aro=%s:%d", p, xdamage_present); } else if (!strcmp(p, "ext_xrandr")) { snprintf(buf, bufn, "aro=%s:%d", p, xrandr_present); } else if (!strcmp(p, "rootwin")) { snprintf(buf, bufn, "aro=%s:0x%x", p, (unsigned int) rootwin); } else if (!strcmp(p, "num_buttons")) { snprintf(buf, bufn, "aro=%s:%d", p, num_buttons); } else if (!strcmp(p, "button_mask")) { snprintf(buf, bufn, "aro=%s:%d", p, button_mask); } else if (!strcmp(p, "mouse_x")) { snprintf(buf, bufn, "aro=%s:%d", p, cursor_x); } else if (!strcmp(p, "mouse_y")) { snprintf(buf, bufn, "aro=%s:%d", p, cursor_y); } else if (!strcmp(p, "bpp")) { snprintf(buf, bufn, "aro=%s:%d", p, bpp); } else if (!strcmp(p, "depth")) { snprintf(buf, bufn, "aro=%s:%d", p, depth); } else if (!strcmp(p, "indexed_color")) { snprintf(buf, bufn, "aro=%s:%d", p, indexed_color); } else if (!strcmp(p, "dpy_x")) { snprintf(buf, bufn, "aro=%s:%d", p, dpy_x); } else if (!strcmp(p, "dpy_y")) { snprintf(buf, bufn, "aro=%s:%d", p, dpy_y); } else if (!strcmp(p, "wdpy_x")) { snprintf(buf, bufn, "aro=%s:%d", p, wdpy_x); } else if (!strcmp(p, "wdpy_y")) { snprintf(buf, bufn, "aro=%s:%d", p, wdpy_y); } else if (!strcmp(p, "off_x")) { snprintf(buf, bufn, "aro=%s:%d", p, off_x); } else if (!strcmp(p, "off_y")) { snprintf(buf, bufn, "aro=%s:%d", p, off_y); } else if (!strcmp(p, "cdpy_x")) { snprintf(buf, bufn, "aro=%s:%d", p, cdpy_x); } else if (!strcmp(p, "cdpy_y")) { snprintf(buf, bufn, "aro=%s:%d", p, cdpy_y); } else if (!strcmp(p, "coff_x")) { snprintf(buf, bufn, "aro=%s:%d", p, coff_x); } else if (!strcmp(p, "coff_y")) { snprintf(buf, bufn, "aro=%s:%d", p, coff_y); } else if (!strcmp(p, "rfbauth")) { NOTAPPRO } else if (!strcmp(p, "passwd")) { NOTAPPRO } else if (!strcmp(p, "viewpasswd")) { NOTAPPRO } else { NOTAPP } goto qry; } else { char tmp[100]; NOTAPP rfbLog("remote_cmd: warning unknown\n"); strncpy(tmp, p, 90); rfbLog("command \"%s\"\n", tmp); goto done; } done: if (*buf == '\0') { sprintf(buf, "ack=1"); } qry: if (stringonly) { return strdup(buf); } else if (client_connect_file) { FILE *out = fopen(client_connect_file, "w"); if (out != NULL) { fprintf(out, "%s\n", buf); fclose(out); usleep(20*1000); } } else { if (dpy) { /* raw_fb hack */ set_x11vnc_remote_prop(buf); XFlush_wr(dpy); } } #endif return NULL; }