You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libtdevnc/x11vnc/remote.c

3767 lines
94 KiB

/* -- 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;
}