summaryrefslogtreecommitdiffstats
path: root/x11vnc/x11vnc.c
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2014-09-03 20:54:39 +0200
committerChristian Beier <dontmind@freeshell.org>2014-09-03 20:54:39 +0200
commit498d222976975f53dea885cfe43ef0f805abd412 (patch)
treebac684fbde46fdc3e4cc3817616816b71bb67f9f /x11vnc/x11vnc.c
parent8d2db0486dcc167f1b02d4454ebf4624ce03e1de (diff)
downloadlibtdevnc-498d222976975f53dea885cfe43ef0f805abd412.tar.gz
libtdevnc-498d222976975f53dea885cfe43ef0f805abd412.zip
Remove x11vnc subdir.
The new x11vnc repo is at https://github.com/LibVNC/x11vnc.
Diffstat (limited to 'x11vnc/x11vnc.c')
-rw-r--r--x11vnc/x11vnc.c5945
1 files changed, 0 insertions, 5945 deletions
diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c
deleted file mode 100644
index 64a73de..0000000
--- a/x11vnc/x11vnc.c
+++ /dev/null
@@ -1,5945 +0,0 @@
-/*
- * x11vnc: a VNC server for X displays.
- *
- * Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- * All rights reserved.
- *
- * This file is part of x11vnc.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License, or (at
- * your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA or see <http://www.gnu.org/licenses/>.
- *
- * In addition, as a special exception, Karl J. Runge
- * gives permission to link the code of its release of x11vnc with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify this file, you may extend this exception to your version of the
- * file, but you are not obligated to do so. If you do not wish to do
- * so, delete this exception statement from your version.
- */
-
-/*
- * This program is based on some ideas from the following programs:
- *
- * the initial x11vnc.c in libvncserver (Johannes E. Schindelin)
- * x0rfbserver, the original native X vnc server (Jens Wagner)
- * krfb, the KDE desktopsharing project (Tim Jansen)
- *
- * Please see http://www.karlrunge.com/x11vnc for the most up-to-date
- * information about x11vnc. Some of the following text may be out
- * of date.
- *
- * The primary goal of this program is to create a portable and simple
- * command-line server utility that allows a VNC viewer to connect
- * to an actual X display (as the above do). The only non-standard
- * dependency of this program is the static library libvncserver.a.
- * Although in some environments libjpeg.so or libz.so may not be
- * readily available and needs to be installed, they may be found
- * at ftp://ftp.uu.net/graphics/jpeg/ and http://www.gzip.org/zlib/,
- * respectively. To increase portability it is written in plain C.
- *
- * Another goal is to improve performance and interactive response.
- * The algorithm of x0rfbserver was used as a base. Many additional
- * heuristics are also applied.
- *
- * Another goal is to add many features that enable and incourage creative
- * usage and application of the tool. Apologies for the large number
- * of options!
- *
- * To build:
- *
- * Obtain the libvncserver package (http://libvncserver.sourceforge.net).
- * As of 12/2002 this version of x11vnc.c is contained in the libvncserver
- * CVS tree and released in version 0.5.
- *
- * gcc should be used on all platforms. To build a threaded version put
- * "-D_REENTRANT -DX11VNC_THREADED" in the environment variable CFLAGS
- * or CPPFLAGS (e.g. before running the libvncserver configure). The
- * threaded mode is a bit more responsive, but can be unstable (e.g.
- * if more than one client the same tight or zrle encoding).
- *
- * Known shortcomings:
- *
- * The screen updates are good, but of course not perfect since the X
- * display must be continuously polled and read for changes and this is
- * slow for most hardware. This can be contrasted with receiving a change
- * callback from the X server, if that were generally possible... (UPDATE:
- * this is handled now with the X DAMAGE extension, but unfortunately
- * that doesn't seem to address the slow read from the video h/w). So,
- * e.g., opaque moves and similar window activity can be very painful;
- * one has to modify one's behavior a bit.
- *
- * General audio at the remote display is lost unless one separately
- * sets up some audio side-channel such as esd.
- *
- * It does not appear possible to query the X server for the current
- * cursor shape. We can use XTest to compare cursor to current window's
- * cursor, but we cannot extract what the cursor is... (UPDATE: we now
- * use XFIXES extension for this. Also on Solaris and IRIX Overlay
- * extensions exists that allow drawing the mouse into the framebuffer)
- *
- * The current *position* of the remote X mouse pointer is shown with
- * the -cursor option. Further, if -cursor X is used, a trick
- * is done to at least show the root window cursor vs non-root cursor.
- * (perhaps some heuristic can be done to further distinguish cases...,
- * currently "-cursor some" is a first hack at this)
- *
- * Under XFIXES mode for showing the cursor shape, the cursor may be
- * poorly approximated if it has transparency (alpha channel).
- *
- * Windows using visuals other than the default X visual may have
- * their colors messed up. When using 8bpp indexed color, the colormap
- * is attempted to be followed, but may become out of date. Use the
- * -flashcmap option to have colormap flashing as the pointer moves
- * windows with private colormaps (slow). Displays with mixed depth 8 and
- * 24 visuals will incorrectly display windows using the non-default one.
- * On Sun and Sgi hardware we can to work around this with -overlay.
- *
- * Feature -id <windowid> can be picky: it can crash for things like
- * the window not sufficiently mapped into server memory, etc (UPDATE:
- * we now use the -xrandr mechanisms to trap errors more robustly for
- * this mode). SaveUnders menus, popups, etc will not be seen.
- *
- * Under some situations the keysym unmapping is not correct, especially
- * if the two keyboards correspond to different languages. The -modtweak
- * option is the default and corrects most problems. One can use the
- * -xkb option to try to use the XKEYBOARD extension to clear up any
- * remaining problems.
- *
- * Occasionally, a few tile updates can be missed leaving a patch of
- * color that needs to be refreshed. This may only be when threaded,
- * which is no longer the default.
- *
- * There seems to be a serious bug with simultaneous clients when
- * threaded, currently the only workaround in this case is -nothreads
- * (which is now the default).
- */
-
-
-/* -- x11vnc.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "xdamage.h"
-#include "xrecord.h"
-#include "xevents.h"
-#include "xinerama.h"
-#include "xrandr.h"
-#include "xkb_bell.h"
-#include "win_utils.h"
-#include "remote.h"
-#include "scan.h"
-#include "gui.h"
-#include "help.h"
-#include "user.h"
-#include "cleanup.h"
-#include "keyboard.h"
-#include "pointer.h"
-#include "cursor.h"
-#include "userinput.h"
-#include "screen.h"
-#include "connections.h"
-#include "rates.h"
-#include "unixpw.h"
-#include "inet.h"
-#include "sslcmds.h"
-#include "sslhelper.h"
-#include "selection.h"
-#include "pm.h"
-#include "solid.h"
-
-/*
- * main routine for the x11vnc program
- */
-void watch_loop(void);
-
-static int limit_shm(void);
-static void check_rcfile(int argc, char **argv);
-static void immediate_switch_user(int argc, char* argv[]);
-static void print_settings(int try_http, int bg, char *gui_str);
-static void check_loop_mode(int argc, char* argv[], int force);
-static void check_appshare_mode(int argc, char* argv[]);
-
-static int tsdo_timeout_flag;
-
-static void tsdo_timeout (int sig) {
- tsdo_timeout_flag = 1;
- if (sig) {};
-}
-
-#define TASKMAX 32
-static pid_t ts_tasks[TASKMAX];
-static int ts_taskn = -1;
-
-int tsdo(int port, int lsock, int *conn) {
- int csock, rsock, i, db = 1;
- pid_t pid;
- struct sockaddr_in addr;
-#ifdef __hpux
- int addrlen = sizeof(addr);
-#else
- socklen_t addrlen = sizeof(addr);
-#endif
-
- if (*conn < 0) {
- signal(SIGALRM, tsdo_timeout);
- tsdo_timeout_flag = 0;
-
- alarm(10);
- csock = accept(lsock, (struct sockaddr *)&addr, &addrlen);
- alarm(0);
-
- if (db) rfbLog("tsdo: accept: lsock: %d, csock: %d, port: %d\n", lsock, csock, port);
-
- if (tsdo_timeout_flag > 0 || csock < 0) {
- close(csock);
- *conn = -1;
- return 1;
- }
- *conn = csock;
- } else {
- csock = *conn;
- if (db) rfbLog("tsdo: using existing csock: %d, port: %d\n", csock, port);
- }
-
- rsock = connect_tcp("127.0.0.1", port);
- if (rsock < 0) {
- if (db) rfbLog("tsdo: connect_tcp(port=%d) failed.\n", port);
- close(csock);
- return 2;
- }
-
- pid = fork();
- if (pid < 0) {
- close(csock);
- close(rsock);
- return 3;
- }
- if (pid > 0) {
- ts_taskn = (ts_taskn+1) % TASKMAX;
- ts_tasks[ts_taskn] = pid;
- close(csock);
- close(rsock);
- *conn = -1;
- return 0;
- }
- if (pid == 0) {
- for (i=0; i<255; i++) {
- if (i != csock && i != rsock && i != 2) {
- close(i);
- }
- }
-#if LIBVNCSERVER_HAVE_SETSID
- if (setsid() == -1) {
- perror("setsid");
- close(csock);
- close(rsock);
- exit(1);
- }
-#else
- if (setpgrp() == -1) {
- perror("setpgrp");
- close(csock);
- close(rsock);
- exit(1);
- }
-#endif /* SETSID */
- raw_xfer(rsock, csock, csock);
- close(csock);
- close(rsock);
- exit(0);
- }
- return 0;
-}
-
-void set_redir_properties(void);
-
-#define TSMAX 32
-#define TSSTK 16
-
-void terminal_services(char *list) {
- int i, j, n, db = 1;
- char *p, *q, *r, *str;
-#if !NO_X11
- char *tag[TSMAX];
- int listen[TSMAX], redir[TSMAX][TSSTK], socks[TSMAX], tstk[TSSTK];
- double rate_start;
- int rate_count;
- Atom at, atom[TSMAX];
- fd_set rd;
- Window rwin;
- XErrorHandler old_handler1;
- XIOErrorHandler old_handler2;
- char num[32];
- time_t last_clean = time(NULL);
-
- if (getenv("TS_REDIR_DEBUG")) {
- db = 2;
- }
-
- if (! dpy) {
- return;
- }
-
- rwin = RootWindow(dpy, DefaultScreen(dpy));
-
- at = XInternAtom(dpy, "TS_REDIR_LIST", False);
- if (at != None) {
- XChangeProperty(dpy, rwin, at, XA_STRING, 8,
- PropModeReplace, (unsigned char *)list, strlen(list));
- XSync(dpy, False);
- }
- if (db) fprintf(stderr, "TS_REDIR_LIST Atom: %d.\n", (int) at);
-
- oh_restart_it_all:
-
- for (i=0; i<TASKMAX; i++) {
- ts_tasks[i] = 0;
- }
- for (i=0; i<TSMAX; i++) {
- socks[i] = -1;
- listen[i] = -1;
- for (j=0; j<TSSTK; j++) {
- redir[i][j] = 0;
- }
- }
-
- rate_start = 0.0;
- rate_count = 0;
-
- n = 0;
- str = strdup(list);
- p = strtok(str, ",");
- while (p) {
- int m1, m2;
- if (db) fprintf(stderr, "item: %s\n", p);
- q = strrchr(p, ':');
- if (!q) {
- p = strtok(NULL, ",");
- continue;
- }
- r = strchr(p, ':');
- if (!r || r == q) {
- p = strtok(NULL, ",");
- continue;
- }
-
- m1 = atoi(q+1);
- *q = '\0';
- m2 = atoi(r+1);
- *r = '\0';
-
- if (m1 <= 0 || m2 <= 0 || m1 >= 0xffff || m2 >= 0xffff) {
- p = strtok(NULL, ",");
- continue;
- }
-
- redir[n][0] = m1;
- listen[n] = m2;
- tag[n] = strdup(p);
-
- if (db) fprintf(stderr, " %d %d %s\n", redir[n][0], listen[n], tag[n]);
-
- *r = ':';
- *q = ':';
-
- n++;
- if (n >= TSMAX) {
- break;
- }
- p = strtok(NULL, ",");
- }
- free(str);
-
- if (n==0) {
- return;
- }
-
- at = XInternAtom(dpy, "TS_REDIR_PID", False);
- if (at != None) {
- sprintf(num, "%d", getpid());
- XChangeProperty(dpy, rwin, at, XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
-
- for (i=0; i<n; i++) {
- int k;
- atom[i] = XInternAtom(dpy, tag[i], False);
- if (db) fprintf(stderr, "tag: %s atom: %d\n", tag[i], (int) atom[i]);
- if (atom[i] == None) {
- continue;
- }
- sprintf(num, "%d", redir[i][0]);
- if (db) fprintf(stderr, " listen: %d redir: %s\n", listen[i], num);
- XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
-
- for (k=1; k <= 5; k++) {
- /* XXX ::1 fallback? */
- socks[i] = listen_tcp(listen[i], htonl(INADDR_LOOPBACK), 1);
- if (socks[i] >= 0) {
- if (db) fprintf(stderr, " listen succeeded: %d\n", listen[i]);
- break;
- }
- if (db) fprintf(stderr, " listen failed***: %d\n", listen[i]);
- usleep(k * 2000*1000);
- }
- }
-
- if (getenv("TSD_RESTART")) {
- if (!strcmp(getenv("TSD_RESTART"), "1")) {
- set_redir_properties();
- }
- }
-
- while (1) {
- struct timeval tv;
- int nfd;
- int fmax = -1;
-
- tv.tv_sec = 3;
- tv.tv_usec = 0;
-
- FD_ZERO(&rd);
- for (i=0; i<n; i++) {
- if (socks[i] >= 0) {
- FD_SET(socks[i], &rd);
- if (socks[i] > fmax) {
- fmax = socks[i];
- }
- }
- }
-
- nfd = select(fmax+1, &rd, NULL, NULL, &tv);
-
- if (db && 0) fprintf(stderr, "nfd=%d\n", nfd);
- if (nfd < 0 && errno == EINTR) {
- XSync(dpy, True);
- continue;
- }
- if (nfd > 0) {
- int did_ts = 0;
- for(i=0; i<n; i++) {
- int k = 0;
- for (j = 0; j < TSSTK; j++) {
- tstk[j] = 0;
- }
- for (j = 0; j < TSSTK; j++) {
- if (redir[i][j] != 0) {
- tstk[k++] = redir[i][j];
- }
- }
- for (j = 0; j < TSSTK; j++) {
- redir[i][j] = tstk[j];
-if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], tag[i]);
- }
- }
- for(i=0; i<n; i++) {
- int s = socks[i];
- if (s < 0) {
- continue;
- }
- if (FD_ISSET(s, &rd)) {
- int p0, p, found = -1, jzero = -1;
- int conn = -1;
-
- get_prop(num, 32, atom[i], None);
- p0 = atoi(num);
-
- for (j = TSSTK-1; j >= 0; j--) {
- if (redir[i][j] == 0) {
- jzero = j;
- continue;
- }
- if (p0 > 0 && p0 < 0xffff) {
- if (redir[i][j] == p0) {
- found = j;
- break;
- }
- }
- }
- if (jzero < 0) {
- jzero = TSSTK-1;
- }
- if (found < 0) {
- if (p0 > 0 && p0 < 0xffff) {
- redir[i][jzero] = p0;
- }
- }
- for (j = TSSTK-1; j >= 0; j--) {
- int rc;
- p = redir[i][j];
- if (p <= 0 || p >= 0xffff) {
- redir[i][j] = 0;
- continue;
- }
-
- if (dnow() > rate_start + 10.0) {
- rate_start = dnow();
- rate_count = 0;
- }
- rate_count++;
-
- rc = tsdo(p, s, &conn);
- did_ts++;
-
- if (rc == 0) {
- /* AOK */
- if (db) fprintf(stderr, "tsdo[%d] OK: %d\n", i, p);
- if (p != p0) {
- sprintf(num, "%d", p);
- XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
- break;
- } else if (rc == 1) {
- /* accept failed */
- if (db) fprintf(stderr, "tsdo[%d] accept failed: %d, sleep 50ms\n", i, p);
- usleep(50*1000);
- break;
- } else if (rc == 2) {
- /* connect failed */
- if (db) fprintf(stderr, "tsdo[%d] connect failed: %d, sleep 50ms rate: %d/10s\n", i, p, rate_count);
- redir[i][j] = 0;
- usleep(50*1000);
- continue;
- } else if (rc == 3) {
- /* fork failed */
- usleep(500*1000);
- break;
- }
- }
- for (j = 0; j < TSSTK; j++) {
- if (redir[i][j] != 0) fprintf(stderr, "A redir[%d][%d] = %d %s\n", i, j, redir[i][j], tag[i]);
- }
- }
- }
- if (did_ts && rate_count > 100) {
- int db_netstat = 1;
- char dcmd[100];
-
- if (no_external_cmds) {
- db_netstat = 0;
- }
-
- rfbLog("terminal_services: throttling high connect rate %d/10s\n", rate_count);
- usleep(2*1000*1000);
- rfbLog("terminal_services: stopping ts services.\n");
- for(i=0; i<n; i++) {
- int s = socks[i];
- if (s < 0) {
- continue;
- }
- rfbLog("terminal_services: closing listen=%d sock=%d.\n", listen[i], socks[i]);
- if (listen[i] >= 0 && db_netstat) {
- sprintf(dcmd, "netstat -an | grep -w '%d'", listen[i]);
- fprintf(stderr, "#1 %s\n", dcmd);
- system(dcmd);
- }
- close(s);
- socks[i] = -1;
- usleep(2*1000*1000);
- if (listen[i] >= 0 && db_netstat) {
- fprintf(stderr, "#2 %s\n", dcmd);
- system(dcmd);
- }
- }
- usleep(10*1000*1000);
-
- rfbLog("terminal_services: restarting ts services\n");
- goto oh_restart_it_all;
- }
- }
- for (i=0; i<TASKMAX; i++) {
- pid_t p = ts_tasks[i];
- if (p > 0) {
- int status;
- pid_t p2 = waitpid(p, &status, WNOHANG);
- if (p2 == p) {
- ts_tasks[i] = 0;
- }
- }
- }
- /* this is to drop events and exit when X server is gone. */
- old_handler1 = XSetErrorHandler(trap_xerror);
- old_handler2 = XSetIOErrorHandler(trap_xioerror);
- trapped_xerror = 0;
- trapped_xioerror = 0;
-
- XSync(dpy, True);
-
- sprintf(num, "%d", (int) time(NULL));
- at = XInternAtom(dpy, "TS_REDIR", False);
- if (at != None) {
- XChangeProperty(dpy, rwin, at, XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
- if (time(NULL) > last_clean + 20 * 60) {
- int i, j;
- for(i=0; i<n; i++) {
- int first = 1;
- for (j = TSSTK-1; j >= 0; j--) {
- int s, p = redir[i][j];
- if (p <= 0 || p >= 0xffff) {
- redir[i][j] = 0;
- continue;
- }
- s = connect_tcp("127.0.0.1", p);
- if (s < 0) {
- redir[i][j] = 0;
- if (db) fprintf(stderr, "tsdo[%d][%d] clean: connect failed: %d\n", i, j, p);
- } else {
- close(s);
- if (first) {
- sprintf(num, "%d", p);
- XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
- first = 0;
- }
- usleep(500*1000);
- }
- }
- last_clean = time(NULL);
- }
- if (trapped_xerror || trapped_xioerror) {
- if (db) fprintf(stderr, "Xerror: %d/%d\n", trapped_xerror, trapped_xioerror);
- exit(0);
- }
- XSetErrorHandler(old_handler1);
- XSetIOErrorHandler(old_handler2);
- }
-#endif
-}
-
-char *ts_services[][2] = {
- {"FD_CUPS", "TS_CUPS_REDIR"},
- {"FD_SMB", "TS_SMB_REDIR"},
- {"FD_ESD", "TS_ESD_REDIR"},
- {"FD_NAS", "TS_NAS_REDIR"},
- {NULL, NULL}
-};
-
-void do_tsd(void) {
-#if !NO_X11
- Atom a;
- char prop[513];
- pid_t pid;
- char *cmd;
- int n, sz = 0;
- char *disp = DisplayString(dpy);
- char *logfile = getenv("TS_REDIR_LOGFILE");
- int db = 0;
-
- if (getenv("TS_REDIR_DEBUG")) {
- db = 1;
- }
- if (db) fprintf(stderr, "do_tsd() in.\n");
-
- prop[0] = '\0';
- a = XInternAtom(dpy, "TS_REDIR_LIST", False);
- if (a != None) {
- get_prop(prop, 512, a, None);
- }
- if (db) fprintf(stderr, "TS_REDIR_LIST Atom: %d = '%s'\n", (int) a, prop);
-
- if (prop[0] == '\0') {
- return;
- }
-
- if (! program_name) {
- program_name = "x11vnc";
- }
- sz += strlen(program_name) + 1;
- sz += strlen("-display") + 1;
- sz += strlen(disp) + 1;
- sz += strlen("-tsd") + 1;
- sz += 1 + strlen(prop) + 1 + 1;
- sz += strlen("-env TSD_RESTART=1") + 1;
- sz += strlen("</dev/null 1>/dev/null 2>&1") + 1;
- sz += strlen(" &") + 1;
- if (logfile) {
- sz += strlen(logfile);
- }
- if (ipv6_listen) {
- sz += strlen("-6") + 1;
- }
-
- cmd = (char *) malloc(sz);
-
- if (getenv("XAUTHORITY")) {
- char *xauth = getenv("XAUTHORITY");
- if (!strcmp(xauth, "") || access(xauth, R_OK) != 0) {
- *(xauth-2) = '_'; /* yow */
- }
- }
- sprintf(cmd, "%s -display %s -tsd '%s' -env TSD_RESTART=1 %s </dev/null 1>%s 2>&1 &",
- program_name, disp, prop, ipv6_listen ? "-6" : "",
- logfile ? logfile : "/dev/null" );
- rfbLog("running: %s\n", cmd);
-
-#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
- /* fork into the background now */
- if ((pid = fork()) > 0) {
- pid_t pidw;
- int status;
- double s = dnow();
-
- while (dnow() < s + 1.5) {
- pidw = waitpid(pid, &status, WNOHANG);
- if (pidw == pid) {
- break;
- }
- usleep(100*1000);
- }
- return;
-
- } else if (pid == -1) {
- system(cmd);
- } else {
- setsid();
- /* adjust our stdio */
- n = open("/dev/null", O_RDONLY);
- dup2(n, 0);
- dup2(n, 1);
- dup2(n, 2);
- if (n > 2) {
- close(n);
- }
- system(cmd);
- exit(0);
- }
-#else
- system(cmd);
-#endif
-
-#endif
-}
-
-void set_redir_properties(void) {
-#if !NO_X11
- char *e, *f, *t;
- Atom a;
- char num[32];
- int i, p;
-
- if (! dpy) {
- return;
- }
-
- i = 0;
- while (ts_services[i][0] != NULL) {
- f = ts_services[i][0];
- t = ts_services[i][1];
- e = getenv(f);
- if (!e || strstr(e, "DAEMON-") != e) {
- i++;
- continue;
- }
- p = atoi(e + strlen("DAEMON-"));
- if (p <= 0) {
- i++;
- continue;
- }
- sprintf(num, "%d", p);
- a = XInternAtom(dpy, t, False);
- if (a != None) {
- Window rwin = RootWindow(dpy, DefaultScreen(dpy));
-fprintf(stderr, "Set: %s %s %s -> %s\n", f, t, e, num);
- XChangeProperty(dpy, rwin, a, XA_STRING, 8,
- PropModeReplace, (unsigned char *) num, strlen(num));
- XSync(dpy, False);
- }
- i++;
- }
-#endif
-}
-
-static void check_redir_services(void) {
-#if !NO_X11
- Atom a;
- char prop[513];
- time_t tsd_last;
- int restart = 0;
- pid_t pid = 0;
- int db = 0;
- db = 0;
-
- if (getenv("TS_REDIR_DEBUG")) {
- db = 1;
- }
- if (db) fprintf(stderr, "check_redir_services in.\n");
-
- if (! dpy) {
- return;
- }
-
- a = XInternAtom(dpy, "TS_REDIR_PID", False);
- if (a != None) {
- prop[0] = '\0';
- get_prop(prop, 512, a, None);
- if (prop[0] != '\0') {
- pid = (pid_t) atoi(prop);
- }
- }
- if (db) fprintf(stderr, "TS_REDIR_PID Atom: %d = '%s'\n", (int) a, prop);
-
- if (getenv("FD_TAG") && strcmp(getenv("FD_TAG"), "")) {
- a = XInternAtom(dpy, "FD_TAG", False);
- if (a != None) {
- Window rwin = RootWindow(dpy, DefaultScreen(dpy));
- char *tag = getenv("FD_TAG");
- XChangeProperty(dpy, rwin, a, XA_STRING, 8,
- PropModeReplace, (unsigned char *)tag, strlen(tag));
- XSync(dpy, False);
- }
- if (db) fprintf(stderr, "FD_TAG Atom: %d = '%s'\n", (int) a, prop);
- }
-
- prop[0] = '\0';
- a = XInternAtom(dpy, "TS_REDIR", False);
- if (a != None) {
- get_prop(prop, 512, a, None);
- }
- if (db) fprintf(stderr, "TS_REDIR Atom: %d = '%s'\n", (int) a, prop);
- if (prop[0] == '\0') {
- rfbLog("TS_REDIR is empty, restarting...\n");
- restart = 1;
- } else {
- tsd_last = (time_t) atoi(prop);
- if (time(NULL) > tsd_last + 30) {
- rfbLog("TS_REDIR seems dead for: %d sec, restarting...\n",
- time(NULL) - tsd_last);
- restart = 1;
- } else if (pid > 0 && time(NULL) > tsd_last + 6) {
- if (kill(pid, 0) != 0) {
- rfbLog("TS_REDIR seems dead via kill(%d, 0), restarting...\n",
- pid);
- restart = 1;
- }
- }
- }
- if (restart) {
-
- if (pid > 1) {
- rfbLog("killing TS_REDIR_PID: %d\n", pid);
- kill(pid, SIGTERM);
- usleep(500*1000);
- kill(pid, SIGKILL);
- }
- do_tsd();
- if (db) fprintf(stderr, "check_redir_services restarted.\n");
- return;
- }
-
- if (db) fprintf(stderr, "check_redir_services, no restart, calling set_redir_properties.\n");
- set_redir_properties();
-#endif
-}
-
-void ssh_remote_tunnel(char *instr, int lport) {
- char *q, *cmd, *ssh;
- char *s = strdup(instr);
- int sleep = 300, disp = 0, sport = 0;
- int rc, len, rport;
-
- /* user@host:port:disp+secs */
-
- /* +sleep */
- q = strrchr(s, '+');
- if (q) {
- sleep = atoi(q+1);
- if (sleep <= 0) {
- sleep = 1;
- }
- *q = '\0';
- }
- /* :disp */
- q = strrchr(s, ':');
- if (q) {
- disp = atoi(q+1);
- *q = '\0';
- }
-
- /* :sshport */
- q = strrchr(s, ':');
- if (q) {
- sport = atoi(q+1);
- *q = '\0';
- }
-
- if (getenv("SSH")) {
- ssh = getenv("SSH");
- } else {
- ssh = "ssh";
- }
-
- len = 0;
- len += strlen(ssh) + strlen(s) + 500;
- cmd = (char *) malloc(len);
-
- if (disp >= 0 && disp <= 200) {
- rport = disp + 5900;
- } else if (disp < 0) {
- rport = -disp;
- } else {
- rport = disp;
- }
-
- if (sport > 0) {
- sprintf(cmd, "%s -f -p %d -R '%d:localhost:%d' '%s' 'sleep %d'", ssh, sport, rport, lport, s, sleep);
- } else {
- sprintf(cmd, "%s -f -R '%d:localhost:%d' '%s' 'sleep %d'", ssh, rport, lport, s, sleep);
- }
-
- if (no_external_cmds || !cmd_ok("ssh")) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", cmd);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
-
- close_exec_fds();
- fprintf(stderr, "\n");
- rfbLog("running: %s\n", cmd);
- rc = system(cmd);
-
- if (rc != 0) {
- free(cmd);
- free(s);
- rfbLog("ssh remote listen failed.\n");
- clean_up_exit(1);
- }
-
- if (1) {
- FILE *pipe;
- int mypid = (int) getpid();
- int bestpid = -1;
- int best = -1;
- char line[1024];
- char *psef = "ps -ef";
- char *psww = "ps wwwwwwaux";
- char *ps = psef;
- /* not portable... but it is really good to terminate the ssh when done. */
- /* ps -ef | egrep 'ssh2.*-R.*5907:localhost:5900.*runge@celias.lbl.gov.*sleep 300' | grep -v grep | awk '{print $2}' */
- if (strstr(UT.sysname, "Linux")) {
- ps = psww;
- } else if (strstr(UT.sysname, "BSD")) {
- ps = psww;
- } else if (strstr(UT.sysname, "Darwin")) {
- ps = psww;
- }
- sprintf(cmd, "env COLUMNS=256 %s | egrep '%s.*-R *%d:localhost:%d.*%s.*sleep *%d' | grep -v grep | awk '{print $2}'", ps, ssh, rport, lport, s, sleep);
- pipe = popen(cmd, "r");
- if (pipe) {
- while (fgets(line, 1024, pipe) != NULL) {
- int p = atoi(line);
- if (p > 0) {
- int score;
- if (p > mypid) {
- score = p - mypid;
- } else {
- score = p - mypid + 32768;
- if (score < 0) {
- score = 32768;
- }
- }
- if (best < 0 || score < best) {
- best = score;
- bestpid = p;
- }
- }
- }
- pclose(pipe);
- }
-
- if (bestpid != -1) {
- ssh_pid = (pid_t) bestpid;
- rfbLog("guessed ssh pid=%d, will terminate it on exit.\n", bestpid);
- }
- }
-
- free(cmd);
- free(s);
-}
-
-/*
- * check blacklist for OSs with tight shm limits.
- */
-static int limit_shm(void) {
- int limit = 0;
-
- if (UT.sysname == NULL) {
- return 0;
- }
- if (getenv("X11VNC_NO_LIMIT_SHM")) {
- return 0;
- }
- if (!strcmp(UT.sysname, "SunOS")) {
- char *r = UT.release;
- if (*r == '5' && *(r+1) == '.') {
- if (strchr("2345678", *(r+2)) != NULL) {
- limit = 1;
- }
- }
- } else if (!strcmp(UT.sysname, "Darwin")) {
- limit = 1;
- }
- if (limit && ! quiet) {
- fprintf(stderr, "reducing shm usage on %s %s (adding "
- "-onetile)\n", UT.sysname, UT.release);
- }
- return limit;
-}
-
-
-/*
- * quick-n-dirty ~/.x11vncrc: each line (except # comments) is a cmdline option.
- */
-static int argc2 = 0;
-static char **argv2;
-
-static void check_rcfile(int argc, char **argv) {
- int i, j, pwlast, enclast, norc = 0, argmax = 1024;
- char *infile = NULL;
- char rcfile[1024];
- FILE *rc = NULL;
-
- for (i=1; i < argc; i++) {
- if (!strcmp(argv[i], "-printgui")) {
- fprintf(stdout, "%s", get_gui_code());
- fflush(stdout);
- exit(0);
- }
- if (!strcmp(argv[i], "-norc")) {
- norc = 1;
- got_norc = 1;
- }
- if (!strcmp(argv[i], "-QD")) {
- norc = 1;
- }
- if (!strcmp(argv[i], "-rc")) {
- if (i+1 >= argc) {
- fprintf(stderr, "-rc option requires a "
- "filename\n");
- exit(1);
- } else {
- infile = argv[i+1];
- }
- }
- }
- rc_norc = norc;
- rc_rcfile = strdup("");
- if (norc) {
- ;
- } else if (infile != NULL) {
- rc = fopen(infile, "r");
- rc_rcfile = strdup(infile);
- if (rc == NULL) {
- fprintf(stderr, "could not open rcfile: %s\n", infile);
- perror("fopen");
- exit(1);
- }
- } else {
- char *home = get_home_dir();
- if (! home) {
- norc = 1;
- } else {
- memset(rcfile, 0, sizeof(rcfile));
- strncpy(rcfile, home, 500);
- free(home);
-
- strcat(rcfile, "/.x11vncrc");
- infile = rcfile;
- rc = fopen(rcfile, "r");
- if (rc == NULL) {
- norc = 1;
- } else {
- rc_rcfile = strdup(rcfile);
- rc_rcfile_default = 1;
- }
- }
- }
-
- argv2 = (char **) malloc(argmax * sizeof(char *));
- argv2[argc2++] = strdup(argv[0]);
-
- if (! norc) {
- char line[4096], parm[400], tmp[401];
- char *buf, *tbuf;
- struct stat sbuf;
- int sz;
-
- if (fstat(fileno(rc), &sbuf) != 0) {
- fprintf(stderr, "problem with %s\n", infile);
- perror("fstat");
- exit(1);
- }
- sz = sbuf.st_size+1; /* allocate whole file size */
- if (sz < 1024) {
- sz = 1024;
- }
-
- buf = (char *) malloc(sz);
- buf[0] = '\0';
-
- while (fgets(line, 4096, rc) != NULL) {
- char *q, *p = line;
- char c;
- int cont = 0;
-
- q = p;
- c = '\0';
- while (*q) {
- if (*q == '#') {
- if (c != '\\') {
- *q = '\0';
- break;
- }
- }
- c = *q;
- q++;
- }
-
- q = p;
- c = '\0';
- while (*q) {
- if (*q == '\n') {
- if (c == '\\') {
- cont = 1;
- *q = '\0';
- *(q-1) = ' ';
- break;
- }
- while (isspace((unsigned char) (*q))) {
- *q = '\0';
- if (q == p) {
- break;
- }
- q--;
- }
- break;
- }
- c = *q;
- q++;
- }
- if (q != p && !cont) {
- if (*q == '\0') {
- q--;
- }
- while (isspace((unsigned char) (*q))) {
- *q = '\0';
- if (q == p) {
- break;
- }
- q--;
- }
- }
-
- p = lblanks(p);
-
- strncat(buf, p, sz - strlen(buf) - 1);
- if (cont) {
- continue;
- }
- if (buf[0] == '\0') {
- continue;
- }
-
- i = 0;
- q = buf;
- while (*q) {
- i++;
- if (*q == '\n' || isspace((unsigned char) (*q))) {
- break;
- }
- q++;
- }
-
- if (i >= 400) {
- fprintf(stderr, "invalid rcfile line: %s/%s\n",
- p, buf);
- exit(1);
- }
-
- if (sscanf(buf, "%s", parm) != 1) {
- fprintf(stderr, "invalid rcfile line: %s\n", p);
- exit(1);
- }
- if (parm[0] == '-') {
- strncpy(tmp, parm, 400);
- } else {
- tmp[0] = '-';
- strncpy(tmp+1, parm, 400);
- }
-
- if (strstr(tmp, "-loop") == tmp) {
- if (! getenv("X11VNC_LOOP_MODE")) {
- check_loop_mode(argc, argv, 1);
- exit(0);
- }
- }
-
- argv2[argc2++] = strdup(tmp);
- if (argc2 >= argmax) {
- fprintf(stderr, "too many rcfile options\n");
- exit(1);
- }
-
- p = buf;
- p += strlen(parm);
- p = lblanks(p);
-
- if (*p == '\0') {
- buf[0] = '\0';
- continue;
- }
-
- tbuf = (char *) calloc(strlen(p) + 1, 1);
-
- j = 0;
- while (*p) {
- if (*p == '\\' && *(p+1) == '#') {
- ;
- } else {
- tbuf[j++] = *p;
- }
- p++;
- }
-
- argv2[argc2++] = strdup(tbuf);
- free(tbuf);
- if (argc2 >= argmax) {
- fprintf(stderr, "too many rcfile options\n");
- exit(1);
- }
- buf[0] = '\0';
- }
- fclose(rc);
- free(buf);
- }
- pwlast = 0;
- enclast = 0;
- for (i=1; i < argc; i++) {
- argv2[argc2++] = strdup(argv[i]);
-
- if (pwlast || !strcmp("-passwd", argv[i])
- || !strcmp("-viewpasswd", argv[i])) {
- char *p = argv[i];
- if (pwlast) {
- pwlast = 0;
- } else {
- pwlast = 1;
- }
- strzero(p);
- }
- if (enclast || !strcmp("-enc", argv[i])) {
- char *q, *p = argv[i];
- if (enclast) {
- enclast = 0;
- } else {
- enclast = 1;
- }
- q = strstr(p, "pw=");
- if (q) {
- strzero(q);
- }
- }
- if (argc2 >= argmax) {
- fprintf(stderr, "too many rcfile options\n");
- exit(1);
- }
- }
-}
-
-static void immediate_switch_user(int argc, char* argv[]) {
- int i, bequiet = 0;
- for (i=1; i < argc; i++) {
- if (strcmp(argv[i], "-inetd")) {
- bequiet = 1;
- }
- if (strcmp(argv[i], "-quiet")) {
- bequiet = 1;
- }
- if (strcmp(argv[i], "-q")) {
- bequiet = 1;
- }
- }
- for (i=1; i < argc; i++) {
- char *u, *q;
-
- if (strcmp(argv[i], "-users")) {
- continue;
- }
- if (i == argc - 1) {
- fprintf(stderr, "not enough arguments for: -users\n");
- exit(1);
- }
- if (*(argv[i+1]) != '=') {
- break;
- }
-
- /* wants an immediate switch: =bob */
- u = strdup(argv[i+1]);
- *u = '+';
- q = strchr(u, '.');
- if (q) {
- user2group = (char **) malloc(2*sizeof(char *));
- user2group[0] = strdup(u+1);
- user2group[1] = NULL;
- *q = '\0';
- }
- if (strstr(u, "+guess") == u) {
- fprintf(stderr, "invalid user: %s\n", u+1);
- exit(1);
- }
- if (!switch_user(u, 0)) {
- fprintf(stderr, "Could not switch to user: %s\n", u+1);
- exit(1);
- } else {
- if (!bequiet) {
- fprintf(stderr, "Switched to user: %s\n", u+1);
- }
- started_as_root = 2;
- }
- free(u);
- break;
- }
-}
-
-static void quick_pw(char *str) {
- char *p, *q;
- char tmp[1024];
- int db = 0;
-
- if (db) fprintf(stderr, "quick_pw: %s\n", str);
-
- if (! str || str[0] == '\0') {
- exit(2);
- }
- if (str[0] != '%') {
- exit(2);
- }
- /*
- * "%-" or "%stdin" means read one line from stdin.
- *
- * "%env" means it is in $UNIXPW env var.
- *
- * starting "%/" or "%." means read the first line from that file.
- *
- * "%%" or "%" means prompt user.
- *
- * otherwise: %user:pass
- */
- if (!strcmp(str, "%-") || !strcmp(str, "%stdin")) {
- if(fgets(tmp, 1024, stdin) == NULL) {
- exit(2);
- }
- q = strdup(tmp);
- } else if (!strcmp(str, "%env")) {
- if (getenv("UNIXPW") == NULL) {
- exit(2);
- }
- q = strdup(getenv("UNIXPW"));
- } else if (!strcmp(str, "%%") || !strcmp(str, "%")) {
- char *t, inp[1024];
- fprintf(stdout, "username: ");
- if(fgets(tmp, 128, stdin) == NULL) {
- exit(2);
- }
- strcpy(inp, tmp);
- t = strchr(inp, '\n');
- if (t) {
- *t = ':';
- } else {
- strcat(inp, ":");
-
- }
- fprintf(stdout, "password: ");
- /* test mode: no_external_cmds does not apply */
- system("stty -echo");
- if(fgets(tmp, 128, stdin) == NULL) {
- fprintf(stdout, "\n");
- system("stty echo");
- exit(2);
- }
- system("stty echo");
- fprintf(stdout, "\n");
- strcat(inp, tmp);
- q = strdup(inp);
- } else if (str[1] == '/' || str[1] == '.') {
- FILE *in = fopen(str+1, "r");
- if (in == NULL) {
- exit(2);
- }
- if(fgets(tmp, 1024, in) == NULL) {
- exit(2);
- }
- fclose(in);
- q = strdup(tmp);
- } else {
- q = strdup(str+1);
- }
- p = (char *) malloc(strlen(q) + 10);
- strcpy(p, q);
- if (strchr(p, '\n') == NULL) {
- strcat(p, "\n");
- }
-
- if ((q = strchr(p, ':')) == NULL) {
- exit(2);
- }
- *q = '\0';
- if (db) fprintf(stderr, "'%s' '%s'\n", p, q+1);
- if (unixpw_cmd) {
- if (cmd_verify(p, q+1)) {
- fprintf(stdout, "Y %s\n", p);
- exit(0);
- } else {
- fprintf(stdout, "N %s\n", p);
- exit(1);
- }
- } else if (unixpw_nis) {
- if (crypt_verify(p, q+1)) {
- fprintf(stdout, "Y %s\n", p);
- exit(0);
- } else {
- fprintf(stdout, "N %s\n", p);
- exit(1);
- }
- } else {
- char *ucmd = getenv("UNIXPW_CMD");
- if (su_verify(p, q+1, ucmd, NULL, NULL, 1)) {
- fprintf(stdout, "Y %s\n", p);
- exit(0);
- } else {
- fprintf(stdout, "N %s\n", p);
- exit(1);
- }
- }
- /* NOTREACHED */
- exit(2);
-}
-
-static void print_settings(int try_http, int bg, char *gui_str) {
-
- fprintf(stderr, "\n");
- fprintf(stderr, "Settings:\n");
- fprintf(stderr, " display: %s\n", use_dpy ? use_dpy
- : "null");
-#if SMALL_FOOTPRINT < 2
- fprintf(stderr, " authfile: %s\n", auth_file ? auth_file
- : "null");
- fprintf(stderr, " subwin: 0x%lx\n", subwin);
- fprintf(stderr, " -sid mode: %d\n", rootshift);
- fprintf(stderr, " clip: %s\n", clip_str ? clip_str
- : "null");
- fprintf(stderr, " flashcmap: %d\n", flash_cmap);
- fprintf(stderr, " shiftcmap: %d\n", shift_cmap);
- fprintf(stderr, " force_idx: %d\n", force_indexed_color);
- fprintf(stderr, " cmap8to24: %d\n", cmap8to24);
- fprintf(stderr, " 8to24_opts: %s\n", cmap8to24_str ? cmap8to24_str
- : "null");
- fprintf(stderr, " 24to32: %d\n", xform24to32);
- fprintf(stderr, " visual: %s\n", visual_str ? visual_str
- : "null");
- fprintf(stderr, " overlay: %d\n", overlay);
- fprintf(stderr, " ovl_cursor: %d\n", overlay_cursor);
- fprintf(stderr, " scaling: %d %.4f %.4f\n", scaling, scale_fac_x, scale_fac_y);
- fprintf(stderr, " viewonly: %d\n", view_only);
- fprintf(stderr, " shared: %d\n", shared);
- fprintf(stderr, " conn_once: %d\n", connect_once);
- fprintf(stderr, " timeout: %d\n", first_conn_timeout);
- fprintf(stderr, " ping: %d\n", ping_interval);
- fprintf(stderr, " inetd: %d\n", inetd);
- fprintf(stderr, " tightfilexfer: %d\n", tightfilexfer);
- fprintf(stderr, " http: %d\n", try_http);
- fprintf(stderr, " connect: %s\n", client_connect
- ? client_connect : "null");
- fprintf(stderr, " connectfile %s\n", client_connect_file
- ? client_connect_file : "null");
- fprintf(stderr, " vnc_conn: %d\n", vnc_connect);
- fprintf(stderr, " allow: %s\n", allow_list ? allow_list
- : "null");
- fprintf(stderr, " input: %s\n", allowed_input_str
- ? allowed_input_str : "null");
- fprintf(stderr, " passfile: %s\n", passwdfile ? passwdfile
- : "null");
- fprintf(stderr, " unixpw: %d\n", unixpw);
- fprintf(stderr, " unixpw_lst: %s\n", unixpw_list ? unixpw_list:"null");
- fprintf(stderr, " ssl: %s\n", openssl_pem ? openssl_pem:"null");
- fprintf(stderr, " ssldir: %s\n", ssl_certs_dir ? ssl_certs_dir:"null");
- fprintf(stderr, " ssltimeout %d\n", ssl_timeout_secs);
- fprintf(stderr, " sslverify: %s\n", ssl_verify ? ssl_verify:"null");
- fprintf(stderr, " stunnel: %d\n", use_stunnel);
- fprintf(stderr, " accept: %s\n", accept_cmd ? accept_cmd
- : "null");
- fprintf(stderr, " accept: %s\n", afteraccept_cmd ? afteraccept_cmd
- : "null");
- fprintf(stderr, " gone: %s\n", gone_cmd ? gone_cmd
- : "null");
- fprintf(stderr, " users: %s\n", users_list ? users_list
- : "null");
- fprintf(stderr, " using_shm: %d\n", using_shm);
- fprintf(stderr, " flipbytes: %d\n", flip_byte_order);
- fprintf(stderr, " onetile: %d\n", single_copytile);
- fprintf(stderr, " solid: %s\n", solid_str
- ? solid_str : "null");
- fprintf(stderr, " blackout: %s\n", blackout_str
- ? blackout_str : "null");
- fprintf(stderr, " xinerama: %d\n", xinerama);
- fprintf(stderr, " xtrap: %d\n", xtrap_input);
- fprintf(stderr, " xrandr: %d\n", xrandr);
- fprintf(stderr, " xrandrmode: %s\n", xrandr_mode ? xrandr_mode
- : "null");
- fprintf(stderr, " padgeom: %s\n", pad_geometry
- ? pad_geometry : "null");
- fprintf(stderr, " logfile: %s\n", logfile ? logfile
- : "null");
- fprintf(stderr, " logappend: %d\n", logfile_append);
- fprintf(stderr, " flag: %s\n", flagfile ? flagfile
- : "null");
- fprintf(stderr, " rm_flag: %s\n", rm_flagfile ? rm_flagfile
- : "null");
- fprintf(stderr, " rc_file: \"%s\"\n", rc_rcfile ? rc_rcfile
- : "null");
- fprintf(stderr, " norc: %d\n", rc_norc);
- fprintf(stderr, " dbg: %d\n", crash_debug);
- fprintf(stderr, " bg: %d\n", bg);
- fprintf(stderr, " mod_tweak: %d\n", use_modifier_tweak);
- fprintf(stderr, " isolevel3: %d\n", use_iso_level3);
- fprintf(stderr, " xkb: %d\n", use_xkb_modtweak);
- fprintf(stderr, " skipkeys: %s\n",
- skip_keycodes ? skip_keycodes : "null");
- fprintf(stderr, " sloppykeys: %d\n", sloppy_keys);
- fprintf(stderr, " skip_dups: %d\n", skip_duplicate_key_events);
- fprintf(stderr, " addkeysyms: %d\n", add_keysyms);
- fprintf(stderr, " xkbcompat: %d\n", xkbcompat);
- fprintf(stderr, " clearmods: %d\n", clear_mods);
- fprintf(stderr, " remap: %s\n", remap_file ? remap_file
- : "null");
- fprintf(stderr, " norepeat: %d\n", no_autorepeat);
- fprintf(stderr, " norepeatcnt:%d\n", no_repeat_countdown);
- fprintf(stderr, " nofb: %d\n", nofb);
- fprintf(stderr, " watchbell: %d\n", watch_bell);
- fprintf(stderr, " watchsel: %d\n", watch_selection);
- fprintf(stderr, " watchprim: %d\n", watch_primary);
- fprintf(stderr, " seldir: %s\n", sel_direction ?
- sel_direction : "null");
- fprintf(stderr, " cursor: %d\n", show_cursor);
- fprintf(stderr, " multicurs: %d\n", show_multiple_cursors);
- fprintf(stderr, " curs_mode: %s\n", multiple_cursors_mode
- ? multiple_cursors_mode : "null");
- fprintf(stderr, " arrow: %d\n", alt_arrow);
- fprintf(stderr, " xfixes: %d\n", use_xfixes);
- fprintf(stderr, " alphacut: %d\n", alpha_threshold);
- fprintf(stderr, " alphafrac: %.2f\n", alpha_frac);
- fprintf(stderr, " alpharemove:%d\n", alpha_remove);
- fprintf(stderr, " alphablend: %d\n", alpha_blend);
- fprintf(stderr, " cursorshape:%d\n", cursor_shape_updates);
- fprintf(stderr, " cursorpos: %d\n", cursor_pos_updates);
- fprintf(stderr, " xwarpptr: %d\n", use_xwarppointer);
- fprintf(stderr, " alwaysinj: %d\n", always_inject);
- fprintf(stderr, " buttonmap: %s\n", pointer_remap
- ? pointer_remap : "null");
- fprintf(stderr, " dragging: %d\n", show_dragging);
- fprintf(stderr, " ncache: %d\n", ncache);
- fprintf(stderr, " wireframe: %s\n", wireframe_str ?
- wireframe_str : WIREFRAME_PARMS);
- fprintf(stderr, " wirecopy: %s\n", wireframe_copyrect ?
- wireframe_copyrect : wireframe_copyrect_default);
- fprintf(stderr, " scrollcopy: %s\n", scroll_copyrect ?
- scroll_copyrect : scroll_copyrect_default);
- fprintf(stderr, " scr_area: %d\n", scrollcopyrect_min_area);
- fprintf(stderr, " scr_skip: %s\n", scroll_skip_str ?
- scroll_skip_str : scroll_skip_str0);
- fprintf(stderr, " scr_inc: %s\n", scroll_good_str ?
- scroll_good_str : scroll_good_str0);
- fprintf(stderr, " scr_keys: %s\n", scroll_key_list_str ?
- scroll_key_list_str : "null");
- fprintf(stderr, " scr_term: %s\n", scroll_term_str ?
- scroll_term_str : "null");
- fprintf(stderr, " scr_keyrep: %s\n", max_keyrepeat_str ?
- max_keyrepeat_str : "null");
- fprintf(stderr, " scr_parms: %s\n", scroll_copyrect_str ?
- scroll_copyrect_str : SCROLL_COPYRECT_PARMS);
- fprintf(stderr, " fixscreen: %s\n", screen_fixup_str ?
- screen_fixup_str : "null");
- fprintf(stderr, " noxrecord: %d\n", noxrecord);
- fprintf(stderr, " grabbuster: %d\n", grab_buster);
- fprintf(stderr, " ptr_mode: %d\n", pointer_mode);
- fprintf(stderr, " inputskip: %d\n", ui_skip);
- fprintf(stderr, " speeds: %s\n", speeds_str
- ? speeds_str : "null");
- fprintf(stderr, " wmdt: %s\n", wmdt_str
- ? wmdt_str : "null");
- fprintf(stderr, " debug_ptr: %d\n", debug_pointer);
- fprintf(stderr, " debug_key: %d\n", debug_keyboard);
- fprintf(stderr, " defer: %d\n", defer_update);
- fprintf(stderr, " waitms: %d\n", waitms);
- fprintf(stderr, " wait_ui: %.2f\n", wait_ui);
- fprintf(stderr, " nowait_bog: %d\n", !wait_bog);
- fprintf(stderr, " slow_fb: %.2f\n", slow_fb);
- fprintf(stderr, " xrefresh: %.2f\n", xrefresh);
- fprintf(stderr, " readtimeout: %d\n", rfbMaxClientWait/1000);
- fprintf(stderr, " take_naps: %d\n", take_naps);
- fprintf(stderr, " sb: %d\n", screen_blank);
- fprintf(stderr, " fbpm: %d\n", !watch_fbpm);
- fprintf(stderr, " dpms: %d\n", !watch_dpms);
- fprintf(stderr, " xdamage: %d\n", use_xdamage);
- fprintf(stderr, " xd_area: %d\n", xdamage_max_area);
- fprintf(stderr, " xd_mem: %.3f\n", xdamage_memory);
- fprintf(stderr, " sigpipe: %s\n", sigpipe
- ? sigpipe : "null");
- fprintf(stderr, " threads: %d\n", use_threads);
- fprintf(stderr, " fs_frac: %.2f\n", fs_frac);
- fprintf(stderr, " gaps_fill: %d\n", gaps_fill);
- fprintf(stderr, " grow_fill: %d\n", grow_fill);
- fprintf(stderr, " tile_fuzz: %d\n", tile_fuzz);
- fprintf(stderr, " snapfb: %d\n", use_snapfb);
- fprintf(stderr, " rawfb: %s\n", raw_fb_str
- ? raw_fb_str : "null");
- fprintf(stderr, " pipeinput: %s\n", pipeinput_str
- ? pipeinput_str : "null");
- fprintf(stderr, " gui: %d\n", launch_gui);
- fprintf(stderr, " gui_mode: %s\n", gui_str
- ? gui_str : "null");
- fprintf(stderr, " noremote: %d\n", !accept_remote_cmds);
- fprintf(stderr, " unsafe: %d\n", !safe_remote_only);
- fprintf(stderr, " privremote: %d\n", priv_remote);
- fprintf(stderr, " safer: %d\n", more_safe);
- fprintf(stderr, " nocmds: %d\n", no_external_cmds);
- fprintf(stderr, " deny_all: %d\n", deny_all);
- fprintf(stderr, " pid: %d\n", getpid());
- fprintf(stderr, "\n");
-#endif
-}
-
-
-static void check_loop_mode(int argc, char* argv[], int force) {
- int i;
- int loop_mode = 0, loop_sleep = 2000, loop_max = 0;
-
- if (force) {
- loop_mode = 1;
- }
- for (i=1; i < argc; i++) {
- char *p = argv[i];
- if (strstr(p, "--") == p) {
- p++;
- }
- if (strstr(p, "-loop") == p) {
- char *q;
- loop_mode = 1;
- if ((q = strchr(p, ',')) != NULL) {
- loop_max = atoi(q+1);
- *q = '\0';
- }
- if (strstr(p, "-loopbg") == p) {
- set_env("X11VNC_LOOP_MODE_BG", "1");
- loop_sleep = 500;
- }
-
- q = strpbrk(p, "0123456789");
- if (q) {
- loop_sleep = atoi(q);
- if (loop_sleep <= 0) {
- loop_sleep = 20;
- }
- }
- }
- }
- if (loop_mode && getenv("X11VNC_LOOP_MODE") == NULL) {
-#if LIBVNCSERVER_HAVE_FORK
- char **argv2;
- int k, i = 1;
-
- set_env("X11VNC_LOOP_MODE", "1");
- argv2 = (char **) malloc((argc+1)*sizeof(char *));
-
- for (k=0; k < argc+1; k++) {
- argv2[k] = NULL;
- if (k < argc) {
- argv2[k] = argv[k];
- }
- }
- while (1) {
- int status;
- pid_t p;
- fprintf(stderr, "\n --- x11vnc loop: %d ---\n\n", i++);
- fflush(stderr);
- usleep(500 * 1000);
- if ((p = fork()) > 0) {
- fprintf(stderr, " --- x11vnc loop: waiting "
- "for: %d\n\n", p);
- wait(&status);
- } else if (p == -1) {
- fprintf(stderr, "could not fork\n");
- perror("fork");
- exit(1);
- } else {
- /* loop mode: no_external_cmds does not apply */
- execvp(argv[0], argv2);
- exit(1);
- }
-
- if (loop_max > 0 && i > loop_max) {
- fprintf(stderr, "\n --- x11vnc loop: did %d"
- " done. ---\n\n", loop_max);
- break;
- }
-
- fprintf(stderr, "\n --- x11vnc loop: sleeping %d ms "
- "---\n\n", loop_sleep);
- usleep(loop_sleep * 1000);
- }
- exit(0);
-#else
- fprintf(stderr, "fork unavailable, cannot do -loop mode\n");
- exit(1);
-#endif
- }
-}
-
-extern int appshare_main(int argc, char* argv[]);
-
-static void check_appshare_mode(int argc, char* argv[]) {
- int i;
-
- for (i=1; i < argc; i++) {
- char *p = argv[i];
- if (strstr(p, "--") == p) {
- p++;
- }
- if (strstr(p, "-appshare") == p) {
- appshare_main(argc, argv);
- exit(0);
- }
- }
-}
-
-static void store_homedir_passwd(char *file) {
- char str1[32], str2[32], *p, *h, *f;
- struct stat sbuf;
-
- str1[0] = '\0';
- str2[0] = '\0';
-
- /* storepasswd */
- if (no_external_cmds || !cmd_ok("storepasswd")) {
- fprintf(stderr, "-nocmds cannot be used with -storepasswd\n");
- exit(1);
- }
-
- fprintf(stderr, "Enter VNC password: ");
- system("stty -echo");
- if (fgets(str1, 32, stdin) == NULL) {
- perror("fgets");
- system("stty echo");
- exit(1);
- }
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Verify password: ");
- if (fgets(str2, 32, stdin) == NULL) {
- perror("fgets");
- system("stty echo");
- exit(1);
- }
- fprintf(stderr, "\n");
- system("stty echo");
-
- if ((p = strchr(str1, '\n')) != NULL) {
- *p = '\0';
- }
- if ((p = strchr(str2, '\n')) != NULL) {
- *p = '\0';
- }
- if (strcmp(str1, str2)) {
- fprintf(stderr, "** passwords differ.\n");
- exit(1);
- }
- if (str1[0] == '\0') {
- fprintf(stderr, "** no password supplied.\n");
- exit(1);
- }
-
- if (file != NULL) {
- f = file;
- } else {
-
- h = getenv("HOME");
- if (! h) {
- fprintf(stderr, "** $HOME not set.\n");
- exit(1);
- }
-
- f = (char *) malloc(strlen(h) + strlen("/.vnc/passwd") + 1);
- sprintf(f, "%s/.vnc", h);
-
- if (stat(f, &sbuf) != 0) {
- if (mkdir(f, 0755) != 0) {
- fprintf(stderr, "** could not create directory %s\n", f);
- perror("mkdir");
- exit(1);
- }
- } else if (! S_ISDIR(sbuf.st_mode)) {
- fprintf(stderr, "** not a directory %s\n", f);
- exit(1);
- }
-
- sprintf(f, "%s/.vnc/passwd", h);
- }
- fprintf(stderr, "Write password to %s? [y]/n ", f);
-
- if (fgets(str2, 32, stdin) == NULL) {
- perror("fgets");
- exit(1);
- }
- if (str2[0] == 'n' || str2[0] == 'N') {
- fprintf(stderr, "not creating password.\n");
- exit(1);
- }
-
- if (rfbEncryptAndStorePasswd(str1, f) != 0) {
- fprintf(stderr, "** error creating password: %s\n", f);
- perror("storepasswd");
- exit(1);
- }
- if (stat(f, &sbuf) != 0) {
- fprintf(stderr, "** error creating password: %s\n", f);
- perror("stat");
- exit(1);
- }
- fprintf(stdout, "Password written to: %s\n", f);
- exit(0);
-}
-
-void ncache_beta_tester_message(void) {
-
-char msg[] =
-"\n"
-"******************************************************************************\n"
-"\n"
-"Hello! Exciting News!!\n"
-"\n"
-"You have been selected at random to beta-test the x11vnc '-ncache' VNC\n"
-"client-side pixel caching feature!\n"
-"\n"
-"This scheme stores pixel data offscreen on the VNC viewer side for faster\n"
-"retrieval. It should work with any VNC viewer.\n"
-"\n"
-"This method requires much testing and so we hope you will try it out and\n"
-"perhaps even report back your observations. However, if you do not want\n"
-"to test or use the feature, run x11vnc like this:\n"
-"\n"
-" x11vnc -noncache ...\n"
-"\n"
-"Your current setting is: -ncache %d\n"
-"\n"
-"The feature needs additional testing because we want to have x11vnc\n"
-"performance enhancements on by default. Otherwise, only a relative few\n"
-"would notice and use the -ncache option (e.g. the wireframe and scroll\n"
-"detection features are on by default). A couple things to note:\n"
-"\n"
-" 1) It uses a large amount of RAM (on both viewer and server sides)\n"
-"\n"
-" 2) You can actually see the cached pixel data if you scroll down\n"
-" to it in your viewer; adjust your viewer's size to hide it.\n"
-"\n"
-"More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching\n"
-"\n"
-"waiting for connections:\n"
-;
-
-char msg2[] =
-"\n"
-"******************************************************************************\n"
-"Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?\n"
-"\n"
-"The scheme stores pixel data offscreen on the VNC viewer side for faster\n"
-"retrieval. It should work with any VNC viewer. Try it by running:\n"
-"\n"
-" x11vnc -ncache 10 ...\n"
-"\n"
-"One can also add -ncache_cr for smooth 'copyrect' window motion.\n"
-"More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching\n"
-"\n"
-;
-
- if (raw_fb_str && !macosx_console) {
- return;
- }
- if (quiet) {
- return;
- }
- if (remote_direct) {
- return;
- }
- if (nofb) {
- return;
- }
-#ifdef NO_NCACHE
- return;
-#endif
-
- if (ncache == 0) {
- fprintf(stderr, "%s", msg2);
- ncache0 = ncache = 0;
- } else {
- fprintf(stderr, msg, ncache);
- }
-}
-
-#define SHOW_NO_PASSWORD_WARNING \
- (!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list) \
- && !query_cmd && !remote_cmd && !unixpw && !got_gui_pw \
- && ! ssl_verify && !inetd && !terminal_services_daemon)
-
-static void do_sleepin(char *sleep) {
- int n1, n2, nt;
- double f1, f2, ft;
-
- if (strchr(sleep, '-')) {
- double s = atof(strchr(sleep, '-')+1);
- if (sscanf(sleep, "%d-%d", &n1, &n2) == 2) {
- if (n1 > n2) {
- nt = n1;
- n1 = n2;
- n2 = nt;
- }
- s = n1 + rfac() * (n2 - n1);
- } else if (sscanf(sleep, "%lf-%lf", &f1, &f2) == 2) {
- if (f1 > f2) {
- ft = f1;
- f1 = f2;
- f2 = ft;
- }
- s = f1 + rfac() * (f2 - f1);
- }
- if (getenv("DEBUG_SLEEPIN")) fprintf(stderr, "sleepin: %f secs\n", s);
- usleep( (int) (1000*1000*s) );
- } else {
- n1 = atoi(sleep);
- if (getenv("DEBUG_SLEEPIN")) fprintf(stderr, "sleepin: %d secs\n", n1);
- if (n1 > 0) {
- usleep(1000*1000*n1);
- }
- }
-}
-
-static void check_guess_auth_file(void) {
- if (!strcasecmp(auth_file, "guess")) {
- char line[4096], *cmd, *q, *disp = use_dpy ? use_dpy: "";
- FILE *p;
- int n;
- if (!program_name) {
- rfbLog("-auth guess: no program_name found.\n");
- clean_up_exit(1);
- }
- if (strpbrk(program_name, " \t\r\n")) {
- rfbLog("-auth guess: whitespace in program_name '%s'\n", program_name);
- clean_up_exit(1);
- }
- if (no_external_cmds || !cmd_ok("findauth")) {
- rfbLog("-auth guess: cannot run external commands in -nocmds mode:\n");
- clean_up_exit(1);
- }
-
- cmd = (char *)malloc(100 + strlen(program_name) + strlen(disp));
- sprintf(cmd, "%s -findauth %s -env _D_XDM=1", program_name, disp);
- p = popen(cmd, "r");
- if (!p) {
- rfbLog("-auth guess: could not run cmd '%s'\n", cmd);
- clean_up_exit(1);
- }
- memset(line, 0, sizeof(line));
- n = fread(line, 1, sizeof(line), p);
- pclose(p);
- q = strrchr(line, '\n');
- if (q) *q = '\0';
- if (!strcmp(disp, "")) {
- disp = getenv("DISPLAY");
- if (!disp) {
- disp = "unset";
- }
- }
- if (strstr(line, "XAUTHORITY=") != line && !getenv("FD_XDM")) {
- if (use_dpy == NULL || strstr(use_dpy, "cmd=FIND") == NULL) {
- if (getuid() == 0 || geteuid() == 0) {
- char *q = strstr(cmd, "_D_XDM=1");
- if (q) {
- *q = 'F';
- rfbLog("-auth guess: failed for display='%s'\n", disp);
- rfbLog("-auth guess: since we are root, retrying with FD_XDM=1\n");
- p = popen(cmd, "r");
- if (!p) {
- rfbLog("-auth guess: could not run cmd '%s'\n", cmd);
- clean_up_exit(1);
- }
- memset(line, 0, sizeof(line));
- n = fread(line, 1, sizeof(line), p);
- pclose(p);
- q = strrchr(line, '\n');
- if (q) *q = '\0';
- }
- }
- }
- }
- if (!strcmp(line, "")) {
- rfbLog("-auth guess: failed for display='%s'\n", disp);
- clean_up_exit(1);
- } else if (strstr(line, "XAUTHORITY=") != line) {
- rfbLog("-auth guess: failed. '%s' for display='%s'\n", line, disp);
- clean_up_exit(1);
- } else if (!strcmp(line, "XAUTHORITY=")) {
- rfbLog("-auth guess: using default XAUTHORITY for display='%s'\n", disp);
- q = getenv("XAUTHORITY");
- if (q) {
- *(q-2) = '_'; /* yow */
- }
- auth_file = NULL;
- } else {
- rfbLog("-auth guess: using '%s' for disp='%s'\n", line, disp);
- auth_file = strdup(line + strlen("XAUTHORITY="));
- }
- }
-}
-
-extern int is_decimal(char *);
-
-int main(int argc, char* argv[]) {
-
- int i, len, tmpi;
- int ev, er, maj, min;
- char *arg;
- int remote_sync = 0;
- char *remote_cmd = NULL;
- char *query_cmd = NULL;
- int query_retries = 0;
- double query_delay = 0.5;
- char *query_match = NULL;
- char *gui_str = NULL;
- int got_gui_pw = 0;
- int pw_loc = -1, got_passwd = 0, got_rfbauth = 0, nopw = NOPW;
- int got_viewpasswd = 0, got_localhost = 0, got_passwdfile = 0;
- int vpw_loc = -1;
- int dt = 0, bg = 0;
- int got_rfbwait = 0;
- int got_httpdir = 0, try_http = 0;
- int orig_use_xdamage = use_xdamage;
- int http_oneport_msg = 0;
- XImage *fb0 = NULL;
- int ncache_msg = 0;
- char *got_rfbport_str = NULL;
- int got_rfbport_pos = -1;
- int got_tls = 0;
- int got_inetd = 0;
- int got_noxrandr = 0;
-
- /* used to pass args we do not know about to rfbGetScreen(): */
- int argc_vnc_max = 1024;
- int argc_vnc = 1; char *argv_vnc[2048];
-
- /* check for -loop mode: */
- check_loop_mode(argc, argv, 0);
-
- /* check for -appshare mode: */
- check_appshare_mode(argc, argv);
-
- dtime0(&x11vnc_start);
-
- for (i=1; i < argc; i++) {
- if (!strcmp(argv[i], "-inetd")) {
- got_inetd = 1;
- }
- }
-
- if (!getuid() || !geteuid()) {
- started_as_root = 1;
- if (0 && !got_inetd) {
- rfbLog("getuid: %d geteuid: %d\n", getuid(), geteuid());
- }
-
- /* check for '-users =bob' */
- immediate_switch_user(argc, argv);
- }
-
- for (i=0; i < 2048; i++) {
- argv_vnc[i] = NULL;
- }
-
- argv_vnc[0] = strdup(argv[0]);
- program_name = strdup(argv[0]);
- program_pid = (int) getpid();
-
- solid_default = strdup(solid_default); /* for freeing with -R */
-
- len = 0;
- for (i=1; i < argc; i++) {
- len += strlen(argv[i]) + 4 + 1;
- }
- program_cmdline = (char *) malloc(len+1);
- program_cmdline[0] = '\0';
- for (i=1; i < argc; i++) {
- char *s = argv[i];
- if (program_cmdline[0]) {
- strcat(program_cmdline, " ");
- }
- if (*s == '-') {
- strcat(program_cmdline, s);
- } else {
- strcat(program_cmdline, "{{");
- strcat(program_cmdline, s);
- strcat(program_cmdline, "}}");
- }
- }
-
- for (i=0; i<ICON_MODE_SOCKS; i++) {
- icon_mode_socks[i] = -1;
- }
-
- check_rcfile(argc, argv);
- /* kludge for the new array argv2 set in check_rcfile() */
-# define argc argc2
-# define argv argv2
-
-# define CHECK_ARGC if (i >= argc-1) { \
- fprintf(stderr, "not enough arguments for: %s\n", arg); \
- exit(1); \
- }
-
- /*
- * do a quick check for parameters that apply to "utility"
- * commands, i.e. ones that do not run the server.
- */
- for (i=1; i < argc; i++) {
- arg = argv[i];
- if (strstr(arg, "--") == arg) {
- arg++;
- }
- if (!strcmp(arg, "-ssldir")) {
- CHECK_ARGC
- ssl_certs_dir = strdup(argv[++i]);
- }
- }
-
- /*
- * do a quick check for -env parameters
- */
- for (i=1; i < argc; i++) {
- char *p, *q;
- arg = argv[i];
- if (strstr(arg, "--") == arg) {
- arg++;
- }
- if (!strcmp(arg, "-env")) {
- CHECK_ARGC
- p = strdup(argv[++i]);
- q = strchr(p, '=');
- if (! q) {
- fprintf(stderr, "no -env '=' found: %s\n", p);
- exit(1);
- } else {
- *q = '\0';
- }
- set_env(p, q+1);
- free(p);
- }
- }
-
- for (i=1; i < argc; i++) {
- /* quick-n-dirty --option handling. */
- arg = argv[i];
- if (strstr(arg, "--") == arg) {
- arg++;
- }
-
- if (!strcmp(arg, "-display")) {
- CHECK_ARGC
- use_dpy = strdup(argv[++i]);
- if (strstr(use_dpy, "WAIT")) {
- extern char find_display[];
- extern char create_display[];
- if (strstr(use_dpy, "cmd=FINDDISPLAY-print")) {
- fprintf(stdout, "%s", find_display);
- exit(0);
- }
- if (strstr(use_dpy, "cmd=FINDCREATEDISPLAY-print")) {
- fprintf(stdout, "%s", create_display);
- exit(0);
- }
- }
- continue;
- }
- if (!strcmp(arg, "-reopen")) {
- char *str = getenv("X11VNC_REOPEN_DISPLAY");
- if (str) {
- int rmax = atoi(str);
- if (rmax > 0) {
- set_env("X11VNC_REOPEN_DISPLAY", str);
- }
- } else {
- set_env("X11VNC_REOPEN_DISPLAY", "1");
- }
- continue;
- }
- if (!strcmp(arg, "-find")) {
- use_dpy = strdup("WAIT:cmd=FINDDISPLAY");
- continue;
- }
- if (!strcmp(arg, "-finddpy") || strstr(arg, "-listdpy") == arg) {
- int ic = 0;
- use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run");
- if (argc > i+1) {
- set_env("X11VNC_USER", argv[i+1]);
- fprintf(stdout, "X11VNC_USER=%s\n", getenv("X11VNC_USER"));
- }
- if (strstr(arg, "-listdpy") == arg) {
- set_env("FIND_DISPLAY_ALL", "1");
- }
- wait_for_client(&ic, NULL, 0);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-findauth")) {
- got_findauth = 1;
- if (argc > i+1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- set_env("FINDAUTH_DISPLAY", argv[i+1]);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-create")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb");
- continue;
- }
- if (!strcmp(arg, "-create_xsrv")) {
- CHECK_ARGC
- use_dpy = (char *) malloc(strlen(argv[i+1])+100);
- sprintf(use_dpy, "WAIT:cmd=FINDCREATEDISPLAY-%s", argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xdummy")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
- continue;
- }
- if (!strcmp(arg, "-xdummy_xvfb")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb");
- continue;
- }
- if (!strcmp(arg, "-xvnc")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc");
- continue;
- }
- if (!strcmp(arg, "-xvnc_redirect")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect");
- continue;
- }
- if (!strcmp(arg, "-redirect")) {
- char *q, *t, *t0 = "WAIT:cmd=FINDDISPLAY-vnc_redirect";
- CHECK_ARGC
- t = (char *) malloc(strlen(t0) + strlen(argv[++i]) + 2);
- q = strrchr(argv[i], ':');
- if (q) *q = ' ';
- sprintf(t, "%s=%s", t0, argv[i]);
- use_dpy = t;
- continue;
- }
- if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
- CHECK_ARGC
- auth_file = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-N")) {
- display_N = 1;
- continue;
- }
- if (!strcmp(arg, "-autoport")) {
- CHECK_ARGC
- auto_port = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-reflect")) {
- CHECK_ARGC
- raw_fb_str = (char *) malloc(4 + strlen(argv[i+1]) + 1);
- sprintf(raw_fb_str, "vnc:%s", argv[++i]);
- shared = 1;
- continue;
- }
- if (!strcmp(arg, "-tsd")) {
- CHECK_ARGC
- terminal_services_daemon = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-id") || !strcmp(arg, "-sid")) {
- CHECK_ARGC
- if (!strcmp(arg, "-sid")) {
- rootshift = 1;
- } else {
- rootshift = 0;
- }
- i++;
- if (!strcmp("pick", argv[i])) {
- if (started_as_root) {
- fprintf(stderr, "unsafe: %s pick\n",
- arg);
- exit(1);
- } else if (! pick_windowid(&subwin)) {
- fprintf(stderr, "invalid %s pick\n",
- arg);
- exit(1);
- }
- } else if (! scan_hexdec(argv[i], &subwin)) {
- fprintf(stderr, "invalid %s arg: %s\n", arg,
- argv[i]);
- exit(1);
- }
- continue;
- }
- if (!strcmp(arg, "-waitmapped")) {
- subwin_wait_mapped = 1;
- continue;
- }
- if (!strcmp(arg, "-clip")) {
- CHECK_ARGC
- clip_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-flashcmap")) {
- flash_cmap = 1;
- continue;
- }
- if (!strcmp(arg, "-shiftcmap")) {
- CHECK_ARGC
- shift_cmap = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-notruecolor")) {
- force_indexed_color = 1;
- continue;
- }
- if (!strcmp(arg, "-advertise_truecolor")) {
- advertise_truecolor = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (strstr(s, "reset")) {
- advertise_truecolor_reset = 1;
- }
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-overlay")) {
- overlay = 1;
- continue;
- }
- if (!strcmp(arg, "-overlay_nocursor")) {
- overlay = 1;
- overlay_cursor = 0;
- continue;
- }
- if (!strcmp(arg, "-overlay_yescursor")) {
- overlay = 1;
- overlay_cursor = 2;
- continue;
- }
- if (!strcmp(arg, "-8to24")) {
-#if !SKIP_8TO24
- cmap8to24 = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- cmap8to24_str = strdup(s);
- i++;
- }
- }
-#endif
- continue;
- }
- if (!strcmp(arg, "-24to32")) {
- xform24to32 = 1;
- continue;
- }
- if (!strcmp(arg, "-visual")) {
- CHECK_ARGC
- visual_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scale")) {
- CHECK_ARGC
- scale_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-geometry")) {
- CHECK_ARGC
- scale_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scale_cursor")) {
- CHECK_ARGC
- scale_cursor_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-viewonly")) {
- view_only = 1;
- continue;
- }
- if (!strcmp(arg, "-noviewonly")) {
- view_only = 0;
- got_noviewonly = 1;
- continue;
- }
- if (!strcmp(arg, "-shared")) {
- shared = 1;
- continue;
- }
- if (!strcmp(arg, "-noshared")) {
- shared = 0;
- continue;
- }
- if (!strcmp(arg, "-once")) {
- connect_once = 1;
- got_connect_once = 1;
- continue;
- }
- if (!strcmp(arg, "-many") || !strcmp(arg, "-forever")) {
- connect_once = 0;
- continue;
- }
- if (strstr(arg, "-loop") == arg) {
- ; /* handled above */
- continue;
- }
- if (strstr(arg, "-appshare") == arg) {
- ; /* handled above */
- continue;
- }
- if (strstr(arg, "-freeze_when_obscured") == arg) {
- freeze_when_obscured = 1;
- continue;
- }
- if (!strcmp(arg, "-timeout")) {
- CHECK_ARGC
- first_conn_timeout = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sleepin")) {
- CHECK_ARGC
- do_sleepin(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-users")) {
- CHECK_ARGC
- users_list = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-inetd")) {
- inetd = 1;
- continue;
- }
- if (!strcmp(arg, "-notightfilexfer")) {
- tightfilexfer = 0;
- continue;
- }
- if (!strcmp(arg, "-tightfilexfer")) {
- tightfilexfer = 1;
- continue;
- }
- if (!strcmp(arg, "-http")) {
- try_http = 1;
- continue;
- }
- if (!strcmp(arg, "-http_ssl")) {
- try_http = 1;
- http_ssl = 1;
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-avahi") || !strcmp(arg, "-mdns") || !strcmp(arg, "-zeroconf")) {
- avahi = 1;
- continue;
- }
- if (!strcmp(arg, "-connect") ||
- !strcmp(arg, "-connect_or_exit") ||
- !strcmp(arg, "-coe")) {
- CHECK_ARGC
- if (!strcmp(arg, "-connect_or_exit")) {
- connect_or_exit = 1;
- } else if (!strcmp(arg, "-coe")) {
- connect_or_exit = 1;
- }
- if (strchr(argv[++i], '/') && !strstr(argv[i], "repeater://")) {
- struct stat sb;
- client_connect_file = strdup(argv[i]);
- if (stat(client_connect_file, &sb) != 0) {
- FILE* f = fopen(client_connect_file, "w");
- if (f != NULL) fclose(f);
- }
- } else {
- client_connect = strdup(argv[i]);
- }
- continue;
- }
- if (!strcmp(arg, "-proxy")) {
- CHECK_ARGC
- connect_proxy = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-vncconnect")) {
- vnc_connect = 1;
- continue;
- }
- if (!strcmp(arg, "-novncconnect")) {
- vnc_connect = 0;
- continue;
- }
- if (!strcmp(arg, "-allow")) {
- CHECK_ARGC
- allow_list = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-localhost")) {
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- continue;
- }
- if (!strcmp(arg, "-unixsock")) {
- CHECK_ARGC
- unix_sock = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-listen6")) {
- CHECK_ARGC
-#if X11VNC_IPV6
- listen_str6 = strdup(argv[++i]);
-#else
- ++i;
-#endif
- continue;
- }
- if (!strcmp(arg, "-nolookup")) {
- host_lookup = 0;
- continue;
- }
- if (!strcmp(arg, "-6")) {
-#if X11VNC_IPV6
- ipv6_listen = 1;
- got_ipv6_listen = 1;
-#endif
- continue;
- }
- if (!strcmp(arg, "-no6")) {
-#if X11VNC_IPV6
- ipv6_listen = 0;
- got_ipv6_listen = 0;
-#endif
- continue;
- }
- if (!strcmp(arg, "-noipv6")) {
- noipv6 = 1;
- continue;
- }
- if (!strcmp(arg, "-noipv4")) {
- noipv4 = 1;
- continue;
- }
-
- if (!strcmp(arg, "-input")) {
- CHECK_ARGC
- allowed_input_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-grabkbd")) {
- grab_kbd = 1;
- continue;
- }
- if (!strcmp(arg, "-grabptr")) {
- grab_ptr = 1;
- continue;
- }
- if (!strcmp(arg, "-ungrabboth")) {
- ungrab_both = 1;
- continue;
- }
- if (!strcmp(arg, "-grabalways")) {
- grab_kbd = 1;
- grab_ptr = 1;
- grab_always = 1;
- continue;
- }
-#ifdef ENABLE_GRABLOCAL
- if (!strcmp(arg, "-grablocal")) {
- CHECK_ARGC
- grab_local = atoi(argv[++i]);
- continue;
- }
-#endif
- if (!strcmp(arg, "-viewpasswd")) {
- vpw_loc = i;
- CHECK_ARGC
- viewonly_passwd = strdup(argv[++i]);
- got_viewpasswd = 1;
- continue;
- }
- if (!strcmp(arg, "-passwdfile")) {
- CHECK_ARGC
- passwdfile = strdup(argv[++i]);
- got_passwdfile = 1;
- continue;
- }
- if (!strcmp(arg, "-svc") || !strcmp(arg, "-service")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-svc_xdummy")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-svc_xdummy_xvfb")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-svc_xvnc")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-xdmsvc") || !strcmp(arg, "-xdm_service")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-sshxdmsvc")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp");
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- continue;
- }
- if (!strcmp(arg, "-unixpw_system_greeter")) {
- unixpw_system_greeter = 1;
- continue;
- }
- if (!strcmp(arg, "-unixpw_cmd")
- || !strcmp(arg, "-unixpw_cmd_unsafe")) {
- CHECK_ARGC
- unixpw_cmd = strdup(argv[++i]);
- unixpw = 1;
- if (strstr(arg, "_unsafe")) {
- /* hidden option for testing. */
- set_env("UNIXPW_DISABLE_SSL", "1");
- set_env("UNIXPW_DISABLE_LOCALHOST", "1");
- }
- continue;
- }
- if (strstr(arg, "-unixpw") == arg) {
- unixpw = 1;
- if (strstr(arg, "-unixpw_nis")) {
- unixpw_nis = 1;
- }
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- unixpw_list = strdup(s);
- i++;
- }
- if (s[0] == '%') {
- unixpw_list = NULL;
- quick_pw(s);
- exit(2);
- }
- }
- if (strstr(arg, "_unsafe")) {
- /* hidden option for testing. */
- set_env("UNIXPW_DISABLE_SSL", "1");
- set_env("UNIXPW_DISABLE_LOCALHOST", "1");
- }
- continue;
- }
- if (strstr(arg, "-nounixpw") == arg) {
- unixpw = 0;
- unixpw_nis = 0;
- if (unixpw_list) {
- unixpw_list = NULL;
- }
- if (unixpw_cmd) {
- unixpw_cmd = NULL;
- }
- continue;
- }
- if (!strcmp(arg, "-vencrypt")) {
- char *s;
- CHECK_ARGC
- s = strdup(argv[++i]);
- got_tls++;
- if (strstr(s, "never")) {
- vencrypt_mode = VENCRYPT_NONE;
- } else if (strstr(s, "support")) {
- vencrypt_mode = VENCRYPT_SUPPORT;
- } else if (strstr(s, "only")) {
- vencrypt_mode = VENCRYPT_SOLE;
- } else if (strstr(s, "force")) {
- vencrypt_mode = VENCRYPT_FORCE;
- } else {
- fprintf(stderr, "invalid %s arg: %s\n", arg, s);
- exit(1);
- }
- if (strstr(s, "nodh")) {
- vencrypt_kx = VENCRYPT_NODH;
- } else if (strstr(s, "nox509")) {
- vencrypt_kx = VENCRYPT_NOX509;
- }
- if (strstr(s, "newdh")) {
- create_fresh_dhparams = 1;
- }
- if (strstr(s, "noplain")) {
- vencrypt_enable_plain_login = 0;
- } else if (strstr(s, "plain")) {
- vencrypt_enable_plain_login = 1;
- }
- free(s);
- continue;
- }
- if (!strcmp(arg, "-anontls")) {
- char *s;
- CHECK_ARGC
- s = strdup(argv[++i]);
- got_tls++;
- if (strstr(s, "never")) {
- anontls_mode = ANONTLS_NONE;
- } else if (strstr(s, "support")) {
- anontls_mode = ANONTLS_SUPPORT;
- } else if (strstr(s, "only")) {
- anontls_mode = ANONTLS_SOLE;
- } else if (strstr(s, "force")) {
- anontls_mode = ANONTLS_FORCE;
- } else {
- fprintf(stderr, "invalid %s arg: %s\n", arg, s);
- exit(1);
- }
- if (strstr(s, "newdh")) {
- create_fresh_dhparams = 1;
- }
- free(s);
- continue;
- }
- if (!strcmp(arg, "-sslonly")) {
- vencrypt_mode = VENCRYPT_NONE;
- anontls_mode = ANONTLS_NONE;
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-dhparams")) {
- CHECK_ARGC
- dhparams_file = strdup(argv[++i]);
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-nossl")) {
- use_openssl = 0;
- openssl_pem = NULL;
- got_tls = -1000;
- continue;
- }
- if (!strcmp(arg, "-ssl")) {
- use_openssl = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (!strcmp(s, "ADH")) {
- openssl_pem = strdup("ANON");
- } else if (!strcmp(s, "ANONDH")) {
- openssl_pem = strdup("ANON");
- } else if (!strcmp(s, "TMP")) {
- openssl_pem = NULL;
- } else {
- openssl_pem = strdup(s);
- }
- i++;
- } else {
- openssl_pem = strdup("SAVE");
- }
- } else {
- openssl_pem = strdup("SAVE");
- }
- continue;
- }
- if (!strcmp(arg, "-enc")) {
- use_openssl = 1;
- CHECK_ARGC
- enc_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-http_oneport")) {
- http_oneport_msg = 1;
- use_openssl = 1;
- enc_str = strdup("none");
- continue;
- }
- if (!strcmp(arg, "-ssltimeout")) {
- CHECK_ARGC
- ssl_timeout_secs = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sslnofail")) {
- ssl_no_fail = 1;
- continue;
- }
- if (!strcmp(arg, "-ssldir")) {
- CHECK_ARGC
- ssl_certs_dir = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sslverify")) {
- CHECK_ARGC
- ssl_verify = strdup(argv[++i]);
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-sslCRL")) {
- CHECK_ARGC
- ssl_crl = strdup(argv[++i]);
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-sslGenCA")) {
- char *cdir = NULL;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- cdir = strdup(s);
- i++;
- }
- }
- sslGenCA(cdir);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslGenCert")) {
- char *ty, *nm = NULL;
- if (i >= argc-1) {
- fprintf(stderr, "Must be:\n");
- fprintf(stderr, " x11vnc -sslGenCert server ...\n");
- fprintf(stderr, "or x11vnc -sslGenCert client ...\n");
- exit(1);
- }
- ty = argv[i+1];
- if (strcmp(ty, "server") && strcmp(ty, "client")) {
- fprintf(stderr, "Must be:\n");
- fprintf(stderr, " x11vnc -sslGenCert server ...\n");
- fprintf(stderr, "or x11vnc -sslGenCert client ...\n");
- exit(1);
- }
- if (i < argc-2) {
- nm = argv[i+2];
- }
- sslGenCert(ty, nm);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslEncKey")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- sslEncKey(s, 0);
- }
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslCertInfo")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- sslEncKey(s, 1);
- }
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslDelCert")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- sslEncKey(s, 2);
- }
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslScripts")) {
- sslScripts();
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-stunnel")) {
- use_stunnel = 1;
- got_tls = -1000;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (!strcmp(s, "TMP")) {
- stunnel_pem = NULL;
- } else {
- stunnel_pem = strdup(s);
- }
- i++;
- } else {
- stunnel_pem = strdup("SAVE");
- }
- } else {
- stunnel_pem = strdup("SAVE");
- }
- continue;
- }
- if (!strcmp(arg, "-stunnel3")) {
- use_stunnel = 3;
- got_tls = -1000;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (!strcmp(s, "TMP")) {
- stunnel_pem = NULL;
- } else {
- stunnel_pem = strdup(s);
- }
- i++;
- } else {
- stunnel_pem = strdup("SAVE");
- }
- } else {
- stunnel_pem = strdup("SAVE");
- }
- continue;
- }
- if (!strcmp(arg, "-https")) {
- https_port_num = 0;
- try_http = 1;
- got_tls++;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- https_port_num = atoi(s);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-httpsredir")) {
- https_port_redir = -1;
- got_tls++;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- https_port_redir = atoi(s);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-nopw")) {
- nopw = 1;
- continue;
- }
- if (!strcmp(arg, "-ssh")) {
- CHECK_ARGC
- ssh_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-usepw")) {
- usepw = 1;
- continue;
- }
- if (!strcmp(arg, "-storepasswd")) {
- if (argc == i+1) {
- store_homedir_passwd(NULL);
- exit(0);
- }
- if (argc == i+2) {
- store_homedir_passwd(argv[i+1]);
- exit(0);
- }
- if (argc >= i+4 || rfbEncryptAndStorePasswd(argv[i+1],
- argv[i+2]) != 0) {
- perror("storepasswd");
- fprintf(stderr, "-storepasswd failed for file: %s\n",
- argv[i+2]);
- exit(1);
- } else {
- fprintf(stderr, "stored passwd in file: %s\n",
- argv[i+2]);
- exit(0);
- }
- continue;
- }
- if (!strcmp(arg, "-showrfbauth")) {
- if (argc >= i+2) {
- char *f = argv[i+1];
- char *s = rfbDecryptPasswdFromFile(f);
- if (!s) {
- perror("showrfbauth");
- fprintf(stderr, "rfbDecryptPasswdFromFile failed: %s\n", f);
- exit(1);
- }
- fprintf(stdout, "rfbDecryptPasswdFromFile file: %s\n", f);
- fprintf(stdout, "rfbDecryptPasswdFromFile pass: %s\n", s);
- }
- exit(0);
- }
- if (!strcmp(arg, "-accept")) {
- CHECK_ARGC
- accept_cmd = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-afteraccept")) {
- CHECK_ARGC
- afteraccept_cmd = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-gone")) {
- CHECK_ARGC
- gone_cmd = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-noshm")) {
- using_shm = 0;
- continue;
- }
- if (!strcmp(arg, "-flipbyteorder")) {
- flip_byte_order = 1;
- continue;
- }
- if (!strcmp(arg, "-onetile")) {
- single_copytile = 1;
- continue;
- }
- if (!strcmp(arg, "-solid")) {
- use_solid_bg = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- solid_str = strdup(s);
- i++;
- }
- }
- if (! solid_str) {
- solid_str = strdup(solid_default);
- }
- continue;
- }
- if (!strcmp(arg, "-blackout")) {
- CHECK_ARGC
- blackout_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xinerama")) {
- xinerama = 1;
- continue;
- }
- if (!strcmp(arg, "-noxinerama")) {
- xinerama = 0;
- continue;
- }
- if (!strcmp(arg, "-xtrap")) {
- xtrap_input = 1;
- continue;
- }
- if (!strcmp(arg, "-xrandr")) {
- xrandr = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (known_xrandr_mode(s)) {
- xrandr_mode = strdup(s);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-noxrandr")) {
- xrandr = 0;
- xrandr_maybe = 0;
- got_noxrandr = 1;
- continue;
- }
- if (!strcmp(arg, "-rotate")) {
- CHECK_ARGC
- rotating_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-padgeom")
- || !strcmp(arg, "-padgeometry")) {
- CHECK_ARGC
- pad_geometry = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-o") || !strcmp(arg, "-logfile")) {
- CHECK_ARGC
- logfile_append = 0;
- logfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-oa") || !strcmp(arg, "-logappend")) {
- CHECK_ARGC
- logfile_append = 1;
- logfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-flag")) {
- CHECK_ARGC
- flagfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-rmflag")) {
- CHECK_ARGC
- rm_flagfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-rc")) {
- i++; /* done above */
- continue;
- }
- if (!strcmp(arg, "-norc")) {
- ; /* done above */
- continue;
- }
- if (!strcmp(arg, "-env")) {
- i++; /* done above */
- continue;
- }
- if (!strcmp(arg, "-prog")) {
- CHECK_ARGC
- if (program_name) {
- free(program_name);
- }
- program_name = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) {
- print_help(0);
- continue;
- }
- if (!strcmp(arg, "-?") || !strcmp(arg, "-opts")) {
- print_help(1);
- continue;
- }
- if (!strcmp(arg, "-V") || !strcmp(arg, "-version")) {
- fprintf(stdout, "x11vnc: %s\n", lastmod);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-license") ||
- !strcmp(arg, "-copying") || !strcmp(arg, "-warranty")) {
- print_license();
- continue;
- }
- if (!strcmp(arg, "-dbg")) {
- crash_debug = 1;
- continue;
- }
- if (!strcmp(arg, "-nodbg")) {
- crash_debug = 0;
- continue;
- }
- if (!strcmp(arg, "-q") || !strcmp(arg, "-quiet")) {
- quiet = 1;
- continue;
- }
- if (!strcmp(arg, "-noquiet")) {
- quiet = 0;
- continue;
- }
- if (!strcmp(arg, "-v") || !strcmp(arg, "-verbose")) {
- verbose = 1;
- continue;
- }
- if (!strcmp(arg, "-bg") || !strcmp(arg, "-background")) {
-#if LIBVNCSERVER_HAVE_SETSID
- bg = 1;
- opts_bg = bg;
-#else
- if (!got_inetd) {
- fprintf(stderr, "warning: -bg mode not supported.\n");
- }
-#endif
- continue;
- }
- if (!strcmp(arg, "-modtweak")) {
- use_modifier_tweak = 1;
- continue;
- }
- if (!strcmp(arg, "-nomodtweak")) {
- use_modifier_tweak = 0;
- got_nomodtweak = 1;
- continue;
- }
- if (!strcmp(arg, "-isolevel3")) {
- use_iso_level3 = 1;
- continue;
- }
- if (!strcmp(arg, "-xkb")) {
- use_modifier_tweak = 1;
- use_xkb_modtweak = 1;
- continue;
- }
- if (!strcmp(arg, "-noxkb")) {
- use_xkb_modtweak = 0;
- got_noxkb = 1;
- continue;
- }
- if (!strcmp(arg, "-capslock")) {
- watch_capslock = 1;
- continue;
- }
- if (!strcmp(arg, "-skip_lockkeys")) {
- skip_lockkeys = 1;
- continue;
- }
- if (!strcmp(arg, "-noskip_lockkeys")) {
- skip_lockkeys = 0;
- continue;
- }
- if (!strcmp(arg, "-xkbcompat")) {
- xkbcompat = 1;
- continue;
- }
- if (!strcmp(arg, "-skip_keycodes")) {
- CHECK_ARGC
- skip_keycodes = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sloppy_keys")) {
- sloppy_keys++;
- continue;
- }
- if (!strcmp(arg, "-skip_dups")) {
- skip_duplicate_key_events = 1;
- continue;
- }
- if (!strcmp(arg, "-noskip_dups")) {
- skip_duplicate_key_events = 0;
- continue;
- }
- if (!strcmp(arg, "-add_keysyms")) {
- add_keysyms++;
- continue;
- }
- if (!strcmp(arg, "-noadd_keysyms")) {
- add_keysyms = 0;
- continue;
- }
- if (!strcmp(arg, "-clear_mods")) {
- clear_mods = 1;
- continue;
- }
- if (!strcmp(arg, "-clear_keys")) {
- clear_mods = 2;
- continue;
- }
- if (!strcmp(arg, "-clear_all")) {
- clear_mods = 3;
- continue;
- }
- if (!strcmp(arg, "-remap")) {
- CHECK_ARGC
- remap_file = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-norepeat")) {
- no_autorepeat = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (*s == '-') {
- s++;
- }
- if (isdigit((unsigned char) (*s))) {
- no_repeat_countdown = atoi(argv[++i]);
- }
- }
- continue;
- }
- if (!strcmp(arg, "-repeat")) {
- no_autorepeat = 0;
- continue;
- }
- if (!strcmp(arg, "-nofb")) {
- nofb = 1;
- continue;
- }
- if (!strcmp(arg, "-nobell")) {
- watch_bell = 0;
- sound_bell = 0;
- continue;
- }
- if (!strcmp(arg, "-nosel")) {
- watch_selection = 0;
- watch_primary = 0;
- watch_clipboard = 0;
- continue;
- }
- if (!strcmp(arg, "-noprimary")) {
- watch_primary = 0;
- continue;
- }
- if (!strcmp(arg, "-nosetprimary")) {
- set_primary = 0;
- continue;
- }
- if (!strcmp(arg, "-noclipboard")) {
- watch_clipboard = 0;
- continue;
- }
- if (!strcmp(arg, "-nosetclipboard")) {
- set_clipboard = 0;
- continue;
- }
- if (!strcmp(arg, "-seldir")) {
- CHECK_ARGC
- sel_direction = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-cursor")) {
- show_cursor = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (known_cursors_mode(s)) {
- multiple_cursors_mode = strdup(s);
- i++;
- if (!strcmp(s, "none")) {
- show_cursor = 0;
- }
- }
- }
- continue;
- }
- if (!strcmp(arg, "-nocursor")) {
- multiple_cursors_mode = strdup("none");
- show_cursor = 0;
- continue;
- }
- if (!strcmp(arg, "-cursor_drag")) {
- cursor_drag_changes = 1;
- continue;
- }
- if (!strcmp(arg, "-nocursor_drag")) {
- cursor_drag_changes = 0;
- continue;
- }
- if (!strcmp(arg, "-arrow")) {
- CHECK_ARGC
- alt_arrow = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xfixes")) {
- use_xfixes = 1;
- continue;
- }
- if (!strcmp(arg, "-noxfixes")) {
- use_xfixes = 0;
- continue;
- }
- if (!strcmp(arg, "-alphacut")) {
- CHECK_ARGC
- alpha_threshold = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-alphafrac")) {
- CHECK_ARGC
- alpha_frac = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-alpharemove")) {
- alpha_remove = 1;
- continue;
- }
- if (!strcmp(arg, "-noalphablend")) {
- alpha_blend = 0;
- continue;
- }
- if (!strcmp(arg, "-nocursorshape")) {
- cursor_shape_updates = 0;
- continue;
- }
- if (!strcmp(arg, "-cursorpos")) {
- cursor_pos_updates = 1;
- got_cursorpos = 1;
- continue;
- }
- if (!strcmp(arg, "-nocursorpos")) {
- cursor_pos_updates = 0;
- continue;
- }
- if (!strcmp(arg, "-xwarppointer")) {
- use_xwarppointer = 1;
- continue;
- }
- if (!strcmp(arg, "-noxwarppointer")) {
- use_xwarppointer = 0;
- got_noxwarppointer = 1;
- continue;
- }
- if (!strcmp(arg, "-always_inject")) {
- always_inject = 1;
- continue;
- }
- if (!strcmp(arg, "-buttonmap")) {
- CHECK_ARGC
- pointer_remap = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nodragging")) {
- show_dragging = 0;
- continue;
- }
-#ifndef NO_NCACHE
- if (!strcmp(arg, "-ncache") || !strcmp(arg, "-nc")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- ncache = atoi(s);
- i++;
- } else {
- ncache = ncache_default;
- }
- } else {
- ncache = ncache_default;
- }
- if (ncache % 2 != 0) {
- ncache++;
- }
- continue;
- }
- if (!strcmp(arg, "-noncache") || !strcmp(arg, "-nonc")) {
- ncache = 0;
- continue;
- }
- if (!strcmp(arg, "-ncache_cr") || !strcmp(arg, "-nc_cr")) {
- ncache_copyrect = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_no_moveraise") || !strcmp(arg, "-nc_no_moveraise")) {
- ncache_wf_raises = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_no_dtchange") || !strcmp(arg, "-nc_no_dtchange")) {
- ncache_dt_change = 0;
- continue;
- }
- if (!strcmp(arg, "-ncache_no_rootpixmap") || !strcmp(arg, "-nc_no_rootpixmap")) {
- ncache_xrootpmap = 0;
- continue;
- }
- if (!strcmp(arg, "-ncache_keep_anims") || !strcmp(arg, "-nc_keep_anims")) {
- ncache_keep_anims = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_old_wm") || !strcmp(arg, "-nc_old_wm")) {
- ncache_old_wm = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_pad") || !strcmp(arg, "-nc_pad")) {
- CHECK_ARGC
- ncache_pad = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_ncache")) {
- ncdb++;
- continue;
- }
-#endif
- if (!strcmp(arg, "-wireframe")
- || !strcmp(arg, "-wf")) {
- wireframe = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (*s != '-') {
- wireframe_str = strdup(argv[++i]);
- }
- }
- continue;
- }
- if (!strcmp(arg, "-nowireframe")
- || !strcmp(arg, "-nowf")) {
- wireframe = 0;
- continue;
- }
- if (!strcmp(arg, "-nowireframelocal")
- || !strcmp(arg, "-nowfl")) {
- wireframe_local = 0;
- continue;
- }
- if (!strcmp(arg, "-wirecopyrect")
- || !strcmp(arg, "-wcr")) {
- CHECK_ARGC
- set_wirecopyrect_mode(argv[++i]);
- got_wirecopyrect = 1;
- continue;
- }
- if (!strcmp(arg, "-nowirecopyrect")
- || !strcmp(arg, "-nowcr")) {
- set_wirecopyrect_mode("never");
- continue;
- }
- if (!strcmp(arg, "-debug_wireframe")
- || !strcmp(arg, "-dwf")) {
- debug_wireframe++;
- continue;
- }
- if (!strcmp(arg, "-scrollcopyrect")
- || !strcmp(arg, "-scr")) {
- CHECK_ARGC
- set_scrollcopyrect_mode(argv[++i]);
- got_scrollcopyrect = 1;
- continue;
- }
- if (!strcmp(arg, "-noscrollcopyrect")
- || !strcmp(arg, "-noscr")) {
- set_scrollcopyrect_mode("never");
- continue;
- }
- if (!strcmp(arg, "-scr_area")) {
- int tn;
- CHECK_ARGC
- tn = atoi(argv[++i]);
- if (tn >= 0) {
- scrollcopyrect_min_area = tn;
- }
- continue;
- }
- if (!strcmp(arg, "-scr_skip")) {
- CHECK_ARGC
- scroll_skip_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_inc")) {
- CHECK_ARGC
- scroll_good_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_keys")) {
- CHECK_ARGC
- scroll_key_list_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_term")) {
- CHECK_ARGC
- scroll_term_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_keyrepeat")) {
- CHECK_ARGC
- max_keyrepeat_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_parms")) {
- CHECK_ARGC
- scroll_copyrect_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-fixscreen")) {
- CHECK_ARGC
- screen_fixup_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_scroll")
- || !strcmp(arg, "-ds")) {
- debug_scroll++;
- continue;
- }
- if (!strcmp(arg, "-noxrecord")) {
- noxrecord = 1;
- continue;
- }
- if (!strcmp(arg, "-pointer_mode")
- || !strcmp(arg, "-pm")) {
- char *p, *s;
- CHECK_ARGC
- s = argv[++i];
- if ((p = strchr(s, ':')) != NULL) {
- ui_skip = atoi(p+1);
- if (! ui_skip) ui_skip = 1;
- *p = '\0';
- }
- if (atoi(s) < 1 || atoi(s) > pointer_mode_max) {
- if (!got_inetd) {
- rfbLog("pointer_mode out of range 1-%d: %d\n",
- pointer_mode_max, atoi(s));
- }
- } else {
- pointer_mode = atoi(s);
- got_pointer_mode = pointer_mode;
- }
- continue;
- }
- if (!strcmp(arg, "-input_skip")) {
- CHECK_ARGC
- ui_skip = atoi(argv[++i]);
- if (! ui_skip) ui_skip = 1;
- continue;
- }
- if (!strcmp(arg, "-allinput")) {
- all_input = 1;
- continue;
- }
- if (!strcmp(arg, "-noallinput")) {
- all_input = 0;
- continue;
- }
- if (!strcmp(arg, "-input_eagerly")) {
- handle_events_eagerly = 1;
- continue;
- }
- if (!strcmp(arg, "-noinput_eagerly")) {
- handle_events_eagerly = 0;
- continue;
- }
- if (!strcmp(arg, "-speeds")) {
- CHECK_ARGC
- speeds_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-wmdt")) {
- CHECK_ARGC
- wmdt_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_pointer")
- || !strcmp(arg, "-dp")) {
- debug_pointer++;
- continue;
- }
- if (!strcmp(arg, "-debug_keyboard")
- || !strcmp(arg, "-dk")) {
- debug_keyboard++;
- continue;
- }
- if (!strcmp(arg, "-debug_xdamage")) {
- debug_xdamage++;
- continue;
- }
- if (!strcmp(arg, "-defer")) {
- CHECK_ARGC
- defer_update = atoi(argv[++i]);
- got_defer = 1;
- continue;
- }
- if (!strcmp(arg, "-setdefer")) {
- CHECK_ARGC
- set_defer = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-wait")) {
- CHECK_ARGC
- waitms = atoi(argv[++i]);
- got_waitms = 1;
- continue;
- }
- if (!strcmp(arg, "-extra_fbur")) {
- CHECK_ARGC
- extra_fbur = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-wait_ui")) {
- CHECK_ARGC
- wait_ui = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nowait_bog")) {
- wait_bog = 0;
- continue;
- }
- if (!strcmp(arg, "-slow_fb")) {
- CHECK_ARGC
- slow_fb = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xrefresh")) {
- CHECK_ARGC
- xrefresh = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-readtimeout")) {
- CHECK_ARGC
- rfbMaxClientWait = atoi(argv[++i]) * 1000;
- continue;
- }
- if (!strcmp(arg, "-ping")) {
- CHECK_ARGC
- ping_interval = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nap")) {
- take_naps = 1;
- continue;
- }
- if (!strcmp(arg, "-nonap")) {
- take_naps = 0;
- continue;
- }
- if (!strcmp(arg, "-sb")) {
- CHECK_ARGC
- screen_blank = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nofbpm")) {
- watch_fbpm = 1;
- continue;
- }
- if (!strcmp(arg, "-fbpm")) {
- watch_fbpm = 0;
- continue;
- }
- if (!strcmp(arg, "-nodpms")) {
- watch_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-dpms")) {
- watch_dpms = 0;
- continue;
- }
- if (!strcmp(arg, "-forcedpms")) {
- force_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-clientdpms")) {
- client_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-noserverdpms")) {
- no_ultra_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-noultraext")) {
- no_ultra_ext = 1;
- continue;
- }
- if (!strcmp(arg, "-chatwindow")) {
- chat_window = 1;
- if (argc_vnc + 1 < argc_vnc_max) {
- if (!got_inetd) {
- rfbLog("setting '-rfbversion 3.6' for -chatwindow.\n");
- }
- argv_vnc[argc_vnc++] = strdup("-rfbversion");
- argv_vnc[argc_vnc++] = strdup("3.6");
- }
- continue;
- }
- if (!strcmp(arg, "-xdamage")) {
- use_xdamage++;
- continue;
- }
- if (!strcmp(arg, "-noxdamage")) {
- use_xdamage = 0;
- continue;
- }
- if (!strcmp(arg, "-xd_area")) {
- int tn;
- CHECK_ARGC
- tn = atoi(argv[++i]);
- if (tn >= 0) {
- xdamage_max_area = tn;
- }
- continue;
- }
- if (!strcmp(arg, "-xd_mem")) {
- double f;
- CHECK_ARGC
- f = atof(argv[++i]);
- if (f >= 0.0) {
- xdamage_memory = f;
- }
- continue;
- }
- if (!strcmp(arg, "-sigpipe") || !strcmp(arg, "-sig")) {
- CHECK_ARGC
- if (known_sigpipe_mode(argv[++i])) {
- sigpipe = strdup(argv[i]);
- } else {
- fprintf(stderr, "invalid -sigpipe arg: %s, must"
- " be \"ignore\" or \"exit\"\n", argv[i]);
- exit(1);
- }
- continue;
- }
-#if LIBVNCSERVER_HAVE_LIBPTHREAD
- if (!strcmp(arg, "-threads")) {
-#if defined(X11VNC_THREADED)
- use_threads = 1;
-#else
- if (getenv("X11VNC_THREADED")) {
- use_threads = 1;
- } else if (1) {
- /* we re-enable it due to threaded mode bugfixes. */
- use_threads = 1;
- } else {
- if (!got_inetd) {
- rfbLog("\n");
- rfbLog("The -threads mode is unstable and not tested or maintained.\n");
- rfbLog("It is disabled in the source code. If you really need\n");
- rfbLog("the feature you can reenable it at build time by setting\n");
- rfbLog("-DX11VNC_THREADED in CPPFLAGS. Or set X11VNC_THREADED=1\n");
- rfbLog("in your runtime environment.\n");
- rfbLog("\n");
- usleep(500*1000);
- }
- }
-#endif
- continue;
- }
- if (!strcmp(arg, "-nothreads")) {
- use_threads = 0;
- continue;
- }
-#endif
- if (!strcmp(arg, "-fs")) {
- CHECK_ARGC
- fs_frac = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-gaps")) {
- CHECK_ARGC
- gaps_fill = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-grow")) {
- CHECK_ARGC
- grow_fill = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-fuzz")) {
- CHECK_ARGC
- tile_fuzz = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_tiles")
- || !strcmp(arg, "-dbt")) {
- debug_tiles++;
- continue;
- }
- if (!strcmp(arg, "-debug_grabs")) {
- debug_grabs++;
- continue;
- }
- if (!strcmp(arg, "-debug_sel")) {
- debug_sel++;
- continue;
- }
- if (!strcmp(arg, "-grab_buster")) {
- grab_buster++;
- continue;
- }
- if (!strcmp(arg, "-nograb_buster")) {
- grab_buster = 0;
- continue;
- }
- if (!strcmp(arg, "-snapfb")) {
- use_snapfb = 1;
- continue;
- }
- if (!strcmp(arg, "-rand")) {
- /* equiv. to -nopw -rawfb rand for quick tests */
- raw_fb_str = strdup("rand");
- nopw = 1;
- continue;
- }
- if (!strcmp(arg, "-rawfb")) {
- CHECK_ARGC
- raw_fb_str = strdup(argv[++i]);
- if (strstr(raw_fb_str, "vnc:") == raw_fb_str) {
- shared = 1;
- }
- continue;
- }
- if (!strcmp(arg, "-freqtab")) {
- CHECK_ARGC
- freqtab = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-pipeinput")) {
- CHECK_ARGC
- pipeinput_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-macnodim")) {
- macosx_nodimming = 1;
- continue;
- }
- if (!strcmp(arg, "-macnosleep")) {
- macosx_nosleep = 1;
- continue;
- }
- if (!strcmp(arg, "-macnosaver")) {
- macosx_noscreensaver = 1;
- continue;
- }
- if (!strcmp(arg, "-macnowait")) {
- macosx_wait_for_switch = 0;
- continue;
- }
- if (!strcmp(arg, "-macwheel")) {
- CHECK_ARGC
- macosx_mouse_wheel_speed = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-macnoswap")) {
- macosx_swap23 = 0;
- continue;
- }
- if (!strcmp(arg, "-macnoresize")) {
- macosx_resize = 0;
- continue;
- }
- if (!strcmp(arg, "-maciconanim")) {
- CHECK_ARGC
- macosx_icon_anim_time = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-macmenu")) {
- macosx_ncache_macmenu = 1;
- continue;
- }
- if (!strcmp(arg, "-macuskbd")) {
- macosx_us_kbd = 1;
- continue;
- }
- if (!strcmp(arg, "-macnoopengl")) {
- macosx_no_opengl = 1;
- continue;
- }
- if (!strcmp(arg, "-macnorawfb")) {
- macosx_no_rawfb = 1;
- continue;
- }
- if (!strcmp(arg, "-gui")) {
- launch_gui = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (*s != '-') {
- gui_str = strdup(s);
- if (strstr(gui_str, "setp")) {
- got_gui_pw = 1;
- }
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-remote") || !strcmp(arg, "-R")
- || !strcmp(arg, "-r") || !strcmp(arg, "-remote-control")) {
- char *str;
- CHECK_ARGC
- i++;
- str = argv[i];
- if (*str == '-') {
- /* accidental leading '-' */
- str++;
- }
- if (!strcmp(str, "ping")) {
- query_cmd = strdup(str);
- } else {
- remote_cmd = strdup(str);
- }
- if (remote_cmd && strchr(remote_cmd, ':') == NULL) {
- /* interpret -R -scale 3/4 at least */
- if (i < argc-1 && *(argv[i+1]) != '-') {
- int n;
-
- /* it must be the parameter value */
- i++;
- n = strlen(remote_cmd) + strlen(argv[i]) + 2;
-
- str = (char *) malloc(n);
- sprintf(str, "%s:%s", remote_cmd, argv[i]);
- free(remote_cmd);
- remote_cmd = str;
- }
- }
- if (!getenv("QUERY_VERBOSE")) {
- quiet = 1;
- }
- xkbcompat = 0;
- continue;
- }
- if (!strcmp(arg, "-query") || !strcmp(arg, "-Q")) {
- CHECK_ARGC
- query_cmd = strdup(argv[++i]);
- if (!getenv("QUERY_VERBOSE")) {
- quiet = 1;
- }
- xkbcompat = 0;
- continue;
- }
- if (!strcmp(arg, "-query_retries")) {
- char *s;
- CHECK_ARGC
- s = strdup(argv[++i]);
- /* n[:t][/match] */
- if (strchr(s, '/')) {
- char *q = strchr(s, '/');
- query_match = strdup(q+1);
- *q = '\0';
- }
- if (strchr(s, ':')) {
- char *q = strchr(s, ':');
- query_delay = atof(q+1);
- }
- query_retries = atoi(s);
- free(s);
- continue;
- }
- if (!strcmp(arg, "-QD")) {
- CHECK_ARGC
- query_cmd = strdup(argv[++i]);
- query_default = 1;
- continue;
- }
- if (!strcmp(arg, "-sync")) {
- remote_sync = 1;
- continue;
- }
- if (!strcmp(arg, "-nosync")) {
- remote_sync = 0;
- continue;
- }
- if (!strcmp(arg, "-remote_prefix")) {
- CHECK_ARGC
- remote_prefix = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-noremote")) {
- accept_remote_cmds = 0;
- continue;
- }
- if (!strcmp(arg, "-yesremote")) {
- accept_remote_cmds = 1;
- continue;
- }
- if (!strcmp(arg, "-unsafe")) {
- safe_remote_only = 0;
- continue;
- }
- if (!strcmp(arg, "-privremote")) {
- priv_remote = 1;
- continue;
- }
- if (!strcmp(arg, "-safer")) {
- more_safe = 1;
- continue;
- }
- if (!strcmp(arg, "-nocmds")) {
- no_external_cmds = 1;
- continue;
- }
- if (!strcmp(arg, "-allowedcmds")) {
- CHECK_ARGC
- allowed_external_cmds = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-deny_all")) {
- deny_all = 1;
- continue;
- }
- if (!strcmp(arg, "-httpdir")) {
- CHECK_ARGC
- http_dir = strdup(argv[++i]);
- got_httpdir = 1;
- continue;
- }
- if (1) {
- if (!strcmp(arg, "-desktop") && i < argc-1) {
- dt = 1;
- rfb_desktop_name = strdup(argv[i+1]);
- }
- if (!strcmp(arg, "-passwd")) {
- pw_loc = i;
- got_passwd = 1;
- }
- if (!strcmp(arg, "-rfbauth")) {
- got_rfbauth = 1;
- }
- if (!strcmp(arg, "-rfbwait")) {
- got_rfbwait = 1;
- }
- if (!strcmp(arg, "-deferupdate")) {
- got_deferupdate = 1;
- }
- if (!strcmp(arg, "-rfbport") && i < argc-1) {
- got_rfbport = 1;
- if (!strcasecmp(argv[i+1], "prompt")) {
- ;
- } else if (!is_decimal(argv[i+1])) {
- if (!got_inetd) {
- rfbLog("Invalid -rfbport value: '%s'\n", argv[i+1]);
- rfbLog("setting it to '-1' to induce failure.\n");
- argv[i+1] = strdup("-1");
- }
- }
- got_rfbport_str = strdup(argv[i+1]);
- got_rfbport_pos = argc_vnc+1;
- got_rfbport_val = atoi(argv[i+1]);
- }
- if (!strcmp(arg, "-httpport") && i < argc-1) {
- if (!is_decimal(argv[i+1])) {
- rfbLog("Invalid -httpport value: '%s'\n", argv[i+1]);
- clean_up_exit(1);
- }
- }
- if (!strcmp(arg, "-alwaysshared ")) {
- got_alwaysshared = 1;
- }
- if (!strcmp(arg, "-nevershared")) {
- got_nevershared = 1;
- }
- if (!strcmp(arg, "-listen") && i < argc-1) {
- listen_str = strdup(argv[i+1]);
- }
- /* otherwise copy it for libvncserver use below. */
- if (!strcmp(arg, "-ultrafilexfer")) {
- got_ultrafilexfer = 1;
- } else if (argc_vnc < argc_vnc_max) {
- argv_vnc[argc_vnc++] = strdup(arg);
- } else {
- rfbLog("too many arguments.\n");
- exit(1);
- }
- continue;
- }
- }
-
- if (! getenv("NO_LIBXCB_ALLOW_SLOPPY_LOCK")) {
- /* libxcb is a bit too strict for us sometimes... */
- set_env("LIBXCB_ALLOW_SLOPPY_LOCK", "1");
- }
-
- if (getenv("PATH") == NULL || !strcmp(getenv("PATH"), "")) {
- /* set a minimal PATH, usually only null in inetd. */
- set_env("PATH", "/bin:/usr/bin");
- }
-
- /* handle -findauth case now that cmdline has been read */
- if (got_findauth) {
- char *s;
- int ic = 0;
- if (use_dpy != NULL) {
- set_env("DISPLAY", use_dpy);
- }
- use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run");
-
- s = getenv("FINDAUTH_DISPLAY");
- if (s && strcmp("", s)) {
- set_env("DISPLAY", s);
- }
- s = getenv("DISPLAY");
- if (s && strcmp("", s)) {
- set_env("X11VNC_SKIP_DISPLAY", s);
- } else {
- set_env("X11VNC_SKIP_DISPLAY", ":0");
- }
- set_env("X11VNC_SKIP_DISPLAY_NEGATE", "1");
- set_env("FIND_DISPLAY_XAUTHORITY_PATH", "1");
- set_env("FIND_DISPLAY_NO_SHOW_XAUTH", "1");
- set_env("FIND_DISPLAY_NO_SHOW_DISPLAY", "1");
- wait_for_client(&ic, NULL, 0);
- exit(0);
- }
-
- /* set OS struct UT */
- uname(&UT);
-
- orig_use_xdamage = use_xdamage;
-
- if (!auto_port && getenv("AUTO_PORT")) {
- auto_port = atoi(getenv("AUTO_PORT"));
- }
-
- if (getenv("X11VNC_LOOP_MODE")) {
- if (bg && !getenv("X11VNC_LOOP_MODE_BG")) {
- if (! quiet) {
- fprintf(stderr, "disabling -bg in -loop "
- "mode\n");
- }
- bg = 0;
- } else if (!bg && getenv("X11VNC_LOOP_MODE_BG")) {
- if (! quiet) {
- fprintf(stderr, "enabling -bg in -loopbg "
- "mode\n");
- }
- bg = 1;
- }
- if (inetd) {
- if (! quiet) {
- fprintf(stderr, "disabling -inetd in -loop "
- "mode\n");
- }
- inetd = 0;
- }
- }
-
- if (launch_gui && (query_cmd || remote_cmd)) {
- launch_gui = 0;
- gui_str = NULL;
- }
- if (more_safe) {
- launch_gui = 0;
- }
-
-#ifdef MACOSX
- if (! use_dpy) {
- /* we need this for gui since no X properties */
- if (!client_connect_file && !client_connect) {
- char *user = get_user_name();
- char *str = (char *) malloc(strlen(user) + strlen("/tmp/x11vnc-macosx-remote.") + 1);
- struct stat sb;
- sprintf(str, "/tmp/x11vnc-macosx-remote.%s", user);
- if (!remote_cmd && !query_cmd) {
- unlink(str);
- if (stat(str, &sb) != 0) {
- int fd = open(str, O_WRONLY|O_EXCL|O_CREAT, 0600);
- if (fd >= 0) {
- close(fd);
- client_connect_file = str;
- }
- }
- } else {
- client_connect_file = str;
- }
- if (client_connect_file) {
- if (!got_inetd) {
- rfbLog("MacOS X: set -connect file to %s\n", client_connect_file);
- }
- }
- }
- }
-#endif
- if (got_rfbport_str != NULL && !strcasecmp(got_rfbport_str, "prompt")) {
- char *opts, tport[32];
-
- if (gui_str) {
- opts = (char *) malloc(strlen(gui_str) + 32);
- sprintf(opts, "%s,portprompt", gui_str);
- } else {
- opts = strdup("portprompt");
- }
- got_rfbport_val = -1;
-
- do_gui(opts, 0);
- if (got_rfbport_val == -1) {
- rfbLog("Port prompt indicated cancel.\n");
- clean_up_exit(1);
- }
- if (!got_inetd) {
- rfbLog("Port prompt selected: %d\n", got_rfbport_val);
- }
- sprintf(tport, "%d", got_rfbport_val);
- argv_vnc[got_rfbport_pos] = strdup(tport);
- free(opts);
- }
-
- {
- char num[32];
- sprintf(num, "%d", got_rfbport_val);
- set_env("X11VNC_GOT_RFBPORT_VAL", num);
- }
-
- if (got_ultrafilexfer && argc_vnc + 2 < argc_vnc_max) {
- argv_vnc[argc_vnc++] = strdup("-rfbversion");
- argv_vnc[argc_vnc++] = strdup("3.6");
- argv_vnc[argc_vnc++] = strdup("-permitfiletransfer");
- }
-
- if (launch_gui) {
- int sleep = 0;
- if (SHOW_NO_PASSWORD_WARNING && !nopw) {
- sleep = 1;
- }
- do_gui(gui_str, sleep);
- }
- if (logfile) {
- int n;
- char *pstr = "%VNCDISPLAY";
- if (strstr(logfile, pstr)) {
- char *h = this_host();
- char *s, *q, *newlog;
- int n, p = got_rfbport_val;
- /* we don't really know the port yet... so guess */
- if (p < 0) {
- p = auto_port;
- }
- if (p <= 0) {
- p = 5900;
- }
- s = (char *) malloc(strlen(h) + 32);
- sprintf(s, "%s:%d", h, p);
- n = 1;
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) break;
- n++;
- q = t+1;
- }
- newlog = (char *) malloc(strlen(logfile) + n * strlen(pstr));
- newlog[0] = '\0';
-
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) {
- strcat(newlog, q);
- break;
- }
- strncat(newlog, q, t - q);
- strcat(newlog, s);
- q = t + strlen(pstr);
- }
- logfile = newlog;
- if (!quiet && !got_inetd) {
- rfbLog("Expanded logfile to '%s'\n", newlog);
-
- }
- free(s);
- }
- pstr = "%HOME";
- if (strstr(logfile, pstr)) {
- char *h = get_home_dir();
- char *s, *q, *newlog;
-
- s = (char *) malloc(strlen(h) + 32);
- sprintf(s, "%s", h);
- n = 1;
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) break;
- n++;
- q = t+1;
- }
- newlog = (char *) malloc(strlen(logfile) + n * strlen(pstr));
- newlog[0] = '\0';
-
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) {
- strcat(newlog, q);
- break;
- }
- strncat(newlog, q, t - q);
- strcat(newlog, s);
- q = t + strlen(pstr);
- }
- logfile = newlog;
- if (!quiet && !got_inetd) {
- rfbLog("Expanded logfile to '%s'\n", newlog);
- }
- free(s);
- }
-
- if (logfile_append) {
- n = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0666);
- } else {
- n = open(logfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
- }
- if (n < 0) {
- fprintf(stderr, "error opening logfile: %s\n", logfile);
- perror("open");
- exit(1);
- }
- if (dup2(n, 2) < 0) {
- fprintf(stderr, "dup2 failed\n");
- perror("dup2");
- exit(1);
- }
- if (n > 2) {
- close(n);
- }
- }
- if (ipv6_listen) {
- if (inetd) {
- ipv6_listen = 0;
- }
- }
- if (inetd && quiet && !logfile) {
- int n;
- /*
- * Redir stderr to /dev/null under -inetd and -quiet
- * but no -o logfile. Typical problem:
- * Xlib: extension "RECORD" missing on display ":1.0".
- * If they want this info, they should use -o logfile,
- * or no -q and 2>logfile.
- */
- n = open("/dev/null", O_WRONLY);
- if (n >= 0) {
- if (dup2(n, 2) >= 0) {
- if (n > 2) {
- close(n);
- }
- }
- }
- }
- if (! quiet && ! inetd) {
- int i;
- if (http_oneport_msg) {
- rfbLog("setting '-enc none' for -http_oneport mode.\n");
- }
- for (i=1; i < argc_vnc; i++) {
- rfbLog("passing arg to libvncserver: %s\n", argv_vnc[i]);
- if (!strcmp(argv_vnc[i], "-passwd")) {
- i++;
- }
- }
- }
-
- if (remote_cmd || query_cmd) {
- /*
- * no need to open DISPLAY, just write it to the file now
- * similar for query_default.
- */
- if (client_connect_file || query_default) {
- int i, rc = 1;
- for (i=0; i <= query_retries; i++) {
- rc = do_remote_query(remote_cmd, query_cmd,
- remote_sync, query_default);
- if (rc == 0) {
- if (query_match) {
- if (query_result && strstr(query_result, query_match)) {
- break;
- }
- rc = 1;
- } else {
- break;
- }
- }
- if (i < query_retries) {
- fprintf(stderr, "sleep: %.3f\n", query_delay);
- usleep( (int) (query_delay * 1000 * 1000) );
- }
- }
- fflush(stderr);
- fflush(stdout);
- exit(rc);
- }
- }
-
- if (usepw && ! got_rfbauth && ! got_passwd && ! got_passwdfile && !unixpw) {
- char *f, *h = getenv("HOME");
- struct stat sbuf;
- int found = 0, set_rfbauth = 0;
-
- if (!h) {
- rfbLog("HOME unset in -usepw mode.\n");
- exit(1);
- }
- f = (char *) malloc(strlen(h)+strlen("/.vnc/passwdfile") + 1);
-
- sprintf(f, "%s/.vnc/passwd", h);
- if (stat(f, &sbuf) == 0) {
- found = 1;
- if (! quiet) {
- rfbLog("-usepw: found %s\n", f);
- }
- got_rfbauth = 1;
- set_rfbauth = 1;
- }
-
- sprintf(f, "%s/.vnc/passwdfile", h);
- if (! found && stat(f, &sbuf) == 0) {
- found = 1;
- if (! quiet) {
- rfbLog("-usepw: found %s\n", f);
- }
- got_passwdfile = 1;
- passwdfile = strdup(f);
- }
-
-#if LIBVNCSERVER_HAVE_FORK
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H
-#if LIBVNCSERVER_HAVE_WAITPID
- if (! found) {
- pid_t pid = fork();
- if (pid < 0) {
- ;
- } else if (pid == 0) {
- execlp(argv[0], argv[0], "-storepasswd",
- (char *) NULL);
- exit(1);
- } else {
- int s;
- waitpid(pid, &s, 0);
- if (WIFEXITED(s) && WEXITSTATUS(s) == 0) {
- got_rfbauth = 1;
- set_rfbauth = 1;
- found = 1;
- }
- }
- }
-#endif
-#endif
-#endif
-
- if (set_rfbauth) {
- sprintf(f, "%s/.vnc/passwd", h);
- if (argc_vnc < 100) {
- argv_vnc[argc_vnc++] = strdup("-rfbauth");
- } else {
- exit(1);
- }
- if (argc_vnc < 100) {
- argv_vnc[argc_vnc++] = strdup(f);
- } else {
- exit(1);
- }
- }
- if (! found) {
- fprintf(stderr, "x11vnc -usepw: could not find"
- " a password to use.\n");
- exit(1);
- }
- free(f);
- }
-
- if (got_rfbauth && (got_passwd || got_viewpasswd || got_passwdfile)) {
- fprintf(stderr, "option -rfbauth is incompatible with:\n");
- fprintf(stderr, " -passwd, -viewpasswd, and -passwdfile\n");
- exit(1);
- }
- if (got_passwdfile && (got_passwd || got_viewpasswd)) {
- fprintf(stderr, "option -passwdfile is incompatible with:\n");
- fprintf(stderr, " -passwd and -viewpasswd\n");
- exit(1);
- }
-
- /*
- * If -passwd was used, clear it out of argv. This does not
- * work on all UNIX, have to use execvp() in general...
- */
- if (pw_loc > 0) {
- int i;
- for (i=pw_loc; i <= pw_loc+1; i++) {
- if (i < argc) {
- char *p = argv[i];
- strzero(p);
- }
- }
- } else if (passwdfile) {
- /* read passwd(s) from file */
- if (strstr(passwdfile, "cmd:") == passwdfile ||
- strstr(passwdfile, "custom:") == passwdfile) {
- char tstr[100], *q;
- sprintf(tstr, "%f", dnow());
- if ((q = strrchr(tstr, '.')) == NULL) {
- q = tstr;
- } else {
- q++;
- }
- /* never used under cmd:, used to force auth */
- argv_vnc[argc_vnc++] = strdup("-passwd");
- argv_vnc[argc_vnc++] = strdup(q);
- } else if (read_passwds(passwdfile)) {
- argv_vnc[argc_vnc++] = strdup("-passwd");
- argv_vnc[argc_vnc++] = strdup(passwd_list[0]);
- }
- got_passwd = 1;
- pw_loc = 100; /* just for pw_loc check below */
- }
- if (vpw_loc > 0) {
- int i;
- for (i=vpw_loc; i <= vpw_loc+1; i++) {
- if (i < argc) {
- char *p = argv[i];
- strzero(p);
- }
- }
- }
-#ifdef HARDWIRE_PASSWD
- if (!got_rfbauth && !got_passwd) {
- argv_vnc[argc_vnc++] = strdup("-passwd");
- argv_vnc[argc_vnc++] = strdup(HARDWIRE_PASSWD);
- got_passwd = 1;
- pw_loc = 100;
- }
-#endif
-#ifdef HARDWIRE_VIEWPASSWD
- if (!got_rfbauth && got_passwd && !viewonly_passwd && !passwd_list) {
- viewonly_passwd = strdup(HARDWIRE_VIEWPASSWD);
- }
-#endif
- if (viewonly_passwd && pw_loc < 0) {
- rfbLog("-passwd must be supplied when using -viewpasswd\n");
- exit(1);
- }
- if (1) {
- /* mix things up a little bit */
- unsigned char buf[CHALLENGESIZE];
- int k, kmax = (int) (50 * rfac()) + 10;
- for (k=0; k < kmax; k++) {
- rfbRandomBytes(buf);
- }
- }
-
- if (SHOW_NO_PASSWORD_WARNING) {
- char message[] = "-rfbauth, -passwdfile, -passwd password, "
- "or -unixpw required.";
- if (! nopw) {
- nopassword_warning_msg(got_localhost);
- }
-#if PASSWD_REQUIRED
- rfbLog("%s\n", message);
- exit(1);
-#endif
-#if PASSWD_UNLESS_NOPW
- if (! nopw) {
- rfbLog("%s\n", message);
- exit(1);
- }
-#endif
- message[0] = '\0'; /* avoid compiler warning */
- }
-
- if (more_safe) {
- if (! quiet) {
- rfbLog("-safer mode:\n");
- rfbLog(" vnc_connect=0\n");
- rfbLog(" accept_remote_cmds=0\n");
- rfbLog(" safe_remote_only=1\n");
- rfbLog(" launch_gui=0\n");
- }
- vnc_connect = 0;
- accept_remote_cmds = 0;
- safe_remote_only = 1;
- launch_gui = 0;
- }
-
- if (users_list && strchr(users_list, '.')) {
- char *p, *q, *tmp = (char *) malloc(strlen(users_list)+1);
- char *str = strdup(users_list);
- int i, n, db = 1;
-
- tmp[0] = '\0';
-
- n = strlen(users_list) + 1;
- user2group = (char **) malloc(n * sizeof(char *));
- for (i=0; i<n; i++) {
- user2group[i] = NULL;
- }
-
- i = 0;
- p = strtok(str, ",");
- if (db) fprintf(stderr, "users_list: %s\n", users_list);
- while (p) {
- if (tmp[0] != '\0') {
- strcat(tmp, ",");
- }
- q = strchr(p, '.');
- if (q) {
- char *s = strchr(p, '=');
- if (! s) {
- s = p;
- } else {
- s++;
- }
- if (s[0] == '+') s++;
- user2group[i++] = strdup(s);
- if (db) fprintf(stderr, "u2g: %s\n", s);
- *q = '\0';
- }
- strcat(tmp, p);
- p = strtok(NULL, ",");
- }
- free(str);
- users_list = tmp;
- if (db) fprintf(stderr, "users_list: %s\n", users_list);
- }
-
- if (got_tls > 0 && !use_openssl) {
- rfbLog("SSL: Error: you did not supply the '-ssl ...' option even\n");
- rfbLog("SSL: though you supplied one of these related options:\n");
- rfbLog("SSL: -sslonly, -sslverify, -sslCRL, -vencrypt, -anontls,\n");
- rfbLog("SSL: -dhparams, -https, -http_ssl, or -httpsredir.\n");
- rfbLog("SSL: Restart with, for example, '-ssl SAVE' on the cmd line.\n");
- rfbLog("SSL: See the '-ssl' x11vnc -help description for more info.\n");
- if (!getenv("X11VNC_FORCE_NO_OPENSSL")) {
- exit(1);
- }
- }
-
- if (unixpw) {
- if (inetd) {
- use_stunnel = 0;
- }
- if (! use_stunnel && ! use_openssl) {
- if (getenv("UNIXPW_DISABLE_SSL")) {
- rfbLog("Skipping -ssl/-stunnel requirement"
- " due to\n");
- rfbLog("UNIXPW_DISABLE_SSL setting.\n");
-
- if (!getenv("UNIXPW_DISABLE_LOCALHOST")) {
- if (!got_localhost) {
- rfbLog("Forcing -localhost mode.\n");
- }
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- }
- } else if (have_ssh_env()) {
- char *s = getenv("SSH_CONNECTION");
- if (! s) s = getenv("SSH_CLIENT");
- if (! s) s = "SSH_CONNECTION";
- fprintf(stderr, "\n");
- rfbLog("Skipping -ssl/-stunnel constraint in"
- " -unixpw mode,\n");
- rfbLog("assuming your SSH encryption"
- " is:\n");
- rfbLog(" %s\n", s);
-
- if (!getenv("UNIXPW_DISABLE_LOCALHOST")) {
- if (!got_localhost) {
- rfbLog("Setting -localhost in SSH + -unixpw mode.\n");
- }
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- }
-
- rfbLog("If you *actually* want SSL, restart"
- " with -ssl on the cmdline\n");
- if (! nopw) {
- usleep(2000*1000);
- }
- } else {
- if (openssl_present()) {
- rfbLog("set -ssl in -unixpw mode.\n");
- use_openssl = 1;
- } else if (inetd) {
- rfbLog("could not set -ssl in -inetd"
- " + -unixpw mode.\n");
- exit(1);
- } else {
- rfbLog("set -stunnel in -unixpw mode.\n");
- use_stunnel = 1;
- }
- }
- rfbLog("\n");
- }
- if (use_threads && !getenv("UNIXPW_THREADS")) {
- if (! quiet) {
- rfbLog("disabling -threads under -unixpw\n");
- rfbLog("\n");
- }
- use_threads = 0;
- }
- }
- if (use_stunnel && ! got_localhost) {
- if (! getenv("STUNNEL_DISABLE_LOCALHOST") &&
- ! getenv("UNIXPW_DISABLE_LOCALHOST")) {
- if (! quiet) {
- rfbLog("Setting -localhost in -stunnel mode.\n");
- }
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- }
- }
- if (ssl_verify && ! use_stunnel && ! use_openssl) {
- rfbLog("-sslverify must be used with -ssl or -stunnel\n");
- exit(1);
- }
- if (https_port_num >= 0 && ! use_openssl) {
- rfbLog("-https must be used with -ssl\n");
- exit(1);
- }
-
- if (use_threads && !got_noxrandr) {
- xrandr = 1;
- if (! quiet) {
- rfbLog("enabling -xrandr in -threads mode.\n");
- }
- }
-
- /* fixup settings that do not make sense */
-
- if (use_threads && nofb && cursor_pos_updates) {
- if (! quiet) {
- rfbLog("disabling -threads under -nofb -cursorpos\n");
- }
- use_threads = 0;
- }
- if (tile_fuzz < 1) {
- tile_fuzz = 1;
- }
- if (waitms < 0) {
- waitms = 0;
- }
-
- if (alpha_threshold < 0) {
- alpha_threshold = 0;
- }
- if (alpha_threshold > 256) {
- alpha_threshold = 256;
- }
- if (alpha_frac < 0.0) {
- alpha_frac = 0.0;
- }
- if (alpha_frac > 1.0) {
- alpha_frac = 1.0;
- }
- if (alpha_blend) {
- alpha_remove = 0;
- }
-
- if (cmap8to24 && overlay) {
- if (! quiet) {
- rfbLog("disabling -overlay in -8to24 mode.\n");
- }
- overlay = 0;
- }
-
- if (tightfilexfer && view_only) {
- if (! quiet) {
- rfbLog("setting -notightfilexfer in -viewonly mode.\n");
- }
- /* how to undo via -R? */
- tightfilexfer = 0;
- }
-
- if (inetd) {
- shared = 0;
- connect_once = 1;
- bg = 0;
- if (use_stunnel) {
- exit(1);
- }
- }
-
- http_try_it = try_http;
-
- if (flip_byte_order && using_shm && ! quiet) {
- rfbLog("warning: -flipbyte order only works with -noshm\n");
- }
-
- if (! wireframe_copyrect) {
- set_wirecopyrect_mode(NULL);
- }
- if (! scroll_copyrect) {
- set_scrollcopyrect_mode(NULL);
- }
- if (screen_fixup_str) {
- parse_fixscreen();
- }
- initialize_scroll_matches();
- initialize_scroll_term();
- initialize_max_keyrepeat();
-
- /* increase rfbwait if threaded */
- if (use_threads && ! got_rfbwait) {
- /* ??? lower this ??? */
- rfbMaxClientWait = 604800000;
- }
-
- /* no framebuffer (Win2VNC) mode */
-
- if (nofb) {
- /* disable things that do not make sense with no fb */
- set_nofb_params(0);
-
- if (! got_deferupdate && ! got_defer) {
- /* reduce defer time under -nofb */
- defer_update = defer_update_nofb;
- }
- if (got_pointer_mode < 0) {
- pointer_mode = POINTER_MODE_NOFB;
- }
- }
-
- if (ncache < 0) {
- ncache_beta_tester = 1;
- ncache_msg = 1;
- if (ncache == -1) {
- ncache = 0;
- }
- ncache = -ncache;
- if (try_http || got_httpdir) {
- /* JVM usually not set to handle all the memory */
- ncache = 0;
- ncache_msg = 0;
- }
- if (subwin) {
- ncache = 0;
- ncache_msg = 0;
- }
- }
-
- if (raw_fb_str) {
- set_raw_fb_params(0);
- }
- if (! got_deferupdate) {
- char tmp[40];
- sprintf(tmp, "%d", defer_update);
- argv_vnc[argc_vnc++] = strdup("-deferupdate");
- argv_vnc[argc_vnc++] = strdup(tmp);
- }
-
- if (debug_pointer || debug_keyboard) {
- if (!logfile) {
- if (bg || quiet) {
- rfbLog("disabling -bg/-q under -debug_pointer"
- "/-debug_keyboard\n");
- bg = 0;
- quiet = 0;
- }
- }
- }
-
- /* initialize added_keysyms[] array to zeros */
- add_keysym(NoSymbol);
-
- /* tie together cases of -localhost vs. -listen localhost */
- if (! listen_str) {
- if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
- listen_str = strdup("localhost");
- argv_vnc[argc_vnc++] = strdup("-listen");
- argv_vnc[argc_vnc++] = strdup(listen_str);
- }
- } else if (!strcmp(listen_str, "localhost") ||
- !strcmp(listen_str, "127.0.0.1")) {
- allow_list = strdup("127.0.0.1");
- }
-
- initialize_crash_handler();
-
- if (! quiet) {
- if (verbose) {
- print_settings(try_http, bg, gui_str);
- }
- rfbLog("x11vnc version: %s pid: %d\n", lastmod, getpid());
- } else {
- rfbLogEnable(0);
- }
-
- X_INIT;
- SCR_INIT;
- CLIENT_INIT;
- INPUT_INIT;
- POINTER_INIT;
-
- /* open the X display: */
-
-#if LIBVNCSERVER_HAVE_XKEYBOARD
- /*
- * Disable XKEYBOARD before calling XOpenDisplay()
- * this should be used if there is ambiguity in the keymapping.
- */
- if (xkbcompat) {
- Bool rc = XkbIgnoreExtension(True);
- if (! quiet) {
- rfbLog("Disabling xkb XKEYBOARD extension. rc=%d\n",
- rc);
- }
- if (watch_bell) {
- watch_bell = 0;
- if (! quiet) rfbLog("Disabling bell.\n");
- }
- }
-#else
- watch_bell = 0;
- use_xkb_modtweak = 0;
-#endif
-
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- if (tightfilexfer) {
- rfbLog("rfbRegisterTightVNCFileTransferExtension: 6\n");
- rfbRegisterTightVNCFileTransferExtension();
- } else {
- if (0) rfbLog("rfbUnregisterTightVNCFileTransferExtension: 3\n");
- rfbUnregisterTightVNCFileTransferExtension();
- }
-#endif
-
- initialize_allowed_input();
-
- if (display_N && !got_rfbport) {
- char *ud = use_dpy;
- if (ud == NULL) {
- ud = getenv("DISPLAY");
- }
- if (ud && strstr(ud, "cmd=") == NULL) {
- char *p;
- ud = strdup(ud);
- p = strrchr(ud, ':');
- if (p) {
- int N;
- char *q = strchr(p, '.');
- if (q) {
- *q = '\0';
- }
- N = atoi(p+1);
- if (argc_vnc+1 < argc_vnc_max) {
- char Nstr[16];
- sprintf(Nstr, "%d", (5900 + N) % 65536);
- argv_vnc[argc_vnc++] = strdup("-rfbport");
- argv_vnc[argc_vnc++] = strdup(Nstr);
- got_rfbport = 1;
- }
- }
- free(ud);
- }
- }
-
- if (users_list && strstr(users_list, "lurk=")) {
- if (use_dpy) {
- rfbLog("warning: -display does not make sense in "
- "\"lurk=\" mode...\n");
- }
- if (auth_file != NULL && strcmp(auth_file, "guess")) {
- set_env("XAUTHORITY", auth_file);
- }
- lurk_loop(users_list);
-
- } else if (use_dpy && strstr(use_dpy, "WAIT:") == use_dpy) {
- char *mcm = multiple_cursors_mode;
-
- if (strstr(use_dpy, "Xdummy")) {
- if (!xrandr && !got_noxrandr) {
- if (! quiet) {
- rfbLog("Enabling -xrandr for possible use of Xdummy server.\n");
- }
- xrandr = 1;
- }
- }
-
- waited_for_client = wait_for_client(&argc_vnc, argv_vnc,
- try_http && ! got_httpdir);
-
- if (!mcm && multiple_cursors_mode) {
- free(multiple_cursors_mode);
- multiple_cursors_mode = NULL;
- }
- }
-
-
- if (auth_file) {
- check_guess_auth_file();
- if (auth_file != NULL) {
- set_env("XAUTHORITY", auth_file);
- }
- }
-
-#ifdef MACOSX
- if (use_dpy && !strcmp(use_dpy, "console")) {
- ;
- } else
-#endif
- if (use_dpy && strcmp(use_dpy, "")) {
- dpy = XOpenDisplay_wr(use_dpy);
-#ifdef MACOSX
- } else if (!subwin && getenv("DISPLAY")
- && strstr(getenv("DISPLAY"), "/tmp/") ) {
- /* e.g. /tmp/launch-XlspvM/:0 on leopard */
- rfbLog("MacOSX: Ignoring $DISPLAY '%s'\n", getenv("DISPLAY"));
- rfbLog("MacOSX: Use -display $DISPLAY to force it.\n");
-#endif
- } else if (raw_fb_str != NULL && raw_fb_str[0] != '+' && !got_noviewonly) {
- rfbLog("Not opening DISPLAY in -rawfb mode (force via -rawfb +str)\n");
- dpy = NULL; /* don't open it. */
- } else if ( (use_dpy = getenv("DISPLAY")) ) {
- if (strstr(use_dpy, "localhost") == use_dpy) {
- rfbLog("\n");
- rfbLog("WARNING: DISPLAY starts with localhost: '%s'\n", use_dpy);
- rfbLog("WARNING: Is this an SSH X11 port forwarding? You most\n");
- rfbLog("WARNING: likely don't want x11vnc to use that DISPLAY.\n");
- rfbLog("WARNING: You probably should supply something\n");
- rfbLog("WARNING: like: -display :0 to access the physical\n");
- rfbLog("WARNING: X display on the machine where x11vnc is running.\n");
- rfbLog("\n");
- usleep(500 * 1000);
- } else if (using_shm && use_dpy[0] != ':') {
- rfbLog("\n");
- rfbLog("WARNING: DISPLAY might not be local: '%s'\n", use_dpy);
- rfbLog("WARNING: Is this the DISPLAY of another machine? Usually,\n");
- rfbLog("WARNING: x11vnc is run on the same machine with the\n");
- rfbLog("WARNING: physical X display to be exported by VNC. If\n");
- rfbLog("WARNING: that is what you really meant, supply something\n");
- rfbLog("WARNING: like: -display :0 on the x11vnc command line.\n");
- rfbLog("\n");
- usleep(250 * 1000);
- }
- dpy = XOpenDisplay_wr(use_dpy);
- } else {
- dpy = XOpenDisplay_wr("");
- }
- last_open_xdisplay = time(NULL);
-
- if (terminal_services_daemon != NULL) {
- terminal_services(terminal_services_daemon);
- exit(0);
- }
-
- if (dpy && !xrandr && !got_noxrandr) {
-#if !NO_X11
- Atom trap_xrandr = XInternAtom(dpy, "X11VNC_TRAP_XRANDR", True);
- if (trap_xrandr != None) {
- if (! quiet) {
- rfbLog("Enabling -xrandr due to X11VNC_TRAP_XRANDR atom.\n");
- }
- xrandr = 1;
- }
-#endif
- }
-
-#ifdef MACOSX
- if (! dpy && ! raw_fb_str) {
- raw_fb_str = strdup("console");
- }
-#endif
-
- if (! dpy && raw_fb_str) {
- rfbLog("Continuing without X display in -rawfb mode.\n");
- goto raw_fb_pass_go_and_collect_200_dollars;
- }
-
- if (! dpy && ! use_dpy && ! getenv("DISPLAY")) {
- int i, s = 4;
- rfbLogEnable(1);
- rfbLog("\a\n");
- rfbLog("*** XOpenDisplay failed. No -display or DISPLAY.\n");
- rfbLog("*** Trying \":0\" in %d seconds. Press Ctrl-C to"
- " abort.\n", s);
- rfbLog("*** ");
- for (i=1; i<=s; i++) {
- fprintf(stderr, "%d ", i);
- sleep(1);
- }
- fprintf(stderr, "\n");
- use_dpy = ":0";
- dpy = XOpenDisplay_wr(use_dpy);
- last_open_xdisplay = time(NULL);
- if (dpy) {
- rfbLog("*** XOpenDisplay of \":0\" successful.\n");
- }
- rfbLog("\n");
- if (quiet) rfbLogEnable(0);
- }
-
- if (! dpy) {
- char *d = use_dpy;
- if (!d) d = getenv("DISPLAY");
- if (!d) d = "null";
- rfbLogEnable(1);
- fprintf(stderr, "\n");
- rfbLog("***************************************\n", d);
- rfbLog("*** XOpenDisplay failed (%s)\n", d);
- xopen_display_fail_message(d);
- exit(1);
- } else if (use_dpy) {
- if (! quiet) rfbLog("Using X display %s\n", use_dpy);
- } else {
- if (! quiet) rfbLog("Using default X display.\n");
- }
-
- if (clip_str != NULL && dpy != NULL) {
- check_xinerama_clip();
- }
-
- scr = DefaultScreen(dpy);
- rootwin = RootWindow(dpy, scr);
-
-#if !NO_X11
- if (dpy) {
- Window w = XCreateSimpleWindow(dpy, rootwin, 0, 0, 1, 1, 0, 0, 0);
- if (! quiet) rfbLog("rootwin: 0x%lx reswin: 0x%lx dpy: 0x%x\n", rootwin, w, dpy);
- if (w != None) {
- XDestroyWindow(dpy, w);
- }
- XSync(dpy, False);
- }
-#endif
-
- if (ncache_beta_tester) {
- int h = DisplayHeight(dpy, scr);
- int w = DisplayWidth(dpy, scr);
- int mem = (w * h * 4) / (1000 * 1000), MEM = 96;
- if (mem < 1) mem = 1;
-
- /* limit poor, unsuspecting beta tester's viewer to 96 MB */
- if ( (ncache+2) * mem > MEM ) {
- int n = (MEM/mem) - 2;
- if (n < 0) n = 0;
- n = 2 * (n / 2);
- if (n < ncache) {
- ncache = n;
- }
- }
- }
-
- if (grab_always) {
- Window save = window;
- window = rootwin;
- adjust_grabs(1, 0);
- window = save;
- }
-
- if ( (remote_cmd && strstr(remote_cmd, "DIRECT:") == remote_cmd)
- || (query_cmd && strstr(query_cmd, "DIRECT:") == query_cmd )) {
- /* handled below after most everything is setup. */
- if (getenv("QUERY_VERBOSE")) {
- quiet = 0;
- } else {
- quiet = 1;
- remote_direct = 1;
- }
- if (!auto_port) {
- auto_port = 5970;
- }
- } else if (remote_cmd || query_cmd) {
- int i, rc = 1;
- for (i=0; i <= query_retries; i++) {
- rc = do_remote_query(remote_cmd, query_cmd, remote_sync,
- query_default);
- if (rc == 0) {
- if (query_match) {
- if (query_result && strstr(query_result, query_match)) {
- break;
- }
- rc = 1;
- } else {
- break;
- }
- }
- if (i < query_retries) {
- fprintf(stderr, "sleep: %.3f\n", query_delay);
- usleep( (int) (query_delay * 1000 * 1000) );
- }
- }
- XFlush_wr(dpy);
- fflush(stderr);
- fflush(stdout);
- usleep(30 * 1000); /* still needed? */
- XCloseDisplay_wr(dpy);
- exit(rc);
- }
-
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("------------------ USEFUL INFORMATION ------------------\n");
- }
-
- if (priv_remote) {
- if (! remote_control_access_ok()) {
- rfbLog("** Disabling remote commands in -privremote mode.\n");
- accept_remote_cmds = 0;
- }
- }
-
- sync_tod_with_servertime();
- if (grab_buster) {
- spawn_grab_buster();
- }
-
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- if (! XFixesQueryExtension(dpy, &xfixes_base_event_type, &er)) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("Disabling XFIXES mode: display does not support it.\n");
- }
- xfixes_base_event_type = 0;
- xfixes_present = 0;
- } else {
- xfixes_present = 1;
- }
-#endif
- if (! xfixes_present) {
- use_xfixes = 0;
- }
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (! XDamageQueryExtension(dpy, &xdamage_base_event_type, &er)) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("Disabling X DAMAGE mode: display does not support it.\n");
- }
- xdamage_base_event_type = 0;
- xdamage_present = 0;
- } else {
- xdamage_present = 1;
- }
-#endif
- if (! xdamage_present) {
- use_xdamage = 0;
- }
- if (! quiet && xdamage_present && use_xdamage && ! raw_fb_str) {
- rfbLog("X DAMAGE available on display, using it for polling hints.\n");
- rfbLog(" To disable this behavior use: '-noxdamage'\n");
- rfbLog("\n");
- rfbLog(" Most compositing window managers like 'compiz' or 'beryl'\n");
- rfbLog(" cause X DAMAGE to fail, and so you may not see any screen\n");
- rfbLog(" updates via VNC. Either disable 'compiz' (recommended) or\n");
- rfbLog(" supply the x11vnc '-noxdamage' command line option.\n");
- }
-
- if (! quiet && wireframe && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("Wireframing: -wireframe mode is in effect for window moves.\n");
- rfbLog(" If this yields undesired behavior (poor response, painting\n");
- rfbLog(" errors, etc) it may be disabled:\n");
- rfbLog(" - use '-nowf' to disable wireframing completely.\n");
- rfbLog(" - use '-nowcr' to disable the Copy Rectangle after the\n");
- rfbLog(" moved window is released in the new position.\n");
- rfbLog(" Also see the -help entry for tuning parameters.\n");
- rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
- rfbLog(" repaint the screen, also see the -fixscreen option for\n");
- rfbLog(" periodic repaints.\n");
- if (scale_str && !strstr(scale_str, "nocr")) {
- rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
- }
- }
-
- overlay_present = 0;
-#if defined(SOLARIS_OVERLAY) && !NO_X11
- if (! XQueryExtension(dpy, "SUN_OVL", &maj, &ev, &er)) {
- if (! quiet && overlay && ! raw_fb_str) {
- rfbLog("Disabling -overlay: SUN_OVL extension not available.\n");
- }
- } else {
- overlay_present = 1;
- }
-#endif
-#if defined(IRIX_OVERLAY) && !NO_X11
- if (! XReadDisplayQueryExtension(dpy, &ev, &er)) {
- if (! quiet && overlay && ! raw_fb_str) {
- rfbLog("Disabling -overlay: IRIX ReadDisplay extension not available.\n");
- }
- } else {
- overlay_present = 1;
- }
-#endif
- if (overlay && !overlay_present) {
- overlay = 0;
- overlay_cursor = 0;
- }
-
- /* cursor shapes setup */
- if (! multiple_cursors_mode) {
- multiple_cursors_mode = strdup("default");
- }
- if (show_cursor) {
- if(!strcmp(multiple_cursors_mode, "default")
- && xfixes_present && use_xfixes) {
- free(multiple_cursors_mode);
- multiple_cursors_mode = strdup("most");
-
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("XFIXES available on display, resetting cursor mode\n");
- rfbLog(" to: '-cursor most'.\n");
- rfbLog(" to disable this behavior use: '-cursor arrow'\n");
- rfbLog(" or '-noxfixes'.\n");
- }
- }
- if(!strcmp(multiple_cursors_mode, "most")) {
- if (xfixes_present && use_xfixes &&
- overlay_cursor == 1) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("using XFIXES for cursor drawing.\n");
- }
- overlay_cursor = 0;
- }
- }
- }
-
- if (overlay) {
- using_shm = 0;
- if (flash_cmap && ! quiet && ! raw_fb_str) {
- rfbLog("warning: -flashcmap may be incompatible with -overlay\n");
- }
- if (show_cursor && overlay_cursor) {
- char *s = multiple_cursors_mode;
- if (*s == 'X' || !strcmp(s, "some") ||
- !strcmp(s, "arrow")) {
- /*
- * user wants these modes, so disable fb cursor
- */
- overlay_cursor = 0;
- } else {
- /*
- * "default" and "most", we turn off
- * show_cursor since it will automatically
- * be in the framebuffer.
- */
- show_cursor = 0;
- }
- }
- }
-
- initialize_cursors_mode();
-
- /* check for XTEST */
- if (! XTestQueryExtension_wr(dpy, &ev, &er, &maj, &min)) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("WARNING: XTEST extension not available (either missing from\n");
- rfbLog(" display or client library libXtst missing at build time).\n");
- rfbLog(" MOST user input (pointer and keyboard) will be DISCARDED.\n");
- rfbLog(" If display does have XTEST, be sure to build x11vnc with\n");
- rfbLog(" a working libXtst build environment (e.g. libxtst-dev,\n");
- rfbLog(" or other packages).\n");
- rfbLog("No XTEST extension, switching to -xwarppointer mode for\n");
- rfbLog(" pointer motion input.\n");
- }
- xtest_present = 0;
- use_xwarppointer = 1;
- } else {
- xtest_present = 1;
- xtest_base_event_type = ev;
- if (maj <= 1 || (maj == 2 && min <= 2)) {
- /* no events defined as of 2.2 */
- xtest_base_event_type = 0;
- }
- }
-
- if (! XETrapQueryExtension_wr(dpy, &ev, &er, &maj)) {
- xtrap_present = 0;
- } else {
- xtrap_present = 1;
- xtrap_base_event_type = ev;
- }
-
- /*
- * Window managers will often grab the display during resize,
- * etc, using XGrabServer(). To avoid deadlock (our user resize
- * input is not processed) we tell the server to process our
- * requests during all grabs:
- */
- disable_grabserver(dpy, 0);
-
- /* check for RECORD */
- if (! XRecordQueryVersion_wr(dpy, &maj, &min)) {
- xrecord_present = 0;
- if (! quiet) {
- rfbLog("\n");
- rfbLog("The RECORD X extension was not found on the display.\n");
- rfbLog("If your system has disabled it by default, you can\n");
- rfbLog("enable it to get a nice x11vnc performance speedup\n");
- rfbLog("for scrolling by putting this into the \"Module\" section\n");
- rfbLog("of /etc/X11/xorg.conf or /etc/X11/XF86Config:\n");
- rfbLog("\n");
- rfbLog(" Section \"Module\"\n");
- rfbLog(" ...\n");
- rfbLog(" Load \"record\"\n");
- rfbLog(" ...\n");
- rfbLog(" EndSection\n");
- rfbLog("\n");
- }
- } else {
- xrecord_present = 1;
- }
-
- initialize_xrecord();
-
- tmpi = 1;
- if (scroll_copyrect) {
- if (strstr(scroll_copyrect, "never")) {
- tmpi = 0;
- }
- } else if (scroll_copyrect_default) {
- if (strstr(scroll_copyrect_default, "never")) {
- tmpi = 0;
- }
- }
- if (! xrecord_present) {
- tmpi = 0;
- }
-#if !LIBVNCSERVER_HAVE_RECORD
- tmpi = 0;
-#endif
- if (! quiet && tmpi && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("Scroll Detection: -scrollcopyrect mode is in effect to\n");
- rfbLog(" use RECORD extension to try to detect scrolling windows\n");
- rfbLog(" (induced by either user keystroke or mouse input).\n");
- rfbLog(" If this yields undesired behavior (poor response, painting\n");
- rfbLog(" errors, etc) it may be disabled via: '-noscr'\n");
- rfbLog(" Also see the -help entry for tuning parameters.\n");
- rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
- rfbLog(" repaint the screen, also see the -fixscreen option for\n");
- rfbLog(" periodic repaints.\n");
- if (scale_str && !strstr(scale_str, "nocr")) {
- rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
- }
- }
-
- if (! quiet && ncache && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("Client Side Caching: -ncache mode is in effect to provide\n");
- rfbLog(" client-side pixel data caching. This speeds up\n");
- rfbLog(" iconifying/deiconifying windows, moving and raising\n");
- rfbLog(" windows, and reposting menus. In the simple CopyRect\n");
- rfbLog(" encoding scheme used (no compression) a huge amount\n");
- rfbLog(" of extra memory (20-100MB) is used on both the server and\n");
- rfbLog(" client sides. This mode works with any VNC viewer.\n");
- rfbLog(" However, in most you can actually see the cached pixel\n");
- rfbLog(" data by scrolling down, so you need to re-adjust its size.\n");
- rfbLog(" See http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching.\n");
- rfbLog(" If this mode yields undesired behavior (poor response,\n");
- rfbLog(" painting errors, etc) it may be disabled via: '-ncache 0'\n");
- rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
- rfbLog(" repaint the screen, also see the -fixscreen option for\n");
- rfbLog(" periodic repaints.\n");
- if (scale_str) {
- rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
- }
- }
- if (ncache && getenv("NCACHE_DEBUG")) {
- ncdb = 1;
- }
-
- /* check for OS with small shm limits */
- if (using_shm && ! single_copytile) {
- if (limit_shm()) {
- single_copytile = 1;
- }
- }
-
- single_copytile_orig = single_copytile;
-
- /* check for MIT-SHM */
- if (! XShmQueryExtension_wr(dpy)) {
- xshm_present = 0;
- if (! using_shm) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("info: display does not support XShm.\n");
- }
- } else {
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("warning: XShm extension is not available.\n");
- rfbLog("For best performance the X Display should be local. (i.e.\n");
- rfbLog("the x11vnc and X server processes should be running on\n");
- rfbLog("the same machine.)\n");
-#if LIBVNCSERVER_HAVE_XSHM
- rfbLog("Restart with -noshm to override this.\n");
- }
- exit(1);
-#else
- rfbLog("Switching to -noshm mode.\n");
- }
- using_shm = 0;
-#endif
- }
- } else {
-#if !NO_X11
- int op, ev, er;
- if (XQueryExtension(dpy, "MIT-SHM", &op, &ev, &er)) {
- xshm_opcode = op;
- if (0) fprintf(stderr, "xshm_opcode: %d %d %d\n", op, ev, er);
- }
-#endif
- }
-
-#if LIBVNCSERVER_HAVE_XKEYBOARD
- /* check for XKEYBOARD */
- initialize_xkb();
- initialize_watch_bell();
- if (!xkb_present && use_xkb_modtweak) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("warning: disabling xkb modtweak. XKEYBOARD ext. not present.\n");
- }
- use_xkb_modtweak = 0;
- }
-#endif
-
- if (xkb_present && !use_xkb_modtweak && !got_noxkb) {
- if (use_modifier_tweak) {
- switch_to_xkb_if_better();
- }
- }
-
-#if LIBVNCSERVER_HAVE_LIBXRANDR
- if (! XRRQueryExtension(dpy, &xrandr_base_event_type, &er)) {
- if (xrandr && ! quiet && ! raw_fb_str) {
- rfbLog("Disabling -xrandr mode: display does not support X RANDR.\n");
- }
- xrandr_base_event_type = 0;
- xrandr = 0;
- xrandr_maybe = 0;
- xrandr_present = 0;
- } else {
- xrandr_present = 1;
- }
-#endif
-
- check_pm();
-
- if (! quiet && ! raw_fb_str) {
- rfbLog("--------------------------------------------------------\n");
- rfbLog("\n");
- }
-
- raw_fb_pass_go_and_collect_200_dollars:
-
- if (! dpy || raw_fb_str) {
- int doit = 0;
- /* XXX this needs improvement (esp. for remote control) */
- if (! raw_fb_str || strstr(raw_fb_str, "console") == raw_fb_str) {
-#ifdef MACOSX
- doit = 1;
-#endif
- }
- if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
- doit = 1;
- }
- if (doit) {
- if (! multiple_cursors_mode) {
- multiple_cursors_mode = strdup("most");
- }
- initialize_cursors_mode();
- use_xdamage = orig_use_xdamage;
- if (use_xdamage) {
- xdamage_present = 1;
- initialize_xdamage();
- }
- }
- }
-
- if (! dt) {
- static char str[] = "-desktop";
- argv_vnc[argc_vnc++] = str;
- argv_vnc[argc_vnc++] = choose_title(use_dpy);
- rfb_desktop_name = strdup(argv_vnc[argc_vnc-1]);
- }
-
- /*
- * Create the XImage corresponding to the display framebuffer.
- */
-
- fb0 = initialize_xdisplay_fb();
-
- /*
- * In some cases (UINPUT touchscreens) we need the dpy_x dpy_y
- * to initialize pipeinput. So we do it after fb is created.
- */
- initialize_pipeinput();
-
- /*
- * n.b. we do not have to X_LOCK any X11 calls until watch_loop()
- * is called since we are single-threaded until then.
- */
-
- initialize_screen(&argc_vnc, argv_vnc, fb0);
-
- if (waited_for_client) {
- if (fake_fb) {
- free(fake_fb);
- fake_fb = NULL;
- }
- if (use_solid_bg && client_count) {
- solid_bg(0);
- }
- if (accept_cmd && strstr(accept_cmd, "popup") == accept_cmd) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl, cl0 = NULL;
- int i = 0;
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- i++;
- if (i != 1) {
- rfbLog("WAIT popup: too many clients\n");
- clean_up_exit(1);
- }
- cl0 = cl;
- }
- rfbReleaseClientIterator(iter);
- if (i != 1 || cl0 == NULL) {
- rfbLog("WAIT popup: no clients.\n");
- clean_up_exit(1);
- }
- if (! accept_client(cl0)) {
- rfbLog("WAIT popup: denied.\n");
- clean_up_exit(1);
- }
- rfbLog("waited_for_client: popup accepted.\n");
- cl0->onHold = FALSE;
- }
- if (macosx_console) {
- refresh_screen(1);
- }
- if (dpy && xdmcp_insert != NULL) {
-#if !NO_X11
- char c;
- int n = strlen(xdmcp_insert);
- KeyCode k, k2;
- KeySym sym;
- int i, ok = 1;
- for (i = 0; i < n; i++) {
- c = xdmcp_insert[i];
- sym = (KeySym) c;
- if (sym < ' ' || sym > 0x7f) {
- ok = 0;
- break;
- }
- k = XKeysymToKeycode(dpy, sym);
- if (k == NoSymbol) {
- ok = 0;
- break;
- }
- }
- if (ok) {
- XFlush_wr(dpy);
- usleep(2*1000*1000);
- if (!quiet) {
- rfbLog("sending XDM '%s'\n", xdmcp_insert);
- }
- for (i = 0; i < n; i++) {
- c = xdmcp_insert[i];
- sym = (KeySym) c;
- k = XKeysymToKeycode(dpy, sym);
- if (isupper(c)) {
- k2 = XKeysymToKeycode(dpy, XK_Shift_L);
- XTestFakeKeyEvent_wr(dpy, k2, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- }
- if (0) fprintf(stderr, "C/k %c/%x\n", c, k);
- XTestFakeKeyEvent_wr(dpy, k, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- XTestFakeKeyEvent_wr(dpy, k, False, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- if (isupper(c)) {
- k2 = XKeysymToKeycode(dpy, XK_Shift_L);
- XTestFakeKeyEvent_wr(dpy, k2, False, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- }
- }
- k2 = XKeysymToKeycode(dpy, XK_Tab);
- XTestFakeKeyEvent_wr(dpy, k2, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- XTestFakeKeyEvent_wr(dpy, k2, False, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- }
- free(xdmcp_insert);
-#endif
- }
- check_redir_services();
- }
-
- if (! waited_for_client) {
- if (try_http && ! got_httpdir && check_httpdir()) {
- http_connections(1);
- }
- if (ssh_str != NULL) {
- ssh_remote_tunnel(ssh_str, screen->port);
- }
- }
-
- initialize_tiles();
-
- /* rectangular blackout regions */
- initialize_blackouts_and_xinerama();
-
- /* created shm or XImages when using_shm = 0 */
- initialize_polling_images();
-
- initialize_signals();
-
- initialize_speeds();
-
- if (speeds_read_rate_measured > 80) {
- /* framebuffer read is fast at > 80 MB/sec */
- int same = 0;
- if (waitms == defer_update) {
- same = 1;
- }
- if (! got_waitms) {
- waitms /= 2;
- if (waitms < 5) {
- waitms = 5;
- }
- if (!quiet) {
- rfbLog("fast read: reset -wait ms to: %d\n", waitms);
- }
- }
- if (! got_deferupdate && ! got_defer) {
- if (defer_update > 10) {
- if (same) {
- defer_update = waitms;
- } else {
- defer_update = 10;
- }
- if (screen) {
- screen->deferUpdateTime = defer_update;
- }
- rfbLog("fast read: reset -defer ms to: %d\n", defer_update);
- }
- }
- }
-
- initialize_keyboard_and_pointer();
-
- if (inetd && use_openssl) {
- if (! waited_for_client) {
- accept_openssl(OPENSSL_INETD, -1);
- }
- }
- if (! inetd && ! use_openssl) {
- if (! screen->port || screen->listenSock < 0) {
- if (got_rfbport && got_rfbport_val == 0) {
- ;
- } else if (ipv6_listen && ipv6_listen_fd >= 0) {
- rfbLog("Info: listening only on IPv6 interface.\n");
- } else {
- rfbLogEnable(1);
- rfbLog("Error: could not obtain listening port.\n");
- if (!got_rfbport && !got_ipv6_listen) {
- rfbLog("If this system is IPv6-only, use the -6 option.\n");
- }
- clean_up_exit(1);
- }
- }
- }
-
-#ifdef MACOSX
- if (remote_cmd || query_cmd) {
- ;
- } else if (macosx_console) {
- double dt = dnow();
- copy_screen();
- dt = dnow() - dt;
- rfbLog("macosx_console: copied screen in %.3f sec %.1f MB/sec\n",
- dt, dpy_x * dpy_y * bpp / (1e+6 * 8 * dt));
-
- }
-#endif
-
- if (! quiet) {
- rfbLog("screen setup finished.\n");
- if (SHOW_NO_PASSWORD_WARNING && !nopw) {
- rfbLog("\n");
- rfbLog("WARNING: You are running x11vnc WITHOUT"
- " a password. See\n");
- rfbLog("WARNING: the warning message printed above"
- " for more info.\n");
- }
- }
- set_vnc_desktop_name();
-
- if (ncache_beta_tester && (ncache != 0 || ncache_msg)) {
- ncache_beta_tester_message();
- }
-
- if (remote_cmd || query_cmd) {
- /* This is DIRECT: case */
- do_remote_query(remote_cmd, query_cmd, remote_sync, query_default);
- if (getenv("SLEEP")) sleep(atoi(getenv("SLEEP")));
- clean_up_exit(0);
- }
-
-#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
- if (bg) {
- int p, n;
- if (getenv("X11VNC_LOOP_MODE_BG")) {
- if (screen && screen->listenSock >= 0) {
- close(screen->listenSock);
- FD_CLR(screen->listenSock,&screen->allFds);
- screen->listenSock = -1;
- }
- if (screen && screen->httpListenSock >= 0) {
- close(screen->httpListenSock);
- screen->httpListenSock = -1;
- }
- if (openssl_sock >= 0) {
- close(openssl_sock);
- openssl_sock = -1;
- }
- if (https_sock >= 0) {
- close(https_sock);
- https_sock = -1;
- }
- if (openssl_sock6 >= 0) {
- close(openssl_sock6);
- openssl_sock6 = -1;
- }
- if (https_sock6 >= 0) {
- close(https_sock6);
- https_sock6 = -1;
- }
- if (ipv6_listen_fd >= 0) {
- close(ipv6_listen_fd);
- ipv6_listen_fd = -1;
- }
- if (ipv6_http_fd >= 0) {
- close(ipv6_http_fd);
- ipv6_http_fd = -1;
- }
- }
- /* fork into the background now */
- if ((p = fork()) > 0) {
- exit(0);
- } else if (p == -1) {
- rfbLogEnable(1);
- fprintf(stderr, "could not fork\n");
- perror("fork");
- clean_up_exit(1);
- }
- if (setsid() == -1) {
- rfbLogEnable(1);
- fprintf(stderr, "setsid failed\n");
- perror("setsid");
- clean_up_exit(1);
- }
- /* adjust our stdio */
- n = open("/dev/null", O_RDONLY);
- dup2(n, 0);
- dup2(n, 1);
- if (! logfile) {
- dup2(n, 2);
- }
- if (n > 2) {
- close(n);
- }
- }
-#endif
-
- watch_loop();
-
- return(0);
-
-#undef argc
-#undef argv
-
-}
-