1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   All rights reserved.
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatThis file is part of x11vnc.
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is free software; you can redistribute it and/or modify
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatit under the terms of the GNU General Public License as published by
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe Free Software Foundation; either version 2 of the License, or (at
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatyour option) any later version.
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is distributed in the hope that it will be useful,
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatbut WITHOUT ANY WARRANTY; without even the implied warranty of
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatGNU General Public License for more details.
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatYou should have received a copy of the GNU General Public License
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatalong with x11vnc; if not, write to the Free Software
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehator see <http://www.gnu.org/licenses/>.
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatIn addition, as a special exception, Karl J. Runge
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatgives permission to link the code of its release of x11vnc with the
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOpenSSL project's "OpenSSL" library (or with modified versions of it
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthat use the same license as the "OpenSSL" library), and distribute
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe linked executables.  You must obey the GNU General Public License
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatin all respects for all of the code used other than "OpenSSL".  If you
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmodify this file, you may extend this exception to your version of the
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfile, but you are not obligated to do so.  If you do not wish to do
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatso, delete this exception statement from your version.
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*/
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* -- user.c -- */
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "x11vnc.h"
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "solid.h"
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "cleanup.h"
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "scan.h"
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "screen.h"
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "unixpw.h"
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "sslhelper.h"
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xwrappers.h"
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "connections.h"
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "inet.h"
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "keyboard.h"
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "cursor.h"
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "remote.h"
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "sslhelper.h"
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "avahi.h"
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid check_switched_user(void);
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid lurk_loop(char *str);
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint switch_user(char *user, int fb_mode);
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint read_passwds(char *passfile);
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid install_passwds(void);
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid check_new_passwds(int force);
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid progress_client(void);
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint wait_for_client(int *argc, char** argv, int http);
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool custom_passwd_check(rfbClientPtr cl, const char *response, int len);
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *xdmcp_insert = NULL;
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void switch_user_task_dummy(void);
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void switch_user_task_solid_bg(void);
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *get_login_list(int with_display);
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char **user_list(char *user_str);
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **home);
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int lurk(char **users);
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int guess_user_and_switch(char *str, int fb_mode);
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int try_user_and_display(uid_t uid, gid_t gid, char *dpystr);
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int switch_user_env(uid_t uid, gid_t gid, char *name, char *home, int fb_mode);
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void try_to_switch_users(void);
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* tasks for after we switch */
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void switch_user_task_dummy(void) {
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	;	/* dummy does nothing */
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void switch_user_task_solid_bg(void) {
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* we have switched users, some things to do. */
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (use_solid_bg && client_count) {
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		solid_bg(0);
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid check_switched_user(void) {
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static time_t sched_switched_user = 0;
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int did_solid = 0;
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int did_dummy = 0;
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int delay = 15;
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time_t now = time(NULL);
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_in_progress) return;
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (started_as_root == 1 && users_list) {
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		try_to_switch_users();
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (started_as_root == 2) {
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/*
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 * schedule the switch_user_tasks() call
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 * 15 secs is for piggy desktops to start up.
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 * might not be enough for slow machines...
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 */
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sched_switched_user = now;
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			did_dummy = 0;
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			did_solid = 0;
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* add other activities */
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! sched_switched_user) {
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! did_dummy) {
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		switch_user_task_dummy();
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		did_dummy = 1;
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! did_solid) {
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int doit = 0;
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *ss = solid_str;
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (now >= sched_switched_user + delay) {
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			doit = 1;
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (ss && strstr(ss, "root:") == ss) {
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    	if (now >= sched_switched_user + 3) {
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				doit = 1;
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strcmp("root", guess_desktop())) {
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(1000 * 1000);
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			doit = 1;
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (doit) {
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			switch_user_task_solid_bg();
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			did_solid = 1;
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (did_dummy && did_solid) {
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sched_switched_user = 0;
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* utilities for switching users */
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *get_login_list(int with_display) {
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *out;
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_UTMPX_H
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int i, cnt, max = 200, ut_namesize = 32;
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int dpymax = 1000, sawdpy[1000];
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	struct utmpx *utx;
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* size based on "username:999," * max */
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	out = (char *) malloc(max * (ut_namesize+1+3+1) + 1);
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	out[0] = '\0';
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<dpymax; i++) {
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sawdpy[i] = 0;
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	setutxent();
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cnt = 0;
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (1) {
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *user, *line, *host, *id;
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char tmp[10];
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int d = -1;
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		utx = getutxent();
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! utx) {
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (utx->ut_type != USER_PROCESS) {
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		user = lblanks(utx->ut_user);
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (*user == '\0') {
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strchr(user, ',')) {
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;	/* unlikely, but comma is our sep. */
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		line = lblanks(utx->ut_line);
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		host = lblanks(utx->ut_host);
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		id   = lblanks(utx->ut_id);
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (with_display) {
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (0 && line[0] != ':' && strcmp(line, "dtlocal")) {
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* XXX useful? */
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				continue;
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (line[0] == ':') {
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (sscanf(line, ":%d", &d) != 1)  {
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					d = -1;
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (d < 0 && host[0] == ':') {
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (sscanf(host, ":%d", &d) != 1)  {
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					d = -1;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (d < 0 && id[0] == ':') {
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (sscanf(id, ":%d", &d) != 1)  {
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					d = -1;
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (d < 0 || d >= dpymax || sawdpy[d]) {
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				continue;
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sawdpy[d] = 1;
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(tmp, ":%d", d);
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* try to eliminate repeats */
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int repeat = 0;
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *q;
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = out;
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while ((q = strstr(q, user)) != NULL) {
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				char *p = q + strlen(user) + strlen(":DPY");
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (q == out || *(q-1) == ',') {
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					/* bounded on left. */
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (*p == ',' || *p == '\0') {
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						/* bounded on right. */
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						repeat = 1;
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = p;
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (repeat) {
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				continue;
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(tmp, ":DPY");
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (*out) {
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strcat(out, ",");
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		strcat(out, user);
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		strcat(out, tmp);
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		cnt++;
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (cnt >= max) {
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	endutxent();
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	out = strdup("");
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return out;
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char **user_list(char *user_str) {
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int n, i;
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *p, **list;
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = user_str;
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	n = 1;
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (*p++) {
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (*p == ',') {
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			n++;
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	list = (char **) calloc((n+1)*sizeof(char *), 1);
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strtok(user_str, ",");
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	i = 0;
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (p) {
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		list[i++] = strdup(p);
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(NULL, ",");
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	list[i] = NULL;
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return list;
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **home) {
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int numerical = 1, gotgroup = 0;
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *q;
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	*uid = (uid_t) -1;
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	*name = NULL;
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	*home = NULL;
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q = user;
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (*q) {
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! isdigit((unsigned char) (*q++))) {
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			numerical = 0;
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (user2group != NULL) {
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		static int *did = NULL;
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int i;
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (did == NULL) {
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int n = 0;
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i = 0;
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (user2group[i] != NULL) {
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				n++;
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				i++;
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			did = (int *) malloc((n+1) * sizeof(int));
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i = 0;
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			for (i=0; i<n; i++) {
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				did[i] = 0;
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		i = 0;
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (user2group[i] != NULL) {
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (strstr(user2group[i], user) == user2group[i]) {
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				char *w = user2group[i] + strlen(user);
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (*w == '.') {
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if (SMALL_FOOTPRINT > 2)
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					gotgroup = 0;
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					struct group* gr = getgrnam(++w);
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (! gr) {
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbLog("Invalid group: %s\n", w);
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						clean_up_exit(1);
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					*gid = gr->gr_gid;
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (! did[i]) {
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbLog("user2uid: using group %s (%d) for %s\n",
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						    w, (int) *gid, user);
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						did[i] = 1;
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					gotgroup = 1;
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (numerical) {
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int u = atoi(user);
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (u < 0) {
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return;
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*uid = (uid_t) u;
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_PWD_H
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (1) {
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		struct passwd *pw;
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (numerical) {
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pw = getpwuid(*uid);
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pw = getpwnam(user);
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (pw) {
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*uid  = pw->pw_uid;
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (! gotgroup) {
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*gid  = pw->pw_gid;
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*name = pw->pw_name;	/* n.b. use immediately */
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*home = pw->pw_dir;
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int lurk(char **users) {
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	uid_t uid;
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	gid_t gid;
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int success = 0, dmin = -1, dmax = -1;
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *p, *logins, **u;
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char **list;
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int lind;
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if ((u = users) != NULL && *u != NULL && *(*u) == ':') {
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int len;
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *tmp;
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* extract min and max display numbers */
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tmp = *u;
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strchr(tmp, '-')) {
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sscanf(tmp, ":%d-%d", &dmin, &dmax) != 2) {
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				dmin = -1;
380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				dmax = -1;
381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (dmin < 0) {
384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sscanf(tmp, ":%d", &dmin) != 1) {
385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				dmin = -1;
386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				dmax = -1;
387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				dmax = dmin;
389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if ((dmin < 0 || dmax < 0) || dmin > dmax || dmax > 10000) {
392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			dmin = -1;
393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			dmax = -1;
394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* get user logins regardless of having a display: */
397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		logins = get_login_list(0);
398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/*
400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 * now we append the list in users (might as well try
401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 * them) this will probably allow weird ways of starting
402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 * xservers to work.
403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 */
404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		len = strlen(logins);
405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		u++;
406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (*u != NULL) {
407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			len += strlen(*u) + strlen(":DPY,");
408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			u++;
409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tmp = (char *) malloc(len+1);
411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		strcpy(tmp, logins);
412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* now concatenate them: */
414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		u = users+1;
415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (*u != NULL) {
416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *q, chk[100];
417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			snprintf(chk, 100, "%s:DPY", *u);
418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = strstr(tmp, chk);
419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (q) {
420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				char *p = q + strlen(chk);
421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (q == tmp || *(q-1) == ',') {
423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					/* bounded on left. */
424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (*p == ',' || *p == '\0') {
425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						/* bounded on right. */
426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						u++;
427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						continue;
428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (*tmp) {
433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				strcat(tmp, ",");
434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strcat(tmp, *u);
436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strcat(tmp, ":DPY");
437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			u++;
438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(logins);
440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		logins = tmp;
441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		logins = get_login_list(1);
444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	list = (char **) calloc((strlen(logins)+2)*sizeof(char *), 1);
447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	lind = 0;
448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strtok(logins, ",");
449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (p) {
450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		list[lind++] = strdup(p);
451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(NULL, ",");
452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(logins);
454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	lind = 0;
456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (list[lind] != NULL) {
457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *user, *name, *home, dpystr[10];
458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q, *t;
459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int ok = 1, dn;
460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = list[lind++];
462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		t = strdup(p);	/* bob:0 */
464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strchr(t, ':');
465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) {
466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(t);
467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*q = '\0';
470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		user = t;
471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(dpystr, 10, ":%s", q+1);
472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (users) {
474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			u = users;
475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ok = 0;
476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (*u != NULL) {
477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (*(*u) == ':') {
478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					u++;
479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					continue;
480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!strcmp(user, *u++)) {
482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					ok = 1;
483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		user2uid(user, &uid, &gid, &name, &home);
489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(t);
490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! uid || ! gid) {
492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ok = 0;
493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! ok) {
496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		for (dn = dmin; dn <= dmax; dn++) {
500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (dn >= 0) {
501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(dpystr, ":%d", dn);
502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (try_user_and_display(uid, gid, dpystr)) {
504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (switch_user_env(uid, gid, name, home, 0)) {
505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("lurk: now user: %s @ %s\n",
506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					    name, dpystr);
507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					started_as_root = 2;
508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					success = 1;
509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				set_env("DISPLAY", dpystr);
511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (success) {
515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 break;
516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	lind = 0;
520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (list[lind] != NULL) {
521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(list[lind]);
522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		lind++;
523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return success;
526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid lurk_loop(char *str) {
529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *tstr = NULL, **users = NULL;
530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(str, "lurk=") != str) {
532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		exit(1);
533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("lurking for logins using: '%s'\n", str);
535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strlen(str) > strlen("lurk=")) {
536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q = strchr(str, '=');
537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tstr = strdup(q+1);
538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		users = user_list(tstr);
539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (1) {
542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (lurk(users)) {
543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sleep(3);
546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (tstr) {
548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(tstr);
549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (users) {
551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(users);
552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int guess_user_and_switch(char *str, int fb_mode) {
556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *dstr, *d;
557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *p, *tstr = NULL, *allowed = NULL, *logins, **users = NULL;
558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int dpy1, ret = 0;
559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char **list;
560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int lind;
561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(0)
563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	d = DisplayString(dpy);
565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* pick out ":N" */
566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	dstr = strchr(d, ':');
567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! dstr) {
568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sscanf(dstr, ":%d", &dpy1) != 1) {
571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (dpy1 < 0) {
574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(str, "guess=") == str && strlen(str) > strlen("guess=")) {
578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		allowed = strchr(str, '=');
579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		allowed++;
580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tstr = strdup(allowed);
582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		users = user_list(tstr);
583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* loop over the utmpx entries looking for this display */
586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	logins = get_login_list(1);
587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	list = (char **) calloc((strlen(logins)+2)*sizeof(char *), 1);
589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	lind = 0;
590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strtok(logins, ",");
591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (p) {
592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		list[lind++] = strdup(p);
593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(NULL, ",");
594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	lind = 0;
597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (list[lind] != NULL) {
598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *user, *q, *t;
599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int dpy2, ok = 1;
600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = list[lind++];
602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		t = strdup(p);
604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strchr(t, ':');
605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) {
606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(t);
607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*q = '\0';
610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		user = t;
611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		dpy2 = atoi(q+1);
612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (users) {
614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char **u = users;
615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ok = 0;
616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (*u != NULL) {
617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!strcmp(user, *u++)) {
618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					ok = 1;
619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (dpy1 != dpy2) {
624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ok = 0;
625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! ok) {
628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(t);
629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (switch_user(user, fb_mode)) {
633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("switched to guessed user: %s\n", user);
634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(t);
635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ret = 1;
636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (tstr) {
640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(tstr);
641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (users) {
643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(users);
644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (logins) {
646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(logins);
647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return ret;
649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int try_user_and_display(uid_t uid, gid_t gid, char *dpystr) {
652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* NO strtoks */
653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_PWD_H
654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	pid_t pid, pidw;
655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *home, *name;
656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int st;
657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	struct passwd *pw;
658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	pw = getpwuid(uid);
660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (pw) {
661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		name = pw->pw_name;
662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		home = pw->pw_dir;
663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/*
668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * We fork here and try to open the display again as the
669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * new user.  Unreadable XAUTHORITY could be a problem...
670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * This is not really needed since we have DISPLAY open but:
671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * 1) is a good indicator this user owns the session and  2)
672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * some activities do spawn new X apps, e.g.  xmessage(1), etc.
673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 */
674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if ((pid = fork()) > 0) {
675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		;
676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (pid == -1) {
677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "could not fork\n");
678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLogPerror("fork");
679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* child */
682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		Display *dpy2 = NULL;
683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int rc;
684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		signal(SIGHUP,  SIG_DFL);
686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		signal(SIGINT,  SIG_DFL);
687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		signal(SIGQUIT, SIG_DFL);
688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		signal(SIGTERM, SIG_DFL);
689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = switch_user_env(uid, gid, name, home, 0);
691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! rc) {
692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			exit(1);
693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fclose(stderr);
696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		dpy2 = XOpenDisplay_wr(dpystr);
697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (dpy2) {
698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			XCloseDisplay_wr(dpy2);
699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			exit(0);	/* success */
700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			exit(2);	/* fail */
702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* see what the child says: */
706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	pidw = waitpid(pid, &st, 0);
707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (pidw == pid && WIFEXITED(st) && WEXITSTATUS(st) == 0) {
708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 1;
709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* LIBVNCSERVER_HAVE_FORK ... */
711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 0;
712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint switch_user(char *user, int fb_mode) {
715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* NO strtoks */
716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int doit = 0;
717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	uid_t uid = 0;
718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	gid_t gid = 0;
719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *name, *home;
720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (*user == '+') {
722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		doit = 1;
723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		user++;
724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	ssl_helper_pid(0, -2);	/* waitall */
727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(user, "guess=") == user) {
729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return guess_user_and_switch(user, fb_mode);
730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	user2uid(user, &uid, &gid, &name, &home);
733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (uid == (uid_t) -1 || uid == 0) {
735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (gid == 0) {
738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! doit && dpy) {
742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* see if this display works: */
743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *dstr = DisplayString(dpy);
744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		doit = try_user_and_display(uid, gid, dstr);
745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (doit) {
748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int rc = switch_user_env(uid, gid, name, home, fb_mode);
749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (rc) {
750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			started_as_root = 2;
751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return rc;
753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int switch_user_env(uid_t uid, gid_t gid, char *name, char *home, int fb_mode) {
759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* NO strtoks */
760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *xauth;
761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int reset_fb = 0;
762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int grp_ok = 0;
763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !LIBVNCSERVER_HAVE_SETUID
765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 0;
766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/*
768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * OK, tricky here, we need to free the shm... otherwise
769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 * we won't be able to delete it as the other user...
770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 */
771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fb_mode == 1 && (using_shm && ! xform24to32)) {
772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		reset_fb = 1;
773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_shm(0);
774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free_tiles();
775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_INITGROUPS
777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_PWD_H
778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getpwuid(uid) != NULL && getenv("X11VNC_SINGLE_GROUP") == NULL) {
779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		struct passwd *p = getpwuid(uid);
780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* another possibility is p->pw_gid instead of gid */
781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (setgid(gid) == 0 && initgroups(p->pw_name, gid) == 0)  {
782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			grp_ok = 1;
783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLogPerror("initgroups");
785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		endgrent();
787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! grp_ok) {
791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (setgid(gid) == 0) {
792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			grp_ok = 1;
793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! grp_ok) {
796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (reset_fb) {
797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* 2 means we did clean_shm and free_tiles */
798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_new_fb(2);
799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (setuid(uid) != 0) {
804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (reset_fb) {
805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* 2 means we did clean_shm and free_tiles */
806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_new_fb(2);
807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (reset_fb) {
812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		do_new_fb(2);
813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	xauth = getenv("XAUTHORITY");
816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (xauth && access(xauth, R_OK) != 0) {
817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*(xauth-2) = '_';	/* yow */
818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("USER", name);
821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("LOGNAME", name);
822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("HOME", home);
823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 1;
824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void try_to_switch_users(void) {
827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static time_t last_try = 0;
828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time_t now = time(NULL);
829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *users, *p;
830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getuid() && geteuid()) {
832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("try_to_switch_users: not root\n");
833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		started_as_root = 2;
834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!last_try) {
837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_try = now;
838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (now <= last_try + 2) {
839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* try every 3 secs or so */
840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	last_try = now;
843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	users = strdup(users_list);
845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(users, "guess=") == users) {
847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (switch_user(users, 1)) {
848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			started_as_root = 2;
849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(users);
851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strtok(users, ",");
855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (p) {
856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (switch_user(p, 1)) {
857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			started_as_root = 2;
858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("try_to_switch_users: now %s\n", p);
859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(NULL, ",");
862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(users);
864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint read_passwds(char *passfile) {
867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char line[1024];
868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *filename;
869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char **old_passwd_list = passwd_list;
870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int linecount = 0, i, remove = 0, read_mode = 0, begin_vo = -1;
871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	struct stat sbuf;
872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int max = -1;
873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FILE *in = NULL;
874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static time_t last_read = 0;
875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int read_cnt = 0;
876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int db_passwd = 0;
877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (max < 0) {
879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		max = 1000;
880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (getenv("X11VNC_MAX_PASSWDS")) {
881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			max = atoi(getenv("X11VNC_MAX_PASSWDS"));
882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	filename = passfile;
886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(filename, "rm:") == filename) {
887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		filename += strlen("rm:");
888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		remove = 1;
889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(filename, "read:") == filename) {
890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		filename += strlen("read:");
891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		read_mode = 1;
892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (stat(filename, &sbuf) == 0) {
893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sbuf.st_mtime <= last_read) {
894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				return 1;
895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			last_read = sbuf.st_mtime;
897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(filename, "cmd:") == filename) {
899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int rc;
900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		filename += strlen("cmd:");
902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		read_mode = 1;
903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		in = tmpfile();
904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (in == NULL) {
905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("run_user_command tmpfile() failed: %s\n",
906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    filename);
907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = run_user_command(filename, latest_client, "read_passwds",
910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    NULL, 0, in);
911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (rc != 0) {
912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("run_user_command command failed: %s\n",
913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    filename);
914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rewind(in);
917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(filename, "custom:") == filename) {
918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 1;
919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (in == NULL && stat(filename, &sbuf) == 0) {
922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* (poor...) upper bound to number of lines */
923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		max = (int) sbuf.st_size;
924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_read = sbuf.st_mtime;
925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* create 1 more than max to have it be the ending NULL */
928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	passwd_list = (char **) malloc( (max+1) * (sizeof(char *)) );
929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<max+1; i++) {
930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		passwd_list[i] = NULL;
931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (in == NULL) {
934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		in = fopen(filename, "r");
935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (in == NULL) {
937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("cannot open passwdfile: %s\n", passfile);
938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLogPerror("fopen");
939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (remove) {
940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unlink(filename);
941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("DEBUG_PASSWDFILE") != NULL) {
946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		db_passwd = 1;
947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (fgets(line, 1024, in) != NULL) {
950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *p;
951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int blank = 1;
952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int len = strlen(line);
953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (db_passwd) {
955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "read_passwds: raw line: %s\n", line);
956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (len == 0) {
959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (line[len-1] == '\n') {
961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			line[len-1] = '\0';
962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (line[0] == '\0') {
964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(line, "__SKIP__") != NULL) {
967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(line, "__COMM__") == line) {
970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!strcmp(line, "__BEGIN_VIEWONLY__")) {
973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (begin_vo < 0) {
974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				begin_vo = linecount;
975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (line[0] == '#') {
979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* commented out, cannot have password beginning with # */
980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = line;
983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (*p != '\0') {
984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (! isspace((unsigned char) (*p))) {
985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				blank = 0;
986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p++;
989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (blank) {
991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		passwd_list[linecount++] = strdup(line);
995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (db_passwd) {
996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "read_passwds: keepline: %s\n", line);
997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "read_passwds: begin_vo: %d\n", begin_vo);
998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (linecount >= max) {
1001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("read_passwds: hit max passwd: %d\n", max);
1002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
1003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fclose(in);
1006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<1024; i++) {
1008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		line[i] = '\0';
1009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (remove) {
1012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		unlink(filename);
1013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! linecount) {
1016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("cannot read a valid line from passwdfile: %s\n",
1017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    passfile);
1018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (read_cnt == 0) {
1019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return 0;
1022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	read_cnt++;
1025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<linecount; i++) {
1027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q, *p = passwd_list[i];
1028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!strcmp(p, "__EMPTY__")) {
1029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*p = '\0';
1030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if ((q = strstr(p, "__COMM__")) != NULL) {
1031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*q = '\0';
1032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		passwd_list[i] = strdup(p);
1034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (db_passwd) {
1035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "read_passwds: trimline: %s\n", p);
1036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		strzero(p);
1038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	begin_viewonly = begin_vo;
1041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (read_mode && read_cnt > 1) {
1042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (viewonly_passwd) {
1043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(viewonly_passwd);
1044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			viewonly_passwd = NULL;
1045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (begin_viewonly < 0 && linecount == 2) {
1049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* for compatibility with previous 2-line usage: */
1050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		viewonly_passwd = strdup(passwd_list[1]);
1051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (db_passwd) {
1052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "read_passwds: linecount is 2.\n");
1053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (screen) {
1055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char **apd = (char **) screen->authPasswdData;
1056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (apd) {
1057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (apd[0] != NULL) {
1058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					strzero(apd[0]);
1059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				apd[0] = strdup(passwd_list[0]);
1061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		begin_viewonly = 1;
1064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (old_passwd_list != NULL) {
1067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *p;
1068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		i = 0;
1069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (old_passwd_list[i] != NULL) {
1070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = old_passwd_list[i];
1071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strzero(p);
1072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(old_passwd_list[i]);
1073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
1074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(old_passwd_list);
1076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 1;
1078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid install_passwds(void) {
1081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (viewonly_passwd) {
1082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* append the view only passwd after the normal passwd */
1083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char **passwds_new = (char **) malloc(3*sizeof(char *));
1084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char **passwds_old = (char **) screen->authPasswdData;
1085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		passwds_new[0] = passwds_old[0];
1086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		passwds_new[1] = viewonly_passwd;
1087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		passwds_new[2] = NULL;
1088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* mutex */
1089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		screen->authPasswdData = (void*) passwds_new;
1090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (passwd_list) {
1091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int i = 0;
1092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while(passwd_list[i] != NULL) {
1093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
1094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (begin_viewonly < 0) {
1096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			begin_viewonly = i+1;
1097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* mutex */
1099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		screen->authPasswdData = (void*) passwd_list;
1100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		screen->authPasswdFirstViewOnly = begin_viewonly;
1101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid check_new_passwds(int force) {
1105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static time_t last_check = 0;
1106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time_t now;
1107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! passwdfile) {
1109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
1110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(passwdfile, "read:") != passwdfile) {
1112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
1113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_in_progress) return;
1115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (force) {
1117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_check = 0;
1118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	now = time(NULL);
1121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (now > last_check + 1) {
1122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (read_passwds(passwdfile)) {
1123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			install_passwds();
1124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_check = now;
1126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool custom_passwd_check(rfbClientPtr cl, const char *response, int len) {
1130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *input, *cmd;
1131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char num[16];
1132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int j, i, n, rc;
1133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("custom_passwd_check: len=%d\n", len);
1135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!passwdfile || strstr(passwdfile, "custom:") != passwdfile) {
1137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return FALSE;
1138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cmd = passwdfile + strlen("custom:");
1140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sprintf(num, "%d\n", len);
1142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	input = (char *) malloc(2 * len + 16 + 1);
1144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	input[0] = '\0';
1146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	strcat(input, num);
1147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	n = strlen(num);
1148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	j = n;
1150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i < len; i++) {
1151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		input[j] = cl->authChallenge[i];
1152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		j++;
1153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i < len; i++) {
1155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		input[j] = response[i];
1156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		j++;
1157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rc = run_user_command(cmd, cl, "custom_passwd", input, n+2*len, NULL);
1159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(input);
1160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (rc == 0) {
1161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return TRUE;
1162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return FALSE;
1164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void handle_one_http_request(void) {
1168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("handle_one_http_request: begin.\n");
1169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (inetd || screen->httpPort == 0) {
1170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int port = find_free_port(5800, 5860);
1171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (port) {
1172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* mutex */
1173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			screen->httpPort = port;
1174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("handle_one_http_request: no http port.\n");
1176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	screen->autoPort = FALSE;
1180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	screen->port = 0;
1181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	http_connections(1);
1183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbInitServer(screen);
1185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!inetd) {
1187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* XXX ipv6 */
1188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int conn = 0;
1189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (1) {
1190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (0) fprintf(stderr, "%d %d %d  %d\n", conn, screen->listenSock, screen->httpSock, screen->httpListenSock);
1191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(10 * 1000);
1192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbHttpCheckFds(screen);
1193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (conn) {
1194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (screen->httpSock < 0) {
1195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
1196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
1198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (screen->httpSock >= 0) {
1199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					conn = 1;
1200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!screen->httpDir) {
1203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
1204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (screen->httpListenSock < 0) {
1206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
1207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("handle_one_http_request: finished.\n");
1210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
1211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* inetd case: */
1213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_FORK
1214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pid_t pid;
1215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int s_in = screen->inetdSock;
1216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (s_in < 0) {
1217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("handle_one_http_request: inetdSock not set up.\n");
1218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pid = fork();
1221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (pid < 0) {
1222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("handle_one_http_request: could not fork.\n");
1223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (pid > 0) {
1225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int status;
1226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pid_t pidw;
1227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (1) {
1228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbHttpCheckFds(screen);
1229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				pidw = waitpid(pid, &status, WNOHANG);
1230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (pidw == pid && WIFEXITED(status)) {
1231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
1232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else if (pidw < 0) {
1233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
1234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("handle_one_http_request: finished.\n");
1237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return;
1238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int sock = connect_tcp("127.0.0.1", screen->httpPort);
1240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sock < 0) {
1241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				exit(1);
1242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			raw_xfer(sock, s_in, s_in);
1244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			exit(0);
1245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("handle_one_http_request: fork not supported.\n");
1248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid user_supplied_opts(char *opts) {
1254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *p, *str;
1255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *allow[] = {
1256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"skip-display", "skip-auth", "skip-shared",
1257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"scale", "scale_cursor", "sc", "solid", "so", "id",
1258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"clear_mods", "cm", "clear_keys", "ck", "repeat",
1259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"clear_all", "ca",
1260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"speeds", "sp", "readtimeout", "rd",
1261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"rotate", "ro",
1262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"geometry", "geom", "ge",
1263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"noncache", "nc",
1264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"nodisplay", "nd",
1265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"viewonly", "vo",
1266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		"tag",
1267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		NULL
1268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	};
1269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("X11VNC_NO_UNIXPW_OPTS")) {
1271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
1272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	str = strdup(opts);
1275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strtok(str, ",");
1277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (p) {
1278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q;
1279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int i, n, m, ok = 0;
1280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		i = 0;
1282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (allow[i] != NULL) {
1283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (strstr(allow[i], "skip-")) {
1284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				i++;
1285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				continue;
1286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (strstr(p, allow[i]) == p) 	{
1288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				ok = 1;
1289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
1290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
1292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! ok && strpbrk(p, "0123456789") == p &&
1295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    sscanf(p, "%d/%d", &n, &m) == 2) {
1296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (scale_str) free(scale_str);
1297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			scale_str = strdup(p);
1298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (ok) {
1299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (0 && strstr(p, "display=") == p) {
1300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (use_dpy) free(use_dpy);
1301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				use_dpy = strdup(p + strlen("display="));
1302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (0 && strstr(p, "auth=") == p) {
1303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (auth_file) free(auth_file);
1304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				auth_file = strdup(p + strlen("auth="));
1305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (0 && !strcmp(p, "shared")) {
1306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				shared = 1;
1307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "scale=") == p) {
1308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (scale_str) free(scale_str);
1309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				scale_str = strdup(p + strlen("scale="));
1310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "scale_cursor=") == p ||
1311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    strstr(p, "sc=") == p) {
1312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (scale_cursor_str) free(scale_cursor_str);
1313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = strchr(p, '=') + 1;
1314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				scale_cursor_str = strdup(q);
1315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "rotate=") == p ||
1316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    strstr(p, "ro=") == p) {
1317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (rotating_str) free(rotating_str);
1318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = strchr(p, '=') + 1;
1319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rotating_str = strdup(q);
1320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "solid") || !strcmp(p, "so")) {
1321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				use_solid_bg = 1;
1322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!solid_str) {
1323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					solid_str = strdup(solid_default);
1324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "viewonly") || !strcmp(p, "vo")) {
1326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				view_only = 1;
1327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "solid=") == p ||
1328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    strstr(p, "so=") == p) {
1329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				use_solid_bg = 1;
1330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (solid_str) free(solid_str);
1331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = strchr(p, '=') + 1;
1332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!strcmp(q, "R")) {
1333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					solid_str = strdup("root:");
1334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
1335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					solid_str = strdup(q);
1336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "id=") == p) {
1338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unsigned long win;
1339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = p + strlen("id=");
1340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (strcmp(q, "pick")) {
1341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (scan_hexdec(q, &win)) {
1342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						subwin = win;
1343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "clear_mods") ||
1346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    !strcmp(p, "cm")) {
1347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clear_mods = 1;
1348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "clear_keys") ||
1349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    !strcmp(p, "ck")) {
1350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clear_mods = 2;
1351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "clear_all") ||
1352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    !strcmp(p, "ca")) {
1353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clear_mods = 3;
1354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "noncache") ||
1355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    !strcmp(p, "nc")) {
1356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				ncache  = 0;
1357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				ncache0 = 0;
1358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "nc=") == p) {
1359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int n2 = atoi(p + strlen("nc="));
1360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (nabs(n2) < nabs(ncache)) {
1361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (ncache < 0) {
1362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						ncache = -nabs(n2);
1363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					} else {
1364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						ncache = nabs(n2);
1365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (!strcmp(p, "repeat")) {
1368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				no_autorepeat = 0;
1369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "speeds=") == p ||
1370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    strstr(p, "sp=") == p) {
1371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (speeds_str) free(speeds_str);
1372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = strchr(p, '=') + 1;
1373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				speeds_str = strdup(q);
1374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = speeds_str;
1375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				while (*q != '\0') {
1376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (*q == '-') {
1377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						*q = ',';
1378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					q++;
1380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (strstr(p, "readtimeout=") == p ||
1382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    strstr(p, "rd=") == p) {
1383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = strchr(p, '=') + 1;
1384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbMaxClientWait = atoi(q) * 1000;
1385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("skipping option: %s\n", p);
1388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(NULL, ",");
1390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(str);
1392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void vnc_redirect_timeout (int sig) {
1395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	write(2, "timeout: no clients connected.\n", 31);
1396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sig) {};
1397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	exit(0);
1398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void do_chvt(int vt) {
1401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char chvt[100];
1402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
1403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("running: %s\n", chvt);
1404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	system(chvt);
1405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sleep(2);
1406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void setup_fake_fb(XImage* fb_image, int w, int h, int b) {
1409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fake_fb) {
1410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(fake_fb);
1411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fake_fb = (char *) calloc(w*h*b/8, 1);
1413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->data = fake_fb;
1415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->format = ZPixmap;
1416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->width  = w;
1417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->height = h;
1418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->bits_per_pixel = b;
1419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->bytes_per_line = w*b/8;
1420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image->bitmap_unit = -1;
1421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (b >= 24) {
1422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->depth = 24;
1423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->red_mask   = 0xff0000;
1424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->green_mask = 0x00ff00;
1425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->blue_mask  = 0x0000ff;
1426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (b >= 16) {
1427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->depth = 16;
1428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->red_mask   = 0x003f;
1429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->green_mask = 0x07c0;
1430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->blue_mask  = 0xf800;
1431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (b >= 2) {
1432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->depth = 8;
1433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->red_mask   = 0x07;
1434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->green_mask = 0x38;
1435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->blue_mask  = 0xc0;
1436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->depth = 1;
1438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->red_mask   = 0x1;
1439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->green_mask = 0x1;
1440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fb_image->blue_mask  = 0x1;
1441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	depth = fb_image->depth;
1444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	dpy_x = wdpy_x = w;
1446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	dpy_y = wdpy_y = h;
1447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	off_x = 0;
1448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	off_y = 0;
1449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid do_announce_http(void);
1452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid do_mention_java_urls(void);
1453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void setup_service(void) {
1455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (remote_direct) {
1456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
1457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!inetd) {
1459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		do_mention_java_urls();
1460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		do_announce_http();
1461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!use_openssl) {
1462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			announce(screen->port, use_openssl, NULL);
1463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stdout, "PORT=%d\n", screen->port);
1464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stdout, "PORT=%d\n", screen->port);
1466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (stunnel_port) {
1467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				fprintf(stdout, "SSLPORT=%d\n", stunnel_port);
1468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (use_openssl) {
1469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				fprintf(stdout, "SSLPORT=%d\n", screen->port);
1470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fflush(stdout);
1473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!use_openssl && avahi) {
1474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *name = rfb_desktop_name;
1475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!name) {
1476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			name = use_dpy;
1477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		avahi_initialise();
1479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		avahi_advertise(name, this_host(), screen->port);
1480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void check_waitbg(void) {
1484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("WAITBG")) {
1485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
1486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int p, n;
1487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if ((p = fork()) > 0)  {
1488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			exit(0);
1489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (p == -1) {
1490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLogEnable(1);
1491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "could not fork\n");
1492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			perror("fork");
1493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (setsid() == -1) {
1496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLogEnable(1);
1497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(stderr, "setsid failed\n");
1498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			perror("setsid");
1499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* adjust our stdio */
1502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		n = open("/dev/null", O_RDONLY);
1503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		dup2(n, 0);
1504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		dup2(n, 1);
1505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! logfile) {
1506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			dup2(n, 2);
1507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (n > 2) {
1509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			close(n);
1510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void setup_client_connect(int *did_client_connect) {
1518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (client_connect != NULL) {
1519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *remainder = NULL;
1520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (inetd) {
1521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: -connect disallowed in inetd mode: %s\n",
1522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    client_connect);
1523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (screen && screen->clientHead) {
1524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: -connect disallowed: client exists: %s\n",
1525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    client_connect);
1526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strchr(client_connect, '=')) {
1527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: invalid -connect string: %s\n",
1528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    client_connect);
1529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *q = strchr(client_connect, ',');
1531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (q) {
1532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: only using first"
1533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    " connect host in: %s\n", client_connect);
1534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				remainder = strdup(q+1);
1535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*q = '\0';
1536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: reverse_connect(%s)\n",
1538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    client_connect);
1539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			reverse_connect(client_connect);
1540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*did_client_connect = 1;
1541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(client_connect);
1543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (remainder != NULL) {
1544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* reset to host2,host3,... */
1545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			client_connect = remainder;
1546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			client_connect = NULL;
1548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void loop_for_connect(int did_client_connect) {
1553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int loop = 0;
1554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	time_t start = time(NULL);
1555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (first_conn_timeout < 0) {
1557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		first_conn_timeout = -first_conn_timeout;
1558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (1) {
1561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		loop++;
1562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (first_conn_timeout && time(NULL) > start + first_conn_timeout) {
1563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("no client connect after %d seconds.\n", first_conn_timeout);
1564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			shut_down = 1;
1565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (shut_down) {
1567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(0);
1568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (loop < 2) {
1570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (did_client_connect) {
1571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				goto screen_check;
1572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (inetd) {
1574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				goto screen_check;
1575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (screen && screen->clientHead) {
1577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				goto screen_check;
1578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if ((use_openssl || use_stunnel) && !inetd) {
1581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int enc_none = (enc_str && !strcmp(enc_str, "none"));
1582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!use_stunnel || enc_none) {
1583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				check_openssl();
1584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				check_https();
1585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/*
1587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 * This is to handle an initial verify cert from viewer,
1588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 * they disconnect right after fetching the cert.
1589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			 */
1590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (use_threads) {
1591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				usleep(10 * 1000);
1592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
1593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbPE(-1);
1594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (screen && screen->clientHead) {
1596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int i;
1597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (unixpw) {
1598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (! unixpw_in_progress && !vencrypt_enable_plain_login) {
1599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbLog("unixpw but no unixpw_in_progress\n");
1600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						clean_up_exit(1);
1601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (unixpw_client && unixpw_client->onHold) {
1603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbLog("taking unixpw_client off hold\n");
1604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						unixpw_client->onHold = FALSE;
1605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				for (i=0; i<10; i++) {
1608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (shut_down) {
1609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						clean_up_exit(0);
1610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					usleep(20 * 1000);
1612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (0) rfbLog("wait_for_client: %d\n", i);
1613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (! use_threads) {
1615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						if (unixpw) {
1616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat							unixpw_in_rfbPE = 1;
1617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						}
1618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbPE(-1);
1619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						if (unixpw) {
1620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat							unixpw_in_rfbPE = 0;
1621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						}
1622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (unixpw && !unixpw_in_progress) {
1625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						/* XXX too soon. */
1626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						goto screen_check;
1627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (!screen->clientHead) {
1629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
1630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (use_openssl) {
1634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			check_openssl();
1635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (use_threads) {
1638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(10 * 1000);
1639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbPE(-1);
1641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		screen_check:
1644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! screen || ! screen->clientHead) {
1645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(100 * 1000);
1646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
1647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: got client\n");
1650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		break;
1651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void do_unixpw_loop(void) {
1655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw) {
1656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! unixpw_in_progress && !vencrypt_enable_plain_login) {
1657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("unixpw but no unixpw_in_progress\n");
1658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (unixpw_client && unixpw_client->onHold) {
1661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("taking unixpw_client off hold.\n");
1662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unixpw_client->onHold = FALSE;
1663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (1) {
1665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (shut_down) {
1666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(0);
1667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (! use_threads) {
1669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unixpw_in_rfbPE = 1;
1670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbPE(-1);
1671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unixpw_in_rfbPE = 0;
1672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (unixpw_in_progress) {
1674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				static double lping = 0.0;
1675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (lping < dnow() + 5) {
1676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					mark_rect_as_modified(0, 0, 1, 1, 1);
1677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					lping = dnow();
1678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (time(NULL) > unixpw_last_try_time + 45) {
1680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("unixpw_deny: timed out waiting for reply.\n");
1681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					unixpw_deny();
1682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				usleep(20 * 1000);
1684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				continue;
1685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: unixpw finished.\n");
1687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
1688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void vnc_redirect_loop(char *vnc_redirect_test, int *vnc_redirect_cnt) {
1693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw) {
1694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: -unixpw and Xvnc.redirect not allowed\n");
1695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (client_connect) {
1698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: -connect and Xvnc.redirect not allowed\n");
1699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (inetd) {
1702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (use_openssl) {
1703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			accept_openssl(OPENSSL_INETD, -1);
1704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pid_t pid = 0;
1707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* XXX ipv6 */
1708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (screen->httpListenSock >= 0) {
1709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_FORK
1710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if ((pid = fork()) > 0) {
1711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				close(screen->httpListenSock);
1712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* mutex */
1713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				screen->httpListenSock = -2;
1714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				usleep(500 * 1000);
1715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
1716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				close(screen->listenSock);
1717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				screen->listenSock = -1;
1718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				while (1) {
1719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					usleep(10 * 1000);
1720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbHttpCheckFds(screen);
1721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				exit(1);
1723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (first_conn_timeout) {
1729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (first_conn_timeout < 0) {
1730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				first_conn_timeout = -first_conn_timeout;
1731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			signal(SIGALRM, vnc_redirect_timeout);
1733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			alarm(first_conn_timeout);
1734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (use_openssl) {
1736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int i;
1737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (pid == 0) {
1738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				accept_openssl(OPENSSL_VNC, -1);
1739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
1740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				for (i=0; i < 16; i++) {
1741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					accept_openssl(OPENSSL_VNC, -1);
1742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("iter %d: vnc_redirect_sock: %d\n", i, vnc_redirect_sock);
1743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (vnc_redirect_sock >= 0) {
1744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
1745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			struct sockaddr_in addr;
1750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __hpux
1751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int addrlen = sizeof(addr);
1752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			socklen_t addrlen = sizeof(addr);
1754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (screen->listenSock < 0) {
1756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: Xvnc.redirect not listening... sock=%d port=%d\n", screen->listenSock, screen->port);
1757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(1);
1758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			vnc_redirect_sock = accept(screen->listenSock, (struct sockaddr *)&addr, &addrlen);
1760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (first_conn_timeout) {
1762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			alarm(0);
1763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (pid > 0) {
1765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_FORK
1766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int rc;
1767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pid_t pidw;
1768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: kill TERM: %d\n", (int) pid);
1769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			kill(pid, SIGTERM);
1770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(1000 * 1000);	/* 1.0 sec */
1771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pidw = waitpid(pid, &rc, WNOHANG);
1772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (pidw <= 0) {
1773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				usleep(1000 * 1000);	/* 1.0 sec */
1774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				pidw = waitpid(pid, &rc, WNOHANG);
1775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect_sock < 0) {
1782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: vnc_redirect failed.\n");
1783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!inetd && use_openssl) {
1786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* check for Fetch Cert closing */
1787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fd_set rfds;
1788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		struct timeval tv;
1789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int nfds;
1790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		usleep(300*1000);
1792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		FD_ZERO(&rfds);
1794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		FD_SET(vnc_redirect_sock, &rfds);
1795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tv.tv_sec = 0;
1797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tv.tv_usec = 200000;
1798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nfds = select(vnc_redirect_sock+1, &rfds, NULL, NULL, &tv);
1799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: vnc_redirect nfds: %d\n", nfds);
1801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (nfds > 0) {
1802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int n;
1803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			n = read(vnc_redirect_sock, vnc_redirect_test, 1);
1804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (n <= 0) {
1805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				close(vnc_redirect_sock);
1806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				vnc_redirect_sock = -1;
1807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: waiting for 2nd connection (Fetch Cert?)\n");
1808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				accept_openssl(OPENSSL_VNC, -1);
1809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (vnc_redirect_sock < 0) {
1810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("wait_for_client: vnc_redirect failed.\n");
1811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					clean_up_exit(1);
1812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
1814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*vnc_redirect_cnt = n;
1815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void do_vnc_redirect(int created_disp, char *vnc_redirect_host, int vnc_redirect_port,
1821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int vnc_redirect_cnt, char *vnc_redirect_test) {
1822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *q = strrchr(use_dpy, ':');
1823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int vdpy = -1, sock = -1;
1824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int s_in, s_out, i;
1825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect == 2) {
1826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char num[32];
1827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(num, ":%d", vnc_redirect_port);
1828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = num;
1829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!q) {
1831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: can't find number in X display: %s\n", use_dpy);
1832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sscanf(q+1, "%d", &vdpy) != 1) {
1835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: can't find number in X display: %s\n", q);
1836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vdpy == -1 && vnc_redirect != 2) {
1839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: can't find number in X display: %s\n", q);
1840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect == 2) {
1843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (vdpy < 0) {
1844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			vdpy = -vdpy;
1845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (vdpy < 200) {
1846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			vdpy += 5900;
1847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		vdpy += 5900;
1850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (created_disp) {
1852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		usleep(1000*1000);
1853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i < 20; i++) {
1855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sock = connect_tcp(vnc_redirect_host, vdpy);
1856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sock >= 0) {
1857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
1858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: ...\n");
1860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		usleep(500*1000);
1861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (sock < 0) {
1863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: could not connect to a VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
1864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (inetd) {
1867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		s_in  = fileno(stdin);
1868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		s_out = fileno(stdout);
1869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		s_in = s_out = vnc_redirect_sock;
1871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect_cnt > 0) {
1873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		write(vnc_redirect_sock, vnc_redirect_test, vnc_redirect_cnt);
1874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("wait_for_client: switching control to VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
1876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	raw_xfer(sock, s_in, s_out);
1877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatextern char find_display[];
1880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatextern char create_display[];
1881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *setup_cmd(char *str, int *vnc_redirect, char **vnc_redirect_host, int *vnc_redirect_port, int db) {
1883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *cmd = NULL;
1884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (no_external_cmds || !cmd_ok("WAIT")) {
1886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client external cmds not allowed:"
1887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    " %s\n", use_dpy);
1888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
1889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cmd = str + strlen("cmd=");
1892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(cmd, "FINDDISPLAY-print")) {
1893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stdout, "%s", find_display);
1894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(0);
1895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(cmd, "FINDDISPLAY-run")) {
1897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char tmp[] = "/tmp/fd.XXXXXX";
1898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char com[100];
1899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int fd = mkstemp(tmp);
1900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (fd >= 0) {
1901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int ret;
1902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			write(fd, find_display, strlen(find_display));
1903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			close(fd);
1904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			set_env("FINDDISPLAY_run", "1");
1905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(com, "/bin/sh %s -n", tmp);
1906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ret = system(com);
1907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
1908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (got_findauth && !getenv("FD_XDM")) {
1909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (getuid() == 0 || geteuid() == 0) {
1910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						set_env("FD_XDM", "1");
1911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						system(com);
1912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
1913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
1914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
1915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		unlink(tmp);
1917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		exit(0);
1918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(str, "FINDCREATEDISPLAY-print")) {
1920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stdout, "%s", create_display);
1921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(0);
1922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (db) fprintf(stderr, "cmd: %s\n", cmd);
1924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(str, "FINDCREATEDISPLAY") || strstr(str, "FINDDISPLAY")) {
1925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(str, "Xvnc.redirect") || strstr(str, "X.redirect")) {
1926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*vnc_redirect = 1;
1927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(cmd, "FINDDISPLAY-vnc_redirect") == cmd) {
1930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int p;
1931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char h[256];
1932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strlen(cmd) >= 256) {
1933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client string too long: %s\n", str);
1934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		h[0] = '\0';
1937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%d", &p) == 1) {
1938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			;
1939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%s %d", h, &p) == 2) {
1940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			;
1941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
1942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client bad string: %s\n", cmd);
1943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
1944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*vnc_redirect_port = p;
1946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strcmp(h, "")) {
1947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*vnc_redirect_host = strdup(h);
1948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*vnc_redirect = 2;
1950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: vnc_redirect: %s:%d\n", *vnc_redirect_host, *vnc_redirect_port);
1951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return cmd;
1953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *build_create_cmd(char *cmd, int *saw_xdmcp, char *usslpeer, char *tmp) {
1956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *create_cmd = NULL;
1957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *opts = strchr(cmd, '-');
1958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char st[] = "";
1959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char fdgeom[128], fdsess[128], fdopts[128], fdextra[256], fdprog[128];
1960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char fdxsrv[128], fdxdum[128], fdcups[128], fdesd[128];
1961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char fdnas[128], fdsmb[128], fdtag[128], fdxdmcpif[128];
1962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char cdout[128];
1963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (opts) {
1965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		opts++;
1966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(opts, "xdmcp")) {
1967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*saw_xdmcp = 1;
1968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
1969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
1970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		opts = st;
1971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sprintf(fdgeom, "NONE");
1973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdsess[0] = '\0';
1974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdgeom[0] = '\0';
1975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdopts[0] = '\0';
1976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdextra[0] = '\0';
1977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdprog[0] = '\0';
1978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdxsrv[0] = '\0';
1979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdxdum[0] = '\0';
1980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdcups[0] = '\0';
1981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdesd[0]  = '\0';
1982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdnas[0]  = '\0';
1983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdsmb[0]  = '\0';
1984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdtag[0]  = '\0';
1985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fdxdmcpif[0]  = '\0';
1986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cdout[0]  = '\0';
1987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw && keep_unixpw_opts && !getenv("X11VNC_NO_UNIXPW_OPTS")) {
1989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q, *p, *t = strdup(keep_unixpw_opts);
1990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(t, "gnome")) {
1992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "gnome");
1993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "kde")) {
1994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "kde");
1995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "lxde")) {
1996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "lxde");
1997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "twm")) {
1998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "twm");
1999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "fvwm")) {
2000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "fvwm");
2001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "mwm")) {
2002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "mwm");
2003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "cde")) {
2004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "cde");
2005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "dtwm")) {
2006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "dtwm");
2007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "xterm")) {
2008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "xterm");
2009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "wmaker")) {
2010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "wmaker");
2011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "xfce")) {
2012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "xfce");
2013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "enlightenment")) {
2014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "enlightenment");
2015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "Xsession")) {
2016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "Xsession");
2017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (strstr(t, "failsafe")) {
2018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(fdsess, "failsafe");
2019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(t, "ge=");
2022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) q = strstr(t, "geom=");
2023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) q = strstr(t, "geometry=");
2024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (q) {
2025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int ok = 1;
2026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = strstr(q, "=");
2027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q++;
2028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = strstr(q, ",");
2029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (p) *p = '\0';
2030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = q;
2031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (*p) {
2032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (*p == 'x') {
2033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					;
2034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else if (isdigit((int) *p)) {
2035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					;
2036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
2037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					ok = 0;
2038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
2039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				p++;
2041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (ok && strlen(q) < 32) {
2043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(fdgeom, "%s", q);
2044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!quiet) {
2045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("set create display geom: %s\n", fdgeom);
2046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(t, "cups=");
2050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (q) {
2051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int p;
2052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sscanf(q, "cups=%d", &p) == 1) {
2053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(fdcups, "%d", p);
2054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(t, "esd=");
2057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (q) {
2058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int p;
2059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sscanf(q, "esd=%d", &p) == 1) {
2060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(fdesd, "%d", p);
2061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!getenv("FD_TAG")) {
2064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *s = NULL;
2065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = strstr(t, "tag=");
2067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (q) s = strchr(q, ',');
2068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (s) *s = '\0';
2069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (q && strlen(q) < 120) {
2071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				char *p;
2072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int ok = 1;
2073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q = strchr(q, '=') + 1;
2074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				p = q;
2075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				while (*p != '\0') {
2076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					char c = *p;
2077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (*p == '_' || *p == '-') {
2078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						;
2079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					} else if (!isalnum((int) c)) {
2080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						ok = 0;
2081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbLog("bad tag char: '%c' in '%s'\n", c, q);
2082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
2083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
2084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					p++;
2085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (ok) {
2087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					sprintf(fdtag, "%s", q);
2088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (s) *s = ',';
2091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(t);
2093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdgeom[0] == '\0' && getenv("FD_GEOM")) {
2095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdgeom,  120, "%s", getenv("FD_GEOM"));
2096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdsess[0] == '\0' && getenv("FD_SESS")) {
2098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdsess, 120, "%s", getenv("FD_SESS"));
2099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdopts[0] == '\0' && getenv("FD_OPTS")) {
2101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdopts, 120, "%s", getenv("FD_OPTS"));
2102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdextra[0] == '\0' && getenv("FD_EXTRA")) {
2104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!strchr(getenv("FD_EXTRA"), '\'')) {
2105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			snprintf(fdextra, 250, "%s", getenv("FD_EXTRA"));
2106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdprog[0] == '\0' && getenv("FD_PROG")) {
2109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdprog, 120, "%s", getenv("FD_PROG"));
2110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdxsrv[0] == '\0' && getenv("FD_XSRV")) {
2112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdxsrv, 120, "%s", getenv("FD_XSRV"));
2113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdcups[0] == '\0' && getenv("FD_CUPS")) {
2115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdcups, 120, "%s", getenv("FD_CUPS"));
2116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdesd[0] == '\0' && getenv("FD_ESD")) {
2118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdesd, 120, "%s", getenv("FD_ESD"));
2119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdnas[0] == '\0' && getenv("FD_NAS")) {
2121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdnas, 120, "%s", getenv("FD_NAS"));
2122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdsmb[0] == '\0' && getenv("FD_SMB")) {
2124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdsmb, 120, "%s", getenv("FD_SMB"));
2125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdtag[0] == '\0' && getenv("FD_TAG")) {
2127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdtag, 120, "%s", getenv("FD_TAG"));
2128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdxdmcpif[0] == '\0' && getenv("FD_XDMCP_IF")) {
2130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdxdmcpif,  120, "%s", getenv("FD_XDMCP_IF"));
2131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (fdxdum[0] == '\0' && getenv("FD_XDUMMY_RUN_AS_ROOT")) {
2133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(fdxdum, 120, "%s", getenv("FD_XDUMMY_RUN_AS_ROOT"));
2134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("CREATE_DISPLAY_OUTPUT")) {
2136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		snprintf(cdout, 120, "CREATE_DISPLAY_OUTPUT='%s'", getenv("CREATE_DISPLAY_OUTPUT"));
2137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdgeom, '\''))	fdgeom[0] = '\0';
2140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdopts, '\''))	fdopts[0] = '\0';
2141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdextra, '\''))	fdextra[0] = '\0';
2142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdprog, '\''))	fdprog[0] = '\0';
2143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdxsrv, '\''))	fdxsrv[0] = '\0';
2144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdcups, '\''))	fdcups[0] = '\0';
2145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdesd, '\''))	fdesd[0] = '\0';
2146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdnas, '\''))	fdnas[0] = '\0';
2147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdsmb, '\''))	fdsmb[0] = '\0';
2148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdtag, '\''))	fdtag[0] = '\0';
2149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdxdmcpif, '\''))	fdxdmcpif[0] = '\0';
2150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdxdum, '\''))	fdxdum[0] = '\0';
2151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(fdsess, '\''))	fdsess[0] = '\0';
2152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strchr(cdout, '\''))	cdout[0] = '\0';
2153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_GEOM", fdgeom);
2155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_OPTS", fdopts);
2156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_EXTRA", fdextra);
2157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_PROG", fdprog);
2158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_XSRV", fdxsrv);
2159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_CUPS", fdcups);
2160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_ESD",  fdesd);
2161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_NAS",  fdnas);
2162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_SMB",  fdsmb);
2163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_TAG",  fdtag);
2164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_XDMCP_IF",  fdxdmcpif);
2165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_XDUMMY_RUN_AS_ROOT", fdxdum);
2166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	set_env("FD_SESS", fdsess);
2167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (usslpeer || (unixpw && keep_unixpw_user)) {
2169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *uu = usslpeer;
2170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!uu) {
2171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			uu = keep_unixpw_user;
2172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strchr(uu, '\''))  {
2174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			uu = "";
2175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		create_cmd = (char *) malloc(strlen(tmp)+1
2177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("env USER='' ")
2178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_GEOM='' ")
2179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_OPTS='' ")
2180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_EXTRA='' ")
2181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_PROG='' ")
2182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_XSRV='' ")
2183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_CUPS='' ")
2184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_ESD='' ")
2185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_NAS='' ")
2186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_SMB='' ")
2187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_TAG='' ")
2188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_XDMCP_IF='' ")
2189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_XDUMMY_RUN_AS_ROOT='' ")
2190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("FD_SESS='' /bin/sh ")
2191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(uu) + 1
2192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdgeom) + 1
2193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdopts) + 1
2194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdextra) + 1
2195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdprog) + 1
2196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdxsrv) + 1
2197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdcups) + 1
2198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdesd) + 1
2199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdnas) + 1
2200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdsmb) + 1
2201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdtag) + 1
2202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdxdmcpif) + 1
2203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdxdum) + 1
2204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(fdsess) + 1
2205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(cdout) + 1
2206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(opts) + 1);
2207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' "
2208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    "FD_OPTS='%s' FD_EXTRA='%s' FD_PROG='%s' FD_XSRV='%s' FD_CUPS='%s' "
2209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    "FD_ESD='%s' FD_NAS='%s' FD_SMB='%s' FD_TAG='%s' FD_XDMCP_IF='%s' "
2210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    "FD_XDUMMY_RUN_AS_ROOT='%s' %s /bin/sh %s %s",
2211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    uu, fdgeom, fdsess, fdopts, fdextra, fdprog, fdxsrv,
2212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    fdcups, fdesd, fdnas, fdsmb, fdtag, fdxdmcpif, fdxdum, cdout, tmp, opts);
2213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
2214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		create_cmd = (char *) malloc(strlen(tmp)
2215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen("/bin/sh ") + 1 + strlen(opts) + 1);
2216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(create_cmd, "/bin/sh %s %s", tmp, opts);
2217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return create_cmd;
2219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *certret_extract() {
2222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *q, *p, *str = strdup(certret_str);
2223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *upeer = NULL;
2224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int ok = 0;
2225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q = strstr(str, "Subject: ");
2227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! q) return NULL;
2228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strstr(q, "\n");
2230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (p) *p = '\0';
2231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q = strstr(q, "CN=");
2233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! q) return NULL;
2234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! getenv("X11VNC_SSLPEER_CN")) {
2236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = q;
2237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(q, "/emailAddress=");
2238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) q = strstr(p, "/Email=");
2239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) return NULL;
2240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q = strstr(q, "=");
2243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! q) return NULL;
2244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q++;
2246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strstr(q, " ");
2247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (p) *p = '\0';
2248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strstr(q, "@");
2249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (p) *p = '\0';
2250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strstr(q, "/");
2251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (p) *p = '\0';
2252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	upeer = strdup(q);
2254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strcmp(upeer, "")) {
2256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = upeer;
2257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (*p != '\0') {
2258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char c = *p;
2259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!isalnum((int) c)) {
2260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*p = '\0';
2261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
2262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p++;
2264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strcmp(upeer, "")) {
2266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			ok = 1;
2267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! ok) {
2270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		upeer = NULL;
2271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return upeer;
2273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void check_nodisplay(char **nd, char **tag) {
2276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw && !getenv("X11VNC_NO_UNIXPW_OPTS") && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
2277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q, *t2, *t = keep_unixpw_opts;
2278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(t, "nd=");
2279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) q = strstr(t, "nodisplay=");
2280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (q) {
2281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = strchr(q, '=') + 1;
2282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			t = strdup(q);
2283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = t;
2284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			t2 = strchr(t, ',');
2285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (t2) *t2 = '\0';
2286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (*t != '\0') {
2288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (*t == '+') {
2289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					*t = ',';
2290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				t++;
2292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!strchr(q, '\'') && !strpbrk(q, "[](){}`'\"$&*|<>")) {
2294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (! quiet) rfbLog("set X11VNC_SKIP_DISPLAY: %s\n", q);
2295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*nd = q;
2296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(keep_unixpw_opts, "tag=");
2300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (getenv("FD_TAG")) {
2301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			*tag = strdup(getenv("FD_TAG"));
2302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (q) {
2303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = strchr(q, '=') + 1;
2304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			t = strdup(q);
2305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = t;
2306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			t2 = strchr(t, ',');
2307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (t2) *t2 = '\0';
2308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (strlen(q) < 120) {
2310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int ok = 1;
2311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				while (*t != '\0') {
2312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					char c = *t;
2313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (*t == '_' || *t == '-') {
2314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						;
2315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					} else if (!isalnum((int) c)) {
2316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						ok = 0;
2317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						rfbLog("bad tag char: '%c' in '%s'\n", c, q);
2318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						break;
2319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
2320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					t++;
2321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (ok) {
2323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (! quiet) rfbLog("set FD_TAG: %s\n", q);
2324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					*tag = q;
2325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_system_greeter_active == 2) {
2330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!keep_unixpw_user) {
2331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
2332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*nd = strdup("all");
2334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *get_usslpeer() {
2338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *u = NULL, *upeer = NULL;
2339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (certret_str) {
2341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		upeer = certret_extract();
2342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!upeer) {
2344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return NULL;
2345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("sslpeer unix username extracted from x509 cert: %s\n", upeer);
2347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	u = (char *) malloc(strlen(upeer+2));
2349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	u[0] = '\0';
2350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(users_list, "sslpeer=")) {
2351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(u, "+%s", upeer);
2352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
2353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *p, *str = strdup(users_list);
2354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(str + strlen("sslpeer="), ",");
2355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		while (p) {
2356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!strcmp(p, upeer)) {
2357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(u, "+%s", upeer);
2358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
2359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = strtok(NULL, ",");
2361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(str);
2363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (u[0] == '\0') {
2365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("sslpeer cannot determine user: %s\n", upeer);
2366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(u);
2367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return NULL;
2368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(u);
2370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return upeer;
2371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void do_try_switch(char *usslpeer, char *users_list_save) {
2374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw_system_greeter_active == 2) {
2375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("unixpw_system_greeter: not trying switch to user '%s'\n", usslpeer ? usslpeer : "");
2376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
2377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (usslpeer) {
2379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *u = (char *) malloc(strlen(usslpeer+2));
2380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(u, "+%s", usslpeer);
2381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (switch_user(u, 0)) {
2382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("sslpeer switched to user: %s\n", usslpeer);
2383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("sslpeer failed to switch to user: %s\n", usslpeer);
2385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(u);
2387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (users_list_save && keep_unixpw_user) {
2389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *user = keep_unixpw_user;
2390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *u = (char *)malloc(strlen(user)+1);
2391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		users_list = users_list_save;
2393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		u[0] = '\0';
2395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!strcmp(users_list, "unixpw=")) {
2396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(u, "+%s", user);
2397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *p, *str = strdup(users_list);
2399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = strtok(str + strlen("unixpw="), ",");
2400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (p) {
2401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!strcmp(p, user)) {
2402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					sprintf(u, "+%s", user);
2403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
2404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				p = strtok(NULL, ",");
2406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(str);
2408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (u[0] == '\0') {
2411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("unixpw_accept skipping switch to user: %s (drc)\n", user);
2412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (switch_user(u, 0)) {
2413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("unixpw_accept switched to user: %s (drc)\n", user);
2414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("unixpw_accept failed to switch to user: %s (drc)\n", user);
2416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(u);
2418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void path_lookup(char *prog) {
2422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* see create_display script */
2423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *create_display_extra = "/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde4/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin:/usr/local/bin";
2424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *path, *try, *p;
2425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int found = 0, len = strlen(create_display_extra);
2426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("PATH")) {
2428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		len += strlen(getenv("PATH")) + 1;
2429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		path = (char *) malloc((len+1) * sizeof(char));
2430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(path, "%s:%s", getenv("PATH"), create_display_extra);
2431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
2432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		path = (char *) malloc((len+1) * sizeof(char));
2433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(path, "%s", create_display_extra);
2434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	try = (char *) malloc((len+2+strlen(prog)) * sizeof(char));
2436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = strtok(path, ":");
2438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (p) {
2439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		struct stat sbuf;
2440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		sprintf(try, "%s/%s", p, prog);
2442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (stat(try, &sbuf) == 0) {
2443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			found = 1;
2444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
2445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		p = strtok(NULL, ":");
2447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(path);
2450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	free(try);
2451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!found) {
2453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "\n");
2454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "The program \"%s\" could not be found in PATH and standard locations.\n", prog);
2455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "You probably need to install a package that provides the \"%s\" program.\n", prog);
2456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "Without it FINDCREATEDISPLAY mode may not be able to create an X display.\n");
2457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "\n");
2458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int created_disp, int db) {
2462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
2463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char line1[1024], line2[16384];
2464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *q, *usslpeer = NULL;
2465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int n, nodisp = 0, saw_xdmcp = 0;
2466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int tmp_fd = -1;
2467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int internal_cmd = 0;
2468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int tried_switch = 0;
2469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	memset(line1, 0, sizeof(line1));
2471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	memset(line2, 0, sizeof(line2));
2472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (users_list && strstr(users_list, "sslpeer=") == users_list) {
2474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		usslpeer = get_usslpeer();
2475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! usslpeer) {
2476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return 0;
2477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("DEBUG_RUN_CMD")) db = 1;
2480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* only sets environment variables: */
2482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	run_user_command("", latest_client, "env", NULL, 0, NULL);
2483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (program_name) {
2485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		set_env("X11VNC_PROG", program_name);
2486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
2487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		set_env("X11VNC_PROG", "x11vnc");
2488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!strcmp(cmd, "FINDDISPLAY") ||
2491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
2492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *nd = "";
2493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *tag = "";
2494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char fdout[128];
2495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		internal_cmd = 1;
2497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tmp_fd = mkstemp(tmp);
2499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (tmp_fd < 0) {
2501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: open failed: %s\n", tmp);
2502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLogPerror("mkstemp");
2503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
2504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		chmod(tmp, 0644);
2506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (getenv("X11VNC_FINDDISPLAY_ALWAYS_FAILS")) {
2507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *s = "#!/bin/sh\necho _FAIL_\nexit 1\n";
2508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			write(tmp_fd, s, strlen(s));
2509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			write(tmp_fd, find_display, strlen(find_display));
2511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		close(tmp_fd);
2513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nodisp = 1;
2514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
2516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			create_cmd = build_create_cmd(cmd, &saw_xdmcp, usslpeer, tmp);
2517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (db) fprintf(stderr, "create_cmd: %s\n", create_cmd);
2518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (getenv("X11VNC_SKIP_DISPLAY")) {
2520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			nd = strdup(getenv("X11VNC_SKIP_DISPLAY"));
2521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		check_nodisplay(&nd, &tag);
2523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fdout[0] = '\0';
2525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (getenv("FIND_DISPLAY_OUTPUT")) {
2526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			snprintf(fdout, 120, " FIND_DISPLAY_OUTPUT='%s' ", getenv("FIND_DISPLAY_OUTPUT"));
2527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		cmd = (char *) malloc(strlen("env X11VNC_SKIP_DISPLAY='' ")
2530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    + strlen(nd) + strlen(" FD_TAG='' ") + strlen(tag) + strlen(tmp) + strlen("/bin/sh ") + strlen(fdout) + 1);
2531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strcmp(tag, "")) {
2533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(cmd, "env X11VNC_SKIP_DISPLAY='%s' FD_TAG='%s' %s /bin/sh %s", nd, tag, fdout, tmp);
2534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			sprintf(cmd, "env X11VNC_SKIP_DISPLAY='%s' %s /bin/sh %s", nd, fdout, tmp);
2536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("wait_for_client: running: %s\n", cmd);
2540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (create_cmd != NULL) {
2542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(create_cmd, "Xvfb")) {
2543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			path_lookup("Xvfb");
2544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(create_cmd, "Xvnc")) {
2546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			path_lookup("Xvnc");
2547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(create_cmd, "Xdummy")) {
2549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			path_lookup("Xdummy");
2550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw && !unixpw_nis) {
2554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int res = 0, k, j, i;
2555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char line[18000];
2556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		memset(line, 0, sizeof(line));
2558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (unixpw_system_greeter_active == 2) {
2560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("unixpw_system_greeter: forcing find display failure.\n");
2561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			res = 0;
2562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (keep_unixpw_user && keep_unixpw_pass) {
2563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			n = sizeof(line);
2564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (unixpw_cmd != NULL) {
2565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				res = unixpw_cmd_run(keep_unixpw_user,
2566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    keep_unixpw_pass, cmd, line, &n);
2567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
2568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				res = su_verify(keep_unixpw_user,
2569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    keep_unixpw_pass, cmd, line, &n, nodisp);
2570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) {fprintf(stderr, "line: "); write(2, line, n); write(2, "\n", 1); fprintf(stderr, "res=%d n=%d\n", res, n);}
2574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! res) {
2575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: find display cmd failed.\n");
2576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! res && create_cmd) {
2579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			FILE *mt = fopen(tmp, "w");
2580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (! mt) {
2581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: open failed: %s\n", tmp);
2582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLogPerror("fopen");
2583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(1);
2584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(mt, "%s", create_display);
2586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fclose(mt);
2587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			findcreatedisplay = 1;
2589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (unixpw_cmd != NULL) {
2591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* let the external unixpw command do it: */
2592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				n = sizeof(line);
2593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				close_exec_fds();
2594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				res = unixpw_cmd_run(keep_unixpw_user,
2595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    keep_unixpw_pass, create_cmd, line, &n);
2596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (getuid() != 0 && unixpw_system_greeter_active != 2) {
2597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* if not root, run as the other user... */
2598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				n = sizeof(line);
2599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				close_exec_fds();
2600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				res = su_verify(keep_unixpw_user,
2601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    keep_unixpw_pass, create_cmd, line, &n, nodisp);
2602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) fprintf(stderr, "c-res=%d n=%d line: '%s'\n", res, n, line);
2603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
2605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				FILE *p;
2606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				close_exec_fds();
2607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (unixpw_system_greeter_active == 2) {
2608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("unixpw_system_greeter: not trying su_verify() to run\n");
2609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("unixpw_system_greeter: create display command.\n");
2610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: running: %s\n", create_cmd);
2612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				p = popen(create_cmd, "r");
2613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (! p) {
2614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("wait_for_client: popen failed: %s\n", create_cmd);
2615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					res = 0;
2616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else if (fgets(line1, 1024, p) == NULL) {
2617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("wait_for_client: read failed: %s\n", create_cmd);
2618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					res = 0;
2619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
2620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					n = fread(line2, 1, 16384, p);
2621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (pclose(p) != 0) {
2622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						res = 0;
2623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					} else {
2624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						strncpy(line, line1, 100);
2625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						memcpy(line + strlen(line1), line2, n);
2626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) fprintf(stderr, "line1: '%s'\n", line1);
2627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						n += strlen(line1);
2628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						created_disp = 1;
2629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						res = 1;
2630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
2631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (res && saw_xdmcp && unixpw_system_greeter_active != 2) {
2634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				xdmcp_insert = strdup(keep_unixpw_user);
2635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (tmp_fd >= 0) {
2639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unlink(tmp);
2640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! res) {
2643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: cmd failed: %s\n", cmd);
2644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unixpw_msg("No DISPLAY found.", 3);
2645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
2646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/*
2649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 * we need to hunt for DISPLAY= since there may be
2650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 * a login banner or something at the beginning.
2651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 */
2652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(line, "DISPLAY=");
2653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! q) {
2654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = line;
2655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		n -= (q - line);
2657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		for (k = 0; k < 1024; k++) {
2659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			line1[k] = q[k];
2660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (q[k] == '\n') {
2661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				k++;
2662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
2663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		n -= k;
2666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		i = 0;
2667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		for (j = 0; j < 16384; j++) {
2668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (j < 16384 - 1) {
2669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/* xauth data, assume pty added CR */
2670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (q[k+j] == '\r' && q[k+j+1] == '\n') {
2671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					continue;
2672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			line2[i] = q[k+j];
2676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			i++;
2677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) write(2, line, 100);
2679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) fprintf(stderr, "\n");
2680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
2682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		FILE *p;
2683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int rc;
2684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		close_exec_fds();
2685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (usslpeer) {
2687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *c;
2688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (getuid() == 0) {
2689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				c = (char *) malloc(strlen("su - '' -c \"")
2690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    + strlen(usslpeer) + strlen(cmd) + 1 + 1);
2691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(c, "su - '%s' -c \"%s\"", usslpeer, cmd);
2692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
2693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				c = strdup(cmd);
2694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = popen(c, "r");
2696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(c);
2697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (unixpw_nis && keep_unixpw_user) {
2699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *c;
2700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (getuid() == 0) {
2701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				c = (char *) malloc(strlen("su - '' -c \"")
2702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				    + strlen(keep_unixpw_user) + strlen(cmd) + 1 + 1);
2703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(c, "su - '%s' -c \"%s\"", keep_unixpw_user, cmd);
2704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
2705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				c = strdup(cmd);
2706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = popen(c, "r");
2708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(c);
2709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = popen(cmd, "r");
2712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! p) {
2715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: cmd failed: %s\n", cmd);
2716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLogPerror("popen");
2717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (tmp_fd >= 0) {
2718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unlink(tmp);
2719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
2721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (fgets(line1, 1024, p) == NULL) {
2723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: read failed: %s\n", cmd);
2724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLogPerror("fgets");
2725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (tmp_fd >= 0) {
2726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				unlink(tmp);
2727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			clean_up_exit(1);
2729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		n = fread(line2, 1, 16384, p);
2731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = pclose(p);
2732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (rc != 0) {
2734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: find display cmd failed.\n");
2735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (create_cmd && rc != 0) {
2738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			FILE *mt = fopen(tmp, "w");
2739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (! mt) {
2740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: open failed: %s\n", tmp);
2741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLogPerror("fopen");
2742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (tmp_fd >= 0) {
2743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					unlink(tmp);
2744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(1);
2746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fprintf(mt, "%s", create_display);
2748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			fclose(mt);
2749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			findcreatedisplay = 1;
2751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client: FINDCREATEDISPLAY cmd: %s\n", create_cmd);
2753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			p = popen(create_cmd, "r");
2755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (! p) {
2756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: cmd failed: %s\n", create_cmd);
2757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLogPerror("popen");
2758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (tmp_fd >= 0) {
2759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					unlink(tmp);
2760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(1);
2762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (fgets(line1, 1024, p) == NULL) {
2764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("wait_for_client: read failed: %s\n", create_cmd);
2765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLogPerror("fgets");
2766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (tmp_fd >= 0) {
2767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					unlink(tmp);
2768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(1);
2770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			n = fread(line2, 1, 16384, p);
2772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pclose(p);
2773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (tmp_fd >= 0) {
2775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unlink(tmp);
2776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) fprintf(stderr, "line1=%s\n", line1);
2780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(line1, "DISPLAY=") != line1) {
2782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: bad reply '%s'\n", line1);
2783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (unixpw) {
2784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			unixpw_msg("No DISPLAY found.", 3);
2785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
2787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(line1, ",VT=")) {
2791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int vt;
2792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *t = strstr(line1, ",VT=");
2793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		vt = atoi(t + strlen(",VT="));
2794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*t = '\0';
2795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (7 <= vt && vt <= 15) {
2796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_chvt(vt);
2797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(line1, ",XPID=")) {
2799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int i, pvt, vt = -1;
2800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *t = strstr(line1, ",XPID=");
2801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pvt = atoi(t + strlen(",XPID="));
2802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*t = '\0';
2803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (pvt > 0) {
2804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			for (i=3; i <= 10; i++) {
2805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int k;
2806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				char proc[100];
2807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				char buf[100];
2808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sprintf(proc, "/proc/%d/fd/%d", pvt, i);
2809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) fprintf(stderr, "%d -- %s\n", i, proc);
2810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				for (k=0; k < 100; k++) {
2811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					buf[k] = '\0';
2812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (readlink(proc, buf, 100) != -1) {
2815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					buf[100-1] = '\0';
2816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) fprintf(stderr, "%d -- %s -- %s\n", i, proc, buf);
2817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (strstr(buf, "/dev/tty") == buf) {
2818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						vt = atoi(buf + strlen("/dev/tty"));
2819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						if (vt > 0) {
2820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat							break;
2821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						}
2822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
2823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (7 <= vt && vt <= 12) {
2827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_chvt(vt);
2828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	use_dpy = strdup(line1 + strlen("DISPLAY="));
2832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q = use_dpy;
2833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (*q != '\0') {
2834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (*q == '\n' || *q == '\r') *q = '\0';
2835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q++;
2836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (line2[0] != '\0') {
2838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(line2, "XAUTHORITY=") == line2) {
2839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = line2;
2840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			while (*q != '\0') {
2841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (*q == '\n' || *q == '\r') *q = '\0';
2842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				q++;
2843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (auth_file) {
2845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				free(auth_file);
2846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			auth_file = strdup(line2 + strlen("XAUTHORITY="));
2848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			xauth_raw_data = (char *)malloc(n);
2851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			xauth_raw_len = n;
2852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			memcpy(xauth_raw_data, line2, n);
2853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (db) {fprintf(stderr, "xauth_raw_len: %d\n", n);
2854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatwrite(2, xauth_raw_data, n);
2855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfprintf(stderr, "\n");}
2856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!tried_switch) {
2860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		do_try_switch(usslpeer, users_list_save);
2861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		tried_switch = 1;
2862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw) {
2865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* Some cleanup and messaging for -unixpw case: */
2866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char str[32];
2867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (keep_unixpw_user && keep_unixpw_pass) {
2869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strzero(keep_unixpw_user);
2870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strzero(keep_unixpw_pass);
2871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			keep_unixpw = 0;
2872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (created_disp) {
2875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			snprintf(str, 30, "Created DISPLAY %s", use_dpy);
2876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			snprintf(str, 30, "Using DISPLAY %s", use_dpy);
2878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		unixpw_msg(str, 2);
2880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 1;
2882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid ssh_remote_tunnel(char *, int);
2885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic XImage ximage_struct;
2887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid progress_client(void) {
2889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int i, j = 0, progressed = 0, db = 0;
2890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	double start = dnow();
2891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("PROGRESS_CLIENT_DBG")) {
2892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("progress_client: begin\n");
2893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		db = 1;
2894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i = 0; i < 15; i++) {
2896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (latest_client) {
2897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			for (j = 0; j < 10; j++) {
2898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (latest_client->state != RFB_PROTOCOL_VERSION) {
2899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					progressed = 1;
2900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					break;
2901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
2902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (db) rfbLog("progress_client: calling-1 rfbCFD(1) %.6f\n", dnow()-start);
2903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbCFD(1);
2904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
2905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (progressed) {
2907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
2908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (db) rfbLog("progress_client: calling-2 rfbCFD(1) %.6f\n", dnow()-start);
2910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbCFD(1);
2911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!quiet) {
2913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("client progressed=%d in %d/%d %.6f s\n",
2914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    progressed, i, j, dnow() - start);
2915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint wait_for_client(int *argc, char** argv, int http) {
2919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* ugh, here we go... */
2920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XImage* fb_image;
2921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int w = 640, h = 480, b = 32;
2922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int w0 = -1, h0 = -1, i, chg_raw_fb = 0;
2923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *str, *q, *cmd = NULL;
2924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int db = 0, dt = 0;
2925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *create_cmd = NULL;
2926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *users_list_save = NULL;
2927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int created_disp = 0, ncache_save;
2928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int did_client_connect = 0;
2929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *vnc_redirect_host = "localhost";
2930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int vnc_redirect_port = -1, vnc_redirect_cnt = 0;
2931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char vnc_redirect_test[10];
2932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (getenv("WAIT_FOR_CLIENT_DB")) {
2934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		db = 1;
2935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	vnc_redirect = 0;
2938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
2940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
2941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i < *argc; i++) {
2944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!strcmp(argv[i], "-desktop")) {
2945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			dt = 1;
2946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (db) fprintf(stderr, "args %d %s\n", i, argv[i]);
2948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!quiet && !strstr(use_dpy, "FINDDISPLAY-run")) {
2950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("\n");
2951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("wait_for_client: %s\n", use_dpy);
2952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("\n");
2953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	str = strdup(use_dpy);
2956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	str += strlen("WAIT");
2957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	xdmcp_insert = NULL;
2959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* get any leading geometry: */
2961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	q = strchr(str+1, ':');
2962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (q) {
2963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*q = '\0';
2964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sscanf(str+1, "%dx%d", &w0, &h0) == 2)  {
2965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w = w0;
2966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h = h0;
2967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("wait_for_client set: w=%d h=%d\n", w, h);
2968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
2969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w0 = -1;
2970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h0 = -1;
2971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*q = ':';
2973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		str = q;
2974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if ((w0 == -1 || h0 == -1) && pad_geometry != NULL) {
2976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int b0, del = 0;
2977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *s = pad_geometry;
2978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (strstr(s, "once:") == s) {
2979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			del = 1;
2980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			s += strlen("once:");
2981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sscanf(s, "%dx%dx%d", &w0, &h0, &b0) == 3)  {
2983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w = nabs(w0);
2984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h = nabs(h0);
2985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			b = nabs(b0);
2986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (sscanf(s, "%dx%d", &w0, &h0) == 2)  {
2987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w = nabs(w0);
2988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h = nabs(h0);
2989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (del) {
2991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pad_geometry = NULL;
2992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
2993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* str currently begins with a ':' */
2996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(str, ":cmd=") == str) {
2997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* cmd=/path/to/mycommand */
2998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		str++;
2999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strpbrk(str, "0123456789") == str+1) {
3000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* :0.0 */
3001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		;
3002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
3003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* hostname:0.0 */
3004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		str++;
3005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (db) fprintf(stderr, "str: %s\n", str);
3008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(str, "cmd=") == str) {
3010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		cmd = setup_cmd(str, &vnc_redirect, &vnc_redirect_host, &vnc_redirect_port, db);
3011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fb_image = &ximage_struct;
3014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	setup_fake_fb(fb_image, w, h, b);
3015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! dt) {
3017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *s;
3018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		argv[*argc] = strdup("-desktop");
3019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*argc = (*argc) + 1;
3020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (cmd) {
3022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *q;
3023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			s = choose_title(":0");
3024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q = strstr(s, ":0");
3025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (q) {
3026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*q = '\0';
3027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
3028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
3029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			s = choose_title(str);
3030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
3031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfb_desktop_name = strdup(s);
3032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		argv[*argc] = s;
3033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*argc = (*argc) + 1;
3034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	ncache_save = ncache;
3037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	ncache = 0;
3038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	initialize_allowed_input();
3040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! multiple_cursors_mode) {
3042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		multiple_cursors_mode = strdup("default");
3043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	initialize_cursors_mode();
3045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	initialize_screen(argc, argv, fb_image);
3047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! inetd && ! use_openssl) {
3049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! screen->port || screen->listenSock < 0) {
3050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (got_rfbport && got_rfbport_val == 0) {
3051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				;
3052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else if (ipv6_listen && ipv6_listen_fd >= 0) {
3053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("Info: listening on IPv6 interface only.  (wait for client)\n");
3054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			} else {
3055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLogEnable(1);
3056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("Error: could not obtain listening port.  (wait for client)\n");
3057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (!got_rfbport && !got_ipv6_listen) {
3058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					rfbLog("If this system is IPv6-only, use the -6 option.\n");
3059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
3060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				clean_up_exit(1);
3061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
3062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
3063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	initialize_signals();
3066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (ssh_str != NULL) {
3068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ssh_remote_tunnel(ssh_str, screen->port);
3069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! raw_fb) {
3072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		chg_raw_fb = 1;
3073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* kludge to get RAWFB_RET with dpy == NULL guards */
3074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		raw_fb = (char *) 0x1;
3075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (cmd && !strcmp(cmd, "HTTPONCE")) {
3078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		handle_one_http_request();
3079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(0);
3080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (http && check_httpdir()) {
3083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		http_connections(1);
3084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (cmd && unixpw) {
3087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		keep_unixpw = 1;
3088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	setup_service();
3091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	check_waitbg();
3093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect) {
3095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		vnc_redirect_loop(vnc_redirect_test, &vnc_redirect_cnt);
3096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
3097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (use_threads && !started_rfbRunEventLoop) {
3099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			started_rfbRunEventLoop = 1;
3100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbRunEventLoop(screen, -1, TRUE);
3101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
3102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (inetd && use_openssl) {
3104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			accept_openssl(OPENSSL_INETD, -1);
3105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
3106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		setup_client_connect(&did_client_connect);
3108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		loop_for_connect(did_client_connect);
3110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (unixpw) {
3112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (cmd && strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
3113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (users_list && strstr(users_list, "unixpw=") == users_list) {
3114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					users_list_save = users_list;
3115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					users_list = NULL;
3116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
3117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
3118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_unixpw_loop();
3119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (cmd && !use_threads) {
3120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* try to get RFB proto done now. */
3121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			progress_client();
3122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
3123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect == 2) {
3126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		;
3127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (cmd) {
3128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!do_run_cmd(cmd, create_cmd, users_list_save, created_disp, db)) {
3129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return 0;
3130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
3131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
3132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		use_dpy = strdup(str);
3133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (chg_raw_fb) {
3135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		raw_fb = NULL;
3136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	ncache = ncache_save;
3139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
3141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		user_supplied_opts(keep_unixpw_opts);
3142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (create_cmd) {
3144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(create_cmd);
3145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (vnc_redirect) {
3148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		do_vnc_redirect(created_disp, vnc_redirect_host, vnc_redirect_port,
3149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    vnc_redirect_cnt, vnc_redirect_test);
3150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(0);
3151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
3152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 1;
3154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
3155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
3156