diff options
Diffstat (limited to 'x11vnc/remote.c')
-rw-r--r-- | x11vnc/remote.c | 3766 |
1 files changed, 3766 insertions, 0 deletions
diff --git a/x11vnc/remote.c b/x11vnc/remote.c new file mode 100644 index 0000000..2a82ca8 --- /dev/null +++ b/x11vnc/remote.c @@ -0,0 +1,3766 @@ +/* -- 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" + +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 (vnc_connect_prop == None) { + initialize_vnc_connect_prop(); + if (vnc_connect_prop == None) { + fprintf(stderr, "send_remote_cmd: could not obtain " + "VNC_CONNECT 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" + " VNC_CONNECT X property.\n", cmd); + set_vnc_connect_prop(cmd); + XFlush(dpy); + } + + if (query || wait) { + char line[VNC_CONNECT_MAX]; + int rc=1, i=0, max=70, ms_sl=50; + + if (!strcmp(cmd, "cmd=stop")) { + max = 20; + } + for (i=0; i<max; i++) { + usleep(ms_sl * 1000); + if (client_connect_file) { + char *q; + in = fopen(client_connect_file, "r"); + if (in == NULL) { + fprintf(stderr, "send_remote_cmd: could" + " not open connect file \"%s\" for" + " writing\n", client_connect_file); + perror("fopen"); + return 1; + } + fgets(line, VNC_CONNECT_MAX, in); + fclose(in); + q = line; + while (*q != '\0') { + if (*q == '\n') *q = '\0'; + q++; + } + } else { + read_vnc_connect_prop(); + strncpy(line, vnc_connect_str, VNC_CONNECT_MAX); + } + if (strcmp(cmd, line)){ + if (query) { + fprintf(stdout, "%s\n", line); + fflush(stdout); + } + rc = 0; + break; + } + } + if (rc) { + fprintf(stderr, "error: could not connect to " + "an x11vnc server at %s (rc=%d)\n", + client_connect_file ? client_connect_file + : DisplayString(dpy), rc); + } + return rc; + } + return 0; +} + +int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync, + int qdefault) { + char *rcmd = NULL, *qcmd = NULL; + int rc = 1; + + if (qdefault && !query_cmd) { + query_cmd = remote_cmd; + remote_cmd = NULL; + } + + if (remote_cmd) { + rcmd = (char *) malloc(strlen(remote_cmd) + 5); + strcpy(rcmd, "cmd="); + strcat(rcmd, remote_cmd); + } + if (query_cmd) { + qcmd = (char *) malloc(strlen(query_cmd) + 5); + strcpy(qcmd, "qry="); + strcat(qcmd, query_cmd); + } + if (qdefault) { + char *res; + if (!qcmd) { + return 1; + } + res = process_remote_cmd(qcmd, 1); + fprintf(stdout, "%s\n", res); + fflush(stdout); + return 0; + } + + if (rcmd && qcmd) { + rc = send_remote_cmd(rcmd, 0, 1); + if (rc) { + free(rcmd); + free(qcmd); + return(rc); + } + rc = send_remote_cmd(qcmd, 1, 1); + } else if (rcmd) { + rc = send_remote_cmd(rcmd, 0, remote_sync); + free(rcmd); + } else if (qcmd) { + rc = send_remote_cmd(qcmd, 1, 1); + free(qcmd); + } + return rc; +} + +static char *add_item(char *instr, char *item) { + char *p, *str; + int len, saw_item = 0; + + if (! instr || *instr == '\0') { + str = strdup(item); + return str; + } + len = strlen(instr) + 1 + strlen(item) + 1; + str = (char *) malloc(len); + str[0] = '\0'; + + /* n.b. instr will be modified; caller replaces with returned string */ + p = strtok(instr, ","); + while (p) { + if (!strcmp(p, item)) { + if (saw_item) { + p = strtok(NULL, ","); + continue; + } + saw_item = 1; + } else if (*p == '\0') { + p = strtok(NULL, ","); + continue; + } + if (str[0]) { + strcat(str, ","); + } + strcat(str, p); + p = strtok(NULL, ","); + } + if (! saw_item) { + if (str[0]) { + strcat(str, ","); + } + strcat(str, item); + } + return str; +} + +static char *delete_item(char *instr, char *item) { + char *p, *str; + int len; + + if (! instr || *instr == '\0') { + str = strdup(""); + return str; + } + len = strlen(instr) + 1; + str = (char *) malloc(len); + str[0] = '\0'; + + /* n.b. instr will be modified; caller replaces with returned string */ + p = strtok(instr, ","); + while (p) { + if (!strcmp(p, item) || *p == '\0') { + p = strtok(NULL, ","); + continue; + } + if (str[0]) { + strcat(str, ","); + } + strcat(str, p); + p = strtok(NULL, ","); + } + return str; +} + +static void if_8bpp_do_new_fb(void) { + if (bpp == 8) { + do_new_fb(0); + } else { + rfbLog(" bpp(%d) is not 8bpp, not resetting fb\n", bpp); + } +} + +void check_black_fb(void) { + if (!screen) { + return; + } + if (new_fb_size_clients(screen) != client_count) { + rfbLog("trying to send a black fb for non-newfbsize" + " clients %d != %d\n", client_count, + new_fb_size_clients(screen)); + push_black_screen(4); + } +} + +int check_httpdir(void) { + if (http_dir) { + return 1; + } else { + char *prog = NULL, *httpdir, *q; + struct stat sbuf; + int len; + + rfbLog("check_httpdir: trying to guess httpdir...\n"); + if (program_name[0] == '/') { + prog = strdup(program_name); + } else { + char cwd[1024]; + getcwd(cwd, 1024); + len = strlen(cwd) + 1 + strlen(program_name) + 1; + prog = (char *) malloc(len); + snprintf(prog, len, "%s/%s", cwd, program_name); + if (stat(prog, &sbuf) != 0) { + char *path = strdup(getenv("PATH")); + char *p, *base; + base = strrchr(program_name, '/'); + if (base) { + base++; + } else { + base = program_name; + } + + p = strtok(path, ":"); + while(p) { + free(prog); + len = strlen(p) + 1 + strlen(base) + 1; + prog = (char *) malloc(len); + snprintf(prog, len, "%s/%s", p, base); + if (stat(prog, &sbuf) == 0) { + break; + } + p = strtok(NULL, ":"); + } + free(path); + } + } + /* + * /path/to/bin/x11vnc + * /path/to/bin/../share/x11vnc/classes + * 12345678901234567 + */ + if ((q = strrchr(prog, '/')) == NULL) { + rfbLog("check_httpdir: bad program path: %s\n", prog); + free(prog); + return 0; + } + + len = strlen(prog) + 17 + 1; + *q = '\0'; + httpdir = (char *) malloc(len); + snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog); + free(prog); + + if (stat(httpdir, &sbuf) == 0) { + /* good enough for me */ + rfbLog("check_httpdir: guessed directory:\n"); + rfbLog(" %s\n", httpdir); + http_dir = httpdir; + return 1; + } else { + /* try some hardwires: */ + if (stat("/usr/local/share/x11vnc/classes", + &sbuf) == 0) { + http_dir = + strdup("/usr/local/share/x11vnc/classes"); + return 1; + } + if (stat("/usr/share/x11vnc/classes", &sbuf) == 0) { + http_dir = strdup("/usr/share/x11vnc/classes"); + return 1; + } + rfbLog("check_httpdir: bad guess:\n"); + rfbLog(" %s\n", httpdir); + return 0; + } + } +} + +void http_connections(int on) { + if (!screen) { + return; + } + if (on) { + rfbLog("http_connections: turning on http service.\n"); + screen->httpInitDone = FALSE; + screen->httpDir = http_dir; + if (check_httpdir()) { + 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 (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<n; i++) { + if (xha[i].family == FamilyInternet) { + char *str = raw2host(xha[i].address, + xha[i].length); + char *ip = raw2ip(xha[i].address); + rfbLog(" %s/%s\n", str, ip); + free(str); + free(ip); + } else { + rfbLog(" unknown-%d\n", i+1); + } + } + XFree(xha); + return 0; + } + + if (getenv("XAUTHORITY")) { + xauth = strdup(getenv("XAUTHORITY")); + } else { + xauth = NULL; + } + set_env("XAUTHORITY", "/impossible/xauthfile"); + + fprintf(stderr, "\nChecking if display %s requires " + "XAUTHORITY\n", dpy_str); + fprintf(stderr, " -- (ignore any Xlib: errors that" + " follow) --\n"); + dpy2 = XOpenDisplay(dpy_str); + fflush(stderr); + fprintf(stderr, " -- (done checking) --\n\n"); + + if (xauth) { + set_env("XAUTHORITY", xauth); + free(xauth); + } else { + xauth = getenv("XAUTHORITY"); + if (xauth) { + *(xauth-2) = '_'; /* yow */ + } + } + if (dpy2) { + rfbLog("XAUTHORITY is not required on display.\n"); + rfbLog(" %s\n", DisplayString(dpy)); + XCloseDisplay(dpy2); + return 0; + } + + } + return 1; +} + +static int hack_val = 0; + +/* + * Huge, ugly switch to handle all remote commands and queries + * -remote/-R and -query/-Q. + */ +char *process_remote_cmd(char *cmd, int stringonly) { +#if REMOTE_CONTROL + char *p = cmd; + char *co = ""; + char buf[VNC_CONNECT_MAX]; + int bufn = VNC_CONNECT_MAX; + int query = 0; + static char *prev_cursors_mode = NULL; + + if (!query_default && !accept_remote_cmds) { + rfbLog("remote commands disabled: %s\n", cmd); + return NULL; + } + + if (!query_default && priv_remote) { + if (! remote_control_access_ok()) { + rfbLog("** Disabling remote commands in -privremote " + "mode.\n"); + accept_remote_cmds = 0; + return NULL; + } + } + + strcpy(buf, ""); + if (strstr(cmd, "cmd=") == cmd) { + p += strlen("cmd="); + } else if (strstr(cmd, "qry=") == cmd) { + query = 1; + if (strchr(cmd, ',')) { + /* comma separated batch mode */ + char *s, *q, *res; + char tmp[512]; + strcpy(buf, ""); + s = strdup(cmd + strlen("qry=")); + q = strtok(s, ","); + while (q) { + strcpy(tmp, "qry="); + strncat(tmp, q, 500); + res = process_remote_cmd(tmp, 1); + if (res && strlen(buf)+strlen(res) + >= VNC_CONNECT_MAX - 1) { + rfbLog("overflow in process_remote_cmd:" + " %s -- %s\n", buf, res); + free(res); + break; + } + if (res) { + strcat(buf, res); + free(res); + } + q = strtok(NULL, ","); + if (q) { + strcat(buf, ","); + } + } + free(s); + goto qry; + } + p += strlen("qry="); + } else { + rfbLog("ignoring malformed command: %s\n", cmd); + goto done; + } + + /* allow var=val usage */ + if (!strchr(p, ':')) { + char *q = strchr(p, '='); + if (q) *q = ':'; + } + + /* always call like: COLON_CHECK("foobar:") */ +#define COLON_CHECK(str) \ + if (strstr(p, str) != p) { \ + co = ":"; \ + if (! query) { \ + goto done; \ + } \ + } else { \ + char *q = strchr(p, ':'); \ + if (query && q != NULL) { \ + *(q+1) = '\0'; \ + } \ + } + +#define NOTAPP \ + if (query) { \ + if (strchr(p, ':')) { \ + snprintf(buf, bufn, "ans=%sN/A", p); \ + } else { \ + snprintf(buf, bufn, "ans=%s:N/A", p); \ + } \ + goto qry; \ + } + +#define NOTAPPRO \ + if (query) { \ + if (strchr(p, ':')) { \ + snprintf(buf, bufn, "aro=%sN/A", p); \ + } else { \ + snprintf(buf, bufn, "aro=%s:N/A", p); \ + } \ + goto qry; \ + } + +/* + * Maybe add: passwdfile logfile bg rfbauth passwd... + */ + if (!strcmp(p, "stop") || !strcmp(p, "quit") || + !strcmp(p, "exit") || !strcmp(p, "shutdown")) { + NOTAPP + close_all_clients(); + rfbLog("remote_cmd: setting shut_down flag\n"); + shut_down = 1; + + } else if (!strcmp(p, "ping")) { + query = 1; + if (rfb_desktop_name) { + snprintf(buf, bufn, "ans=%s:%s", p, rfb_desktop_name); + } else { + snprintf(buf, bufn, "ans=%s:%s", p, "unknown"); + } + goto qry; + + } else if (!strcmp(p, "blacken") || !strcmp(p, "zero")) { + NOTAPP + push_black_screen(4); + } else if (!strcmp(p, "refresh")) { + NOTAPP + refresh_screen(1); + } else if (!strcmp(p, "reset")) { + NOTAPP + do_new_fb(1); + } else if (strstr(p, "zero:") == p) { /* skip-cmd-list */ + int x1, y1, x2, y2; + NOTAPP + p += strlen("zero:"); + if (sscanf(p, "%d,%d,%d,%d", &x1, &y1, &x2, &y2) == 4) { + int mark = 1; + rfbLog("zeroing rect: %s\n", p); + if (x1 < 0 || x2 < 0) { + x1 = nabs(x1); + x2 = nabs(x2); + mark = 0; /* hack for testing */ + } + + zero_fb(x1, y1, x2, y2); + if (mark) { + mark_rect_as_modified(x1, y1, x2, y2, 0); + } + push_sleep(4); + } + } else if (strstr(p, "damagefb:") == p) { /* skip-cmd-list */ + int delay; + NOTAPP + p += strlen("damagefb:"); + if (sscanf(p, "%d", &delay) == 1) { + rfbLog("damaging client fb's for %d secs " + "(by not marking rects.)\n", delay); + damage_time = time(0); + damage_delay = delay; + } + + } else if (strstr(p, "close") == p) { + NOTAPP + COLON_CHECK("close:") + p += strlen("close:"); + close_clients(p); + } else if (strstr(p, "disconnect") == p) { + NOTAPP + COLON_CHECK("disconnect:") + p += strlen("disconnect:"); + close_clients(p); + + } else if (strstr(p, "id") == p) { + int ok = 0; + Window twin; + COLON_CHECK("id:") + if (query) { + snprintf(buf, bufn, "ans=%s%s0x%lx", p, co, + rootshift ? 0 : subwin); + goto qry; + } + p += strlen("id:"); + if (*p == '\0' || !strcmp("root", p)) { + /* back to root win */ + twin = 0x0; + ok = 1; + } else if (!strcmp("pick", p)) { + twin = 0x0; + if (safe_remote_only) { + rfbLog("unsafe: '-id pick'\n"); + } else if (pick_windowid(&twin)) { + ok = 1; + } + } else if (! scan_hexdec(p, &twin)) { + rfbLog("-id: skipping incorrect hex/dec number:" + " %s\n", p); + } else { + ok = 1; + } + if (ok) { + if (twin && ! valid_window(twin, NULL, 0)) { + rfbLog("skipping invalid sub-window: 0x%lx\n", + twin); + } else { + subwin = twin; + rootshift = 0; + check_black_fb(); + do_new_fb(1); + } + } + } else if (strstr(p, "sid") == p) { + int ok = 0; + Window twin; + COLON_CHECK("sid:") + if (query) { + snprintf(buf, bufn, "ans=%s%s0x%lx", p, co, + !rootshift ? 0 : subwin); + goto qry; + } + p += strlen("sid:"); + if (*p == '\0' || !strcmp("root", p)) { + /* back to root win */ + twin = 0x0; + ok = 1; + } else if (!strcmp("pick", p)) { + twin = 0x0; + if (safe_remote_only) { + rfbLog("unsafe: '-sid pick'\n"); + } else if (pick_windowid(&twin)) { + ok = 1; + } + } else if (! scan_hexdec(p, &twin)) { + rfbLog("-sid: skipping incorrect hex/dec number: %s\n", p); + } else { + ok = 1; + } + if (ok) { + if (twin && ! valid_window(twin, NULL, 0)) { + rfbLog("skipping invalid sub-window: 0x%lx\n", + twin); + } else { + subwin = twin; + rootshift = 1; + check_black_fb(); + do_new_fb(1); + } + } + } else if (strstr(p, "waitmapped") == p) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, + subwin_wait_mapped); + goto qry; + } + subwin_wait_mapped = 1; + } else if (strstr(p, "nowaitmapped") == p) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, + !subwin_wait_mapped); + goto qry; + } + subwin_wait_mapped = 0; + + } else if (!strcmp(p, "clip") || + strstr(p, "clip:") == p) { /* skip-cmd-list */ + COLON_CHECK("clip:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(clip_str)); + goto qry; + } + p += strlen("clip:"); + if (clip_str) free(clip_str); + clip_str = strdup(p); + + /* OK, this requires a new fb... */ + do_new_fb(1); + + } else if (!strcmp(p, "flashcmap")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, flash_cmap); + goto qry; + } + rfbLog("remote_cmd: turning on flashcmap mode.\n"); + flash_cmap = 1; + } else if (!strcmp(p, "noflashcmap")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !flash_cmap); + goto qry; + } + rfbLog("remote_cmd: turning off flashcmap mode.\n"); + flash_cmap = 0; + + } else if (strstr(p, "shiftcmap") == p) { + COLON_CHECK("shiftcmap:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%d", p, co, shift_cmap); + goto qry; + } + p += strlen("shiftcmap:"); + shift_cmap = atoi(p); + rfbLog("remote_cmd: set -shiftcmap %d\n", shift_cmap); + do_new_fb(1); + + } else if (!strcmp(p, "truecolor")) { + int orig = force_indexed_color; + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, + !force_indexed_color); + goto qry; + } + rfbLog("remote_cmd: turning off notruecolor mode.\n"); + force_indexed_color = 0; + if (orig != force_indexed_color) { + if_8bpp_do_new_fb(); + } + } else if (!strcmp(p, "notruecolor")) { + int orig = force_indexed_color; + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, + force_indexed_color); + goto qry; + } + rfbLog("remote_cmd: turning on notruecolor mode.\n"); + force_indexed_color = 1; + if (orig != force_indexed_color) { + if_8bpp_do_new_fb(); + } + + } else if (!strcmp(p, "overlay")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, overlay); + goto qry; + } + rfbLog("remote_cmd: turning on -overlay mode.\n"); + if (!overlay_present) { + rfbLog("skipping: overlay extension not present.\n"); + } else if (overlay) { + rfbLog("skipping: already in -overlay mode.\n"); + } else { + int reset_mem = 0; + /* here we go... */ + if (using_shm) { + rfbLog("setting -noshm mode.\n"); + using_shm = 0; + reset_mem = 1; + } + overlay = 1; + do_new_fb(reset_mem); + } + } else if (!strcmp(p, "nooverlay")) { + int orig = overlay; + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !overlay); + goto qry; + } + rfbLog("remote_cmd: turning off overlay mode\n"); + overlay = 0; + if (!overlay_present) { + rfbLog("warning: overlay extension not present.\n"); + } else if (!orig) { + rfbLog("skipping: already not in -overlay mode.\n"); + } else { + /* here we go... */ + do_new_fb(0); + } + + } else if (!strcmp(p, "overlay_cursor") || + !strcmp(p, "overlay_yescursor") || + !strcmp(p, "nooverlay_nocursor")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, overlay_cursor); + goto qry; + } + rfbLog("remote_cmd: turning on overlay_cursor mode.\n"); + overlay_cursor = 1; + if (!overlay_present) { + rfbLog("warning: overlay extension not present.\n"); + } else if (!overlay) { + rfbLog("warning: not in -overlay mode.\n"); + } else { + rfbLog("You may want to run -R noshow_cursor or\n"); + rfbLog(" -R cursor:none to disable any extra " + "cursors.\n"); + } + } else if (!strcmp(p, "nooverlay_cursor") || + !strcmp(p, "nooverlay_yescursor") || + !strcmp(p, "overlay_nocursor")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !overlay_cursor); + goto qry; + } + rfbLog("remote_cmd: turning off overlay_cursor mode\n"); + overlay_cursor = 0; + if (!overlay_present) { + rfbLog("warning: overlay extension not present.\n"); + } else if (!overlay) { + rfbLog("warning: not in -overlay mode.\n"); + } else { + rfbLog("You may want to run -R show_cursor or\n"); + rfbLog(" -R cursor:... to re-enable any cursors.\n"); + } + + } else if (strstr(p, "visual") == p) { + COLON_CHECK("visual:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(visual_str)); + goto qry; + } + p += strlen("visual:"); + if (visual_str) free(visual_str); + visual_str = strdup(p); + + /* OK, this requires a new fb... */ + do_new_fb(0); + + } else if (!strcmp(p, "scale") || + strstr(p, "scale:") == p) { /* skip-cmd-list */ + COLON_CHECK("scale:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(scale_str)); + goto qry; + } + p += strlen("scale:"); + if (scale_str) free(scale_str); + scale_str = strdup(p); + + /* OK, this requires a new fb... */ + check_black_fb(); + do_new_fb(0); + + } else if (!strcmp(p, "scale_cursor") || + strstr(p, "scale_cursor:") == p) { /* skip-cmd-list */ + COLON_CHECK("scale_cursor:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(scale_cursor_str)); + goto qry; + } + p += strlen("scale_cursor:"); + if (scale_cursor_str) free(scale_cursor_str); + if (*p == '\0') { + scale_cursor_str = NULL; + } else { + scale_cursor_str = strdup(p); + } + setup_cursors_and_push(); + + } else if (!strcmp(p, "viewonly")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, view_only); + goto qry; + } + rfbLog("remote_cmd: enable viewonly mode.\n"); + view_only = 1; + } else if (!strcmp(p, "noviewonly")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !view_only); + goto qry; + } + rfbLog("remote_cmd: disable viewonly mode.\n"); + view_only = 0; + if (raw_fb) set_raw_fb_params(0); + + } else if (!strcmp(p, "shared")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, shared); goto qry; + } + rfbLog("remote_cmd: enable sharing.\n"); + shared = 1; + if (screen) { + screen->alwaysShared = 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); + +#if 0 + } else if (!strcmp(p, "filexfer")) { + /* does this work after rfbInitServer? */ + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, filexfer); + goto qry; + } + rfbLog("remote_cmd: enabling -filexfer.\n"); + filexfer = 1; + rfbRegisterTightVNCFileTransferExtension(); +#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; + } + 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 (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 (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; + COLON_CHECK("accept:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(accept_cmd)); + goto qry; + } + p += strlen("accept:"); + if (safe_remote_only) { + if (icon_mode && !strcmp(p, "")) { /* skip-cmd-list */ + ; + } else if (icon_mode && !strcmp(p, "popup")) { /* skip-cmd-list */ + ; + } else { + 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) { + COLON_CHECK("afteraccept:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(afteraccept_cmd)); + goto qry; + } + if (safe_remote_only) { + rfbLog("unsafe: %s\n", p); + } else { + p += strlen("afteraccept:"); + if (afteraccept_cmd) free(afteraccept_cmd); + afteraccept_cmd = strdup(p); + } + + } else if (strstr(p, "gone") == p) { + COLON_CHECK("gone:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(gone_cmd)); + goto qry; + } + if (safe_remote_only) { + rfbLog("unsafe: %s\n", p); + } else { + p += strlen("gone:"); + 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) { + 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) { + 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 (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; + + } 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; + + } 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 (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<max; i++) { + /* XXX: try to force empty cursor back to client */ + rfbPE(-1); + } + cursor_shape_updates = 0; + disable_cursor_shape_updates(screen); + first_cursor(); + + } else if (!strcmp(p, "cursorpos")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, + cursor_pos_updates); + goto qry; + } + rfbLog("remote_cmd: turning on cursorpos mode.\n"); + cursor_pos_updates = 1; + } else if (!strcmp(p, "nocursorpos")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, + !cursor_pos_updates); + goto qry; + } + rfbLog("remote_cmd: turning off cursorpos mode.\n"); + cursor_pos_updates = 0; + + } else if (strstr(p, "cursor") == p) { + COLON_CHECK("cursor:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(multiple_cursors_mode)); + goto qry; + } + p += strlen("cursor:"); + if (multiple_cursors_mode) { + if (prev_cursors_mode) free(prev_cursors_mode); + prev_cursors_mode = strdup(multiple_cursors_mode); + free(multiple_cursors_mode); + } + multiple_cursors_mode = strdup(p); + + rfbLog("remote_cmd: changed -cursor mode " + "to: %s\n", multiple_cursors_mode); + + if (strcmp(multiple_cursors_mode, "none") && !show_cursor) { + show_cursor = 1; + rfbLog("remote_cmd: changed show_cursor " + "to: %d\n", show_cursor); + } + initialize_cursors_mode(); + first_cursor(); + + } else if (!strcmp(p, "show_cursor")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, show_cursor); + goto qry; + } + rfbLog("remote_cmd: enabling show_cursor.\n"); + show_cursor = 1; + if (multiple_cursors_mode && !strcmp(multiple_cursors_mode, + "none")) { + free(multiple_cursors_mode); + if (prev_cursors_mode) { + multiple_cursors_mode = + strdup(prev_cursors_mode); + } else { + multiple_cursors_mode = strdup("default"); + } + rfbLog("remote_cmd: changed -cursor mode " + "to: %s\n", multiple_cursors_mode); + } + initialize_cursors_mode(); + first_cursor(); + } else if (!strcmp(p, "noshow_cursor") || !strcmp(p, "nocursor")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !show_cursor); + goto qry; + } + if (prev_cursors_mode) free(prev_cursors_mode); + prev_cursors_mode = strdup(multiple_cursors_mode); + + rfbLog("remote_cmd: disabling show_cursor.\n"); + show_cursor = 0; + initialize_cursors_mode(); + first_cursor(); + + } else if (strstr(p, "arrow") == p) { + COLON_CHECK("arrow:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%d", p, co, alt_arrow); + goto qry; + } + p += strlen("arrow:"); + alt_arrow = atoi(p); + rfbLog("remote_cmd: setting alt_arrow: %d.\n", alt_arrow); + setup_cursors_and_push(); + + } else if (!strcmp(p, "xfixes")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, use_xfixes); + goto qry; + } + if (! xfixes_present) { + rfbLog("remote_cmd: cannot enable xfixes " + "(not supported on X display)\n"); + goto done; + } + rfbLog("remote_cmd: enabling -xfixes" + " (if supported).\n"); + use_xfixes = 1; + initialize_xfixes(); + first_cursor(); + } else if (!strcmp(p, "noxfixes")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !use_xfixes); + goto qry; + } + if (! xfixes_present) { + rfbLog("remote_cmd: disabling xfixes " + "(but not supported on X display)\n"); + goto done; + } + rfbLog("remote_cmd: disabling -xfixes.\n"); + use_xfixes = 0; + initialize_xfixes(); + first_cursor(); + + } else if (!strcmp(p, "xdamage")) { + int orig = use_xdamage; + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, use_xdamage); + goto qry; + } + if (! xdamage_present) { + rfbLog("remote_cmd: cannot enable xdamage hints " + "(not supported on X display)\n"); + goto done; + } + rfbLog("remote_cmd: enabling xdamage hints" + " (if supported).\n"); + use_xdamage = 1; + if (use_xdamage != orig) { + initialize_xdamage(); + create_xdamage_if_needed(); + } + } else if (!strcmp(p, "noxdamage")) { + int orig = use_xdamage; + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !use_xdamage); + goto qry; + } + if (! xdamage_present) { + rfbLog("remote_cmd: disabling xdamage hints " + "(but not supported on X display)\n"); + goto done; + } + rfbLog("remote_cmd: disabling xdamage hints.\n"); + use_xdamage = 0; + if (use_xdamage != orig) { + initialize_xdamage(); + destroy_xdamage_if_needed(); + } + + } else if (strstr(p, "xd_area") == p) { + int a; + COLON_CHECK("xd_area:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%d", p, co, + xdamage_max_area); + goto qry; + } + p += strlen("xd_area:"); + a = atoi(p); + if (a >= 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 (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 (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 (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; + rfbLog("restoring per-rawfb settings...\n"); + set_raw_fb_params(1); + } + rfbLog("hang on tight, here we go...\n"); + do_new_fb(1); + + } 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, "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)); + } 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_vnc_connect_prop(buf); + XFlush(dpy); + } + } +#endif + return NULL; +} + + |