~edubuntu-italc-devel/italc/italc-intrepid

« back to all changes in this revision

Viewing changes to debian/patches/05_x11vnc.patch

  • Committer: Stéphane graber
  • Date: 2008-07-07 12:31:49 UTC
  • Revision ID: stgraber@ubuntu.com-20080707123149-n0lvoe7s052e45zi
Update for 1.0.9-rc4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /bin/sh /usr/share/dpatch/dpatch-run
2
 
## 05_x11vnc.patch by Stéphane Graber <stgraber@ubuntu.com>
3
 
##
4
 
## All lines beginning with `## DP:' are a description of the patch.
5
 
## DP: Update X11VNC to fix tight encoding crash
6
 
 
7
 
@DPATCH@
8
 
Index: ../ica/src/ivs.cpp
9
 
===================================================================
10
 
--- ../ica/src/ivs.cpp  (Revision 401)
11
 
+++ ../ica/src/ivs.cpp  (Arbeitskopie)
12
 
@@ -195,7 +195,9 @@
13
 
                }
14
 
                return;
15
 
        }
16
 
+#if 0
17
 
        cmdline << "-dbg";// << "-o" << "/tmp/italc_client_x11vnc.log";
18
 
+#endif
19
 
 
20
 
        char * old_av = m_argv[0];
21
 
        m_argv = new char *[cmdline.size()+1];
22
 
Index: ../ica/x11/x11vnc/userinput.c
23
 
===================================================================
24
 
--- ../ica/x11/x11vnc/userinput.c       (Revision 401)
25
 
+++ ../ica/x11/x11vnc/userinput.c       (Arbeitskopie)
26
 
@@ -790,8 +790,10 @@
27
 
        if (cmap8to24 && cmap8to24_fb) {
28
 
                use_fb = cmap8to24_fb;
29
 
                pixelsize = 4;
30
 
-               if (depth == 8) {
31
 
+               if (depth <= 8) {
32
 
                        use_Bpl *= 4;
33
 
+               } else if (depth <= 16) {
34
 
+                       use_Bpl *= 2;
35
 
                }
36
 
        }
37
 
 
38
 
@@ -1882,9 +1884,14 @@
39
 
                                        }
40
 
                                }
41
 
 if (0) fprintf(stderr, "copyrect: cmap8to24_fb: mode=%d\n", mode);
42
 
-                               if (cmap8to24 && depth == 8) {
43
 
-                                       Bpp = 4 * Bpp0;
44
 
-                                       stride = 4 * stride0;
45
 
+                               if (cmap8to24) {
46
 
+                                       if (depth <= 8) {
47
 
+                                               Bpp    = 4 * Bpp0;
48
 
+                                               stride = 4 * stride0;
49
 
+                                       } else if (depth <= 16) {
50
 
+                                               Bpp    = 2 * Bpp0;
51
 
+                                               stride = 2 * stride0;
52
 
+                                       }
53
 
                                }
54
 
                                dst = cmap8to24_fb + y1*stride + x1*Bpp;
55
 
                                src = cmap8to24_fb + (y1-dy)*stride + (x1-dx)*Bpp;
56
 
@@ -3566,6 +3573,17 @@
57
 
                        didfull = 1;
58
 
                }
59
 
        }
60
 
+       if (advertise_truecolor && advertise_truecolor_reset && indexed_color) {
61
 
+               /* this will reset framebuffer to correct colors, if needed */
62
 
+               static dlast = 0.0;
63
 
+               now = dnow();
64
 
+               if (now > last_client + 1.0 && now < last_client + 3.0 && now > dlast + 5.0) {
65
 
+                       rfbLog("advertise truecolor reset framebuffer\n");
66
 
+                       do_new_fb(1);
67
 
+                       dlast = dnow();
68
 
+                       return;
69
 
+               }
70
 
+       }
71
 
 }
72
 
 
73
 
 static int wireframe_mod_state() {
74
 
@@ -8083,8 +8101,12 @@
75
 
 
76
 
        if (cmap8to24 && cmap8to24_fb) {
77
 
                src_fb = cmap8to24_fb;
78
 
-               if (scaling && depth == 8) {
79
 
-                       fac = 4;
80
 
+               if (scaling) {
81
 
+                       if (depth <= 8) {
82
 
+                               fac = 4;
83
 
+                       } else if (depth <= 16) {
84
 
+                               fac = 2;
85
 
+                       }
86
 
                }
87
 
        }
88
 
        dst_fb = rfb_fb;
89
 
Index: ../ica/x11/x11vnc/options.h
90
 
===================================================================
91
 
--- ../ica/x11/x11vnc/options.h (Revision 401)
92
 
+++ ../ica/x11/x11vnc/options.h (Arbeitskopie)
93
 
@@ -89,6 +89,8 @@
94
 
 extern int flash_cmap;
95
 
 extern int shift_cmap;
96
 
 extern int force_indexed_color;
97
 
+extern int advertise_truecolor;
98
 
+extern int advertise_truecolor_reset;
99
 
 extern int cmap8to24;
100
 
 extern char *cmap8to24_str;
101
 
 extern int xform24to32;
102
 
@@ -256,6 +258,7 @@
103
 
 extern int using_shm;
104
 
 extern int flip_byte_order;
105
 
 extern int waitms;
106
 
+extern int got_waitms;
107
 
 extern double wait_ui;
108
 
 extern double slow_fb;
109
 
 extern double xrefresh;
110
 
Index: ../ica/x11/x11vnc/xinerama.c
111
 
===================================================================
112
 
--- ../ica/x11/x11vnc/xinerama.c        (Revision 401)
113
 
+++ ../ica/x11/x11vnc/xinerama.c        (Arbeitskopie)
114
 
@@ -227,6 +227,76 @@
115
 
        }
116
 
 }
117
 
 
118
 
+static int did_xinerama_clip = 0;
119
 
+
120
 
+void check_xinerama_clip(void) {
121
 
+#if LIBVNCSERVER_HAVE_LIBXINERAMA
122
 
+       int n, k, i, ev, er, juse = -1;
123
 
+       int score[32], is = 0;
124
 
+       XineramaScreenInfo *x;
125
 
+
126
 
+       if (!clip_str || !dpy) {
127
 
+               return;
128
 
+       }
129
 
+       if (sscanf(clip_str, "xinerama%d", &k) == 1) {
130
 
+               ;
131
 
+       } else if (sscanf(clip_str, "screen%d", &k) == 1) {
132
 
+               ;
133
 
+       } else {
134
 
+               return;
135
 
+       }
136
 
+
137
 
+       free(clip_str);
138
 
+       clip_str = NULL;
139
 
+
140
 
+       if (! XineramaQueryExtension(dpy, &ev, &er)) {
141
 
+               return;
142
 
+       }
143
 
+       if (! XineramaIsActive(dpy)) {
144
 
+               return;
145
 
+       }
146
 
+       x = XineramaQueryScreens(dpy, &n);
147
 
+       if (k < 0 || k >= n) {
148
 
+               XFree_wr(x);
149
 
+               return;
150
 
+       }
151
 
+       for (i=0; i < n; i++) {
152
 
+               score[is++] = nabs(x[i].x_org) + nabs(x[i].y_org);
153
 
+               if (is >= 32) {
154
 
+                       break;
155
 
+               }
156
 
+       }
157
 
+       for (i=0; i <= k; i++) {
158
 
+               int j, jmon, mon = -1, mox = -1;
159
 
+               for (j=0; j < is; j++) {
160
 
+                       if (mon < 0 || score[j] < mon) {
161
 
+                               mon = score[j];
162
 
+                               jmon = j;
163
 
+                       }
164
 
+                       if (mox < 0 || score[j] > mox) {
165
 
+                               mox = score[j];
166
 
+                       }
167
 
+               }
168
 
+               juse = jmon;
169
 
+               score[juse] = mox+1+i;
170
 
+       }
171
 
+
172
 
+       if (juse >= 0 && juse < n) {
173
 
+               char str[64];
174
 
+               sprintf(str, "%dx%d+%d+%d", x[juse].width, x[juse].height,
175
 
+                   x[juse].x_org, x[juse].y_org);
176
 
+               clip_str = strdup(str);
177
 
+               did_xinerama_clip = 1;
178
 
+       } else {
179
 
+               clip_str = strdup("");
180
 
+       }
181
 
+       XFree_wr(x);
182
 
+       if (!quiet) {
183
 
+               rfbLog("set -clip to '%s' for xinerama%d\n", clip_str, k);
184
 
+       }
185
 
+#endif
186
 
+}
187
 
+
188
 
 static void initialize_xinerama (void) {
189
 
 #if !LIBVNCSERVER_HAVE_LIBXINERAMA
190
 
        rfbLog("Xinerama: Library libXinerama is not available to determine\n");
191
 
@@ -263,19 +333,19 @@
192
 
        rfbLog("\n");
193
 
        rfbLog("Xinerama is present and active (e.g. multi-head).\n");
194
 
 
195
 
-       if (! use_xwarppointer && ! got_noxwarppointer) {
196
 
+       /* n.b. change to XineramaGetData() someday */
197
 
+       xineramas = XineramaQueryScreens(dpy, &n);
198
 
+       if (verbose) {
199
 
+               rfbLog("Xinerama: number of sub-screens: %d\n", n);
200
 
+       }
201
 
+
202
 
+       if (! use_xwarppointer && ! got_noxwarppointer && n > 1) {
203
 
                rfbLog("Xinerama: enabling -xwarppointer mode to try to correct\n");
204
 
                rfbLog("Xinerama: mouse pointer motion. XTEST+XINERAMA bug.\n");
205
 
                rfbLog("Xinerama: Use -noxwarppointer to force XTEST.\n");
206
 
                use_xwarppointer = 1;
207
 
        }
208
 
 
209
 
-       /* n.b. change to XineramaGetData() someday */
210
 
-       xineramas = XineramaQueryScreens(dpy, &n);
211
 
-       if (verbose) {
212
 
-               rfbLog("Xinerama: number of sub-screens: %d\n", n);
213
 
-       }
214
 
-
215
 
        if (n == 1) {
216
 
                if (verbose) {
217
 
                        rfbLog("Xinerama: no blackouts needed (only one"
218
 
@@ -305,6 +375,7 @@
219
 
        }
220
 
        XFree_wr(xineramas);
221
 
 
222
 
+
223
 
        if (sraRgnEmpty(black_region)) {
224
 
                rfbLog("Xinerama: no blackouts needed (screen fills"
225
 
                    " rectangle)\n");
226
 
@@ -312,6 +383,10 @@
227
 
                sraRgnDestroy(black_region);
228
 
                return;
229
 
        }
230
 
+       if (did_xinerama_clip) {
231
 
+               rfbLog("Xinerama: no blackouts due to -clip xinerama.\n");
232
 
+               return;
233
 
+       }
234
 
 
235
 
        /* max len is 10000x10000+10000+10000 (23 chars) per geometry */
236
 
        rcnt = (int) sraRgnCountRects(black_region);
237
 
Index: ../ica/x11/x11vnc/user.c
238
 
===================================================================
239
 
--- ../ica/x11/x11vnc/user.c    (Revision 401)
240
 
+++ ../ica/x11/x11vnc/user.c    (Arbeitskopie)
241
 
@@ -1094,7 +1094,6 @@
242
 
 }
243
 
 
244
 
 static void handle_one_http_request(void) {
245
 
-
246
 
        rfbLog("handle_one_http_request: begin.\n");
247
 
        if (inetd || screen->httpPort == 0) {
248
 
                int port = find_free_port(5800, 5860);
249
 
@@ -1111,7 +1110,7 @@
250
 
        http_connections(1);
251
 
        rfbInitServer(screen);
252
 
 
253
 
-       if (! inetd) {
254
 
+       if (!inetd) {
255
 
                int conn = 0;
256
 
                while (1) {
257
 
                        if (0) fprintf(stderr, "%d %d %d  %d\n", conn, screen->listenSock, screen->httpSock, screen->httpListenSock);
258
 
@@ -1136,6 +1135,7 @@
259
 
                rfbLog("handle_one_http_request: finished.\n");
260
 
                return;
261
 
        } else {
262
 
+               /* inetd case: */
263
 
 #if LIBVNCSERVER_HAVE_FORK
264
 
                pid_t pid;
265
 
                int s_in = screen->inetdSock;
266
 
@@ -1147,7 +1147,6 @@
267
 
                if (pid < 0) {
268
 
                        rfbLog("handle_one_http_request: could not fork.\n");
269
 
                        clean_up_exit(1);
270
 
-
271
 
                } else if (pid > 0) {
272
 
                        int status;
273
 
                        pid_t pidw;
274
 
@@ -1162,7 +1161,6 @@
275
 
                        }
276
 
                        rfbLog("handle_one_http_request: finished.\n");
277
 
                        return;
278
 
-                       
279
 
                } else {
280
 
                        int sock = rfbConnectToTcpAddr("127.0.0.1",
281
 
                            screen->httpPort);
282
 
@@ -1322,149 +1320,20 @@
283
 
        exit(0);
284
 
 }
285
 
 
286
 
-extern char find_display[];
287
 
-extern char create_display[];
288
 
-static XImage ximage_struct;
289
 
+static void do_chvt(int vt) {
290
 
+       char chvt[100];
291
 
+       sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
292
 
+       rfbLog("running: %s\n", chvt);
293
 
+       system(chvt);
294
 
+       sleep(2);
295
 
+}
296
 
 
297
 
-int wait_for_client(int *argc, char** argv, int http) {
298
 
-       XImage* fb_image;
299
 
-       int w = 640, h = 480, b = 32;
300
 
-       int w0, h0, i, chg_raw_fb = 0;
301
 
-       char *str, *q, *cmd = NULL;
302
 
-       int db = 0;
303
 
-       char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
304
 
-       int tmp_fd = -1, dt = 0;
305
 
-       char *create_cmd = NULL;
306
 
-       char *users_list_save = NULL;
307
 
-       int created_disp = 0;
308
 
-       int ncache_save;
309
 
-       int did_client_connect = 0;
310
 
-       int loop = 0;
311
 
-       time_t start;
312
 
-       char *vnc_redirect_host = "localhost";
313
 
-       int vnc_redirect_port = -1;
314
 
-       int vnc_redirect_cnt = 0;
315
 
-       char vnc_redirect_test[10];
316
 
-
317
 
-       vnc_redirect = 0;
318
 
-
319
 
-       if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
320
 
-               return 0;
321
 
-       }
322
 
-
323
 
-       if (getenv("WAIT_FOR_CLIENT_DB")) {
324
 
-               db = 1;
325
 
-       }
326
 
-
327
 
-       for (i=0; i < *argc; i++) {
328
 
-               if (!strcmp(argv[i], "-desktop")) {
329
 
-                       dt = 1;
330
 
-               }
331
 
-               if (db) fprintf(stderr, "args %d %s\n", i, argv[i]);
332
 
-       }
333
 
-       if (!quiet && !strstr(use_dpy, "FINDDISPLAY-run")) {
334
 
-               rfbLog("wait_for_client: %s\n", use_dpy);
335
 
-       }
336
 
-
337
 
-       str = strdup(use_dpy);
338
 
-       str += strlen("WAIT");
339
 
-
340
 
-       xdmcp_insert = NULL;
341
 
-
342
 
-       /* get any leading geometry: */
343
 
-       q = strchr(str+1, ':');
344
 
-       if (q) {
345
 
-               *q = '\0';
346
 
-               if (sscanf(str+1, "%dx%d", &w0, &h0) == 2)  {
347
 
-                       w = w0;
348
 
-                       h = h0;
349
 
-                       rfbLog("wait_for_client set: w=%d h=%d\n", w, h);
350
 
-               }
351
 
-               *q = ':';
352
 
-               str = q;
353
 
-       }
354
 
-
355
 
-       /* str currently begins with a ':' */
356
 
-       if (strstr(str, ":cmd=") == str) {
357
 
-               /* cmd=/path/to/mycommand */
358
 
-               str++;
359
 
-       } else if (strpbrk(str, "0123456789") == str+1) {
360
 
-               /* :0.0 */
361
 
-               ;
362
 
-       } else {
363
 
-               /* hostname:0.0 */
364
 
-               str++;
365
 
-       }
366
 
-
367
 
-       if (db) fprintf(stderr, "str: %s\n", str);
368
 
-
369
 
-       if (strstr(str, "cmd=") == str) {
370
 
-               if (no_external_cmds || !cmd_ok("WAIT")) {
371
 
-                       rfbLog("wait_for_client external cmds not allowed:"
372
 
-                           " %s\n", use_dpy);
373
 
-                       clean_up_exit(1);
374
 
-               }
375
 
-
376
 
-               cmd = str + strlen("cmd=");
377
 
-               if (!strcmp(cmd, "FINDDISPLAY-print")) {
378
 
-                       fprintf(stdout, "%s", find_display);
379
 
-                       clean_up_exit(0);
380
 
-               }
381
 
-               if (!strcmp(cmd, "FINDDISPLAY-run")) {
382
 
-                       char tmp[] = "/tmp/fd.XXXXXX";
383
 
-                       char com[100];
384
 
-                       int fd = mkstemp(tmp);
385
 
-                       if (fd >= 0) {
386
 
-                               write(fd, find_display, strlen(find_display));
387
 
-                               close(fd);
388
 
-                               set_env("FINDDISPLAY_run", "1");
389
 
-                               sprintf(com, "/bin/sh %s -n; rm -f %s", tmp, tmp);
390
 
-                               system(com);
391
 
-                       }
392
 
-                       unlink(tmp);
393
 
-                       exit(0);
394
 
-               }
395
 
-               if (!strcmp(str, "FINDCREATEDISPLAY-print")) {
396
 
-                       fprintf(stdout, "%s", create_display);
397
 
-                       clean_up_exit(0);
398
 
-               }
399
 
-               if (db) fprintf(stderr, "cmd: %s\n", cmd);
400
 
-               if (strstr(str, "FINDCREATEDISPLAY") || strstr(str, "FINDDISPLAY")) {
401
 
-                       if (strstr(str, "Xvnc.redirect") || strstr(str, "X.redirect")) {
402
 
-                               vnc_redirect = 1;
403
 
-                       }
404
 
-               }
405
 
-               if (strstr(cmd, "FINDDISPLAY-vnc_redirect") == cmd) {
406
 
-                       int p;
407
 
-                       char h[256];
408
 
-                       if (strlen(cmd) >= 256) {
409
 
-                               rfbLog("wait_for_client string too long: %s\n", str);
410
 
-                               clean_up_exit(1);
411
 
-                       }
412
 
-                       h[0] = '\0';
413
 
-                       if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%d", &p) == 1) {
414
 
-                               ;
415
 
-                       } else if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%s %d", h, &p) == 2) {
416
 
-                               ;
417
 
-                       } else {
418
 
-                               rfbLog("wait_for_client bad string: %s\n", cmd);
419
 
-                               clean_up_exit(1);
420
 
-                       }
421
 
-                       vnc_redirect_port = p;
422
 
-                       if (strcmp(h, "")) {
423
 
-                               vnc_redirect_host = strdup(h);
424
 
-                       }
425
 
-                       vnc_redirect = 2;
426
 
-                       rfbLog("wait_for_client: vnc_redirect: %s:%d\n", vnc_redirect_host, vnc_redirect_port);
427
 
-               }
428
 
-       }
429
 
-       
430
 
+static void setup_fake_fb(XImage* fb_image, int w, int h, int b) {
431
 
        if (fake_fb) {
432
 
                free(fake_fb);
433
 
        }
434
 
        fake_fb = (char *) calloc(w*h*b/8, 1);
435
 
 
436
 
-       fb_image = &ximage_struct;
437
 
        fb_image->data = fake_fb;
438
 
        fb_image->format = ZPixmap;
439
 
        fb_image->width  = w;
440
 
@@ -1483,64 +1352,9 @@
441
 
        dpy_y = wdpy_y = h;
442
 
        off_x = 0;
443
 
        off_y = 0;
444
 
+}
445
 
 
446
 
-       if (! dt) {
447
 
-               char *s;
448
 
-               argv[*argc] = strdup("-desktop");
449
 
-               *argc = (*argc) + 1;
450
 
-
451
 
-               if (cmd) {
452
 
-                       char *q;
453
 
-                       s = choose_title(":0");
454
 
-                       q = strstr(s, ":0");
455
 
-                       if (q) {
456
 
-                               *q = '\0';
457
 
-                       }
458
 
-               } else {
459
 
-                       s = choose_title(str);
460
 
-               }
461
 
-               rfb_desktop_name = strdup(s);
462
 
-               argv[*argc] = s;
463
 
-               *argc = (*argc) + 1;
464
 
-       }
465
 
-
466
 
-       ncache_save = ncache;
467
 
-       ncache = 0;
468
 
-
469
 
-       initialize_allowed_input();
470
 
-
471
 
-       if (! multiple_cursors_mode) {
472
 
-               multiple_cursors_mode = strdup("default");
473
 
-       }
474
 
-       initialize_cursors_mode();
475
 
-       
476
 
-       initialize_screen(argc, argv, fb_image);
477
 
-
478
 
-       initialize_signals();
479
 
-
480
 
-       if (ssh_str != NULL) {
481
 
-               ssh_remote_tunnel(ssh_str, screen->port);
482
 
-       }
483
 
-
484
 
-       if (! raw_fb) {
485
 
-               chg_raw_fb = 1;
486
 
-               /* kludge to get RAWFB_RET with dpy == NULL guards */
487
 
-               raw_fb = (char *) 0x1;
488
 
-       }
489
 
-
490
 
-       if (cmd && !strcmp(cmd, "HTTPONCE")) {
491
 
-               handle_one_http_request();      
492
 
-               clean_up_exit(0);
493
 
-       }
494
 
-
495
 
-       if (http && check_httpdir()) {
496
 
-               http_connections(1);
497
 
-       }
498
 
-
499
 
-       if (cmd && unixpw) {
500
 
-               keep_unixpw = 1;
501
 
-       }
502
 
-
503
 
+static void setup_service(void) {
504
 
        if (!inetd) {
505
 
                if (!use_openssl) {
506
 
                        announce(screen->port, use_openssl, NULL);
507
 
@@ -1562,7 +1376,9 @@
508
 
                avahi_initialise();
509
 
                avahi_advertise(name, this_host(), screen->port);
510
 
        }
511
 
+}
512
 
 
513
 
+static void check_waitbg(void) {
514
 
        if (getenv("WAITBG")) {
515
 
 #if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
516
 
                int p, n;
517
 
@@ -1594,91 +1410,9 @@
518
 
                clean_up_exit(1);
519
 
 #endif
520
 
        }
521
 
+}
522
 
 
523
 
-       if (vnc_redirect) {
524
 
-               if (unixpw) {
525
 
-                       rfbLog("wait_for_client: -unixpw and Xvnc.redirect not allowed\n");
526
 
-                       clean_up_exit(1);
527
 
-               }
528
 
-               if (client_connect) {
529
 
-                       rfbLog("wait_for_client: -connect and Xvnc.redirect not allowed\n");
530
 
-                       clean_up_exit(1);
531
 
-               }
532
 
-               if (inetd) {
533
 
-                       if (use_openssl) {
534
 
-                               accept_openssl(OPENSSL_INETD, -1);
535
 
-                       }
536
 
-               } else {
537
 
-                       if (first_conn_timeout) {
538
 
-                               if (first_conn_timeout < 0) {
539
 
-                                       first_conn_timeout = -first_conn_timeout;
540
 
-                               }
541
 
-                               signal(SIGALRM, vnc_redirect_timeout);
542
 
-                               alarm(first_conn_timeout);
543
 
-                       }
544
 
-                       if (use_openssl) {
545
 
-                               accept_openssl(OPENSSL_VNC, -1);
546
 
-                       } else {
547
 
-                               struct sockaddr_in addr;
548
 
-#ifdef __hpux
549
 
-                               int addrlen = sizeof(addr);
550
 
-#else
551
 
-                               socklen_t addrlen = sizeof(addr);
552
 
-#endif
553
 
-                               if (screen->listenSock < 0) {
554
 
-                                       rfbLog("wait_for_client: Xvnc.redirect not listening... sock=%d port=%d\n", screen->listenSock, screen->port);
555
 
-                                       clean_up_exit(1);
556
 
-                               }
557
 
-                               vnc_redirect_sock = accept(screen->listenSock, (struct sockaddr *)&addr, &addrlen);
558
 
-                       }
559
 
-                       if (first_conn_timeout) {
560
 
-                               alarm(0);
561
 
-                       }
562
 
-               }
563
 
-               if (vnc_redirect_sock < 0) {
564
 
-                       rfbLog("wait_for_client: vnc_redirect failed.\n");
565
 
-                       clean_up_exit(1);
566
 
-               }
567
 
-               if (!inetd && use_openssl) {
568
 
-                       /* check for Fetch Cert closing */
569
 
-                       fd_set rfds;
570
 
-                       struct timeval tv;
571
 
-                       int nfds;
572
 
-
573
 
-                       usleep(300*1000);
574
 
-
575
 
-                       FD_ZERO(&rfds);
576
 
-                       FD_SET(vnc_redirect_sock, &rfds);
577
 
-
578
 
-                       tv.tv_sec = 0;
579
 
-                       tv.tv_usec = 200000;
580
 
-                       nfds = select(vnc_redirect_sock+1, &rfds, NULL, NULL, &tv);
581
 
-
582
 
-                       rfbLog("wait_for_client: vnc_redirect nfds: %d\n", nfds);
583
 
-                       if (nfds > 0) {
584
 
-                               int n;
585
 
-                               n = read(vnc_redirect_sock, vnc_redirect_test, 1);
586
 
-                               if (n <= 0) {
587
 
-                                       close(vnc_redirect_sock);
588
 
-                                       vnc_redirect_sock = -1;
589
 
-                                       rfbLog("wait_for_client: waiting for 2nd connection (Fetch Cert?)\n");
590
 
-                                       accept_openssl(OPENSSL_VNC, -1);
591
 
-                                       if (vnc_redirect_sock < 0) {
592
 
-                                               rfbLog("wait_for_client: vnc_redirect failed.\n");
593
 
-                                               clean_up_exit(1);
594
 
-                                       }
595
 
-                               } else {
596
 
-                                       vnc_redirect_cnt = n;
597
 
-                               }
598
 
-                       }
599
 
-               }
600
 
-               goto vnc_redirect_place;
601
 
-       }
602
 
-
603
 
-       if (inetd && use_openssl) {
604
 
-               accept_openssl(OPENSSL_INETD, -1);
605
 
-       }
606
 
-
607
 
+static void setup_client_connect(int *did_client_connect) {
608
 
        if (client_connect != NULL) {
609
 
                char *remainder = NULL;
610
 
                if (inetd) {
611
 
@@ -1701,7 +1435,7 @@
612
 
                        rfbLog("wait_for_client: reverse_connect(%s)\n",
613
 
                            client_connect);
614
 
                        reverse_connect(client_connect);
615
 
-                       did_client_connect = 1;
616
 
+                       *did_client_connect = 1;
617
 
                }
618
 
                free(client_connect);
619
 
                if (remainder != NULL) {
620
 
@@ -1711,11 +1445,14 @@
621
 
                        client_connect = NULL;
622
 
                }
623
 
        }
624
 
+}
625
 
 
626
 
+static void loop_for_connect(int did_client_connect) {
627
 
+       int loop = 0;
628
 
+       time_t start = time(NULL);
629
 
        if (first_conn_timeout < 0) {
630
 
                first_conn_timeout = -first_conn_timeout;
631
 
        }
632
 
-       start = time(NULL);
633
 
 
634
 
        while (1) {
635
 
                loop++;
636
 
@@ -1789,16 +1526,19 @@
637
 
                if (! use_threads) {
638
 
                        rfbPE(-1);
639
 
                }
640
 
+
641
 
                screen_check:
642
 
                if (! screen || ! screen->clientHead) {
643
 
                        usleep(100 * 1000);
644
 
                        continue;
645
 
                }
646
 
+
647
 
                rfbLog("wait_for_client: got client\n");
648
 
                break;
649
 
        }
650
 
+}
651
 
 
652
 
-
653
 
+static void do_unixpw_loop(void) {
654
 
        if (unixpw) {
655
 
                if (! unixpw_in_progress) {
656
 
                        rfbLog("unixpw but no unixpw_in_progress\n");
657
 
@@ -1808,12 +1548,6 @@
658
 
                        rfbLog("taking unixpw_client off hold.\n");
659
 
                        unixpw_client->onHold = FALSE;
660
 
                }
661
 
-               if (cmd && strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
662
 
-                       if (users_list && strstr(users_list, "unixpw=") == users_list) {
663
 
-                               users_list_save = users_list;
664
 
-                               users_list = NULL;
665
 
-                       }
666
 
-               }
667
 
                while (1) {
668
 
                        if (shut_down) {
669
 
                                clean_up_exit(0);
670
 
@@ -1831,482 +1565,803 @@
671
 
                        break;
672
 
                }
673
 
        }
674
 
+}
675
 
 
676
 
-if (0) db = 1;
677
 
-
678
 
-       vnc_redirect_place:
679
 
-
680
 
-       if (vnc_redirect == 2) {
681
 
-               ;
682
 
-       } else if (cmd) {
683
 
-               char line1[1024];
684
 
-               char line2[16384];
685
 
-               char *q;
686
 
-               int n;
687
 
-               int nodisp = 0;
688
 
-               int saw_xdmcp = 0;
689
 
-               char *usslpeer = NULL;
690
 
-
691
 
-               memset(line1, 0, 1024);
692
 
-               memset(line2, 0, 16384);
693
 
-
694
 
-               if (users_list && strstr(users_list, "sslpeer=") == users_list) {
695
 
-                       int ok = 0;
696
 
-                       char *u = NULL, *upeer = NULL;
697
 
-
698
 
-                       if (certret_str) {
699
 
-                               char *q, *p, *str = strdup(certret_str);
700
 
-                               q = strstr(str, "Subject: ");
701
 
-                               if (! q) return 0;
702
 
-                               p = strstr(q, "\n");
703
 
-                               if (p) *p = '\0';
704
 
-                               q = strstr(q, "CN=");
705
 
-                               if (! q) return 0;
706
 
-                               if (! getenv("X11VNC_SSLPEER_CN")) {
707
 
-                                       p = q;
708
 
-                                       q = strstr(q, "/emailAddress=");
709
 
-                                       if (! q) q = strstr(p, "/Email=");
710
 
-                                       if (! q) return 0;
711
 
+static void vnc_redirect_loop(char *vnc_redirect_test, int *vnc_redirect_cnt) {
712
 
+       if (unixpw) {
713
 
+               rfbLog("wait_for_client: -unixpw and Xvnc.redirect not allowed\n");
714
 
+               clean_up_exit(1);
715
 
+       }
716
 
+       if (client_connect) {
717
 
+               rfbLog("wait_for_client: -connect and Xvnc.redirect not allowed\n");
718
 
+               clean_up_exit(1);
719
 
+       }
720
 
+       if (inetd) {
721
 
+               if (use_openssl) {
722
 
+                       accept_openssl(OPENSSL_INETD, -1);
723
 
+               }
724
 
+       } else {
725
 
+               pid_t pid = 0;
726
 
+               if (screen->httpListenSock >= 0) {
727
 
+#if LIBVNCSERVER_HAVE_FORK
728
 
+                       if ((pid = fork()) > 0) {
729
 
+                               close(screen->httpListenSock);
730
 
+                               screen->httpListenSock = -2;
731
 
+                               usleep(500 * 1000);
732
 
+                       } else {
733
 
+                               close(screen->listenSock);
734
 
+                               screen->listenSock = -1;
735
 
+                               while (1) {
736
 
+                                       usleep(10 * 1000);
737
 
+                                       rfbHttpCheckFds(screen);
738
 
                                }
739
 
-                               q = strstr(q, "=");
740
 
-                               if (! q) return 0;
741
 
-                               q++;
742
 
-                               p = strstr(q, " ");
743
 
-                               if (p) *p = '\0';
744
 
-                               p = strstr(q, "@");
745
 
-                               if (p) *p = '\0';
746
 
-                               p = strstr(q, "/");
747
 
-                               if (p) *p = '\0';
748
 
-                               upeer = strdup(q);
749
 
-                               if (strcmp(upeer, "")) {
750
 
-                                       p = upeer;
751
 
-                                       while (*p != '\0') {
752
 
-                                               char c = *p;
753
 
-                                               if (!isalnum((int) c)) {
754
 
-                                                       *p = '\0';
755
 
-                                                       break;
756
 
-                                               }
757
 
-                                               p++;
758
 
-                                       }
759
 
-                                       if (strcmp(upeer, "")) {
760
 
-                                               ok = 1;
761
 
-                                       }
762
 
-                               }
763
 
+                               exit(1);
764
 
                        }
765
 
-                       if (! ok || !upeer) {
766
 
-                               return 0;
767
 
+#else
768
 
+                       clean_up_exit(1);
769
 
+#endif
770
 
+               }
771
 
+               if (first_conn_timeout) {
772
 
+                       if (first_conn_timeout < 0) {
773
 
+                               first_conn_timeout = -first_conn_timeout;
774
 
                        }
775
 
-                       rfbLog("sslpeer unix username extracted from x509 cert: %s\n", upeer);
776
 
-                       u = (char *) malloc(strlen(upeer+2));
777
 
-                       u[0] = '\0';
778
 
-                       if (!strcmp(users_list, "sslpeer=")) {
779
 
-                               sprintf(u, "+%s", upeer);
780
 
+                       signal(SIGALRM, vnc_redirect_timeout);
781
 
+                       alarm(first_conn_timeout);
782
 
+               }
783
 
+               if (use_openssl) {
784
 
+                       int i;
785
 
+                       if (pid == 0) {
786
 
+                               accept_openssl(OPENSSL_VNC, -1);
787
 
                        } else {
788
 
-                               char *p, *str = strdup(users_list);
789
 
-                               p = strtok(str + strlen("sslpeer="), ",");
790
 
-                               while (p) {
791
 
-                                       if (!strcmp(p, upeer)) {
792
 
-                                               sprintf(u, "+%s", upeer);
793
 
+                               for (i=0; i < 16; i++) {
794
 
+                                       accept_openssl(OPENSSL_VNC, -1);
795
 
+                                       rfbLog("iter %d: vnc_redirect_sock: %d\n", i, vnc_redirect_sock);
796
 
+                                       if (vnc_redirect_sock >= 0) {
797
 
                                                break;
798
 
                                        }
799
 
-                                       p = strtok(NULL, ",");
800
 
                                }
801
 
-                               free(str);
802
 
                        }
803
 
-                       if (u[0] == '\0') {
804
 
-                               rfbLog("sslpeer cannot determine user: %s\n", upeer);
805
 
-                               free(u);
806
 
-                               return 0;
807
 
+               } else {
808
 
+                       struct sockaddr_in addr;
809
 
+#ifdef __hpux
810
 
+                       int addrlen = sizeof(addr);
811
 
+#else
812
 
+                       socklen_t addrlen = sizeof(addr);
813
 
+#endif
814
 
+                       if (screen->listenSock < 0) {
815
 
+                               rfbLog("wait_for_client: Xvnc.redirect not listening... sock=%d port=%d\n", screen->listenSock, screen->port);
816
 
+                               clean_up_exit(1);
817
 
                        }
818
 
-                       free(u);
819
 
-                       usslpeer = upeer;
820
 
+                       vnc_redirect_sock = accept(screen->listenSock, (struct sockaddr *)&addr, &addrlen);
821
 
                }
822
 
+               if (first_conn_timeout) {
823
 
+                       alarm(0);
824
 
+               }
825
 
+               if (pid > 0) {
826
 
+#if LIBVNCSERVER_HAVE_FORK
827
 
+                       int rc;
828
 
+                       pid_t pidw;
829
 
+                       rfbLog("wait_for_client: kill TERM: %d\n", (int) pid);
830
 
+                       kill(pid, SIGTERM);
831
 
+                       usleep(1000 * 1000);    /* 1.0 sec */
832
 
+                       pidw = waitpid(pid, &rc, WNOHANG);
833
 
+                       if (pidw <= 0) {
834
 
+                               usleep(1000 * 1000);    /* 1.0 sec */
835
 
+                               pidw = waitpid(pid, &rc, WNOHANG);
836
 
+                       }
837
 
+#else
838
 
+                       clean_up_exit(1);
839
 
+#endif
840
 
+               }
841
 
+       }
842
 
+       if (vnc_redirect_sock < 0) {
843
 
+               rfbLog("wait_for_client: vnc_redirect failed.\n");
844
 
+               clean_up_exit(1);
845
 
+       }
846
 
+       if (!inetd && use_openssl) {
847
 
+               /* check for Fetch Cert closing */
848
 
+               fd_set rfds;
849
 
+               struct timeval tv;
850
 
+               int nfds;
851
 
 
852
 
-               /* only sets environment variables: */
853
 
-               run_user_command("", latest_client, "env", NULL, 0, NULL);
854
 
+               usleep(300*1000);
855
 
 
856
 
-               if (program_name) {
857
 
-                       set_env("X11VNC_PROG", program_name);
858
 
-               } else {
859
 
-                       set_env("X11VNC_PROG", "x11vnc");
860
 
-               }
861
 
+               FD_ZERO(&rfds);
862
 
+               FD_SET(vnc_redirect_sock, &rfds);
863
 
 
864
 
-               if (!strcmp(cmd, "FINDDISPLAY") ||
865
 
-                   strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
866
 
-                       char *nd = "";
867
 
-                       tmp_fd = mkstemp(tmp);
868
 
-                       if (tmp_fd < 0) {
869
 
-                               rfbLog("wait_for_client: open failed: %s\n", tmp);
870
 
-                               rfbLogPerror("mkstemp");
871
 
-                               clean_up_exit(1);
872
 
-                       }
873
 
-                       chmod(tmp, 0644);
874
 
-                       if (getenv("X11VNC_FINDDISPLAY_ALWAYS_FAILS")) {
875
 
-                               char *s = "#!/bin/sh\necho _FAIL_\nexit 1\n";
876
 
-                               write(tmp_fd, s, strlen(s));
877
 
+               tv.tv_sec = 0;
878
 
+               tv.tv_usec = 200000;
879
 
+               nfds = select(vnc_redirect_sock+1, &rfds, NULL, NULL, &tv);
880
 
+
881
 
+               rfbLog("wait_for_client: vnc_redirect nfds: %d\n", nfds);
882
 
+               if (nfds > 0) {
883
 
+                       int n;
884
 
+                       n = read(vnc_redirect_sock, vnc_redirect_test, 1);
885
 
+                       if (n <= 0) {
886
 
+                               close(vnc_redirect_sock);
887
 
+                               vnc_redirect_sock = -1;
888
 
+                               rfbLog("wait_for_client: waiting for 2nd connection (Fetch Cert?)\n");
889
 
+                               accept_openssl(OPENSSL_VNC, -1);
890
 
+                               if (vnc_redirect_sock < 0) {
891
 
+                                       rfbLog("wait_for_client: vnc_redirect failed.\n");
892
 
+                                       clean_up_exit(1);
893
 
+                               }
894
 
                        } else {
895
 
-                               write(tmp_fd, find_display, strlen(find_display));
896
 
+                               *vnc_redirect_cnt = n;
897
 
                        }
898
 
-                       close(tmp_fd);
899
 
-                       nodisp = 1;
900
 
+               }
901
 
+       }
902
 
+}
903
 
 
904
 
-                       if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
905
 
-                               char *opts = strchr(cmd, '-');
906
 
-                               char st[] = "";
907
 
-                               char fdgeom[128], fdsess[128], fdopts[128], fdprog[128];
908
 
-                               char fdxsrv[128], fdxdum[128], fdcups[128], fdesd[128];
909
 
-                               char fdnas[128], fdsmb[128], fdtag[128];
910
 
-                               if (opts) {
911
 
-                                       opts++;
912
 
-                                       if (strstr(opts, "xdmcp")) {
913
 
-                                               saw_xdmcp = 1;
914
 
-                                       }
915
 
-                               } else {
916
 
-                                       opts = st;
917
 
-                               }
918
 
-                               sprintf(fdgeom, "NONE");
919
 
-                               fdsess[0] = '\0';
920
 
-                               fdgeom[0] = '\0';
921
 
-                               fdopts[0] = '\0';
922
 
-                               fdprog[0] = '\0';
923
 
-                               fdxsrv[0] = '\0';
924
 
-                               fdxdum[0] = '\0';
925
 
-                               fdcups[0] = '\0';
926
 
-                               fdesd[0]  = '\0';
927
 
-                               fdnas[0]  = '\0';
928
 
-                               fdsmb[0]  = '\0';
929
 
-                               fdtag[0]  = '\0';
930
 
+static void do_vnc_redirect(int created_disp, char *vnc_redirect_host, int vnc_redirect_port,
931
 
+    int vnc_redirect_cnt, char *vnc_redirect_test) {
932
 
+       char *q = strchr(use_dpy, ':');
933
 
+       int vdpy = -1, sock = -1;
934
 
+       int s_in, s_out, i;
935
 
+       if (vnc_redirect == 2) {
936
 
+               char num[32];   
937
 
+               sprintf(num, ":%d", vnc_redirect_port);
938
 
+               q = num;
939
 
+       }
940
 
+       if (!q) {
941
 
+               rfbLog("wait_for_client: can't find number in X display: %s\n", use_dpy);
942
 
+               clean_up_exit(1);
943
 
+       }
944
 
+       if (sscanf(q+1, "%d", &vdpy) != 1) {
945
 
+               rfbLog("wait_for_client: can't find number in X display: %s\n", q);
946
 
+               clean_up_exit(1);
947
 
+       }
948
 
+       if (vdpy == -1 && vnc_redirect != 2) {
949
 
+               rfbLog("wait_for_client: can't find number in X display: %s\n", q);
950
 
+               clean_up_exit(1);
951
 
+       }
952
 
+       if (vnc_redirect == 2) {
953
 
+               if (vdpy < 0) {
954
 
+                       vdpy = -vdpy;
955
 
+               } else if (vdpy < 200) {
956
 
+                       vdpy += 5900;
957
 
+               }
958
 
+       } else {
959
 
+               vdpy += 5900;
960
 
+       }
961
 
+       if (created_disp) {
962
 
+               usleep(1000*1000);
963
 
+       }
964
 
+       for (i=0; i < 20; i++) {
965
 
+               sock = rfbConnectToTcpAddr(vnc_redirect_host, vdpy);
966
 
+               if (sock >= 0) {
967
 
+                       break;
968
 
+               }
969
 
+               rfbLog("wait_for_client: ...\n");
970
 
+               usleep(500*1000);
971
 
+       }
972
 
+       if (sock < 0) {
973
 
+               rfbLog("wait_for_client: could not connect to a VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
974
 
+               clean_up_exit(1);
975
 
+       }
976
 
+       if (inetd) {
977
 
+               s_in  = fileno(stdin);
978
 
+               s_out = fileno(stdout);
979
 
+       } else {
980
 
+               s_in = s_out = vnc_redirect_sock;
981
 
+       }
982
 
+       if (vnc_redirect_cnt > 0) {
983
 
+               write(vnc_redirect_sock, vnc_redirect_test, vnc_redirect_cnt);
984
 
+       }
985
 
+       rfbLog("wait_for_client: switching control to VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
986
 
+       raw_xfer(sock, s_in, s_out);
987
 
+}
988
 
 
989
 
-                               if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
990
 
-                                       char *q, *p, *t = strdup(keep_unixpw_opts);
991
 
-                                       if (strstr(t, "gnome")) {
992
 
-                                               sprintf(fdsess, "gnome");
993
 
-                                       } else if (strstr(t, "kde")) {
994
 
-                                               sprintf(fdsess, "kde");
995
 
-                                       } else if (strstr(t, "twm")) {
996
 
-                                               sprintf(fdsess, "twm");
997
 
-                                       } else if (strstr(t, "fvwm")) {
998
 
-                                               sprintf(fdsess, "fvwm");
999
 
-                                       } else if (strstr(t, "mwm")) {
1000
 
-                                               sprintf(fdsess, "mwm");
1001
 
-                                       } else if (strstr(t, "cde")) {
1002
 
-                                               sprintf(fdsess, "cde");
1003
 
-                                       } else if (strstr(t, "dtwm")) {
1004
 
-                                               sprintf(fdsess, "dtwm");
1005
 
-                                       } else if (strstr(t, "xterm")) {
1006
 
-                                               sprintf(fdsess, "xterm");
1007
 
-                                       } else if (strstr(t, "wmaker")) {
1008
 
-                                               sprintf(fdsess, "wmaker");
1009
 
-                                       } else if (strstr(t, "xfce")) {
1010
 
-                                               sprintf(fdsess, "xfce");
1011
 
-                                       } else if (strstr(t, "enlightenment")) {
1012
 
-                                               sprintf(fdsess, "enlightenment");
1013
 
-                                       } else if (strstr(t, "Xsession")) {
1014
 
-                                               sprintf(fdsess, "Xsession");
1015
 
-                                       } else if (strstr(t, "failsafe")) {
1016
 
-                                               sprintf(fdsess, "failsafe");
1017
 
-                                       }
1018
 
+extern char find_display[];
1019
 
+extern char create_display[];
1020
 
 
1021
 
-                                       q = strstr(t, "ge=");
1022
 
-                                       if (! q) q = strstr(t, "geom=");
1023
 
-                                       if (! q) q = strstr(t, "geometry=");
1024
 
-                                       if (q) {
1025
 
-                                               int ok = 1;
1026
 
-                                               q = strstr(q, "=");
1027
 
-                                               q++;
1028
 
-                                               p = strstr(q, ",");
1029
 
-                                               if (p) *p = '\0';
1030
 
-                                               p = q;
1031
 
-                                               while (*p) {
1032
 
-                                                       if (*p == 'x') {
1033
 
-                                                               ;
1034
 
-                                                       } else if (isdigit((int) *p)) {
1035
 
-                                                               ;
1036
 
-                                                       } else {
1037
 
-                                                               ok = 0;
1038
 
-                                                               break;
1039
 
-                                                       }
1040
 
-                                                       p++;
1041
 
-                                               }
1042
 
-                                               if (ok && strlen(q) < 32) {
1043
 
-                                                       sprintf(fdgeom, q);
1044
 
-                                                       if (!quiet) {
1045
 
-                                                               rfbLog("set create display geom: %s\n", fdgeom);
1046
 
-                                                       }
1047
 
-                                               }
1048
 
-                                       }
1049
 
-                                       q = strstr(t, "cups=");
1050
 
-                                       if (q) {
1051
 
-                                               int p;
1052
 
-                                               if (sscanf(q, "cups=%d", &p) == 1) {
1053
 
-                                                       sprintf(fdcups, "%d", p);
1054
 
-                                               }
1055
 
-                                       }
1056
 
-                                       q = strstr(t, "esd=");
1057
 
-                                       if (q) {
1058
 
-                                               int p;
1059
 
-                                               if (sscanf(q, "esd=%d", &p) == 1) {
1060
 
-                                                       sprintf(fdesd, "%d", p);
1061
 
-                                               }
1062
 
-                                       }
1063
 
-                                       free(t);
1064
 
-                               }
1065
 
-                               if (fdgeom[0] == '\0' && getenv("FD_GEOM")) {
1066
 
-                                       snprintf(fdgeom,  120, "%s", getenv("FD_GEOM"));
1067
 
-                               }
1068
 
-                               if (fdsess[0] == '\0' && getenv("FD_SESS")) {
1069
 
-                                       snprintf(fdsess, 120, "%s", getenv("FD_SESS"));
1070
 
-                               }
1071
 
-                               if (fdopts[0] == '\0' && getenv("FD_OPTS")) {
1072
 
-                                       snprintf(fdopts, 120, "%s", getenv("FD_OPTS"));
1073
 
-                               }
1074
 
-                               if (fdprog[0] == '\0' && getenv("FD_PROG")) {
1075
 
-                                       snprintf(fdprog, 120, "%s", getenv("FD_PROG"));
1076
 
-                               }
1077
 
-                               if (fdxsrv[0] == '\0' && getenv("FD_XSRV")) {
1078
 
-                                       snprintf(fdxsrv, 120, "%s", getenv("FD_XSRV"));
1079
 
-                               }
1080
 
-                               if (fdcups[0] == '\0' && getenv("FD_CUPS")) {
1081
 
-                                       snprintf(fdcups, 120, "%s", getenv("FD_CUPS"));
1082
 
-                               }
1083
 
-                               if (fdesd[0] == '\0' && getenv("FD_ESD")) {
1084
 
-                                       snprintf(fdesd, 120, "%s", getenv("FD_ESD"));
1085
 
-                               }
1086
 
-                               if (fdnas[0] == '\0' && getenv("FD_NAS")) {
1087
 
-                                       snprintf(fdnas, 120, "%s", getenv("FD_NAS"));
1088
 
-                               }
1089
 
-                               if (fdsmb[0] == '\0' && getenv("FD_SMB")) {
1090
 
-                                       snprintf(fdsmb, 120, "%s", getenv("FD_SMB"));
1091
 
-                               }
1092
 
-                               if (fdtag[0] == '\0' && getenv("FD_TAG")) {
1093
 
-                                       snprintf(fdtag, 120, "%s", getenv("FD_TAG"));
1094
 
-                               }
1095
 
-                               if (fdxdum[0] == '\0' && getenv("FD_XDUMMY_NOROOT")) {
1096
 
-                                       snprintf(fdxdum, 120, "%s", getenv("FD_XDUMMY_NOROOT"));
1097
 
-                               }
1098
 
+char *setup_cmd(char *str, int *vnc_redirect, char **vnc_redirect_host, int *vnc_redirect_port, int db) {
1099
 
+       char *cmd = NULL;
1100
 
+       
1101
 
+       if (no_external_cmds || !cmd_ok("WAIT")) {
1102
 
+               rfbLog("wait_for_client external cmds not allowed:"
1103
 
+                   " %s\n", use_dpy);
1104
 
+               clean_up_exit(1);
1105
 
+       }
1106
 
 
1107
 
-                               set_env("FD_GEOM", fdgeom);
1108
 
-                               set_env("FD_OPTS", fdopts);
1109
 
-                               set_env("FD_PROG", fdprog);
1110
 
-                               set_env("FD_XSRV", fdxsrv);
1111
 
-                               set_env("FD_CUPS", fdcups);
1112
 
-                               set_env("FD_ESD",  fdesd);
1113
 
-                               set_env("FD_NAS",  fdnas);
1114
 
-                               set_env("FD_SMB",  fdsmb);
1115
 
-                               set_env("FD_TAG",  fdtag);
1116
 
-                               set_env("FD_XDUMMY_NOROOT", fdxdum);
1117
 
-                               set_env("FD_SESS", fdsess);
1118
 
+       cmd = str + strlen("cmd=");
1119
 
+       if (!strcmp(cmd, "FINDDISPLAY-print")) {
1120
 
+               fprintf(stdout, "%s", find_display);
1121
 
+               clean_up_exit(0);
1122
 
+       }
1123
 
+       if (!strcmp(cmd, "FINDDISPLAY-run")) {
1124
 
+               char tmp[] = "/tmp/fd.XXXXXX";
1125
 
+               char com[100];
1126
 
+               int fd = mkstemp(tmp);
1127
 
+               if (fd >= 0) {
1128
 
+                       write(fd, find_display, strlen(find_display));
1129
 
+                       close(fd);
1130
 
+                       set_env("FINDDISPLAY_run", "1");
1131
 
+                       sprintf(com, "/bin/sh %s -n; rm -f %s", tmp, tmp);
1132
 
+                       system(com);
1133
 
+               }
1134
 
+               unlink(tmp);
1135
 
+               exit(0);
1136
 
+       }
1137
 
+       if (!strcmp(str, "FINDCREATEDISPLAY-print")) {
1138
 
+               fprintf(stdout, "%s", create_display);
1139
 
+               clean_up_exit(0);
1140
 
+       }
1141
 
+       if (db) fprintf(stderr, "cmd: %s\n", cmd);
1142
 
+       if (strstr(str, "FINDCREATEDISPLAY") || strstr(str, "FINDDISPLAY")) {
1143
 
+               if (strstr(str, "Xvnc.redirect") || strstr(str, "X.redirect")) {
1144
 
+                       *vnc_redirect = 1;
1145
 
+               }
1146
 
+       }
1147
 
+       if (strstr(cmd, "FINDDISPLAY-vnc_redirect") == cmd) {
1148
 
+               int p;
1149
 
+               char h[256];
1150
 
+               if (strlen(cmd) >= 256) {
1151
 
+                       rfbLog("wait_for_client string too long: %s\n", str);
1152
 
+                       clean_up_exit(1);
1153
 
+               }
1154
 
+               h[0] = '\0';
1155
 
+               if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%d", &p) == 1) {
1156
 
+                       ;
1157
 
+               } else if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%s %d", h, &p) == 2) {
1158
 
+                       ;
1159
 
+               } else {
1160
 
+                       rfbLog("wait_for_client bad string: %s\n", cmd);
1161
 
+                       clean_up_exit(1);
1162
 
+               }
1163
 
+               *vnc_redirect_port = p;
1164
 
+               if (strcmp(h, "")) {
1165
 
+                       *vnc_redirect_host = strdup(h);
1166
 
+               }
1167
 
+               *vnc_redirect = 2;
1168
 
+               rfbLog("wait_for_client: vnc_redirect: %s:%d\n", *vnc_redirect_host, *vnc_redirect_port);
1169
 
+       }
1170
 
+       return cmd;
1171
 
+}
1172
 
 
1173
 
-                               if (usslpeer || (unixpw && keep_unixpw_user)) {
1174
 
-                                       char *uu = usslpeer;
1175
 
-                                       if (!uu) {
1176
 
-                                               uu = keep_unixpw_user;
1177
 
-                                       }
1178
 
-                                       create_cmd = (char *) malloc(strlen(tmp)+1
1179
 
-                                           + strlen("env USER='' ")
1180
 
-                                           + strlen("FD_GEOM='' ")
1181
 
-                                           + strlen("FD_OPTS='' ")
1182
 
-                                           + strlen("FD_PROG='' ")
1183
 
-                                           + strlen("FD_XSRV='' ")
1184
 
-                                           + strlen("FD_CUPS='' ")
1185
 
-                                           + strlen("FD_ESD='' ")
1186
 
-                                           + strlen("FD_NAS='' ")
1187
 
-                                           + strlen("FD_SMB='' ")
1188
 
-                                           + strlen("FD_TAG='' ")
1189
 
-                                           + strlen("FD_XDUMMY_NOROOT='' ")
1190
 
-                                           + strlen("FD_SESS='' /bin/sh ")
1191
 
-                                           + strlen(uu) + 1
1192
 
-                                           + strlen(fdgeom) + 1
1193
 
-                                           + strlen(fdopts) + 1
1194
 
-                                           + strlen(fdprog) + 1
1195
 
-                                           + strlen(fdxsrv) + 1
1196
 
-                                           + strlen(fdcups) + 1
1197
 
-                                           + strlen(fdesd) + 1
1198
 
-                                           + strlen(fdnas) + 1
1199
 
-                                           + strlen(fdsmb) + 1
1200
 
-                                           + strlen(fdtag) + 1
1201
 
-                                           + strlen(fdxdum) + 1
1202
 
-                                           + strlen(fdsess) + 1
1203
 
-                                           + strlen(opts) + 1);
1204
 
-                                       sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' "
1205
 
-                                           "FD_OPTS='%s' FD_PROG='%s' FD_XSRV='%s' FD_CUPS='%s' "
1206
 
-                                           "FD_ESD='%s' FD_NAS='%s' FD_SMB='%s' FD_TAG='%s' "
1207
 
-                                           "FD_XDUMMY_NOROOT='%s' /bin/sh %s %s",
1208
 
-                                           uu, fdgeom, fdsess, fdopts, fdprog, fdxsrv,
1209
 
-                                           fdcups, fdesd, fdnas, fdsmb, fdtag, fdxdum, tmp, opts);
1210
 
+static char *build_create_cmd(char *cmd, int *saw_xdmcp, char *usslpeer, char *tmp) {
1211
 
+       char *create_cmd = NULL;
1212
 
+       char *opts = strchr(cmd, '-');
1213
 
+       char st[] = "";
1214
 
+       char fdgeom[128], fdsess[128], fdopts[128], fdprog[128];
1215
 
+       char fdxsrv[128], fdxdum[128], fdcups[128], fdesd[128];
1216
 
+       char fdnas[128], fdsmb[128], fdtag[128];
1217
 
+
1218
 
+       if (opts) {
1219
 
+               opts++;
1220
 
+               if (strstr(opts, "xdmcp")) {
1221
 
+                       *saw_xdmcp = 1;
1222
 
+               }
1223
 
+       } else {
1224
 
+               opts = st;
1225
 
+       }
1226
 
+       sprintf(fdgeom, "NONE");
1227
 
+       fdsess[0] = '\0';
1228
 
+       fdgeom[0] = '\0';
1229
 
+       fdopts[0] = '\0';
1230
 
+       fdprog[0] = '\0';
1231
 
+       fdxsrv[0] = '\0';
1232
 
+       fdxdum[0] = '\0';
1233
 
+       fdcups[0] = '\0';
1234
 
+       fdesd[0]  = '\0';
1235
 
+       fdnas[0]  = '\0';
1236
 
+       fdsmb[0]  = '\0';
1237
 
+       fdtag[0]  = '\0';
1238
 
+
1239
 
+       if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
1240
 
+               char *q, *p, *t = strdup(keep_unixpw_opts);
1241
 
+               if (strstr(t, "gnome")) {
1242
 
+                       sprintf(fdsess, "gnome");
1243
 
+               } else if (strstr(t, "kde")) {
1244
 
+                       sprintf(fdsess, "kde");
1245
 
+               } else if (strstr(t, "twm")) {
1246
 
+                       sprintf(fdsess, "twm");
1247
 
+               } else if (strstr(t, "fvwm")) {
1248
 
+                       sprintf(fdsess, "fvwm");
1249
 
+               } else if (strstr(t, "mwm")) {
1250
 
+                       sprintf(fdsess, "mwm");
1251
 
+               } else if (strstr(t, "cde")) {
1252
 
+                       sprintf(fdsess, "cde");
1253
 
+               } else if (strstr(t, "dtwm")) {
1254
 
+                       sprintf(fdsess, "dtwm");
1255
 
+               } else if (strstr(t, "xterm")) {
1256
 
+                       sprintf(fdsess, "xterm");
1257
 
+               } else if (strstr(t, "wmaker")) {
1258
 
+                       sprintf(fdsess, "wmaker");
1259
 
+               } else if (strstr(t, "xfce")) {
1260
 
+                       sprintf(fdsess, "xfce");
1261
 
+               } else if (strstr(t, "enlightenment")) {
1262
 
+                       sprintf(fdsess, "enlightenment");
1263
 
+               } else if (strstr(t, "Xsession")) {
1264
 
+                       sprintf(fdsess, "Xsession");
1265
 
+               } else if (strstr(t, "failsafe")) {
1266
 
+                       sprintf(fdsess, "failsafe");
1267
 
+               }
1268
 
+
1269
 
+               q = strstr(t, "ge=");
1270
 
+               if (! q) q = strstr(t, "geom=");
1271
 
+               if (! q) q = strstr(t, "geometry=");
1272
 
+               if (q) {
1273
 
+                       int ok = 1;
1274
 
+                       q = strstr(q, "=");
1275
 
+                       q++;
1276
 
+                       p = strstr(q, ",");
1277
 
+                       if (p) *p = '\0';
1278
 
+                       p = q;
1279
 
+                       while (*p) {
1280
 
+                               if (*p == 'x') {
1281
 
+                                       ;
1282
 
+                               } else if (isdigit((int) *p)) {
1283
 
+                                       ;
1284
 
                                } else {
1285
 
-                                       create_cmd = (char *) malloc(strlen(tmp)
1286
 
-                                           + strlen("/bin/sh ") + 1 + strlen(opts) + 1);
1287
 
-                                       sprintf(create_cmd, "/bin/sh %s %s", tmp, opts);
1288
 
+                                       ok = 0;
1289
 
+                                       break;
1290
 
                                }
1291
 
-
1292
 
-if (db) fprintf(stderr, "create_cmd: %s\n", create_cmd);
1293
 
+                               p++;
1294
 
                        }
1295
 
-                       if (getenv("X11VNC_SKIP_DISPLAY")) {
1296
 
-                               nd = strdup(getenv("X11VNC_SKIP_DISPLAY"));
1297
 
-                       }
1298
 
-                       if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
1299
 
-                               char *q, *t = keep_unixpw_opts;
1300
 
-                               q = strstr(t, "nd=");
1301
 
-                               if (! q) q = strstr(t, "nodisplay=");
1302
 
-                               if (q) {
1303
 
-                                       char *t2;
1304
 
-                                       q = strchr(q, '=') + 1;
1305
 
-                                       t = strdup(q);
1306
 
-                                       q = t;
1307
 
-                                       t2 = strchr(t, ',');
1308
 
-                                       if (t2) *t2 = '\0';
1309
 
-                                       while (*t != '\0') {
1310
 
-                                               if (*t == '-') {
1311
 
-                                                       *t = ',';
1312
 
-                                               }
1313
 
-                                               t++;
1314
 
-                                       }
1315
 
-                                       if (!strchr(q, '\'')) {
1316
 
-                                               if (! quiet) rfbLog("set X11VNC_SKIP_DISPLAY: %s\n", q);
1317
 
-                                               nd = q;
1318
 
-                                       }
1319
 
+                       if (ok && strlen(q) < 32) {
1320
 
+                               sprintf(fdgeom, q);
1321
 
+                               if (!quiet) {
1322
 
+                                       rfbLog("set create display geom: %s\n", fdgeom);
1323
 
                                }
1324
 
                        }
1325
 
+               }
1326
 
+               q = strstr(t, "cups=");
1327
 
+               if (q) {
1328
 
+                       int p;
1329
 
+                       if (sscanf(q, "cups=%d", &p) == 1) {
1330
 
+                               sprintf(fdcups, "%d", p);
1331
 
+                       }
1332
 
+               }
1333
 
+               q = strstr(t, "esd=");
1334
 
+               if (q) {
1335
 
+                       int p;
1336
 
+                       if (sscanf(q, "esd=%d", &p) == 1) {
1337
 
+                               sprintf(fdesd, "%d", p);
1338
 
+                       }
1339
 
+               }
1340
 
+               free(t);
1341
 
+       }
1342
 
+       if (fdgeom[0] == '\0' && getenv("FD_GEOM")) {
1343
 
+               snprintf(fdgeom,  120, "%s", getenv("FD_GEOM"));
1344
 
+       }
1345
 
+       if (fdsess[0] == '\0' && getenv("FD_SESS")) {
1346
 
+               snprintf(fdsess, 120, "%s", getenv("FD_SESS"));
1347
 
+       }
1348
 
+       if (fdopts[0] == '\0' && getenv("FD_OPTS")) {
1349
 
+               snprintf(fdopts, 120, "%s", getenv("FD_OPTS"));
1350
 
+       }
1351
 
+       if (fdprog[0] == '\0' && getenv("FD_PROG")) {
1352
 
+               snprintf(fdprog, 120, "%s", getenv("FD_PROG"));
1353
 
+       }
1354
 
+       if (fdxsrv[0] == '\0' && getenv("FD_XSRV")) {
1355
 
+               snprintf(fdxsrv, 120, "%s", getenv("FD_XSRV"));
1356
 
+       }
1357
 
+       if (fdcups[0] == '\0' && getenv("FD_CUPS")) {
1358
 
+               snprintf(fdcups, 120, "%s", getenv("FD_CUPS"));
1359
 
+       }
1360
 
+       if (fdesd[0] == '\0' && getenv("FD_ESD")) {
1361
 
+               snprintf(fdesd, 120, "%s", getenv("FD_ESD"));
1362
 
+       }
1363
 
+       if (fdnas[0] == '\0' && getenv("FD_NAS")) {
1364
 
+               snprintf(fdnas, 120, "%s", getenv("FD_NAS"));
1365
 
+       }
1366
 
+       if (fdsmb[0] == '\0' && getenv("FD_SMB")) {
1367
 
+               snprintf(fdsmb, 120, "%s", getenv("FD_SMB"));
1368
 
+       }
1369
 
+       if (fdtag[0] == '\0' && getenv("FD_TAG")) {
1370
 
+               snprintf(fdtag, 120, "%s", getenv("FD_TAG"));
1371
 
+       }
1372
 
+       if (fdxdum[0] == '\0' && getenv("FD_XDUMMY_NOROOT")) {
1373
 
+               snprintf(fdxdum, 120, "%s", getenv("FD_XDUMMY_NOROOT"));
1374
 
+       }
1375
 
 
1376
 
-                       cmd = (char *) malloc(strlen("env X11VNC_SKIP_DISPLAY='' ")
1377
 
-                           + strlen(nd) + strlen(tmp) + strlen("/bin/sh ") + 1);
1378
 
-                       sprintf(cmd, "env X11VNC_SKIP_DISPLAY='%s' /bin/sh %s", nd, tmp);
1379
 
+       set_env("FD_GEOM", fdgeom);
1380
 
+       set_env("FD_OPTS", fdopts);
1381
 
+       set_env("FD_PROG", fdprog);
1382
 
+       set_env("FD_XSRV", fdxsrv);
1383
 
+       set_env("FD_CUPS", fdcups);
1384
 
+       set_env("FD_ESD",  fdesd);
1385
 
+       set_env("FD_NAS",  fdnas);
1386
 
+       set_env("FD_SMB",  fdsmb);
1387
 
+       set_env("FD_TAG",  fdtag);
1388
 
+       set_env("FD_XDUMMY_NOROOT", fdxdum);
1389
 
+       set_env("FD_SESS", fdsess);
1390
 
+
1391
 
+       if (usslpeer || (unixpw && keep_unixpw_user)) {
1392
 
+               char *uu = usslpeer;
1393
 
+               if (!uu) {
1394
 
+                       uu = keep_unixpw_user;
1395
 
                }
1396
 
+               create_cmd = (char *) malloc(strlen(tmp)+1
1397
 
+                   + strlen("env USER='' ")
1398
 
+                   + strlen("FD_GEOM='' ")
1399
 
+                   + strlen("FD_OPTS='' ")
1400
 
+                   + strlen("FD_PROG='' ")
1401
 
+                   + strlen("FD_XSRV='' ")
1402
 
+                   + strlen("FD_CUPS='' ")
1403
 
+                   + strlen("FD_ESD='' ")
1404
 
+                   + strlen("FD_NAS='' ")
1405
 
+                   + strlen("FD_SMB='' ")
1406
 
+                   + strlen("FD_TAG='' ")
1407
 
+                   + strlen("FD_XDUMMY_NOROOT='' ")
1408
 
+                   + strlen("FD_SESS='' /bin/sh ")
1409
 
+                   + strlen(uu) + 1
1410
 
+                   + strlen(fdgeom) + 1
1411
 
+                   + strlen(fdopts) + 1
1412
 
+                   + strlen(fdprog) + 1
1413
 
+                   + strlen(fdxsrv) + 1
1414
 
+                   + strlen(fdcups) + 1
1415
 
+                   + strlen(fdesd) + 1
1416
 
+                   + strlen(fdnas) + 1
1417
 
+                   + strlen(fdsmb) + 1
1418
 
+                   + strlen(fdtag) + 1
1419
 
+                   + strlen(fdxdum) + 1
1420
 
+                   + strlen(fdsess) + 1
1421
 
+                   + strlen(opts) + 1);
1422
 
+               sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' "
1423
 
+                   "FD_OPTS='%s' FD_PROG='%s' FD_XSRV='%s' FD_CUPS='%s' "
1424
 
+                   "FD_ESD='%s' FD_NAS='%s' FD_SMB='%s' FD_TAG='%s' "
1425
 
+                   "FD_XDUMMY_NOROOT='%s' /bin/sh %s %s",
1426
 
+                   uu, fdgeom, fdsess, fdopts, fdprog, fdxsrv,
1427
 
+                   fdcups, fdesd, fdnas, fdsmb, fdtag, fdxdum, tmp, opts);
1428
 
+       } else {
1429
 
+               create_cmd = (char *) malloc(strlen(tmp)
1430
 
+                   + strlen("/bin/sh ") + 1 + strlen(opts) + 1);
1431
 
+               sprintf(create_cmd, "/bin/sh %s %s", tmp, opts);
1432
 
+       }
1433
 
+       return create_cmd;
1434
 
+}
1435
 
 
1436
 
-               rfbLog("wait_for_client: running: %s\n", cmd);
1437
 
+static char *certret_extract() {
1438
 
+       char *q, *p, *str = strdup(certret_str);
1439
 
+       char *upeer = NULL;
1440
 
+       int ok = 0;
1441
 
 
1442
 
-               if (unixpw) {
1443
 
-                       int res = 0, k, j, i;
1444
 
-                       char line[18000];
1445
 
+       q = strstr(str, "Subject: ");
1446
 
+       if (! q) return NULL;
1447
 
 
1448
 
-                       memset(line, 0, 18000);
1449
 
+       p = strstr(q, "\n");
1450
 
+       if (p) *p = '\0';
1451
 
 
1452
 
-                       if (keep_unixpw_user && keep_unixpw_pass) {
1453
 
-                               n = 18000;
1454
 
-                               res = su_verify(keep_unixpw_user,
1455
 
-                                   keep_unixpw_pass, cmd, line, &n, nodisp);
1456
 
+       q = strstr(q, "CN=");
1457
 
+       if (! q) return NULL;
1458
 
+
1459
 
+       if (! getenv("X11VNC_SSLPEER_CN")) {
1460
 
+               p = q;
1461
 
+               q = strstr(q, "/emailAddress=");
1462
 
+               if (! q) q = strstr(p, "/Email=");
1463
 
+               if (! q) return NULL;
1464
 
+       }
1465
 
+
1466
 
+       q = strstr(q, "=");
1467
 
+       if (! q) return NULL;
1468
 
+
1469
 
+       q++;
1470
 
+       p = strstr(q, " ");
1471
 
+       if (p) *p = '\0';
1472
 
+       p = strstr(q, "@");
1473
 
+       if (p) *p = '\0';
1474
 
+       p = strstr(q, "/");
1475
 
+       if (p) *p = '\0';
1476
 
+
1477
 
+       upeer = strdup(q);
1478
 
+
1479
 
+       if (strcmp(upeer, "")) {
1480
 
+               p = upeer;
1481
 
+               while (*p != '\0') {
1482
 
+                       char c = *p;
1483
 
+                       if (!isalnum((int) c)) {
1484
 
+                               *p = '\0';
1485
 
+                               break;
1486
 
                        }
1487
 
+                       p++;
1488
 
+               }
1489
 
+               if (strcmp(upeer, "")) {
1490
 
+                       ok = 1;
1491
 
+               }
1492
 
+       }
1493
 
+       if (! ok) {
1494
 
+               upeer = NULL;
1495
 
+       }
1496
 
+       return upeer;
1497
 
+}
1498
 
 
1499
 
+static void check_nodisplay(char **nd) {
1500
 
+       if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
1501
 
+               char *q, *t = keep_unixpw_opts;
1502
 
+               q = strstr(t, "nd=");
1503
 
+               if (! q) q = strstr(t, "nodisplay=");
1504
 
+               if (q) {
1505
 
+                       char *t2;
1506
 
+                       q = strchr(q, '=') + 1;
1507
 
+                       t = strdup(q);
1508
 
+                       q = t;
1509
 
+                       t2 = strchr(t, ',');
1510
 
+                       if (t2) *t2 = '\0';
1511
 
+                       while (*t != '\0') {
1512
 
+                               if (*t == '-') {
1513
 
+                                       *t = ',';
1514
 
+                               }
1515
 
+                               t++;
1516
 
+                       }
1517
 
+                       if (!strchr(q, '\'')) {
1518
 
+                               if (! quiet) rfbLog("set X11VNC_SKIP_DISPLAY: %s\n", q);
1519
 
+                               *nd = q;
1520
 
+                       }
1521
 
+               }
1522
 
+       }
1523
 
+}
1524
 
+
1525
 
+static char *get_usslpeer() {
1526
 
+       char *u = NULL, *upeer = NULL;
1527
 
+
1528
 
+       if (certret_str) {
1529
 
+               upeer = certret_extract();
1530
 
+       }
1531
 
+       if (!upeer) {
1532
 
+               return NULL;
1533
 
+       }
1534
 
+       rfbLog("sslpeer unix username extracted from x509 cert: %s\n", upeer);
1535
 
+
1536
 
+       u = (char *) malloc(strlen(upeer+2));
1537
 
+       u[0] = '\0';
1538
 
+       if (!strcmp(users_list, "sslpeer=")) {
1539
 
+               sprintf(u, "+%s", upeer);
1540
 
+       } else {
1541
 
+               char *p, *str = strdup(users_list);
1542
 
+               p = strtok(str + strlen("sslpeer="), ",");
1543
 
+               while (p) {
1544
 
+                       if (!strcmp(p, upeer)) {
1545
 
+                               sprintf(u, "+%s", upeer);
1546
 
+                               break;
1547
 
+                       }
1548
 
+                       p = strtok(NULL, ",");
1549
 
+               }
1550
 
+               free(str);
1551
 
+       }
1552
 
+       if (u[0] == '\0') {
1553
 
+               rfbLog("sslpeer cannot determine user: %s\n", upeer);
1554
 
+               free(u);
1555
 
+               return NULL;
1556
 
+       }
1557
 
+       free(u);
1558
 
+       return upeer;
1559
 
+}
1560
 
+
1561
 
+static int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int created_disp, int db) {
1562
 
+       char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
1563
 
+       char line1[1024], line2[16384];
1564
 
+       char *q, *usslpeer = NULL;
1565
 
+       int n, nodisp = 0, saw_xdmcp = 0;
1566
 
+       int tmp_fd = -1;
1567
 
+
1568
 
+       memset(line1, 0, 1024);
1569
 
+       memset(line2, 0, 16384);
1570
 
+
1571
 
+       if (users_list && strstr(users_list, "sslpeer=") == users_list) {
1572
 
+               usslpeer = get_usslpeer();
1573
 
+               if (! usslpeer) {
1574
 
+                       return 0;
1575
 
+               }
1576
 
+       }
1577
 
+
1578
 
+       /* only sets environment variables: */
1579
 
+       run_user_command("", latest_client, "env", NULL, 0, NULL);
1580
 
+
1581
 
+       if (program_name) {
1582
 
+               set_env("X11VNC_PROG", program_name);
1583
 
+       } else {
1584
 
+               set_env("X11VNC_PROG", "x11vnc");
1585
 
+       }
1586
 
+
1587
 
+       if (!strcmp(cmd, "FINDDISPLAY") ||
1588
 
+           strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
1589
 
+               char *nd = "";
1590
 
+               tmp_fd = mkstemp(tmp);
1591
 
+               if (tmp_fd < 0) {
1592
 
+                       rfbLog("wait_for_client: open failed: %s\n", tmp);
1593
 
+                       rfbLogPerror("mkstemp");
1594
 
+                       clean_up_exit(1);
1595
 
+               }
1596
 
+               chmod(tmp, 0644);
1597
 
+               if (getenv("X11VNC_FINDDISPLAY_ALWAYS_FAILS")) {
1598
 
+                       char *s = "#!/bin/sh\necho _FAIL_\nexit 1\n";
1599
 
+                       write(tmp_fd, s, strlen(s));
1600
 
+               } else {
1601
 
+                       write(tmp_fd, find_display, strlen(find_display));
1602
 
+               }
1603
 
+               close(tmp_fd);
1604
 
+               nodisp = 1;
1605
 
+
1606
 
+               if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
1607
 
+                       create_cmd = build_create_cmd(cmd, &saw_xdmcp, usslpeer, tmp);
1608
 
+                       if (db) fprintf(stderr, "create_cmd: %s\n", create_cmd);
1609
 
+               }
1610
 
+               if (getenv("X11VNC_SKIP_DISPLAY")) {
1611
 
+                       nd = strdup(getenv("X11VNC_SKIP_DISPLAY"));
1612
 
+               }
1613
 
+               check_nodisplay(&nd);
1614
 
+
1615
 
+               cmd = (char *) malloc(strlen("env X11VNC_SKIP_DISPLAY='' ")
1616
 
+                   + strlen(nd) + strlen(tmp) + strlen("/bin/sh ") + 1);
1617
 
+               sprintf(cmd, "env X11VNC_SKIP_DISPLAY='%s' /bin/sh %s", nd, tmp);
1618
 
+       }
1619
 
+
1620
 
+       rfbLog("wait_for_client: running: %s\n", cmd);
1621
 
+
1622
 
+       if (unixpw) {
1623
 
+               int res = 0, k, j, i;
1624
 
+               char line[18000];
1625
 
+
1626
 
+               memset(line, 0, 18000);
1627
 
+
1628
 
+               if (keep_unixpw_user && keep_unixpw_pass) {
1629
 
+                       n = 18000;
1630
 
+                       res = su_verify(keep_unixpw_user,
1631
 
+                           keep_unixpw_pass, cmd, line, &n, nodisp);
1632
 
+               }
1633
 
+
1634
 
 if (db) {fprintf(stderr, "line: "); write(2, line, n); write(2, "\n", 1); fprintf(stderr, "res=%d n=%d\n", res, n);}
1635
 
-                       if (! res) {
1636
 
-                               rfbLog("wait_for_client: find display cmd failed\n");
1637
 
+               if (! res) {
1638
 
+                       rfbLog("wait_for_client: find display cmd failed\n");
1639
 
+               }
1640
 
+
1641
 
+               if (! res && create_cmd) {
1642
 
+                       FILE *mt = fopen(tmp, "w");
1643
 
+                       if (! mt) {
1644
 
+                               rfbLog("wait_for_client: open failed: %s\n", tmp);
1645
 
+                               rfbLogPerror("fopen");
1646
 
+                               clean_up_exit(1);
1647
 
                        }
1648
 
+                       fprintf(mt, "%s", create_display);
1649
 
+                       fclose(mt);
1650
 
 
1651
 
-                       if (! res && create_cmd) {
1652
 
-                               FILE *mt = fopen(tmp, "w");
1653
 
-                               if (! mt) {
1654
 
-                                       rfbLog("wait_for_client: open failed: %s\n", tmp);
1655
 
-                                       rfbLogPerror("fopen");
1656
 
-                                       clean_up_exit(1);
1657
 
-                               }
1658
 
-                               fprintf(mt, "%s", create_display);
1659
 
-                               fclose(mt);
1660
 
+                       findcreatedisplay = 1;
1661
 
 
1662
 
-                               findcreatedisplay = 1;
1663
 
-
1664
 
-                               if (getuid() != 0) {
1665
 
-                                       /* if not root, run as the other user... */
1666
 
-                                       n = 18000;
1667
 
-                                       close_exec_fds();
1668
 
-                                       res = su_verify(keep_unixpw_user,
1669
 
-                                           keep_unixpw_pass, create_cmd, line, &n, nodisp);
1670
 
+                       if (getuid() != 0) {
1671
 
+                               /* if not root, run as the other user... */
1672
 
+                               n = 18000;
1673
 
+                               close_exec_fds();
1674
 
+                               res = su_verify(keep_unixpw_user,
1675
 
+                                   keep_unixpw_pass, create_cmd, line, &n, nodisp);
1676
 
 if (db) fprintf(stderr, "c-res=%d n=%d line: '%s'\n", res, n, line);
1677
 
 
1678
 
+                       } else {
1679
 
+                               FILE *p;
1680
 
+                               close_exec_fds();
1681
 
+                               rfbLog("wait_for_client: running: %s\n", create_cmd);
1682
 
+                               p = popen(create_cmd, "r");
1683
 
+                               if (! p) {
1684
 
+                                       rfbLog("wait_for_client: popen failed: %s\n", create_cmd);
1685
 
+                                       res = 0;
1686
 
+                               } else if (fgets(line1, 1024, p) == NULL) {
1687
 
+                                       rfbLog("wait_for_client: read failed: %s\n", create_cmd);
1688
 
+                                       res = 0;
1689
 
                                } else {
1690
 
-                                       FILE *p;
1691
 
-                                       close_exec_fds();
1692
 
-                                       rfbLog("wait_for_client: running: %s\n", create_cmd);
1693
 
-                                       p = popen(create_cmd, "r");
1694
 
-                                       if (! p) {
1695
 
-                                               rfbLog("wait_for_client: popen failed: %s\n", create_cmd);
1696
 
+                                       n = fread(line2, 1, 16384, p);
1697
 
+                                       if (pclose(p) != 0) {
1698
 
                                                res = 0;
1699
 
-                                       } else if (fgets(line1, 1024, p) == NULL) {
1700
 
-                                               rfbLog("wait_for_client: read failed: %s\n", create_cmd);
1701
 
-                                               res = 0;
1702
 
                                        } else {
1703
 
-                                               n = fread(line2, 1, 16384, p);
1704
 
-                                               if (pclose(p) != 0) {
1705
 
-                                                       res = 0;
1706
 
-                                               } else {
1707
 
-                                                       strncpy(line, line1, 100);
1708
 
-                                                       memcpy(line + strlen(line1), line2, n);
1709
 
+                                               strncpy(line, line1, 100);
1710
 
+                                               memcpy(line + strlen(line1), line2, n);
1711
 
 if (db) fprintf(stderr, "line1: '%s'\n", line1);
1712
 
-                                                       n += strlen(line1);
1713
 
-                                                       created_disp = 1;
1714
 
-                                                       res = 1;
1715
 
-                                               }
1716
 
+                                               n += strlen(line1);
1717
 
+                                               created_disp = 1;
1718
 
+                                               res = 1;
1719
 
                                        }
1720
 
                                }
1721
 
-                               if (res && saw_xdmcp) {
1722
 
-                                       xdmcp_insert = strdup(keep_unixpw_user);
1723
 
-                               }
1724
 
                        }
1725
 
-
1726
 
-                       if (tmp_fd >= 0) {
1727
 
-                               unlink(tmp);
1728
 
+                       if (res && saw_xdmcp) {
1729
 
+                               xdmcp_insert = strdup(keep_unixpw_user);
1730
 
                        }
1731
 
+               }
1732
 
 
1733
 
-                       if (! res) {
1734
 
-                               rfbLog("wait_for_client: cmd failed: %s\n", cmd);
1735
 
-                               unixpw_msg("No DISPLAY found.", 3);
1736
 
-                               clean_up_exit(1);
1737
 
-                       }
1738
 
+               if (tmp_fd >= 0) {
1739
 
+                       unlink(tmp);
1740
 
+               }
1741
 
 
1742
 
-                       /*
1743
 
-                        * we need to hunt for DISPLAY= since there may be
1744
 
-                        * a login banner or something at the beginning.
1745
 
-                        */
1746
 
-                       q = strstr(line, "DISPLAY=");
1747
 
-                       if (! q) {
1748
 
-                               q = line;
1749
 
-                       }
1750
 
-                       n -= (q - line);
1751
 
+               if (! res) {
1752
 
+                       rfbLog("wait_for_client: cmd failed: %s\n", cmd);
1753
 
+                       unixpw_msg("No DISPLAY found.", 3);
1754
 
+                       clean_up_exit(1);
1755
 
+               }
1756
 
 
1757
 
-                       for (k = 0; k < 1024; k++) {
1758
 
-                               line1[k] = q[k];
1759
 
-                               if (q[k] == '\n') {
1760
 
-                                       k++;
1761
 
-                                       break;
1762
 
-                               }
1763
 
+               /*
1764
 
+                * we need to hunt for DISPLAY= since there may be
1765
 
+                * a login banner or something at the beginning.
1766
 
+                */
1767
 
+               q = strstr(line, "DISPLAY=");
1768
 
+               if (! q) {
1769
 
+                       q = line;
1770
 
+               }
1771
 
+               n -= (q - line);
1772
 
+
1773
 
+               for (k = 0; k < 1024; k++) {
1774
 
+                       line1[k] = q[k];
1775
 
+                       if (q[k] == '\n') {
1776
 
+                               k++;
1777
 
+                               break;
1778
 
                        }
1779
 
-                       n -= k;
1780
 
-                       i = 0;
1781
 
-                       for (j = 0; j < 16384; j++) {
1782
 
-                               if (j < 16384 - 1) {
1783
 
-                                       /* xauth data, assume pty added CR */
1784
 
-                                       if (q[k+j] == '\r' && q[k+j+1] == '\n') {
1785
 
-                                               continue;
1786
 
-                                       }
1787
 
+               }
1788
 
+               n -= k;
1789
 
+               i = 0;
1790
 
+               for (j = 0; j < 16384; j++) {
1791
 
+                       if (j < 16384 - 1) {
1792
 
+                               /* xauth data, assume pty added CR */
1793
 
+                               if (q[k+j] == '\r' && q[k+j+1] == '\n') {
1794
 
+                                       continue;
1795
 
                                }
1796
 
-                               
1797
 
-                               line2[i] = q[k+j];
1798
 
-                               i++;
1799
 
                        }
1800
 
+                       
1801
 
+                       line2[i] = q[k+j];
1802
 
+                       i++;
1803
 
+               }
1804
 
 if (db) write(2, line, 100);
1805
 
 if (db) fprintf(stderr, "\n");
1806
 
+       } else {
1807
 
+               FILE *p;
1808
 
+               int rc;
1809
 
+               close_exec_fds();
1810
 
+
1811
 
+               if (usslpeer) {
1812
 
+                       char *c;
1813
 
+                       if (getuid() == 0) {
1814
 
+                               c = (char *) malloc(strlen("su - '' -c \"")
1815
 
+                                   + strlen(usslpeer) + strlen(cmd) + 1 + 1);
1816
 
+                               sprintf(c, "su - '%s' -c \"%s\"", usslpeer, cmd);
1817
 
+                       } else {
1818
 
+                               c = strdup(cmd);
1819
 
+                       }
1820
 
+                       p = popen(c, "r");
1821
 
+                       free(c);
1822
 
+                       
1823
 
                } else {
1824
 
-                       FILE *p;
1825
 
-                       int rc;
1826
 
-                       close_exec_fds();
1827
 
+                       p = popen(cmd, "r");
1828
 
+               }
1829
 
+               if (! p) {
1830
 
+                       rfbLog("wait_for_client: cmd failed: %s\n", cmd);
1831
 
+                       rfbLogPerror("popen");
1832
 
+                       if (tmp_fd >= 0) {
1833
 
+                               unlink(tmp);
1834
 
+                       }
1835
 
+                       clean_up_exit(1);
1836
 
+               }
1837
 
+               if (fgets(line1, 1024, p) == NULL) {
1838
 
+                       rfbLog("wait_for_client: read failed: %s\n", cmd);
1839
 
+                       rfbLogPerror("fgets");
1840
 
+                       if (tmp_fd >= 0) {
1841
 
+                               unlink(tmp);
1842
 
+                       }
1843
 
+                       clean_up_exit(1);
1844
 
+               }
1845
 
+               n = fread(line2, 1, 16384, p);
1846
 
+               rc = pclose(p);
1847
 
 
1848
 
-                       if (usslpeer) {
1849
 
-                               char *c;
1850
 
-                               if (getuid() == 0) {
1851
 
-                                       c = (char *) malloc(strlen("su - '' -c \"")
1852
 
-                                           + strlen(usslpeer) + strlen(cmd) + 1 + 1);
1853
 
-                                       sprintf(c, "su - '%s' -c \"%s\"", usslpeer, cmd);
1854
 
-                               } else {
1855
 
-                                       c = strdup(cmd);
1856
 
+               if (rc != 0) {
1857
 
+                       rfbLog("wait_for_client: find display cmd failed\n");
1858
 
+               }
1859
 
+
1860
 
+               if (create_cmd && rc != 0) {
1861
 
+                       FILE *mt = fopen(tmp, "w");
1862
 
+                       if (! mt) {
1863
 
+                               rfbLog("wait_for_client: open failed: %s\n", tmp);
1864
 
+                               rfbLogPerror("fopen");
1865
 
+                               if (tmp_fd >= 0) {
1866
 
+                                       unlink(tmp);
1867
 
                                }
1868
 
-                               p = popen(c, "r");
1869
 
-                               free(c);
1870
 
-                               
1871
 
-                       } else {
1872
 
-                               p = popen(cmd, "r");
1873
 
+                               clean_up_exit(1);
1874
 
                        }
1875
 
+                       fprintf(mt, "%s", create_display);
1876
 
+                       fclose(mt);
1877
 
+
1878
 
+                       findcreatedisplay = 1;
1879
 
+
1880
 
+                       rfbLog("wait_for_client: FINDCREATEDISPLAY cmd: %s\n", create_cmd);
1881
 
+
1882
 
+                       p = popen(create_cmd, "r");
1883
 
                        if (! p) {
1884
 
-                               rfbLog("wait_for_client: cmd failed: %s\n", cmd);
1885
 
+                               rfbLog("wait_for_client: cmd failed: %s\n", create_cmd);
1886
 
                                rfbLogPerror("popen");
1887
 
                                if (tmp_fd >= 0) {
1888
 
                                        unlink(tmp);
1889
 
@@ -2314,7 +2369,7 @@
1890
 
                                clean_up_exit(1);
1891
 
                        }
1892
 
                        if (fgets(line1, 1024, p) == NULL) {
1893
 
-                               rfbLog("wait_for_client: read failed: %s\n", cmd);
1894
 
+                               rfbLog("wait_for_client: read failed: %s\n", create_cmd);
1895
 
                                rfbLogPerror("fgets");
1896
 
                                if (tmp_fd >= 0) {
1897
 
                                        unlink(tmp);
1898
 
@@ -2322,199 +2377,318 @@
1899
 
                                clean_up_exit(1);
1900
 
                        }
1901
 
                        n = fread(line2, 1, 16384, p);
1902
 
-                       rc = pclose(p);
1903
 
-
1904
 
-                       if (rc != 0) {
1905
 
-                               rfbLog("wait_for_client: find display cmd failed\n");
1906
 
-                       }
1907
 
-
1908
 
-                       if (create_cmd && rc != 0) {
1909
 
-                               FILE *mt = fopen(tmp, "w");
1910
 
-                               if (! mt) {
1911
 
-                                       rfbLog("wait_for_client: open failed: %s\n", tmp);
1912
 
-                                       rfbLogPerror("fopen");
1913
 
-                                       if (tmp_fd >= 0) {
1914
 
-                                               unlink(tmp);
1915
 
-                                       }
1916
 
-                                       clean_up_exit(1);
1917
 
-                               }
1918
 
-                               fprintf(mt, "%s", create_display);
1919
 
-                               fclose(mt);
1920
 
-
1921
 
-                               findcreatedisplay = 1;
1922
 
-
1923
 
-                               rfbLog("wait_for_client: FINDCREATEDISPLAY cmd: %s\n", create_cmd);
1924
 
-
1925
 
-                               p = popen(create_cmd, "r");
1926
 
-                               if (! p) {
1927
 
-                                       rfbLog("wait_for_client: cmd failed: %s\n", create_cmd);
1928
 
-                                       rfbLogPerror("popen");
1929
 
-                                       if (tmp_fd >= 0) {
1930
 
-                                               unlink(tmp);
1931
 
-                                       }
1932
 
-                                       clean_up_exit(1);
1933
 
-                               }
1934
 
-                               if (fgets(line1, 1024, p) == NULL) {
1935
 
-                                       rfbLog("wait_for_client: read failed: %s\n", create_cmd);
1936
 
-                                       rfbLogPerror("fgets");
1937
 
-                                       if (tmp_fd >= 0) {
1938
 
-                                               unlink(tmp);
1939
 
-                                       }
1940
 
-                                       clean_up_exit(1);
1941
 
-                               }
1942
 
-                               n = fread(line2, 1, 16384, p);
1943
 
-                       }
1944
 
-                       if (tmp_fd >= 0) {
1945
 
-                               unlink(tmp);
1946
 
-                       }
1947
 
                }
1948
 
+               if (tmp_fd >= 0) {
1949
 
+                       unlink(tmp);
1950
 
+               }
1951
 
+       }
1952
 
 
1953
 
 if (db) fprintf(stderr, "line1=%s\n", line1);
1954
 
 
1955
 
-               if (strstr(line1, "DISPLAY=") != line1) {
1956
 
-                       rfbLog("wait_for_client: bad reply '%s'\n", line1);
1957
 
-                       if (unixpw) {
1958
 
-                               unixpw_msg("No DISPLAY found.", 3);
1959
 
-                       }
1960
 
-                       clean_up_exit(1);
1961
 
+       if (strstr(line1, "DISPLAY=") != line1) {
1962
 
+               rfbLog("wait_for_client: bad reply '%s'\n", line1);
1963
 
+               if (unixpw) {
1964
 
+                       unixpw_msg("No DISPLAY found.", 3);
1965
 
                }
1966
 
+               clean_up_exit(1);
1967
 
+       }
1968
 
 
1969
 
 
1970
 
-               if (strstr(line1, ",VT=")) {
1971
 
-                       int vt;
1972
 
-                       char *t = strstr(line1, ",VT=");
1973
 
-                       vt = atoi(t + strlen(",VT="));
1974
 
-                       *t = '\0';
1975
 
-                       if (7 <= vt && vt <= 15) {
1976
 
-                               char chvt[100];
1977
 
-                               sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
1978
 
-                               rfbLog("running: %s\n", chvt);
1979
 
-                               system(chvt);
1980
 
-                               sleep(2);
1981
 
-                       }
1982
 
-               } else if (strstr(line1, ",XPID=")) {
1983
 
-                       int i, pvt, vt = -1;
1984
 
-                       char *t = strstr(line1, ",XPID=");
1985
 
-                       pvt = atoi(t + strlen(",XPID="));
1986
 
-                       *t = '\0';
1987
 
-                       if (pvt > 0) {
1988
 
-                               for (i=3; i <= 10; i++) {
1989
 
-                                       int k;
1990
 
-                                       char proc[100];
1991
 
-                                       char buf[100];
1992
 
-                                       sprintf(proc, "/proc/%d/fd/%d", pvt, i);
1993
 
+       if (strstr(line1, ",VT=")) {
1994
 
+               int vt;
1995
 
+               char *t = strstr(line1, ",VT=");
1996
 
+               vt = atoi(t + strlen(",VT="));
1997
 
+               *t = '\0';
1998
 
+               if (7 <= vt && vt <= 15) {
1999
 
+                       do_chvt(vt);
2000
 
+               }
2001
 
+       } else if (strstr(line1, ",XPID=")) {
2002
 
+               int i, pvt, vt = -1;
2003
 
+               char *t = strstr(line1, ",XPID=");
2004
 
+               pvt = atoi(t + strlen(",XPID="));
2005
 
+               *t = '\0';
2006
 
+               if (pvt > 0) {
2007
 
+                       for (i=3; i <= 10; i++) {
2008
 
+                               int k;
2009
 
+                               char proc[100];
2010
 
+                               char buf[100];
2011
 
+                               sprintf(proc, "/proc/%d/fd/%d", pvt, i);
2012
 
 if (db) fprintf(stderr, "%d -- %s\n", i, proc);
2013
 
-                                       for (k=0; k < 100; k++) {
2014
 
-                                               buf[k] = '\0';
2015
 
-                                       }
2016
 
-               
2017
 
-                                       if (readlink(proc, buf, 100) != -1) {
2018
 
-                                               buf[100-1] = '\0';
2019
 
+                               for (k=0; k < 100; k++) {
2020
 
+                                       buf[k] = '\0';
2021
 
+                               }
2022
 
+       
2023
 
+                               if (readlink(proc, buf, 100) != -1) {
2024
 
+                                       buf[100-1] = '\0';
2025
 
 if (db) fprintf(stderr, "%d -- %s -- %s\n", i, proc, buf);
2026
 
-                                               if (strstr(buf, "/dev/tty") == buf) {
2027
 
-                                                       vt = atoi(buf + strlen("/dev/tty"));
2028
 
-                                                       if (vt > 0) {
2029
 
-                                                               break;
2030
 
-                                                       }
2031
 
+                                       if (strstr(buf, "/dev/tty") == buf) {
2032
 
+                                               vt = atoi(buf + strlen("/dev/tty"));
2033
 
+                                               if (vt > 0) {
2034
 
+                                                       break;
2035
 
                                                }
2036
 
                                        }
2037
 
                                }
2038
 
                        }
2039
 
-                       if (7 <= vt && vt <= 12) {
2040
 
-                               char chvt[100];
2041
 
-                               sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
2042
 
-                               rfbLog("running: %s\n", chvt);
2043
 
-                               system(chvt);
2044
 
-                               sleep(2);
2045
 
-                       }
2046
 
                }
2047
 
-
2048
 
-               use_dpy = strdup(line1 + strlen("DISPLAY="));
2049
 
-               q = use_dpy;
2050
 
-               while (*q != '\0') {
2051
 
-                       if (*q == '\n' || *q == '\r') *q = '\0';
2052
 
-                       q++;
2053
 
+               if (7 <= vt && vt <= 12) {
2054
 
+                       do_chvt(vt);
2055
 
                }
2056
 
-               if (line2[0] != '\0') {
2057
 
-                       if (strstr(line2, "XAUTHORITY=") == line2) {
2058
 
-                               q = line2;
2059
 
-                               while (*q != '\0') {
2060
 
-                                       if (*q == '\n' || *q == '\r') *q = '\0';
2061
 
-                                       q++;
2062
 
-                               }
2063
 
-                               if (auth_file) {
2064
 
-                                       free(auth_file);
2065
 
-                               }
2066
 
-                               auth_file = strdup(line2 + strlen("XAUTHORITY="));
2067
 
+       }
2068
 
 
2069
 
-                       } else {
2070
 
-                               xauth_raw_data = (char *)malloc(n);
2071
 
-                               xauth_raw_len = n;
2072
 
-                               memcpy(xauth_raw_data, line2, n);
2073
 
+       use_dpy = strdup(line1 + strlen("DISPLAY="));
2074
 
+       q = use_dpy;
2075
 
+       while (*q != '\0') {
2076
 
+               if (*q == '\n' || *q == '\r') *q = '\0';
2077
 
+               q++;
2078
 
+       }
2079
 
+       if (line2[0] != '\0') {
2080
 
+               if (strstr(line2, "XAUTHORITY=") == line2) {
2081
 
+                       q = line2;
2082
 
+                       while (*q != '\0') {
2083
 
+                               if (*q == '\n' || *q == '\r') *q = '\0';
2084
 
+                               q++;
2085
 
+                       }
2086
 
+                       if (auth_file) {
2087
 
+                               free(auth_file);
2088
 
+                       }
2089
 
+                       auth_file = strdup(line2 + strlen("XAUTHORITY="));
2090
 
+
2091
 
+               } else {
2092
 
+                       xauth_raw_data = (char *)malloc(n);
2093
 
+                       xauth_raw_len = n;
2094
 
+                       memcpy(xauth_raw_data, line2, n);
2095
 
 if (db) {fprintf(stderr, "xauth_raw_len: %d\n", n);
2096
 
 write(2, xauth_raw_data, n);
2097
 
 fprintf(stderr, "\n");}
2098
 
-                       }
2099
 
                }
2100
 
+       }
2101
 
 
2102
 
-               if (usslpeer) {
2103
 
-                       char *u = (char *) malloc(strlen(usslpeer+2));
2104
 
-                       sprintf(u, "+%s", usslpeer);
2105
 
-                       if (switch_user(u, 0)) {
2106
 
-                               rfbLog("sslpeer switched to user: %s\n", usslpeer);
2107
 
-                       } else {
2108
 
-                               rfbLog("sslpeer failed to switch to user: %s\n", usslpeer);
2109
 
-                       }
2110
 
-                       free(u);
2111
 
-                       
2112
 
-               } else if (users_list_save && keep_unixpw_user) {
2113
 
-                       char *user = keep_unixpw_user;
2114
 
-                       char *u = (char *)malloc(strlen(user)+1); 
2115
 
+       if (usslpeer) {
2116
 
+               char *u = (char *) malloc(strlen(usslpeer+2));
2117
 
+               sprintf(u, "+%s", usslpeer);
2118
 
+               if (switch_user(u, 0)) {
2119
 
+                       rfbLog("sslpeer switched to user: %s\n", usslpeer);
2120
 
+               } else {
2121
 
+                       rfbLog("sslpeer failed to switch to user: %s\n", usslpeer);
2122
 
+               }
2123
 
+               free(u);
2124
 
+               
2125
 
+       } else if (users_list_save && keep_unixpw_user) {
2126
 
+               char *user = keep_unixpw_user;
2127
 
+               char *u = (char *)malloc(strlen(user)+1); 
2128
 
 
2129
 
-                       users_list = users_list_save;
2130
 
+               users_list = users_list_save;
2131
 
 
2132
 
-                       u[0] = '\0';
2133
 
-                       if (!strcmp(users_list, "unixpw=")) {
2134
 
-                               sprintf(u, "+%s", user);
2135
 
-                       } else {
2136
 
-                               char *p, *str = strdup(users_list);
2137
 
-                               p = strtok(str + strlen("unixpw="), ",");
2138
 
-                               while (p) {
2139
 
-                                       if (!strcmp(p, user)) {
2140
 
-                                               sprintf(u, "+%s", user);
2141
 
-                                               break;
2142
 
-                                       }
2143
 
-                                       p = strtok(NULL, ",");
2144
 
+               u[0] = '\0';
2145
 
+               if (!strcmp(users_list, "unixpw=")) {
2146
 
+                       sprintf(u, "+%s", user);
2147
 
+               } else {
2148
 
+                       char *p, *str = strdup(users_list);
2149
 
+                       p = strtok(str + strlen("unixpw="), ",");
2150
 
+                       while (p) {
2151
 
+                               if (!strcmp(p, user)) {
2152
 
+                                       sprintf(u, "+%s", user);
2153
 
+                                       break;
2154
 
                                }
2155
 
-                               free(str);
2156
 
+                               p = strtok(NULL, ",");
2157
 
                        }
2158
 
-                       
2159
 
-                       if (u[0] == '\0') {
2160
 
-                               rfbLog("unixpw_accept skipping switch to user: %s\n", user);
2161
 
-                       } else if (switch_user(u, 0)) {
2162
 
-                               rfbLog("unixpw_accept switched to user: %s\n", user);
2163
 
-                       } else {
2164
 
-                               rfbLog("unixpw_accept failed to switch to user: %s\n", user);
2165
 
-                       }
2166
 
-                       free(u);
2167
 
+                       free(str);
2168
 
                }
2169
 
+               
2170
 
+               if (u[0] == '\0') {
2171
 
+                       rfbLog("unixpw_accept skipping switch to user: %s\n", user);
2172
 
+               } else if (switch_user(u, 0)) {
2173
 
+                       rfbLog("unixpw_accept switched to user: %s\n", user);
2174
 
+               } else {
2175
 
+                       rfbLog("unixpw_accept failed to switch to user: %s\n", user);
2176
 
+               }
2177
 
+               free(u);
2178
 
+       }
2179
 
 
2180
 
-               if (unixpw) {
2181
 
-                       char str[32];
2182
 
+       if (unixpw) {
2183
 
+               char str[32];
2184
 
 
2185
 
-                       if (keep_unixpw_user && keep_unixpw_pass) {
2186
 
-                               strzero(keep_unixpw_user);
2187
 
-                               strzero(keep_unixpw_pass);
2188
 
-                               keep_unixpw = 0;
2189
 
+               if (keep_unixpw_user && keep_unixpw_pass) {
2190
 
+                       strzero(keep_unixpw_user);
2191
 
+                       strzero(keep_unixpw_pass);
2192
 
+                       keep_unixpw = 0;
2193
 
+               }
2194
 
+
2195
 
+               if (created_disp) {
2196
 
+                       snprintf(str, 30, "Created DISPLAY %s", use_dpy);
2197
 
+               } else {
2198
 
+                       snprintf(str, 30, "Using DISPLAY %s", use_dpy);
2199
 
+               }
2200
 
+               unixpw_msg(str, 2);
2201
 
+       }
2202
 
+       return 1;
2203
 
+}
2204
 
+
2205
 
+static XImage ximage_struct;
2206
 
+
2207
 
+int wait_for_client(int *argc, char** argv, int http) {
2208
 
+       /* ugh, here we go... */
2209
 
+       XImage* fb_image;
2210
 
+       int w = 640, h = 480, b = 32;
2211
 
+       int w0, h0, i, chg_raw_fb = 0;
2212
 
+       char *str, *q, *cmd = NULL;
2213
 
+       int db = 0, dt = 0;
2214
 
+       char *create_cmd = NULL;
2215
 
+       char *users_list_save = NULL;
2216
 
+       int created_disp = 0, ncache_save;
2217
 
+       int did_client_connect = 0;
2218
 
+       char *vnc_redirect_host = "localhost";
2219
 
+       int vnc_redirect_port = -1, vnc_redirect_cnt = 0;
2220
 
+       char vnc_redirect_test[10];
2221
 
+
2222
 
+       if (getenv("WAIT_FOR_CLIENT_DB")) {
2223
 
+               db = 1;
2224
 
+       }
2225
 
+
2226
 
+       vnc_redirect = 0;
2227
 
+
2228
 
+       if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
2229
 
+               return 0;
2230
 
+       }
2231
 
+
2232
 
+       for (i=0; i < *argc; i++) {
2233
 
+               if (!strcmp(argv[i], "-desktop")) {
2234
 
+                       dt = 1;
2235
 
+               }
2236
 
+               if (db) fprintf(stderr, "args %d %s\n", i, argv[i]);
2237
 
+       }
2238
 
+       if (!quiet && !strstr(use_dpy, "FINDDISPLAY-run")) {
2239
 
+               rfbLog("wait_for_client: %s\n", use_dpy);
2240
 
+       }
2241
 
+
2242
 
+       str = strdup(use_dpy);
2243
 
+       str += strlen("WAIT");
2244
 
+
2245
 
+       xdmcp_insert = NULL;
2246
 
+
2247
 
+       /* get any leading geometry: */
2248
 
+       q = strchr(str+1, ':');
2249
 
+       if (q) {
2250
 
+               *q = '\0';
2251
 
+               if (sscanf(str+1, "%dx%d", &w0, &h0) == 2)  {
2252
 
+                       w = w0;
2253
 
+                       h = h0;
2254
 
+                       rfbLog("wait_for_client set: w=%d h=%d\n", w, h);
2255
 
+               }
2256
 
+               *q = ':';
2257
 
+               str = q;
2258
 
+       }
2259
 
+
2260
 
+       /* str currently begins with a ':' */
2261
 
+       if (strstr(str, ":cmd=") == str) {
2262
 
+               /* cmd=/path/to/mycommand */
2263
 
+               str++;
2264
 
+       } else if (strpbrk(str, "0123456789") == str+1) {
2265
 
+               /* :0.0 */
2266
 
+               ;
2267
 
+       } else {
2268
 
+               /* hostname:0.0 */
2269
 
+               str++;
2270
 
+       }
2271
 
+
2272
 
+       if (db) fprintf(stderr, "str: %s\n", str);
2273
 
+
2274
 
+       if (strstr(str, "cmd=") == str) {
2275
 
+               cmd = setup_cmd(str, &vnc_redirect, &vnc_redirect_host, &vnc_redirect_port, db);
2276
 
+       }
2277
 
+       
2278
 
+       fb_image = &ximage_struct;
2279
 
+       setup_fake_fb(fb_image, w, h, b);
2280
 
+
2281
 
+       if (! dt) {
2282
 
+               char *s;
2283
 
+               argv[*argc] = strdup("-desktop");
2284
 
+               *argc = (*argc) + 1;
2285
 
+
2286
 
+               if (cmd) {
2287
 
+                       char *q;
2288
 
+                       s = choose_title(":0");
2289
 
+                       q = strstr(s, ":0");
2290
 
+                       if (q) {
2291
 
+                               *q = '\0';
2292
 
                        }
2293
 
+               } else {
2294
 
+                       s = choose_title(str);
2295
 
+               }
2296
 
+               rfb_desktop_name = strdup(s);
2297
 
+               argv[*argc] = s;
2298
 
+               *argc = (*argc) + 1;
2299
 
+       }
2300
 
 
2301
 
-                       if (created_disp) {
2302
 
-                               snprintf(str, 30, "Created DISPLAY %s", use_dpy);
2303
 
-                       } else {
2304
 
-                               snprintf(str, 30, "Using DISPLAY %s", use_dpy);
2305
 
+       ncache_save = ncache;
2306
 
+       ncache = 0;
2307
 
+
2308
 
+       initialize_allowed_input();
2309
 
+
2310
 
+       if (! multiple_cursors_mode) {
2311
 
+               multiple_cursors_mode = strdup("default");
2312
 
+       }
2313
 
+       initialize_cursors_mode();
2314
 
+       
2315
 
+       initialize_screen(argc, argv, fb_image);
2316
 
+
2317
 
+       initialize_signals();
2318
 
+
2319
 
+       if (ssh_str != NULL) {
2320
 
+               ssh_remote_tunnel(ssh_str, screen->port);
2321
 
+       }
2322
 
+
2323
 
+       if (! raw_fb) {
2324
 
+               chg_raw_fb = 1;
2325
 
+               /* kludge to get RAWFB_RET with dpy == NULL guards */
2326
 
+               raw_fb = (char *) 0x1;
2327
 
+       }
2328
 
+
2329
 
+       if (cmd && !strcmp(cmd, "HTTPONCE")) {
2330
 
+               handle_one_http_request();      
2331
 
+               clean_up_exit(0);
2332
 
+       }
2333
 
+
2334
 
+       if (http && check_httpdir()) {
2335
 
+               http_connections(1);
2336
 
+       }
2337
 
+
2338
 
+       if (cmd && unixpw) {
2339
 
+               keep_unixpw = 1;
2340
 
+       }
2341
 
+
2342
 
+       setup_service();
2343
 
+
2344
 
+       check_waitbg();
2345
 
+
2346
 
+       if (vnc_redirect) {
2347
 
+               vnc_redirect_loop(vnc_redirect_test, &vnc_redirect_cnt);
2348
 
+       } else {
2349
 
+               if (inetd && use_openssl) {
2350
 
+                       accept_openssl(OPENSSL_INETD, -1);
2351
 
+               }
2352
 
+
2353
 
+               setup_client_connect(&did_client_connect);
2354
 
+
2355
 
+               loop_for_connect(did_client_connect);
2356
 
+
2357
 
+               if (unixpw) {
2358
 
+                       if (cmd && strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
2359
 
+                               if (users_list && strstr(users_list, "unixpw=") == users_list) {
2360
 
+                                       users_list_save = users_list;
2361
 
+                                       users_list = NULL;
2362
 
+                               }
2363
 
                        }
2364
 
-                       unixpw_msg(str, 2);
2365
 
+                       do_unixpw_loop();
2366
 
                }
2367
 
+       }
2368
 
+
2369
 
+       if (vnc_redirect == 2) {
2370
 
+               ;
2371
 
+       } else if (cmd) {
2372
 
+               if (!do_run_cmd(cmd, create_cmd, users_list_save, created_disp, db)) {
2373
 
+                       return 0;
2374
 
+               }
2375
 
        } else {
2376
 
                use_dpy = strdup(str);
2377
 
        }
2378
 
@@ -2532,61 +2706,8 @@
2379
 
        }
2380
 
 
2381
 
        if (vnc_redirect) {
2382
 
-               char *q = strchr(use_dpy, ':');
2383
 
-               int vdpy = -1, sock = -1;
2384
 
-               int s_in, s_out, i;
2385
 
-               if (vnc_redirect == 2) {
2386
 
-                       char num[32];   
2387
 
-                       sprintf(num, ":%d", vnc_redirect_port);
2388
 
-                       q = num;
2389
 
-               }
2390
 
-               if (!q) {
2391
 
-                       rfbLog("wait_for_client: can't find number in X display: %s\n", use_dpy);
2392
 
-                       clean_up_exit(1);
2393
 
-               }
2394
 
-               if (sscanf(q+1, "%d", &vdpy) != 1) {
2395
 
-                       rfbLog("wait_for_client: can't find number in X display: %s\n", q);
2396
 
-                       clean_up_exit(1);
2397
 
-               }
2398
 
-               if (vdpy == -1 && vnc_redirect != 2) {
2399
 
-                       rfbLog("wait_for_client: can't find number in X display: %s\n", q);
2400
 
-                       clean_up_exit(1);
2401
 
-               }
2402
 
-               if (vnc_redirect == 2) {
2403
 
-                       if (vdpy < 0) {
2404
 
-                               vdpy = -vdpy;
2405
 
-                       } else if (vdpy < 200) {
2406
 
-                               vdpy += 5900;
2407
 
-                       }
2408
 
-               } else {
2409
 
-                       vdpy += 5900;
2410
 
-               }
2411
 
-               if (created_disp) {
2412
 
-                       usleep(1000*1000);
2413
 
-               }
2414
 
-               for (i=0; i < 20; i++) {
2415
 
-                       sock = rfbConnectToTcpAddr(vnc_redirect_host, vdpy);
2416
 
-                       if (sock >= 0) {
2417
 
-                               break;
2418
 
-                       }
2419
 
-                       rfbLog("wait_for_client: ...\n");
2420
 
-                       usleep(500*1000);
2421
 
-               }
2422
 
-               if (sock < 0) {
2423
 
-                       rfbLog("wait_for_client: could not connect to a VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
2424
 
-                       clean_up_exit(1);
2425
 
-               }
2426
 
-               if (inetd) {
2427
 
-                       s_in  = fileno(stdin);
2428
 
-                       s_out = fileno(stdout);
2429
 
-               } else {
2430
 
-                       s_in = s_out = vnc_redirect_sock;
2431
 
-               }
2432
 
-               if (vnc_redirect_cnt > 0) {
2433
 
-                       write(vnc_redirect_sock, vnc_redirect_test, vnc_redirect_cnt);
2434
 
-               }
2435
 
-               rfbLog("wait_for_client: switching control to VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
2436
 
-               raw_xfer(sock, s_in, s_out);
2437
 
+               do_vnc_redirect(created_disp, vnc_redirect_host, vnc_redirect_port,
2438
 
+                   vnc_redirect_cnt, vnc_redirect_test);
2439
 
                clean_up_exit(0);
2440
 
        }
2441
 
 
2442
 
Index: ../ica/x11/x11vnc/8to24.c
2443
 
===================================================================
2444
 
--- ../ica/x11/x11vnc/8to24.c   (Revision 401)
2445
 
+++ ../ica/x11/x11vnc/8to24.c   (Arbeitskopie)
2446
 
@@ -59,10 +59,11 @@
2447
 
        MARK_8BPP_TOP
2448
 
 };
2449
 
 
2450
 
+
2451
 
 #define NCOLOR 256
2452
 
 
2453
 
 static Colormap root_cmap = 0;
2454
 
-static unsigned int root_rgb[NCOLOR];
2455
 
+static unsigned int *root_rgb = NULL;
2456
 
 
2457
 
 static void set_root_cmap(void) {
2458
 
 #if NO_X11
2459
 
@@ -72,11 +73,25 @@
2460
 
        static time_t last_set = 0;
2461
 
        time_t now = time(NULL);
2462
 
        XWindowAttributes attr;
2463
 
-       static XColor color[NCOLOR];
2464
 
+       static XColor *color = NULL;
2465
 
        int redo = 0;
2466
 
+       int ncolor = 0;
2467
 
 
2468
 
        RAWFB_RET_VOID
2469
 
 
2470
 
+       if (depth > 8) {
2471
 
+               ncolor = 1 << depth;
2472
 
+       } else {
2473
 
+               ncolor = NCOLOR;
2474
 
+       }
2475
 
+
2476
 
+       if (!root_rgb) {
2477
 
+               root_rgb = (unsigned int *) malloc(ncolor * sizeof(unsigned int));
2478
 
+       }
2479
 
+       if (!color) {
2480
 
+               color = (XColor *) malloc(ncolor * sizeof(XColor));
2481
 
+       }
2482
 
+
2483
 
        if (now > last_set + 10) {
2484
 
                redo = 1;
2485
 
        }
2486
 
@@ -87,7 +102,11 @@
2487
 
                        return;
2488
 
                }
2489
 
                if (attr.colormap) {
2490
 
-                       int i, ncells = NCOLOR;
2491
 
+                       int i, ncells = ncolor;
2492
 
+
2493
 
+                       if (depth < 8) {
2494
 
+                               ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
2495
 
+                       }
2496
 
                        for (i=0; i < ncells; i++) {
2497
 
                                color[i].pixel = i;
2498
 
                                color[i].pad = 0;
2499
 
@@ -236,7 +255,11 @@
2500
 
                return;         /* this saves a bit of RAM */
2501
 
        }
2502
 
        pfb(4, &poll24_fb, &poll24_fb_w, &poll24_fb_h);
2503
 
-       pfb(1, &poll8_fb,  &poll8_fb_w,  &poll8_fb_h);
2504
 
+       if (depth > 8) {
2505
 
+               pfb(2, &poll8_fb,  &poll8_fb_w,  &poll8_fb_h);  /* 2X for rare 16bpp colormap case */
2506
 
+       } else {
2507
 
+               pfb(1, &poll8_fb,  &poll8_fb_w,  &poll8_fb_h);
2508
 
+       }
2509
 
 }
2510
 
 
2511
 
 int MV_glob = 0;
2512
 
@@ -428,7 +451,7 @@
2513
 
                if (check_depth(win, win, doall)) {
2514
 
                        /*
2515
 
                         * returns 1 if no need to recurse down e.g. It
2516
 
-                        * is 8bpp and we assume all lower one are too.
2517
 
+                        * is 8bpp and we assume all lower ones are too.
2518
 
                         */
2519
 
                        continue;
2520
 
                }
2521
 
@@ -529,7 +552,7 @@
2522
 
                mark_8bpp(MARK_8BPP_ALL);
2523
 
                last_poll = now;
2524
 
 
2525
 
-       } else if (depth == 8 && multivis_24count) {
2526
 
+       } else if (depth <= 16 && multivis_24count) {
2527
 
                static double last_check = 0.0;
2528
 
                if (now > last_check + 0.4) {
2529
 
                        last_check = now;
2530
 
@@ -656,8 +679,7 @@
2531
 
        if (attr->depth > 0) {
2532
 
                if (depth == 24 && attr->depth != 24) {
2533
 
                        store_it = 1;
2534
 
-               } else if (depth == 8 && root_cmap && attr->colormap !=
2535
 
-                   root_cmap) {
2536
 
+               } else if (depth <= 16 && root_cmap && attr->colormap != root_cmap) {
2537
 
                        store_it = 1;
2538
 
                }
2539
 
        }
2540
 
@@ -759,6 +781,7 @@
2541
 
        return 0;
2542
 
 }
2543
 
 
2544
 
+/* polling line XImage */
2545
 
 static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w) {
2546
 
        RAWFB_RET(NULL)
2547
 
 
2548
 
@@ -771,8 +794,12 @@
2549
 
                if (xi) {
2550
 
                        XDestroyImage(xi);
2551
 
                }
2552
 
-               if (win_depth == 8) {
2553
 
-                       d = (char *) malloc(dpy_x * 1);
2554
 
+               if (win_depth != 24) {
2555
 
+                       if (win_depth > 8) {
2556
 
+                               d = (char *) malloc(dpy_x * 2);
2557
 
+                       } else {
2558
 
+                               d = (char *) malloc(dpy_x * 1);
2559
 
+                       }
2560
 
                } else {
2561
 
                        d = (char *) malloc(dpy_x * 4);
2562
 
                }
2563
 
@@ -837,14 +864,18 @@
2564
 
                last_win = win;
2565
 
        }
2566
 
 
2567
 
-       if (attr.depth != 8 && attr.depth != 24) {
2568
 
+       if (attr.depth > 16 && attr.depth != 24) {
2569
 
                X_UNLOCK;
2570
 
                return 1;
2571
 
-       } else if (attr.depth == 8) {
2572
 
-               xi = xi8 = p_xi(xi8, attr.visual, 8, &xi8_w);
2573
 
+       } else if (attr.depth <= 16) {
2574
 
+               xi = xi8 = p_xi(xi8, attr.visual, attr.depth, &xi8_w);
2575
 
 
2576
 
                poll_fb = poll8_fb;
2577
 
-               fac = 1;
2578
 
+               if (attr.depth > 8) {
2579
 
+                       fac = 2;
2580
 
+               } else {
2581
 
+                       fac = 1;
2582
 
+               }
2583
 
                n_off = poll8_fb_w * y1 + x1;
2584
 
        } else {
2585
 
                xi = xi24 = p_xi(xi24, attr.visual, 24, &xi24_w);
2586
 
@@ -1280,7 +1311,7 @@
2587
 
                                        break;
2588
 
                                }
2589
 
                        }
2590
 
-                       if (! seen && attr.depth == 8) {
2591
 
+                       if (!seen && attr.depth <= 16) {
2592
 
                                /* store only new ones: */
2593
 
                                cmaps[ncmaps++] = attr.colormap;
2594
 
                        }
2595
 
@@ -1292,10 +1323,11 @@
2596
 
        return mapcount;
2597
 
 }
2598
 
 
2599
 
-static XColor color[CMAPMAX][NCOLOR];
2600
 
-static unsigned int rgb[CMAPMAX][NCOLOR];
2601
 
+static XColor *color[CMAPMAX];
2602
 
+static unsigned int *rgb[CMAPMAX];
2603
 
 static int cmap_failed[CMAPMAX];
2604
 
-int histo[256];
2605
 
+static int color_init = 0;
2606
 
+int histo[65536];
2607
 
 
2608
 
 static int get_cmap(int j, Colormap cmap) {
2609
 
 #if NO_X11
2610
 
@@ -1303,27 +1335,38 @@
2611
 
        if (!j || !cmap) {}
2612
 
        return 0;
2613
 
 #else
2614
 
-       int i, ncells;
2615
 
+       int i, ncells, ncolor;
2616
 
        XErrorHandler old_handler = NULL;
2617
 
 
2618
 
        RAWFB_RET(0)
2619
 
 
2620
 
-       if (0) {
2621
 
+       if (depth > 8) {
2622
 
+               ncolor = 1 << depth;
2623
 
+       } else {
2624
 
+               ncolor = NCOLOR;
2625
 
+       }
2626
 
+       if (!color_init) {
2627
 
+               int cm;
2628
 
+               for (cm = 0; cm < CMAPMAX; cm++) {
2629
 
+                       color[cm] = (XColor *) malloc(ncolor * sizeof(XColor));
2630
 
+                       rgb[cm] = (unsigned int *) malloc(ncolor * sizeof(unsigned int));
2631
 
+               }
2632
 
+               color_init = 1;
2633
 
+       }
2634
 
+
2635
 
+       if (depth <= 16) {
2636
 
                /* not working properly for depth 24... */
2637
 
                X_LOCK;
2638
 
                ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
2639
 
                X_UNLOCK;
2640
 
-       } else {
2641
 
-               ncells = NCOLOR;
2642
 
        }
2643
 
 if (db24 > 1) fprintf(stderr, "get_cmap: %d 0x%x\n", j, (unsigned int) cmap);
2644
 
 
2645
 
-       /* ncells should "always" be 256. */
2646
 
-       if (ncells > NCOLOR) {
2647
 
-               ncells = NCOLOR;
2648
 
-       } else if (ncells == 8) {
2649
 
-               /* hmmm. see set_colormap() */
2650
 
-               ncells = NCOLOR;
2651
 
+       if (ncells > ncolor) {
2652
 
+               ncells = ncolor;
2653
 
+       } else if (ncells == 8 && depth != 3) {
2654
 
+               /* XXX. see set_colormap() */
2655
 
+               ncells = 1 << depth;
2656
 
        }
2657
 
 
2658
 
        /* initialize XColor array: */
2659
 
@@ -1404,7 +1447,7 @@
2660
 
                }
2661
 
        }
2662
 
 
2663
 
-       if (windows_8bpp[n].depth == 8) {       /* 24 won't have a cmap */
2664
 
+       if (windows_8bpp[n].depth != 24) {      /* 24 won't have a cmap */
2665
 
                if (failed || cm == -1) {
2666
 
                        return;
2667
 
                }
2668
 
@@ -1448,17 +1491,18 @@
2669
 
        if (! dpy || ! valid_window(win, &attr, 1)) {
2670
 
                return (XImage *) NULL;
2671
 
        }
2672
 
-       if (attr.depth != win_depth) {
2673
 
-               return (XImage *) NULL;
2674
 
-       } else if (win_depth == 8) {
2675
 
-               d = (char *) malloc(dpy_x * dpy_y * 1);
2676
 
-       } else if (win_depth == 24) {
2677
 
+       if (win_depth == 24) {
2678
 
                d = (char *) malloc(dpy_x * dpy_y * 4);
2679
 
+       } else if (win_depth <= 16) {
2680
 
+               if (win_depth > 8) {
2681
 
+                       d = (char *) malloc(dpy_x * dpy_y * 2);
2682
 
+               } else {
2683
 
+                       d = (char *) malloc(dpy_x * dpy_y * 1);
2684
 
+               }
2685
 
        } else {
2686
 
                return (XImage *) NULL;
2687
 
        }
2688
 
-       return XCreateImage(dpy, attr.visual, win_depth, ZPixmap, 0, d, dpy_x,
2689
 
-           dpy_y, 8, 0);
2690
 
+       return XCreateImage(dpy, attr.visual, win_depth, ZPixmap, 0, d, dpy_x, dpy_y, 8, 0);
2691
 
 #endif /* NO_X11 */
2692
 
 }
2693
 
 
2694
 
@@ -1472,6 +1516,7 @@
2695
 
 
2696
 
        char *src, *dst, *poll;
2697
 
        unsigned int *ui;
2698
 
+       unsigned short *us;
2699
 
        unsigned char *uc;
2700
 
        int ps, pixelsize = bpp/8;
2701
 
        int poll_Bpl;
2702
 
@@ -1495,7 +1540,7 @@
2703
 
        h = rect.y2 - rect.y1;
2704
 
        w = rect.x2 - rect.x1;
2705
 
 
2706
 
-       if (depth == 8) {
2707
 
+       if (depth != 24) {
2708
 
                /* need to fetch depth 24 data. */
2709
 
                do_getimage = 1;
2710
 
        }
2711
 
@@ -1524,21 +1569,32 @@
2712
 
                X_LOCK;
2713
 
 #define GETSUBIMAGE
2714
 
 #ifdef GETSUBIMAGE
2715
 
-               if (win_depth == 8) {
2716
 
-                       if (xi_8 == NULL || xi_8->width != dpy_x ||
2717
 
-                           xi_8->height != dpy_y) {
2718
 
-                               xi_8 = cmap_xi(xi_8, win, 8);
2719
 
-                       }
2720
 
-                       xi = xi_8;
2721
 
-               } else if (win_depth == 24) {
2722
 
+               if (win_depth == 24) {
2723
 
                        if (xi_24 == NULL || xi_24->width != dpy_x ||
2724
 
                            xi_24->height != dpy_y) {
2725
 
                                xi_24 = cmap_xi(xi_24, win, 24);
2726
 
                        }
2727
 
                        xi = xi_24;
2728
 
+               } else if (win_depth <= 16) {
2729
 
+                       if (xi_8 == NULL || xi_8->width != dpy_x ||
2730
 
+                           xi_8->height != dpy_y) {
2731
 
+                               if (win_depth > 8) {
2732
 
+                                       /* XXX */
2733
 
+                                       xi_8 = cmap_xi(xi_8, win, 16);
2734
 
+                               } else {
2735
 
+                                       xi_8 = cmap_xi(xi_8, win, 8);
2736
 
+                               }
2737
 
+                       }
2738
 
+                       xi = xi_8;
2739
 
                }
2740
 
 #endif
2741
 
 
2742
 
+               if (xi == NULL) {
2743
 
+                       rfbLog("transform_rect: xi is NULL\n");
2744
 
+                       X_UNLOCK;
2745
 
+                       clean_up_exit(1);
2746
 
+               }
2747
 
+
2748
 
                old_handler = XSetErrorHandler(trap_xerror);
2749
 
                trapped_xerror = 0;
2750
 
 
2751
 
@@ -1578,7 +1634,7 @@
2752
 
                }
2753
 
                trapped_xerror = 0;
2754
 
 
2755
 
-               if (xi->depth != 8 && xi->depth != 24) {
2756
 
+               if (xi->depth > 16 && xi->depth != 24) {
2757
 
 #ifndef GETSUBIMAGE
2758
 
                        X_LOCK;
2759
 
                        XDestroyImage(xi);
2760
 
@@ -1590,64 +1646,76 @@
2761
 
 
2762
 
                set_poll_fb();
2763
 
 
2764
 
-               if (xi->depth == 8) {
2765
 
-                       int ps1, ps2, fac;
2766
 
-
2767
 
-                       if (depth == 8) {
2768
 
-                               ps1 = 1;
2769
 
-                               ps2 = 4;
2770
 
+               if (xi->depth == 24) {
2771
 
+                       /* line by line ... */
2772
 
+                       int ps1 = 4, fac;
2773
 
+                       if (depth <= 8) {
2774
 
                                fac = 4;
2775
 
+                       } else if (depth <= 16) {
2776
 
+                               fac = 2;
2777
 
                        } else {
2778
 
-                               ps1 = 1;
2779
 
-                               ps2 = pixelsize;
2780
 
-                               fac = 1;
2781
 
+                               fac = 1;        /* will not happen 24 on 24 */
2782
 
                        }
2783
 
 
2784
 
                        src = xi->data;
2785
 
                        dst = cmap8to24_fb + fac * n_off;
2786
 
 
2787
 
-                       poll = poll8_fb + poll8_fb_w * rect.y1 + rect.x1;
2788
 
-                       poll_Bpl = poll8_fb_w * 1;
2789
 
+                       poll = poll24_fb + (poll24_fb_w * rect.y1 + rect.x1) * 4;
2790
 
+                       poll_Bpl = poll24_fb_w * 4;
2791
 
 
2792
 
-                       /* line by line ... */
2793
 
                        for (line = 0; line < h; line++) {
2794
 
-                               /* pixel by pixel... */
2795
 
-                               for (j = 0; j < w; j++) {
2796
 
+                               memcpy(dst,  src, w * ps1);
2797
 
+                               memcpy(poll, src, w * ps1);
2798
 
 
2799
 
-                                       uc = (unsigned char *) (src + ps1 * j);
2800
 
-                                       ui = (unsigned int *)  (dst + ps2 * j);
2801
 
-
2802
 
-                                       idx = (int) (*uc);
2803
 
-
2804
 
-                                       *ui = rgb[cm][idx];
2805
 
-
2806
 
-                                       *(poll + ps1 * j) = *uc;
2807
 
-                               }
2808
 
                                src += xi->bytes_per_line;
2809
 
                                dst += main_bytes_per_line * fac;
2810
 
                                poll += poll_Bpl;
2811
 
                        }
2812
 
-               } else if (xi->depth == 24) {
2813
 
-                       /* line by line ... */
2814
 
-                       int ps1 = 4, fac;
2815
 
-                       if (depth == 8) {
2816
 
+               } else if (xi->depth <= 16) {
2817
 
+                       int ps1, ps2, fac;
2818
 
+
2819
 
+                       if (depth <= 8) {
2820
 
+                               ps1 = 1;
2821
 
+                               ps2 = 4;
2822
 
                                fac = 4;
2823
 
+                       } else if (depth <= 16) {
2824
 
+                               ps1 = 2;
2825
 
+                               ps2 = 4;
2826
 
+                               fac = 4;
2827
 
                        } else {
2828
 
-                               fac = 1;        /* will not happen */
2829
 
+                               /* should be 24 case */
2830
 
+                               ps1 = 1;
2831
 
+                               ps2 = pixelsize;
2832
 
+                               fac = 1;
2833
 
                        }
2834
 
 
2835
 
                        src = xi->data;
2836
 
-                       dst = cmap8to24_fb + fac * n_off;
2837
 
+                       dst = cmap8to24_fb + (fac/ps1) * n_off;
2838
 
 
2839
 
-                       poll = poll24_fb + (poll24_fb_w * rect.y1 + rect.x1)*4;
2840
 
-                       poll_Bpl = poll24_fb_w * 4;
2841
 
+                       poll = poll8_fb + poll8_fb_w * rect.y1 * ps1 + rect.x1 * ps1;
2842
 
+                       poll_Bpl = poll8_fb_w * ps1;
2843
 
 
2844
 
+                       /* line by line ... */
2845
 
                        for (line = 0; line < h; line++) {
2846
 
-                               memcpy(dst,  src, w * ps1);
2847
 
-                               memcpy(poll, src, w * ps1);
2848
 
+                               /* pixel by pixel... */
2849
 
+                               for (j = 0; j < w; j++) {
2850
 
+                                       if (ps1 == 2) {
2851
 
+                                               unsigned short *ptmp;
2852
 
+                                               us    = (unsigned short *) (src + ps1 * j);
2853
 
+                                               idx   = (int) (*us);
2854
 
+                                               ptmp  = (unsigned short *) (poll + ps1 * j);
2855
 
+                                               *ptmp = *us;
2856
 
+                                       } else {
2857
 
+                                               uc  = (unsigned char *) (src + ps1 * j);
2858
 
+                                               idx = (int) (*uc);
2859
 
+                                               *(poll + ps1 * j) = *uc;
2860
 
+                                       }
2861
 
+                                       ui = (unsigned int *) (dst + ps2 * j);
2862
 
+                                       *ui = rgb[cm][idx];
2863
 
 
2864
 
+                               }
2865
 
                                src += xi->bytes_per_line;
2866
 
-                               dst += main_bytes_per_line * fac;
2867
 
+                               dst += main_bytes_per_line * (fac/ps1);
2868
 
                                poll += poll_Bpl;
2869
 
                        }
2870
 
                }
2871
 
@@ -1661,11 +1729,12 @@
2872
 
        } else if (! do_getimage) {
2873
 
                int fac;
2874
 
 
2875
 
-               if (depth == 8) {
2876
 
+               if (depth <= 16) {
2877
 
                        /* cooked up depth 24 TrueColor  */
2878
 
                        /* but currently disabled (high bits no useful?) */
2879
 
                        ps = 4;
2880
 
                        fac = 4;
2881
 
+                       /* XXX not correct for depth > 8, but do we ever come here in that case? */
2882
 
                        src = cmap8to24_fb + 4 * n_off;
2883
 
                } else {
2884
 
                        ps = pixelsize;
2885
 
@@ -1697,6 +1766,7 @@
2886
 
 void bpp8to24(int x1, int y1, int x2, int y2) {
2887
 
        char *src, *dst;
2888
 
        unsigned char *uc;
2889
 
+       unsigned short *us;
2890
 
        unsigned int *ui;
2891
 
        int idx, pixelsize = bpp/8;
2892
 
        int line, k, i, j, h, w;
2893
 
@@ -1741,18 +1811,34 @@
2894
 
        h = y2 - y1;
2895
 
        w = x2 - x1;
2896
 
 
2897
 
-       if (depth == 8) {
2898
 
+       if (depth == 24) {
2899
 
+               /* pixelsize = 4 */
2900
 
+               n_off = main_bytes_per_line * y1 + pixelsize * x1;
2901
 
+
2902
 
+               src = main_fb      + n_off;
2903
 
+               dst = cmap8to24_fb + n_off;
2904
 
+
2905
 
+               /* otherwise, the pixel data as is */
2906
 
+               for (line = 0; line < h; line++) {
2907
 
+                       memcpy(dst, src, w * pixelsize);
2908
 
+                       src += main_bytes_per_line;
2909
 
+                       dst += main_bytes_per_line;
2910
 
+               }
2911
 
+       } else if (depth <= 16) {
2912
 
                /* need to cook up to depth 24 TrueColor  */
2913
 
-               /* pixelsize = 1 */
2914
 
+               int ps1 = 1, ps2 = 4;
2915
 
+               if (depth > 8) {
2916
 
+                       ps1 = 2;
2917
 
+               }
2918
 
 
2919
 
+               /* pixelsize = 1, 2 */
2920
 
                n_off = main_bytes_per_line * y1 + pixelsize * x1;
2921
 
 
2922
 
                src = main_fb + n_off;
2923
 
-               dst = cmap8to24_fb + 4 * n_off;
2924
 
+               dst = cmap8to24_fb + (4/ps1) * n_off;
2925
 
 
2926
 
                set_root_cmap();
2927
 
                if (root_cmap) {
2928
 
-                       int ps1 = 1, ps2 = 4;
2929
 
 #if 0
2930
 
                        unsigned int hi;
2931
 
 #endif
2932
 
@@ -1761,12 +1847,15 @@
2933
 
                        for (line = 0; line < h; line++) {
2934
 
                                /* pixel by pixel... */
2935
 
                                for (j = 0; j < w; j++) {
2936
 
-
2937
 
-                                       uc = (unsigned char *) (src + ps1 * j);
2938
 
+                                       if (ps1 == 2) {
2939
 
+                                               us = (unsigned short *) (src + ps1 * j);
2940
 
+                                               idx = (int) (*us);
2941
 
+                                       } else {
2942
 
+                                               uc = (unsigned char *)  (src + ps1 * j);
2943
 
+                                               idx = (int) (*uc);
2944
 
+                                       }
2945
 
                                        ui = (unsigned int *)  (dst + ps2 * j);
2946
 
 
2947
 
-                                       idx = (int) (*uc);
2948
 
-
2949
 
 if (0 && line % 100 == 0 && j % 32 == 0) fprintf(stderr, "%d %d %u  x1=%d y1=%d\n", line, j, root_rgb[idx], x1, y1);
2950
 
 #if 0
2951
 
                                        if (do_hibits) {
2952
 
@@ -1779,23 +1868,10 @@
2953
 
 if (db24 > 2) histo[idx]++;
2954
 
                                }
2955
 
                                src += main_bytes_per_line;
2956
 
-                               dst += main_bytes_per_line * 4;
2957
 
+                               dst += main_bytes_per_line * (4/ps1);
2958
 
                        }
2959
 
                }
2960
 
                
2961
 
-       } else if (depth == 24) {
2962
 
-               /* pixelsize = 4 */
2963
 
-               n_off = main_bytes_per_line * y1 + pixelsize * x1;
2964
 
-
2965
 
-               src = main_fb      + n_off;
2966
 
-               dst = cmap8to24_fb + n_off;
2967
 
-
2968
 
-               /* otherwise, the pixel data as is */
2969
 
-               for (line = 0; line < h; line++) {
2970
 
-                       memcpy(dst, src, w * pixelsize);
2971
 
-                       src += main_bytes_per_line;
2972
 
-                       dst += main_bytes_per_line;
2973
 
-               }
2974
 
        }
2975
 
 
2976
 
        if (last_map_count > MAX_8BPP_WINDOWS/4) {
2977
 
@@ -1871,7 +1947,7 @@
2978
 
         * now go back and transform and 8bpp regions to TrueColor in
2979
 
         * cmap8to24_fb.
2980
 
         */
2981
 
-       if (last_map_count && (ncmaps || depth == 8)) {
2982
 
+       if (last_map_count && (ncmaps || depth <= 16)) {
2983
 
                int i, j;
2984
 
                int win[MAX_8BPP_WINDOWS];
2985
 
                int did[MAX_8BPP_WINDOWS];
2986
 
Index: ../ica/x11/x11vnc/connections.c
2987
 
===================================================================
2988
 
--- ../ica/x11/x11vnc/connections.c     (Revision 401)
2989
 
+++ ../ica/x11/x11vnc/connections.c     (Arbeitskopie)
2990
 
@@ -2149,15 +2149,95 @@
2991
 
        return psock;
2992
 
 }
2993
 
 
2994
 
+char *get_repeater_string(char *str, int *len) {
2995
 
+       int pren, which = 0;
2996
 
+       int prestring_len = 0;  
2997
 
+       char *prestring = NULL, *ptmp = NULL;
2998
 
+       char *equals = strchr(str, '=');
2999
 
+       char *plus   = strrchr(str, '+');
3000
 
+
3001
 
+       *len = 0;
3002
 
+       if (!plus || !equals) {
3003
 
+               return NULL;
3004
 
+       }
3005
 
+
3006
 
+       *plus = '\0';
3007
 
+       if (strstr(str, "repeater=") == str) {
3008
 
+               /* ultravnc repeater http://www.uvnc.com/addons/repeater.html */
3009
 
+               prestring_len = 250;
3010
 
+               ptmp = (char *) calloc(prestring_len+1, 1);
3011
 
+               snprintf(ptmp, 250, "%s", str + strlen("repeater="));
3012
 
+               which = 1;
3013
 
+       } else if (strstr(str, "pre=") == str) {
3014
 
+               prestring_len = strlen(str + strlen("pre="));
3015
 
+               ptmp = (char *) calloc(prestring_len+1, 1);
3016
 
+               snprintf(ptmp, prestring_len+1, "%s", str + strlen("pre="));
3017
 
+               which = 2;
3018
 
+       } else if (sscanf(str, "pre%d=", &pren) == 1) {
3019
 
+               if (pren > 0 && pren <= 16384) {
3020
 
+                       prestring_len = pren;
3021
 
+                       ptmp = (char *) calloc(prestring_len+1, 1);
3022
 
+                       snprintf(prestring, prestring_len, "%s", equals+1);
3023
 
+                       which = 3;
3024
 
+               }
3025
 
+       }
3026
 
+       if (ptmp != NULL) {
3027
 
+               int i, k = 0;
3028
 
+               char *p = ptmp;
3029
 
+               prestring = (char *)calloc(prestring_len+1, 1);
3030
 
+               /* translate \n to newline, etc. */
3031
 
+               for (i=0; i < prestring_len; i++) {
3032
 
+                       if (i < prestring_len-1 && *(p+i) == '\\') {
3033
 
+                               if (*(p+i+1) == 'r') {
3034
 
+                                       prestring[k++] = '\r'; i++;
3035
 
+                               } else if (*(p+i+1) == 'n') {
3036
 
+                                       prestring[k++] = '\n'; i++;
3037
 
+                               } else if (*(p+i+1) == 't') {
3038
 
+                                       prestring[k++] = '\t'; i++;
3039
 
+                               } else if (*(p+i+1) == 'a') {
3040
 
+                                       prestring[k++] = '\a'; i++;
3041
 
+                               } else if (*(p+i+1) == 'b') {
3042
 
+                                       prestring[k++] = '\b'; i++;
3043
 
+                               } else if (*(p+i+1) == 'v') {
3044
 
+                                       prestring[k++] = '\v'; i++;
3045
 
+                               } else if (*(p+i+1) == 'f') {
3046
 
+                                       prestring[k++] = '\f'; i++;
3047
 
+                               } else if (*(p+i+1) == '\\') {
3048
 
+                                       prestring[k++] = '\\'; i++;
3049
 
+                               } else if (*(p+i+1) == 'c') {
3050
 
+                                       prestring[k++] = ','; i++;
3051
 
+                               } else {
3052
 
+                                       prestring[k++] = *(p+i);
3053
 
+                               }
3054
 
+                       } else {
3055
 
+                               prestring[k++] = *(p+i);
3056
 
+                       }
3057
 
+               }
3058
 
+               if (which == 2) {
3059
 
+                       prestring_len = k;
3060
 
+               }
3061
 
+               if (!quiet) {
3062
 
+                       rfbLog("-connect prestring: '%s'\n", prestring);
3063
 
+               }
3064
 
+               free(ptmp);
3065
 
+       }
3066
 
+       *plus = '+';
3067
 
+
3068
 
+       *len = prestring_len;
3069
 
+       return prestring;
3070
 
+}
3071
 
+
3072
 
 /*
3073
 
  * Do a reverse connect for a single "host" or "host:port"
3074
 
  */
3075
 
 
3076
 
 extern int ssl_client_mode;
3077
 
 
3078
 
-static int do_reverse_connect(char *str) {
3079
 
+static int do_reverse_connect(char *str_in) {
3080
 
        rfbClientPtr cl;
3081
 
-       char *host, *p;
3082
 
+       char *host, *p, *str = str_in, *s = NULL;
3083
 
+       char *prestring = NULL;
3084
 
+       int prestring_len = 0;
3085
 
        int rport = 5500, len = strlen(str);
3086
 
 
3087
 
        if (len < 1) {
3088
 
@@ -2173,6 +2253,24 @@
3089
 
        }
3090
 
        if (unixpw_in_progress) return 0;
3091
 
 
3092
 
+       /* look for repeater pre-string */
3093
 
+       if (strchr(str, '=') && strrchr(str, '+')
3094
 
+           && (strstr(str, "pre") == str || strstr(str, "repeater=") == str)) {
3095
 
+               prestring = get_repeater_string(str, &prestring_len);
3096
 
+               str = strrchr(str, '+') + 1;
3097
 
+       } else if (strrchr(str, '+') && strstr(str, "repeater://") == str) {
3098
 
+               /* repeater://host:port+string */
3099
 
+               /*   repeater=string+host:port */
3100
 
+               char *plus = strrchr(str, '+');
3101
 
+               str = (char *) malloc(strlen(str_in)+1);
3102
 
+               s = str;
3103
 
+               *plus = '\0';
3104
 
+               sprintf(str, "repeater=%s+%s", plus+1, str_in + strlen("repeater://"));
3105
 
+               prestring = get_repeater_string(str, &prestring_len);
3106
 
+               str = strrchr(str, '+') + 1;
3107
 
+               *plus = '+';
3108
 
+       }
3109
 
+
3110
 
        /* copy in to host */
3111
 
        host = (char *) malloc(len+1);
3112
 
        if (! host) {
3113
 
@@ -2204,10 +2302,15 @@
3114
 
                        rfbLog("reverse_connect: failed to connect to: %s\n", str);
3115
 
                        return 0;
3116
 
                }
3117
 
+               if (prestring != NULL) {
3118
 
+                       write(vncsock, prestring, prestring_len);
3119
 
+                       free(prestring);
3120
 
+               }
3121
 
 #define OPENSSL_REVERSE 4
3122
 
                openssl_init(1);
3123
 
                accept_openssl(OPENSSL_REVERSE, vncsock);
3124
 
                openssl_init(0);
3125
 
+               free(host);
3126
 
                return 1;
3127
 
        }
3128
 
        if (use_stunnel) {
3129
 
@@ -2220,17 +2323,17 @@
3130
 
        }
3131
 
 
3132
 
        if (unixpw) {
3133
 
-               int is_localhost = 0, user_disabled = 0;
3134
 
+               int is_localhost = 0, user_disabled_it = 0;
3135
 
 
3136
 
                if(!strcmp(host, "localhost") || !strcmp(host, "127.0.0.1")) {
3137
 
                        is_localhost = 1;
3138
 
                }
3139
 
                if (getenv("UNIXPW_DISABLE_LOCALHOST")) {
3140
 
-                       user_disabled = 1;
3141
 
+                       user_disabled_it = 1;
3142
 
                }
3143
 
 
3144
 
                if (! is_localhost) {
3145
 
-                       if (user_disabled ) {
3146
 
+                       if (user_disabled_it) {
3147
 
                                rfbLog("reverse_connect: warning disabling localhost constraint in -unixpw\n");
3148
 
                        } else {
3149
 
                                rfbLog("reverse_connect: error not localhost in -unixpw\n");
3150
 
@@ -2242,10 +2345,23 @@
3151
 
        if (connect_proxy != NULL) {
3152
 
                int sock = proxy_connect(host, rport);
3153
 
                if (sock >= 0) {
3154
 
+                       if (prestring != NULL) {
3155
 
+                               write(sock, prestring, prestring_len);
3156
 
+                               free(prestring);
3157
 
+                       }
3158
 
                        cl = rfbNewClient(screen, sock);
3159
 
                } else {
3160
 
                        return 0;
3161
 
                }
3162
 
+       } else if (prestring != NULL) {
3163
 
+               int sock = rfbConnectToTcpAddr(host, rport);
3164
 
+               if (sock >= 0) {
3165
 
+                       write(sock, prestring, prestring_len);
3166
 
+                       free(prestring);
3167
 
+                       cl = rfbNewClient(screen, sock);
3168
 
+               } else {
3169
 
+                       return 0;
3170
 
+               }
3171
 
        } else {
3172
 
                cl = rfbReverseConnection(screen, host, rport);
3173
 
        }
3174
 
@@ -2618,6 +2734,23 @@
3175
 
        }
3176
 
 }
3177
 
 
3178
 
+static int turn_off_truecolor = 0;
3179
 
+
3180
 
+static void turn_off_truecolor_ad(rfbClientPtr client) {
3181
 
+       if (turn_off_truecolor) {
3182
 
+               rfbLog("turning off truecolor advertising.\n");
3183
 
+               screen->serverFormat.trueColour = FALSE;
3184
 
+               screen->displayHook = NULL;
3185
 
+               screen->serverFormat.redShift   = 0;
3186
 
+               screen->serverFormat.greenShift = 0;
3187
 
+               screen->serverFormat.blueShift  = 0;
3188
 
+               screen->serverFormat.redMax     = 0;
3189
 
+               screen->serverFormat.greenMax   = 0;
3190
 
+               screen->serverFormat.blueMax    = 0;
3191
 
+               turn_off_truecolor = 0;
3192
 
+       }
3193
 
+}
3194
 
+
3195
 
 /*
3196
 
  * libvncserver callback for when a new client connects
3197
 
  */
3198
 
@@ -2761,6 +2894,43 @@
3199
 
                check_ncache(1, 0);
3200
 
        }
3201
 
 
3202
 
+       if (advertise_truecolor && indexed_color) {
3203
 
+               int rs = 0, gs = 2, bs = 4;
3204
 
+               int rm = 3, gm = 3, bm = 3;
3205
 
+               if (bpp >= 24) {
3206
 
+                       rs = 0, gs = 8, bs = 16;
3207
 
+                       rm = 255, gm = 255, bm = 255;
3208
 
+               } else if (bpp >= 16) {
3209
 
+                       rs = 0, gs = 5, bs = 10;
3210
 
+                       rm = 31, gm = 31, bm = 31;
3211
 
+               }
3212
 
+               rfbLog("advertising truecolor.\n");
3213
 
+               if (getenv("ADVERT_BMSHIFT")) {
3214
 
+                       bm--;
3215
 
+               }
3216
 
+
3217
 
+               client->format.trueColour = TRUE;
3218
 
+               client->format.redShift   = rs;
3219
 
+               client->format.greenShift = gs;
3220
 
+               client->format.blueShift  = bs;
3221
 
+               client->format.redMax     = rm;
3222
 
+               client->format.greenMax   = gm;
3223
 
+               client->format.blueMax    = bm;
3224
 
+
3225
 
+               rfbSetTranslateFunction(client);
3226
 
+
3227
 
+               screen->serverFormat.trueColour = TRUE;
3228
 
+               screen->serverFormat.redShift   = rs;
3229
 
+               screen->serverFormat.greenShift = gs;
3230
 
+               screen->serverFormat.blueShift  = bs;
3231
 
+               screen->serverFormat.redMax     = rm;
3232
 
+               screen->serverFormat.greenMax   = gm;
3233
 
+               screen->serverFormat.blueMax    = bm;
3234
 
+               screen->displayHook = turn_off_truecolor_ad;
3235
 
+
3236
 
+               turn_off_truecolor = 1;
3237
 
+       }
3238
 
+
3239
 
        if (unixpw) {
3240
 
                unixpw_in_progress = 1;
3241
 
                unixpw_client = client;
3242
 
Index: ../ica/x11/x11vnc/cursor.c
3243
 
===================================================================
3244
 
--- ../ica/x11/x11vnc/cursor.c  (Revision 401)
3245
 
+++ ../ica/x11/x11vnc/cursor.c  (Arbeitskopie)
3246
 
@@ -976,8 +976,8 @@
3247
 
                first = 0;
3248
 
        }
3249
 
 
3250
 
-       if (cmap8to24 && cmap8to24_fb && depth == 8) {
3251
 
-               if (Bpp == 1) {
3252
 
+       if (cmap8to24 && cmap8to24_fb && depth <= 16) {
3253
 
+               if (Bpp <= 2) {
3254
 
                        Bpp = 4;
3255
 
                }
3256
 
        }
3257
 
Index: ../ica/x11/x11vnc/x11vnc_defs.c
3258
 
===================================================================
3259
 
--- ../ica/x11/x11vnc/x11vnc_defs.c     (Revision 401)
3260
 
+++ ../ica/x11/x11vnc/x11vnc_defs.c     (Arbeitskopie)
3261
 
@@ -15,7 +15,7 @@
3262
 
 int xdamage_base_event_type = 0;
3263
 
 
3264
 
 /*               date +'lastmod: %Y-%m-%d' */
3265
 
-char lastmod[] = "0.9.4 lastmod: 2008-01-24";
3266
 
+char lastmod[] = "0.9.4 lastmod: 2008-06-24";
3267
 
 
3268
 
 /* X display info */
3269
 
 
3270
 
Index: ../ica/x11/x11vnc/tkx11vnc.h
3271
 
===================================================================
3272
 
--- ../ica/x11/x11vnc/tkx11vnc.h        (Revision 401)
3273
 
+++ ../ica/x11/x11vnc/tkx11vnc.h        (Arbeitskopie)
3274
 
@@ -682,7 +682,7 @@
3275
 
 "\n"
3276
 
 "    Properties      - Brings up the Properties dialog to set some basic\n"
3277
 
 "                      parameters.  The full tkx11vnc GUI may be accessed\n"
3278
 
-"                      via the \\\"Advanced ...\\\" button.  Press \\\"Help ...\\\"\n"
3279
 
+"                      via the \\\"Advanced ...\\\" button.  Press \\\"Help\\\"\n"
3280
 
 "                      in the Properties dialog for more info.\n"
3281
 
 "    \n"
3282
 
 "    Help            - Displays this help text.\n"
3283
 
@@ -792,7 +792,7 @@
3284
 
 "If you set \\\"ViewOnly Password\\\" to the empty string that just removes\n"
3285
 
 "the ViewOnly log in aspect: \\\"Password\\\" is still required to log in.\n"
3286
 
 "\n"
3287
 
-" - The \\\"Help ...\\\" button shows this help text.\n"
3288
 
+" - The \\\"Help\\\" button shows this help text.\n"
3289
 
 "   \n"
3290
 
 " - The \\\"Advanced ...\\\" button replaces the Properties dialog with the full\n"
3291
 
 "   tkx11vnc GUI.  All dynamic settings can be modified in the full GUI.\n"
3292
 
@@ -4283,7 +4283,7 @@
3293
 
 "\n"
3294
 
 "      bind $w <KeyPress-Escape> \"destroy $w\"\n"
3295
 
 "\n"
3296
 
-"      pack $b1.apply $b1.cancel $b1.ok -side right -expand 1\n"
3297
 
+"      pack $b1.ok $b1.cancel $b1.apply -side left -expand 0\n"
3298
 
 "      lappend props_buttons $b1.apply $b1.cancel $b1.ok\n"
3299
 
 "\n"
3300
 
 "      set b2 \"$w.buttons2\"\n"
3301
 
@@ -4293,12 +4293,12 @@
3302
 
 "              -command \"destroy $w; props_advanced\" -font $bfont\n"
3303
 
 "      if {! $icon_noadvanced} {\n"
3304
 
 "              lappend props_buttons $b2.advanced\n"
3305
 
-"              pack $b2.advanced -side right -expand 1\n"
3306
 
+"              pack $b2.advanced -side left -expand 0\n"
3307
 
 "      }\n"
3308
 
 "\n"
3309
 
-"      button $b2.help -text \"Help ...\" -command \"menu_help Properties\" -font $bfont\n"
3310
 
+"      button $b2.help -text \"Help\" -command \"menu_help Properties\" -font $bfont\n"
3311
 
 "      lappend props_buttons $b2.help\n"
3312
 
-"      pack $b2.help -side right -expand 1\n"
3313
 
+"      pack $b2.help -side left -expand 0\n"
3314
 
 "\n"
3315
 
 "      set vp \"$w.viewpw\"\n"
3316
 
 "      if {$have_labelframes} {\n"
3317
 
@@ -6637,14 +6637,8 @@
3318
 
 "\n"
3319
 
 "dtime D\n"
3320
 
 "\n"
3321
 
-"if {$icon_mode} {\n"
3322
 
-"      if {$tray_embed} {\n"
3323
 
-"              make_gui \"tray\"\n"
3324
 
-"      } else {\n"
3325
 
-"              make_gui \"icon\"\n"
3326
 
-"      }\n"
3327
 
-"      dtime G\n"
3328
 
-"      old_balloon\n"
3329
 
+"proc check_setpasswd {} {\n"
3330
 
+"      global icon_setpasswd\n"
3331
 
 "      if {$icon_setpasswd} {\n"
3332
 
 "              set m \"You must specify a Session Password\\n\" \n"
3333
 
 "              set m \"${m}before VNC clients can connect.\\n\" \n"
3334
 
@@ -6654,9 +6648,33 @@
3335
 
 "              do_props $m\n"
3336
 
 "              #push_new_value \"unlock\" \"unlock\" 1 0\n"
3337
 
 "      }\n"
3338
 
+"}\n"
3339
 
+"\n"
3340
 
+"if {0} {\n"
3341
 
+"      if {[info exists env(X11VNC_ICON_SETPASS)]} {\n"
3342
 
+"              if {$env(X11VNC_ICON_SETPASS) == \"2\"} {\n"
3343
 
+"                      global icon_mode_at_startup icon_mode\n"
3344
 
+"                      set icon_mode_at_startup 1\n"
3345
 
+"                      set icon_mode 2\n"
3346
 
+"              }\n"
3347
 
+"      }\n"
3348
 
+"}\n"
3349
 
+"\n"
3350
 
+"if {$icon_mode} {\n"
3351
 
+"      if {$icon_mode == 2} {\n"
3352
 
+"              make_gui \"full\"\n"
3353
 
+"      } elseif {$tray_embed} {\n"
3354
 
+"              make_gui \"tray\"\n"
3355
 
+"      } else {\n"
3356
 
+"              make_gui \"icon\"\n"
3357
 
+"      }\n"
3358
 
+"      dtime G\n"
3359
 
+"      old_balloon\n"
3360
 
+"      check_setpasswd\n"
3361
 
 "} else {\n"
3362
 
 "      make_gui \"full\"\n"
3363
 
 "      dtime G\n"
3364
 
+"      check_setpasswd\n"
3365
 
 "}\n"
3366
 
 "\n"
3367
 
 "\n"
3368
 
Index: ../ica/x11/x11vnc/scan.c
3369
 
===================================================================
3370
 
--- ../ica/x11/x11vnc/scan.c    (Revision 401)
3371
 
+++ ../ica/x11/x11vnc/scan.c    (Arbeitskopie)
3372
 
@@ -881,7 +881,10 @@
3373
 
        j1 = nfix(j1, ny);
3374
 
        j2 = nfix(j2, ny) + 1;
3375
 
 
3376
 
-       /* special case integer magnification with no blending */
3377
 
+       /*
3378
 
+        * special case integer magnification with no blending.
3379
 
+        * vision impaired magnification usage is interested in this case.
3380
 
+        */
3381
 
        if (mark && ! blend && mag_int && Bpp != 3) {
3382
 
                int jmin, jmax, imin, imax;
3383
 
 
3384
 
@@ -1122,14 +1125,10 @@
3385
 
                                 */
3386
 
                                if (Bpp == 4) {
3387
 
                                        /* unroll the loops, can give 20% */
3388
 
-                                       pixave[0] += w *
3389
 
-                                           ((unsigned char) *(src  ));
3390
 
-                                       pixave[1] += w *
3391
 
-                                           ((unsigned char) *(src+1));
3392
 
-                                       pixave[2] += w *
3393
 
-                                           ((unsigned char) *(src+2));
3394
 
-                                       pixave[3] += w *
3395
 
-                                           ((unsigned char) *(src+3));
3396
 
+                                       pixave[0] += w * ((unsigned char) *(src  ));
3397
 
+                                       pixave[1] += w * ((unsigned char) *(src+1));
3398
 
+                                       pixave[2] += w * ((unsigned char) *(src+2));
3399
 
+                                       pixave[3] += w * ((unsigned char) *(src+3));
3400
 
                                } else if (Bpp == 2) {
3401
 
                                        /*
3402
 
                                         * 16bpp: trickier with green
3403
 
@@ -1286,8 +1285,12 @@
3404
 
 
3405
 
        if (cmap8to24 && cmap8to24_fb) {
3406
 
                src_fb = cmap8to24_fb;
3407
 
-               if (scaling && depth == 8) {
3408
 
-                       fac = 4;
3409
 
+               if (scaling) {
3410
 
+                       if (depth <= 8) {
3411
 
+                               fac = 4;
3412
 
+                       } else if (depth <= 16) {
3413
 
+                               fac = 2;
3414
 
+                       }
3415
 
                }
3416
 
        }
3417
 
        dst_fb = rfb_fb;
3418
 
Index: ../ica/x11/x11vnc/gui.c
3419
 
===================================================================
3420
 
--- ../ica/x11/x11vnc/gui.c     (Revision 401)
3421
 
+++ ../ica/x11/x11vnc/gui.c     (Arbeitskopie)
3422
 
@@ -558,8 +558,11 @@
3423
 
                        if ((q = strchr(p, '=')) != NULL) {
3424
 
                                icon_mode_font = strdup(q+1);
3425
 
                        }
3426
 
-               } else if (!strcmp(p, "full")) {
3427
 
-                       ;
3428
 
+               } else if (strstr(p, "full") == p) {
3429
 
+                       if (strstr(p, "setp") && 0) {
3430
 
+                               set_env("X11VNC_ICON_MODE", "2");
3431
 
+                               set_env("X11VNC_ICON_SETPASS", "2");
3432
 
+                       }
3433
 
                } else if (strstr(p, "tray") == p || strstr(p, "icon") == p) {
3434
 
                        char *q;
3435
 
                        icon_mode = 1;
3436
 
Index: ../ica/x11/x11vnc/selection.c
3437
 
===================================================================
3438
 
--- ../ica/x11/x11vnc/selection.c       (Revision 401)
3439
 
+++ ../ica/x11/x11vnc/selection.c       (Arbeitskopie)
3440
 
@@ -133,8 +133,6 @@
3441
 
                targets[0] = (Atom) xa_targets;
3442
 
                targets[1] = (Atom) XA_STRING;
3443
 
 
3444
 
-               data = (unsigned char *)str;
3445
 
-
3446
 
                ret = XChangeProperty(ev->xselectionrequest.display,
3447
 
                    ev->xselectionrequest.requestor,
3448
 
                    ev->xselectionrequest.property,
3449
 
Index: ../ica/x11/x11vnc/unixpw.c
3450
 
===================================================================
3451
 
--- ../ica/x11/x11vnc/unixpw.c  (Revision 401)
3452
 
+++ ../ica/x11/x11vnc/unixpw.c  (Arbeitskopie)
3453
 
@@ -25,6 +25,11 @@
3454
 
 #endif
3455
 
 #endif
3456
 
 
3457
 
+#ifdef IGNORE_GETSPNAM
3458
 
+#undef LIBVNCSERVER_HAVE_GETSPNAM
3459
 
+#define LIBVNCSERVER_HAVE_GETSPNAM 0
3460
 
+#endif
3461
 
+
3462
 
 #if LIBVNCSERVER_HAVE_PWD_H && LIBVNCSERVER_HAVE_GETPWNAM
3463
 
 #if LIBVNCSERVER_HAVE_CRYPT || LIBVNCSERVER_HAVE_LIBCRYPT
3464
 
 #define UNIXPW_CRYPT
3465
 
Index: ../ica/x11/x11vnc/screen.c
3466
 
===================================================================
3467
 
--- ../ica/x11/x11vnc/screen.c  (Revision 401)
3468
 
+++ ../ica/x11/x11vnc/screen.c  (Arbeitskopie)
3469
 
@@ -81,6 +81,7 @@
3470
 
  */
3471
 
 #define NCOLOR 256
3472
 
 
3473
 
+/* this is only for rawfb */
3474
 
 void set_greyscale_colormap(void) {
3475
 
        int i;
3476
 
        if (! screen) {
3477
 
@@ -141,6 +142,8 @@
3478
 
 
3479
 
        rfbSetClientColourMaps(screen, 0, 256);
3480
 
 }
3481
 
+
3482
 
+/* this is only for rawfb */
3483
 
 void unset_colormap(void) {
3484
 
        if (! screen) {
3485
 
                return;
3486
 
@@ -153,35 +156,55 @@
3487
 
 if (0) fprintf(stderr, "unset_colormap: %s\n", raw_fb_pixfmt);
3488
 
 }
3489
 
 
3490
 
+/* this is X11 case */
3491
 
 void set_colormap(int reset) {
3492
 
+
3493
 
 #if NO_X11
3494
 
        if (!reset) {}
3495
 
        return;
3496
 
 #else
3497
 
        static int init = 1;
3498
 
-       static XColor color[NCOLOR], prev[NCOLOR];
3499
 
+       static XColor *color = NULL, *prev = NULL;
3500
 
+       static int ncolor = 0;
3501
 
        Colormap cmap;
3502
 
        Visual *vis;
3503
 
        int i, ncells, diffs = 0;
3504
 
 
3505
 
        if (reset) {
3506
 
                init = 1;
3507
 
+               ncolor = 0;
3508
 
                if (screen->colourMap.data.shorts) {
3509
 
                        free(screen->colourMap.data.shorts);
3510
 
                        screen->colourMap.data.shorts = NULL;
3511
 
                }
3512
 
+               if (color) {
3513
 
+                       free(color);
3514
 
+                       color = NULL;
3515
 
+               }
3516
 
+               if (prev) {
3517
 
+                       free(prev);
3518
 
+                       prev = NULL;
3519
 
+               }
3520
 
        }
3521
 
-if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
3522
 
 
3523
 
        if (init) {
3524
 
-               screen->colourMap.count = NCOLOR;
3525
 
+               if (depth > 8) {
3526
 
+                       ncolor = 1 << depth;
3527
 
+               } else {
3528
 
+                       ncolor = NCOLOR;
3529
 
+               }
3530
 
+               screen->colourMap.count = ncolor;
3531
 
                screen->serverFormat.trueColour = FALSE;
3532
 
                screen->colourMap.is16 = TRUE;
3533
 
                screen->colourMap.data.shorts = (unsigned short *)
3534
 
-                       malloc(3*sizeof(unsigned short) * NCOLOR);
3535
 
+                       malloc(3*sizeof(unsigned short) * ncolor);
3536
 
        }
3537
 
+       if (color == NULL) {
3538
 
+               color = (XColor *) calloc(ncolor * sizeof(XColor), 1);
3539
 
+               prev  = (XColor *) calloc(ncolor * sizeof(XColor), 1);
3540
 
+       }
3541
 
 
3542
 
-       for (i=0; i < NCOLOR; i++) {
3543
 
+       for (i=0; i < ncolor; i++) {
3544
 
                prev[i].red   = color[i].red;
3545
 
                prev[i].green = color[i].green;
3546
 
                prev[i].blue  = color[i].blue;
3547
 
@@ -205,15 +228,15 @@
3548
 
                }
3549
 
        }
3550
 
 
3551
 
-       if (ncells != NCOLOR) {
3552
 
-               if (init && ! quiet) {
3553
 
-                       rfbLog("set_colormap: number of cells is %d "
3554
 
-                           "instead of %d.\n", ncells, NCOLOR);
3555
 
-               }
3556
 
+       if (ncells != ncolor) {
3557
 
                if (! shift_cmap) {
3558
 
                        screen->colourMap.count = ncells;
3559
 
                }
3560
 
        }
3561
 
+       if (init && ! quiet) {
3562
 
+               rfbLog("set_colormap: number of cells: %d, "
3563
 
+                   "ncolor(%d) is %d.\n", ncells, depth, ncolor);
3564
 
+       }
3565
 
 
3566
 
        if (flash_cmap && ! init) {
3567
 
                XWindowAttributes attr;
3568
 
@@ -235,9 +258,9 @@
3569
 
                        }
3570
 
                }
3571
 
        }
3572
 
-       if (ncells > NCOLOR && ! quiet) {
3573
 
+       if (ncells > ncolor && ! quiet) {
3574
 
                rfbLog("set_colormap: big problem: ncells=%d > %d\n",
3575
 
-                   ncells, NCOLOR);
3576
 
+                   ncells, ncolor);
3577
 
        }
3578
 
 
3579
 
        if (vis->class == TrueColor || vis->class == DirectColor) {
3580
 
@@ -247,7 +270,7 @@
3581
 
                 * mentioned in xdpyinfo.  Looks OK... perhaps fortuitously.
3582
 
                 */
3583
 
                if (ncells == 8 && ! shift_cmap) {
3584
 
-                       ncells = NCOLOR;
3585
 
+                       ncells = ncolor;
3586
 
                }
3587
 
        }
3588
 
 
3589
 
@@ -273,7 +296,7 @@
3590
 
                        diffs++;
3591
 
                }
3592
 
 
3593
 
-               if (shift_cmap && k >= 0 && k < NCOLOR) {
3594
 
+               if (shift_cmap && k >= 0 && k < ncolor) {
3595
 
                        /* kludge to copy the colors to higher pixel values */
3596
 
                        screen->colourMap.data.shorts[k*3+0] = color[i].red;
3597
 
                        screen->colourMap.data.shorts[k*3+1] = color[i].green;
3598
 
@@ -287,7 +310,7 @@
3599
 
                            "with uninitialized clients.\n");
3600
 
                }
3601
 
                if (shift_cmap) {
3602
 
-                       rfbSetClientColourMaps(screen, 0, NCOLOR);
3603
 
+                       rfbSetClientColourMaps(screen, 0, ncolor);
3604
 
                } else {
3605
 
                        rfbSetClientColourMaps(screen, 0, ncells);
3606
 
                }
3607
 
@@ -299,7 +322,8 @@
3608
 
 
3609
 
 static void debug_colormap(XImage *fb) {
3610
 
        static int debug_cmap = -1;
3611
 
-       int i, k, histo[NCOLOR];
3612
 
+       int i, k, *histo;
3613
 
+       int ncolor;
3614
 
 
3615
 
        if (debug_cmap < 0) {
3616
 
                if (getenv("DEBUG_CMAP") != NULL) {
3617
 
@@ -314,11 +338,13 @@
3618
 
        if (! fb) {
3619
 
                return;
3620
 
        }
3621
 
-       if (fb->bits_per_pixel > 8) {
3622
 
+       if (fb->bits_per_pixel > 16) {
3623
 
                return;
3624
 
        }
3625
 
+       ncolor = screen->colourMap.count;
3626
 
+       histo = (int *) calloc(ncolor * sizeof(int), 1);
3627
 
 
3628
 
-       for (i=0; i < NCOLOR; i++) {
3629
 
+       for (i=0; i < ncolor; i++) {
3630
 
                histo[i] = 0;
3631
 
        }
3632
 
        for (k = 0; k < fb->width * fb->height; k++) {
3633
 
@@ -329,7 +355,7 @@
3634
 
                histo[n]++;
3635
 
        }
3636
 
        fprintf(stderr, "\nColormap histogram for current screen contents:\n");
3637
 
-       for (i=0; i < NCOLOR; i++) {
3638
 
+       for (i=0; i < ncolor; i++) {
3639
 
                unsigned short r = screen->colourMap.data.shorts[i*3+0];
3640
 
                unsigned short g = screen->colourMap.data.shorts[i*3+1];
3641
 
                unsigned short b = screen->colourMap.data.shorts[i*3+2];
3642
 
@@ -340,6 +366,7 @@
3643
 
                        fprintf(stderr, "\n");
3644
 
                }
3645
 
        }
3646
 
+       free(histo);
3647
 
        fprintf(stderr, "\n");
3648
 
 }
3649
 
 
3650
 
@@ -1355,7 +1382,7 @@
3651
 
        raw_fb_addr = NULL;
3652
 
        raw_fb_offset = 0;
3653
 
        raw_fb_bytes_per_line = 0;
3654
 
-/*     rawfb_vnc_reflect = 0;*/
3655
 
+       rawfb_vnc_reflect = 0;
3656
 
 
3657
 
        last_mode = 0;
3658
 
        if (last_file) {
3659
 
@@ -1406,6 +1433,7 @@
3660
 
                initialize_pipeinput();
3661
 
 #endif
3662
 
        }
3663
 
+
3664
 
        if (closedpy && !view_only && got_noviewonly) {
3665
 
                rfbLog("not closing X DISPLAY under -noviewonly option.\n");
3666
 
                closedpy = 0;
3667
 
@@ -1936,12 +1964,38 @@
3668
 
        if (xform24to32) {
3669
 
                if (DefaultDepth(dpy, scr) == 24) {
3670
 
                        vis_str = strdup("TrueColor:32");
3671
 
-                       rfbLog("initialize_xdisplay_fb: vis_str set to: %s ",
3672
 
+                       rfbLog("initialize_xdisplay_fb: vis_str set to: %s\n",
3673
 
                            vis_str);
3674
 
                        visual_id = (VisualID) 0;
3675
 
                        visual_depth = 0;
3676
 
                        set_visual_str_to_something = 1;
3677
 
                }
3678
 
+       } else if (DefaultDepth(dpy, scr) < 8) {
3679
 
+               /* check very low bpp case, e.g. mono or vga16 */
3680
 
+               Screen *s = DefaultScreenOfDisplay(dpy);
3681
 
+               XImage *xi = XGetImage_wr(dpy, DefaultRootWindow(dpy), 0, 0, 2, 2, AllPlanes,
3682
 
+                   ZPixmap);
3683
 
+               if (xi && xi->bits_per_pixel < 8) {
3684
 
+                       int lowbpp = xi->bits_per_pixel; 
3685
 
+                       if (!vis_str) {
3686
 
+                               char tmp[32];
3687
 
+                               sprintf(tmp, "0x%x:8", (int) s->root_visual->visualid);
3688
 
+                               vis_str = strdup(tmp);
3689
 
+                               rfbLog("initialize_xdisplay_fb: low bpp[%d], vis_str "
3690
 
+                                   "set to: %s\n", lowbpp, vis_str);
3691
 
+                       }
3692
 
+                       if (using_shm) {
3693
 
+                               using_shm = 0;
3694
 
+                               rfbLog("initialize_xdisplay_fb: low bpp[%d], "
3695
 
+                                   "disabling shm\n", lowbpp);
3696
 
+                       }
3697
 
+                       visual_id = (VisualID) 0;
3698
 
+                       visual_depth = 0;
3699
 
+                       set_visual_str_to_something = 1;
3700
 
+               }
3701
 
+               if (xi) {
3702
 
+                       XDestroyImage(xi);
3703
 
+               }
3704
 
        }
3705
 
 
3706
 
        if (vis_str != NULL) {
3707
 
@@ -2425,13 +2479,13 @@
3708
 
                                    " bpp != 32 with depth == 24\n");
3709
 
                                cmap8to24 = 0;
3710
 
                        }
3711
 
-               } else if (depth == 8) {
3712
 
+               } else if (depth <= 16) {
3713
 
                        /* need to cook up the screen fb to be depth 24 */
3714
 
                        fb_bpp = 32;
3715
 
                        fb_depth = 24;
3716
 
                } else {
3717
 
                        if (!quiet) rfbLog("disabling -8to24 mode:"
3718
 
-                           " default depth not 24 or 8\n");
3719
 
+                           " default depth not 16 or less\n");
3720
 
                        cmap8to24 = 0;
3721
 
                }
3722
 
        }
3723
 
@@ -2494,9 +2548,14 @@
3724
 
        }
3725
 
 #endif
3726
 
 
3727
 
-       if (cmap8to24 && depth == 8) {
3728
 
-               rfb_bytes_per_line *= 4;
3729
 
-               rot_bytes_per_line *= 4;
3730
 
+       if (cmap8to24) {
3731
 
+               if (depth <= 8) {
3732
 
+                       rfb_bytes_per_line *= 4;
3733
 
+                       rot_bytes_per_line *= 4;
3734
 
+               } else if (depth <= 16) {
3735
 
+                       rfb_bytes_per_line *= 2;
3736
 
+                       rot_bytes_per_line *= 2;
3737
 
+               }
3738
 
        }
3739
 
 
3740
 
        /*
3741
 
@@ -2601,7 +2660,7 @@
3742
 
                have_masks = 0;
3743
 
        }
3744
 
 
3745
 
-       if (cmap8to24 && depth == 8 && dpy) {
3746
 
+       if (cmap8to24 && depth <= 16 && dpy) {
3747
 
                XVisualInfo vinfo;
3748
 
                vinfo.red_mask = 0;
3749
 
                vinfo.green_mask = 0;
3750
 
@@ -2643,13 +2702,14 @@
3751
 
                free(fmt);
3752
 
        }
3753
 
 
3754
 
-       if (! have_masks && screen->serverFormat.bitsPerPixel == 8
3755
 
+       if (! have_masks && screen->serverFormat.bitsPerPixel <= 16
3756
 
            && dpy && CellsOfScreen(ScreenOfDisplay(dpy, scr))) {
3757
 
-               /* indexed color */
3758
 
+               /* indexed color. we let 1 <= bpp <= 16, but it is normally 8 */
3759
 
                if (!quiet) {
3760
 
                        rfbLog("\n");
3761
 
-                       rfbLog("X display %s is 8bpp indexed color\n",
3762
 
-                           DisplayString(dpy));
3763
 
+                       rfbLog("X display %s is %dbpp indexed color, depth=%d\n",
3764
 
+                           DisplayString(dpy), screen->serverFormat.bitsPerPixel,
3765
 
+                           screen->serverFormat.depth);
3766
 
                        if (! flash_cmap && ! overlay) {
3767
 
                                rfbLog("\n");
3768
 
                                rfbLog("In 8bpp PseudoColor mode if you "
3769
 
@@ -2661,6 +2721,18 @@
3770
 
                                rfbLog("\n");
3771
 
                        }
3772
 
                }
3773
 
+               if (screen->serverFormat.depth < 8) {
3774
 
+                       rfbLog("resetting serverFormat.depth %d -> 8.\n",
3775
 
+                           screen->serverFormat.depth);
3776
 
+                       rfbLog("resetting serverFormat.bpp   %d -> 8.\n",
3777
 
+                           screen->serverFormat.bitsPerPixel);
3778
 
+                       screen->serverFormat.depth = 8;
3779
 
+                       screen->serverFormat.bitsPerPixel = 8;
3780
 
+               }
3781
 
+               if (screen->serverFormat.depth > 8) {
3782
 
+                       rfbLog("WARNING: indexed color depth > 8, Tight encoding will crash.\n");
3783
 
+               }
3784
 
+
3785
 
                screen->serverFormat.trueColour = FALSE;
3786
 
                indexed_color = 1;
3787
 
                set_colormap(1);
3788
 
@@ -2693,6 +2765,29 @@
3789
 
 
3790
 
                indexed_color = 0;
3791
 
 
3792
 
+               if (!have_masks) {
3793
 
+                       int M, B = bits_per_color;
3794
 
+
3795
 
+                       if (3*B > fb_bpp) B--;
3796
 
+                       if (B < 1) B = 1;
3797
 
+                       M = (1 << B) - 1;
3798
 
+
3799
 
+                       rfbLog("WARNING: all TrueColor RGB masks are zero!\n");
3800
 
+                       rfbLog("WARNING: cooking something up for VNC fb...  B=%d M=%d\n", B, M);
3801
 
+                       main_red_mask   = M;
3802
 
+                       main_green_mask = M;
3803
 
+                       main_blue_mask  = M;
3804
 
+                       main_red_mask   = main_red_mask   << (2*B);
3805
 
+                       main_green_mask = main_green_mask << (1*B);
3806
 
+                       main_blue_mask  = main_blue_mask  << (0*B);
3807
 
+                       fprintf(stderr, " red_mask:   0x%08lx  %s\n", main_red_mask,
3808
 
+                           bitprint(main_red_mask, 32));
3809
 
+                       fprintf(stderr, " green_mask: 0x%08lx  %s\n", main_green_mask,
3810
 
+                           bitprint(main_green_mask, 32));
3811
 
+                       fprintf(stderr, " blue_mask:  0x%08lx  %s\n", main_blue_mask,
3812
 
+                           bitprint(main_blue_mask, 32));
3813
 
+               }
3814
 
+
3815
 
                /* convert masks to bit shifts and max # colors */
3816
 
                if (main_red_mask) {
3817
 
                        while (! (main_red_mask
3818
 
@@ -2826,8 +2921,10 @@
3819
 
 
3820
 
                if (cmap8to24) {
3821
 
                        int n = main_bytes_per_line * fb->height;
3822
 
-                       if (depth == 8) {
3823
 
+                       if (depth <= 8) {
3824
 
                                n *= 4;
3825
 
+                       } else if (depth <= 16) {
3826
 
+                               n *= 2;
3827
 
                        }
3828
 
                        cmap8to24_fb = (char *) malloc(n);
3829
 
                        memset(cmap8to24_fb, 0, n);
3830
 
Index: ../ica/x11/x11vnc/x11vnc.c
3831
 
===================================================================
3832
 
--- ../ica/x11/x11vnc/x11vnc.c  (Revision 401)
3833
 
+++ ../ica/x11/x11vnc/x11vnc.c  (Arbeitskopie)
3834
 
@@ -1,7 +1,7 @@
3835
 
 /*
3836
 
  * x11vnc: a VNC server for X displays.
3837
 
  *
3838
 
- * Copyright (c) 2002-2007 Karl J. Runge <runge@karlrunge.com>
3839
 
+ * Copyright (c) 2002-2008 Karl J. Runge <runge@karlrunge.com>
3840
 
  * All rights reserved.
3841
 
  *
3842
 
  *  This is free software; you can redistribute it and/or modify
3843
 
@@ -2514,6 +2514,17 @@
3844
 
                        shift_cmap = atoi(argv[++i]);
3845
 
                } else if (!strcmp(arg, "-notruecolor")) {
3846
 
                        force_indexed_color = 1;
3847
 
+               } else if (!strcmp(arg, "-advertise_truecolor")) {
3848
 
+                       advertise_truecolor = 1;
3849
 
+                       if (i < argc-1) {
3850
 
+                               char *s = argv[i+1];
3851
 
+                               if (s[0] != '-') {
3852
 
+                                       if (strstr(s, "reset")) {
3853
 
+                                               advertise_truecolor_reset = 1;
3854
 
+                                       }
3855
 
+                                       i++;
3856
 
+                               }
3857
 
+                       }
3858
 
                } else if (!strcmp(arg, "-overlay")) {
3859
 
                        overlay = 1;
3860
 
                } else if (!strcmp(arg, "-overlay_nocursor")) {
3861
 
@@ -2589,7 +2600,7 @@
3862
 
                } else if (!strcmp(arg, "-connect") ||
3863
 
                    !strcmp(arg, "-connect_or_exit")) {
3864
 
                        CHECK_ARGC
3865
 
-                       if (strchr(argv[++i], '/')) {
3866
 
+                       if (strchr(argv[++i], '/' && !strstr(argv[i], "repeater://"))) {
3867
 
                                client_connect_file = strdup(argv[i]);
3868
 
                        } else {
3869
 
                                client_connect = strdup(argv[i]);
3870
 
@@ -3211,6 +3222,7 @@
3871
 
                } else if (!strcmp(arg, "-wait")) {
3872
 
                        CHECK_ARGC
3873
 
                        waitms = atoi(argv[++i]);
3874
 
+                       got_waitms = 1;
3875
 
                } else if (!strcmp(arg, "-wait_ui")) {
3876
 
                        CHECK_ARGC
3877
 
                        wait_ui = atof(argv[++i]);
3878
 
@@ -3280,7 +3292,22 @@
3879
 
                        }
3880
 
 #if LIBVNCSERVER_HAVE_LIBPTHREAD
3881
 
                } else if (!strcmp(arg, "-threads")) {
3882
 
+#if defined(X11VNC_THREADED)
3883
 
                        use_threads = 1;
3884
 
+#else
3885
 
+                       if (getenv("X11VNC_THREADED")) {
3886
 
+                               use_threads = 1;
3887
 
+                       } else {
3888
 
+                               rfbLog("\n");
3889
 
+                               rfbLog("The -threads mode is unstable and not tested or maintained.\n");
3890
 
+                               rfbLog("It is disabled in the source code.  If you really need\n");
3891
 
+                               rfbLog("the feature you can reenable it at build time by setting\n");
3892
 
+                               rfbLog("-DX11VNC_THREADED in CPPFLAGS. Or set X11VNC_THREADED=1\n");
3893
 
+                               rfbLog("in your runtime environment.\n");
3894
 
+                               rfbLog("\n");
3895
 
+                               usleep(500*1000);
3896
 
+                       }
3897
 
+#endif
3898
 
                } else if (!strcmp(arg, "-nothreads")) {
3899
 
                        use_threads = 0;
3900
 
 #endif
3901
 
@@ -3830,11 +3857,14 @@
3902
 
                                if (! s) s = "SSH_CONNECTION";
3903
 
                                fprintf(stderr, "\n");
3904
 
                                rfbLog("Skipping -ssl/-stunnel constraint in"
3905
 
-                                   " -unixpw\n");
3906
 
-                               rfbLog("mode, assuming your SSH encryption"
3907
 
-                                   " is: %s\n", s);
3908
 
+                                   " -unixpw mode,\n");
3909
 
+                               rfbLog("assuming your SSH encryption"
3910
 
+                                   " is:\n");
3911
 
+                               rfbLog("   %s\n", s);
3912
 
                                rfbLog("Setting -localhost in SSH + -unixpw"
3913
 
                                    " mode.\n");
3914
 
+                               rfbLog("If you *actually* want SSL, restart"
3915
 
+                                   " with -ssl on the cmdline\n");
3916
 
                                fprintf(stderr, "\n");
3917
 
                                allow_list = strdup("127.0.0.1");
3918
 
                                got_localhost = 1;
3919
 
@@ -4202,6 +4232,9 @@
3920
 
                if (! quiet) rfbLog("Using default X display.\n");
3921
 
        }
3922
 
 
3923
 
+       if (clip_str != NULL && dpy != NULL) {
3924
 
+               check_xinerama_clip();
3925
 
+       }
3926
 
 
3927
 
        scr = DefaultScreen(dpy);
3928
 
        rootwin = RootWindow(dpy, scr);
3929
 
@@ -4756,6 +4789,28 @@
3930
 
 
3931
 
        initialize_speeds();
3932
 
 
3933
 
+       if (speeds_read_rate_measured > 100) {
3934
 
+               /* framebuffer read is fast at  > 100 MB/sec */
3935
 
+               if (! got_waitms) {
3936
 
+                       waitms /= 2;
3937
 
+                       if (waitms < 10) {
3938
 
+                               waitms = 10;
3939
 
+                       }
3940
 
+                       if (!quiet) {
3941
 
+                               rfbLog("fast read: reset wait  ms to: %d\n", waitms);
3942
 
+                       }
3943
 
+               }
3944
 
+               if (! got_deferupdate && ! got_defer) {
3945
 
+                       if (defer_update > 15) {
3946
 
+                               defer_update = 15;
3947
 
+                               if (screen) {
3948
 
+                                       screen->deferUpdateTime = defer_update;
3949
 
+                               }
3950
 
+                               rfbLog("fast read: reset defer ms to: %d\n", defer_update);
3951
 
+                       }
3952
 
+               }
3953
 
+       }
3954
 
+
3955
 
        initialize_keyboard_and_pointer();
3956
 
 
3957
 
        if (inetd && use_openssl) {
3958
 
Index: ../ica/x11/x11vnc/ssltools.h
3959
 
===================================================================
3960
 
--- ../ica/x11/x11vnc/ssltools.h        (Revision 401)
3961
 
+++ ../ica/x11/x11vnc/ssltools.h        (Arbeitskopie)
3962
 
@@ -76,7 +76,7 @@
3963
 
 "name_opt      = ca_default            # Subject Name options\n"
3964
 
 "cert_opt      = ca_default            # Certificate field options\n"
3965
 
 "\n"
3966
 
-"default_days  = 365                   # how long to certify for\n"
3967
 
+"default_days  = 730                   # how long to certify for\n"
3968
 
 "default_crl_days= 30                  # how long before next CRL\n"
3969
 
 "default_md    = md5                   # which md to use.\n"
3970
 
 "preserve      = no                    # keep passed DN ordering\n"
3971
 
@@ -333,6 +333,13 @@
3972
 
 "      echo \"Creating new x11vnc certificate and key for name: $type $name0\"\n"
3973
 
 "      echo \"\"\n"
3974
 
 "\n"
3975
 
+"      req_args=$REQ_ARGS\n"
3976
 
+"      if echo \"$req_args\" | grep 'days' > /dev/null; then\n"
3977
 
+"              :\n"
3978
 
+"      else\n"
3979
 
+"              req_args=\"$req_args -days 730\"\n"
3980
 
+"      fi\n"
3981
 
+"\n"
3982
 
 "      cnf=\"$DIR/tmp/cnf.$$\"\n"
3983
 
 "      trap \"rm -f \\\"$cnf\\\"\" 0 1 2 15\n"
3984
 
 "\n"
3985
 
@@ -343,7 +350,7 @@
3986
 
 "                      direrror \"$DIR/CA/self.cnf.$type\"\n"
3987
 
 "              fi\n"
3988
 
 "              cat \"$DIR/CA/self.cnf.$type\" | sed -e \"s/%NAME/$name0/\" > \"$cnf\" || exit 1\n"
3989
 
-"              \"$OPENSSL\" req -config \"$cnf\" -nodes -new -newkey rsa:2048 -x509 $REQ_ARGS \\\n"
3990
 
+"              \"$OPENSSL\" req -config \"$cnf\" -nodes -new -newkey rsa:2048 -x509 $req_args \\\n"
3991
 
 "                      -keyout \"$DIR/$dest.key\" \\\n"
3992
 
 "                      -out    \"$DIR/$dest.crt\"\n"
3993
 
 "      else\n"
3994
 
@@ -351,7 +358,7 @@
3995
 
 "                      direrror \"$DIR/CA/ssl.cnf.$type\"\n"
3996
 
 "              fi\n"
3997
 
 "              cat \"$DIR/CA/ssl.cnf.$type\" | sed  -e \"s/%NAME/$name0/\" > \"$cnf\" || exit 1\n"
3998
 
-"              \"$OPENSSL\" req -config \"$cnf\" -nodes -new -newkey rsa:2048 $REQ_ARGS \\\n"
3999
 
+"              \"$OPENSSL\" req -config \"$cnf\" -nodes -new -newkey rsa:2048 $req_args \\\n"
4000
 
 "                      -keyout \"$DIR/$dest.key\" \\\n"
4001
 
 "                      -out    \"$DIR/$dest.req\"\n"
4002
 
 "      fi\n"
4003
 
@@ -1400,32 +1407,32 @@
4004
 
 "              else\n"
4005
 
 "                      sxcmd=$have_xinit\n"
4006
 
 "              fi\n"
4007
 
-"              echo \"$sxcmd $sess -- $* -nolisten tcp -auth $authfile $FD_OPTS\" 1>&2\n"
4008
 
+"              echo \"$sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS\" 1>&2\n"
4009
 
 "              if [ \"X$have_root\" != \"X\" ]; then\n"
4010
 
-"                      $sxcmd $sess -- $* -nolisten tcp -auth $authfile $FD_OPTS 1>&2 &\n"
4011
 
+"                      $sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS 1>&2 &\n"
4012
 
 "              else\n"
4013
 
 "                      if [ \"X$ns\" = \"X0\" ]; then\n"
4014
 
-"                              $have_nohup sh -c \"$sxcmd $sess -- $* -nolisten tcp -auth $authfile $FD_OPTS\" 1>&2 &\n"
4015
 
+"                              $have_nohup sh -c \"$sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS\" 1>&2 &\n"
4016
 
 "                      else\n"
4017
 
 "                              # Why did we ever sleep before starting the server??\n"
4018
 
-"                              $have_nohup sh -c \"(sleep $ns; $sxcmd $sess -- $* -nolisten tcp -auth $authfile $FD_OPTS)\" 1>&2 &\n"
4019
 
+"                              $have_nohup sh -c \"(sleep $ns; $sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS)\" 1>&2 &\n"
4020
 
 "                              #result=1\n"
4021
 
 "                      fi\n"
4022
 
 "              fi\n"
4023
 
 "              pid=$!\n"
4024
 
 "      else\n"
4025
 
 "              # need to emulate startx/xinit ourselves...\n"
4026
 
-"              echo \"$* -nolisten tcp -auth $authfile $FD_OPTS\" 1>&2\n"
4027
 
+"              echo \"$* $nolisten -auth $authfile $FD_OPTS\" 1>&2\n"
4028
 
 "              if [ \"X$have_root\" != \"X\" ]; then\n"
4029
 
-"                      $have_nohup $* -nolisten tcp -auth $authfile $FD_OPTS 1>&2 &\n"
4030
 
+"                      $have_nohup $* $nolisten -auth $authfile $FD_OPTS 1>&2 &\n"
4031
 
 "                      pid=$!\n"
4032
 
 "                      sleep 3\n"
4033
 
 "                      $have_nohup $sess 1>&2 &\n"
4034
 
 "              else\n"
4035
 
 "                      if [ \"X$ns\" = \"X0\" ]; then\n"
4036
 
-"                              $have_nohup sh -c \"$* -nolisten tcp -auth $authfile $FD_OPTS\" 1>&2 &\n"
4037
 
+"                              $have_nohup sh -c \"$* $nolisten -auth $authfile $FD_OPTS\" 1>&2 &\n"
4038
 
 "                      else\n"
4039
 
-"                              $have_nohup sh -c \"(sleep $ns; $* -nolisten tcp -auth $authfile $FD_OPTS)\" 1>&2 &\n"
4040
 
+"                              $have_nohup sh -c \"(sleep $ns; $* $nolisten -auth $authfile $FD_OPTS)\" 1>&2 &\n"
4041
 
 "                              #result=1\n"
4042
 
 "                      fi\n"
4043
 
 "                      pid=$!\n"
4044
 
@@ -1719,6 +1726,8 @@
4045
 
 "depth=${depth:-16}\n"
4046
 
 "geom=${geom:-1280x1024}\n"
4047
 
 "\n"
4048
 
+"nolisten=${FD_NOLISTEN:-\"-nolisten tcp\"}\n"
4049
 
+"\n"
4050
 
 "if [ \"X$X11VNC_CREATE_GEOM\" != \"X\" -a \"X$FD_GEOM\" = \"X\" ]; then\n"
4051
 
 "      FD_GEOM=$X11VNC_CREATE_GEOM\n"
4052
 
 "fi\n"
4053
 
Index: ../ica/x11/x11vnc/sslhelper.c
4054
 
===================================================================
4055
 
--- ../ica/x11/x11vnc/sslhelper.c       (Revision 401)
4056
 
+++ ../ica/x11/x11vnc/sslhelper.c       (Arbeitskopie)
4057
 
@@ -1567,6 +1567,9 @@
4058
 
                if (screen->httpListenSock >= 0 && screen->httpPort > 0) {
4059
 
                        have_httpd = 1;
4060
 
                }
4061
 
+               if (screen->httpListenSock == -2) {
4062
 
+                       have_httpd = 1;
4063
 
+               }
4064
 
                if (mode == OPENSSL_HTTPS && ! have_httpd) {
4065
 
                        rfbLog("SSL: accept_openssl[%d]: no httpd socket for "
4066
 
                            "-https mode\n", getpid());
4067
 
@@ -1695,10 +1698,11 @@
4068
 
                        /* send the failure tag: */
4069
 
                        strcpy(tbuf, uniq);
4070
 
 
4071
 
-                       if (https_port_redir < 0) {
4072
 
+                       if (https_port_redir < 0 || (strstr(buf, "PORT=") || strstr(buf, "port="))) {
4073
 
                                char *q = strstr(buf, "Host:");
4074
 
-                               int fport = 443;
4075
 
+                               int fport = 443, match = 0;
4076
 
                                char num[16];
4077
 
+
4078
 
                                if (q && strstr(q, "\n")) {
4079
 
                                    q += strlen("Host:") + 1;
4080
 
                                    while (*q != '\n') {
4081
 
@@ -1706,12 +1710,25 @@
4082
 
                                        if (*q == ':' && sscanf(q, ":%d", &p) == 1) {
4083
 
                                                if (p > 0 && p < 65536) {
4084
 
                                                        fport = p;
4085
 
+                                                       match = 1;
4086
 
                                                        break;
4087
 
                                                }
4088
 
                                        }
4089
 
                                        q++;
4090
 
                                    }
4091
 
                                }
4092
 
+                               if (!match || !https_port_redir) {
4093
 
+                                       int p;
4094
 
+                                       if (sscanf(buf, "PORT=%d,", &p) == 1) {
4095
 
+                                               if (p > 0 && p < 65536) {
4096
 
+                                                       fport = p;
4097
 
+                                               }
4098
 
+                                       } else if (sscanf(buf, "port=%d,", &p) == 1) {
4099
 
+                                               if (p > 0 && p < 65536) {
4100
 
+                                                       fport = p;
4101
 
+                                               }
4102
 
+                                       }
4103
 
+                               }
4104
 
                                sprintf(num, "HP=%d,", fport);
4105
 
                                strcat(tbuf, num);
4106
 
                        }
4107
 
@@ -2113,8 +2130,16 @@
4108
 
                        return 0;
4109
 
 
4110
 
                } else if (rc < 0) {
4111
 
+                       unsigned long err;
4112
 
+                       int cnt = 0;
4113
 
 
4114
 
-                       rfbLog("SSL: ssl_helper[%d]: SSL_accept() *FATAL: %d\n", getpid(), rc);
4115
 
+                       rfbLog("SSL: ssl_helper[%d]: SSL_accept() *FATAL: %d SSL FAILED\n", getpid(), rc);
4116
 
+                       while ((err = ERR_get_error()) != 0) {
4117
 
+                               rfbLog("SSL: %s\n", ERR_error_string(err, NULL));
4118
 
+                               if (cnt++ > 100) {
4119
 
+                                       break;
4120
 
+                               }
4121
 
+                       }
4122
 
                        return 0;
4123
 
 
4124
 
                } else if (dnow() > start + 3.0) {
4125
 
@@ -2157,9 +2182,18 @@
4126
 
                        }
4127
 
                } else {
4128
 
                        rfbLog("SSL: ssl_helper[%d]: accepted client %s x509 cert is:\n", getpid(), name);
4129
 
+#if LIBVNCSERVER_HAVE_X509_PRINT_EX_FP
4130
 
                        X509_print_ex_fp(stderr, x, 0, XN_FLAG_MULTILINE);
4131
 
+#endif
4132
 
                        if (cr != NULL) {
4133
 
+#if LIBVNCSERVER_HAVE_X509_PRINT_EX_FP
4134
 
                                X509_print_ex_fp(cr, x, 0, XN_FLAG_MULTILINE);
4135
 
+#else
4136
 
+                               rfbLog("** not compiled with libssl X509_print_ex_fp() function **\n");
4137
 
+                               if (users_list && strstr(users_list, "sslpeer=")) {
4138
 
+                                       rfbLog("** -users sslpeer= will not work! **\n");
4139
 
+                               }
4140
 
+#endif
4141
 
                                fclose(cr);
4142
 
                        }
4143
 
                }
4144
 
Index: ../ica/x11/x11vnc/help.c
4145
 
===================================================================
4146
 
--- ../ica/x11/x11vnc/help.c    (Revision 401)
4147
 
+++ ../ica/x11/x11vnc/help.c    (Arbeitskopie)
4148
 
@@ -128,6 +128,13 @@
4149
 
 "                       into two parts to be accessed via separate viewers by\n"
4150
 
 "                       running a separate x11vnc on each part.\n"
4151
 
 "\n"
4152
 
+"                       Use '-clip xinerama0' to clip to the first xinerama\n"
4153
 
+"                       sub-screen (if xinerama is active).  xinerama1 for the\n"
4154
 
+"                       2nd sub-screen, etc.  This way you don't need to figure\n"
4155
 
+"                       out the WxH+X+Y of the desired xinerama sub-screen.\n"
4156
 
+"                       screens are sorted in increasing distance from the\n"
4157
 
+"                       (0,0) origin (I.e. not the Xserver's order).\n"
4158
 
+"\n"
4159
 
 "-flashcmap             In 8bpp indexed color, let the installed colormap flash\n"
4160
 
 "                       as the pointer moves from window to window (slow).\n"
4161
 
 "                       Also try the -8to24 option to avoid flash altogether.\n"
4162
 
@@ -140,6 +147,11 @@
4163
 
 "                       a colormap histogram.  Example: -shiftcmap 240\n"
4164
 
 "-notruecolor           For 8bpp displays, force indexed color (i.e. a colormap)\n"
4165
 
 "                       even if it looks like 8bpp TrueColor (rare problem).\n"
4166
 
+"-advertise_truecolor   If the X11 display is indexed color, lie to clients\n"
4167
 
+"                       when they first connect by telling them it is truecolor.\n"
4168
 
+"                       To workaround RealVNC: inPF has colourMap but not 8bpp\n"
4169
 
+"                       Use '-advertise_truecolor reset' to reset client fb too.\n"
4170
 
+"\n"
4171
 
 "-visual n              This option probably does not do what you think.\n"
4172
 
 "                       It simply *forces* the visual used for the framebuffer;\n"
4173
 
 "                       this may be a bad thing... (e.g. messes up colors or\n"
4174
 
@@ -147,8 +159,10 @@
4175
 
 "                       workarounds.  n may be a decimal number, or 0x hex.\n"
4176
 
 "                       Run xdpyinfo(1) for the values.  One may also use\n"
4177
 
 "                       \"TrueColor\", etc. see <X11/X.h> for a list.  If the\n"
4178
 
-"                       string ends in \":m\" then for better or for worse the\n"
4179
 
-"                       visual depth is forced to be m.\n"
4180
 
+"                       string ends in \":m\" then for better or for worse\n"
4181
 
+"                       the visual depth is forced to be m.  You may want to\n"
4182
 
+"                       use -noshm when using this option (so XGetImage may\n"
4183
 
+"                       automatically translate the pixel data).\n"
4184
 
 "\n"
4185
 
 "-overlay               Handle multiple depth visuals on one screen, e.g. 8+24\n"
4186
 
 "                       and 24+8 overlay visuals (the 32 bits per pixel are\n"
4187
 
@@ -429,6 +443,46 @@
4188
 
 "                       Be careful about the location of this file if x11vnc\n"
4189
 
 "                       is running as root (e.g. via gdm(1), etc).\n"
4190
 
 "\n"
4191
 
+"\n"
4192
 
+"                       Repeater mode: Some services provide an intermediate\n"
4193
 
+"                       \"vnc repeater\": http://www.uvnc.com/addons/repeater.html\n"
4194
 
+"                       (and also http://koti.mbnet.fi/jtko/ for linux port)\n"
4195
 
+"                       that acts as a proxy / gateway.  Modes like these require\n"
4196
 
+"                       an initial string to be sent for the reverse connection\n"
4197
 
+"                       before the VNC protocol is started.  Here are the ways\n"
4198
 
+"                       to do this:\n"
4199
 
+"\n"
4200
 
+"                         -connect pre=some_string+host:port\n"
4201
 
+"                         -connect pre128=some_string+host:port\n"
4202
 
+"                         -connect repeater=ID:1234+host:port\n"
4203
 
+"                         -connect repeater=23.45.67.89::5501+host:port\n"
4204
 
+"\n"
4205
 
+"                       SSVNC notation is also supported:\n"
4206
 
+"\n"
4207
 
+"                         -connect repeater://host:port+ID:1234\n"
4208
 
+"\n"
4209
 
+"                       As with normal -connect usage, if the repeater port is\n"
4210
 
+"                       not supplied 5500 is assumed.\n"
4211
 
+"\n"
4212
 
+"                       The basic idea is between the special tag, e.g. \"pre=\"\n"
4213
 
+"                       and \"+\" is the pre-string to be sent.  Note that in\n"
4214
 
+"                       this case host:port is the repeater server, NOT the\n"
4215
 
+"                       vnc viewer.  Somehow the pre-string tells the repeater\n"
4216
 
+"                       server how to find the vnc viewer and connect you to it.\n"
4217
 
+"\n"
4218
 
+"                       In the case pre=some_string+host:port, \"some_string\"\n"
4219
 
+"                       is simply sent. In the case preNNN=some_string+host:port\n"
4220
 
+"                       \"some_string\" is sent in a null padded buffer of\n"
4221
 
+"                       length NNN.  repeater= is the same as pre250=, this is\n"
4222
 
+"                       the ultravnc repeater buffer size.\n"
4223
 
+"\n"
4224
 
+"                       Strings like \"\\n\" and \"\\r\", etc. are expanded to\n"
4225
 
+"                       newline and carriage return.  \"\\c\" is expanded to\n"
4226
 
+"                       \",\" since the connect string is comma separated.\n"
4227
 
+"\n"
4228
 
+"                       See also the -proxy option below for additional ways\n"
4229
 
+"                       to plumb reverse connections.\n"
4230
 
+"\n"
4231
 
 "-connect_or_exit str   As with -connect, except if none of the reverse\n"
4232
 
 "                       connections succeed, then x11vnc shutdowns immediately.\n"
4233
 
 "\n"
4234
 
@@ -896,6 +950,10 @@
4235
 
 "                       and so \"-ssl SAVE -redirect host:port\" can act as a\n"
4236
 
 "                       replacement for stunnel(1).\n"
4237
 
 "\n"
4238
 
+"                       This mode only allows one redirected connection.\n"
4239
 
+"                       The -forever option does not apply.  Use -inetd or\n"
4240
 
+"                       -loop for persistant service.\n"
4241
 
+"\n"
4242
 
 "-display WAIT:...      A special usage mode for the normal -display option.\n"
4243
 
 "                       Useful with -unixpw, but can be used independently\n"
4244
 
 "                       of it.  If the display string begins with WAIT: then\n"
4245
 
@@ -1531,8 +1589,8 @@
4246
 
 "\n"
4247
 
 "                       If you set the env. var REQ_ARGS='...' it will be\n"
4248
 
 "                       passed to openssl req(1).  A common use would be\n"
4249
 
-"                       REQ_ARGS='-days 730' to bump up the expiration date\n"
4250
 
-"                       (2 years in this case).\n"
4251
 
+"                       REQ_ARGS='-days 1095' to bump up the expiration date\n"
4252
 
+"                       (3 years in this case).\n"
4253
 
 "\n"
4254
 
 "-sslEncKey [pem]       Utility to encrypt an existing PEM file with a\n"
4255
 
 "                       passphrase you supply when prompted.  For that key to be\n"
4256
 
@@ -3075,8 +3133,8 @@
4257
 
 "-forcedpms             If the system supports the DPMS (Display Power\n"
4258
 
 "                       Management Signaling) extension, then try to keep the\n"
4259
 
 "                       monitor in a powered off state.  This is to prevent\n"
4260
 
-"                       nosey people at the physical display from viewing\n"
4261
 
-"                       what is on the screen.  Be sure lock the screen before\n"
4262
 
+"                       nosey people at the physical display from viewing what\n"
4263
 
+"                       is on the screen.  Be sure to lock the screen before\n"
4264
 
 "                       disconnecting.\n"
4265
 
 "\n"
4266
 
 "                       This method is far from bullet proof, e.g. suppose\n"
4267
 
@@ -3151,7 +3209,11 @@
4268
 
 "\n"
4269
 
 "-threads               Whether or not to use the threaded libvncserver\n"
4270
 
 "-nothreads             algorithm [rfbRunEventLoop] if libpthread is available\n"
4271
 
-"                       Default: %s\n"
4272
 
+"                       Default: %s.  NOTE:  The -threads mode is now\n"
4273
 
+"                       disabled due to its unstable behavior.  Not recommended,\n"
4274
 
+"                       but you can recompile with -DX11VNC_THREADED in\n"
4275
 
+"                       CPPFLAGS if you need to use it.  You can also set the\n"
4276
 
+"                       env. variable X11VNC_THREADED=1\n"
4277
 
 "\n"
4278
 
 "-fs f                  If the fraction of changed tiles in a poll is greater\n"
4279
 
 "                       than f, the whole screen is updated.  Default: %.2f\n"
4280
 
Index: ../ica/x11/x11vnc/options.c
4281
 
===================================================================
4282
 
--- ../ica/x11/x11vnc/options.c (Revision 401)
4283
 
+++ ../ica/x11/x11vnc/options.c (Arbeitskopie)
4284
 
@@ -114,6 +114,8 @@
4285
 
 int flash_cmap = 0;            /* follow installed colormaps */
4286
 
 int shift_cmap = 0;            /* ncells < 256 and needs shift of pixel values */
4287
 
 int force_indexed_color = 0;   /* whether to force indexed color for 8bpp */
4288
 
+int advertise_truecolor = 0;
4289
 
+int advertise_truecolor_reset = 0;
4290
 
 int cmap8to24 = 0;             /* -8to24 */
4291
 
 int xform24to32 = 0;           /* -24to32 */
4292
 
 char *cmap8to24_str = NULL;
4293
 
@@ -351,6 +353,7 @@
4294
 
  * poll times of 10-35ms, so maybe this value cuts the idle load by 2 or so.
4295
 
  */
4296
 
 int waitms = 20;
4297
 
+int got_waitms = 0;
4298
 
 double wait_ui = 2.0;
4299
 
 double slow_fb = 0.0;
4300
 
 double xrefresh = 0.0;
4301
 
@@ -414,7 +417,7 @@
4302
 
 
4303
 
 /* threaded vs. non-threaded (default) */
4304
 
 #if LIBVNCSERVER_HAVE_LIBPTHREAD && defined(X11VNC_THREADED)
4305
 
-int use_threads = 1;
4306
 
+int use_threads = 0;   /* not 1. now X11VNC_THREADED means enable it at all. */
4307
 
 #else
4308
 
 int use_threads = 0;
4309
 
 #endif
4310
 
Index: ../ica/x11/libvncserver/stats.c
4311
 
===================================================================
4312
 
--- ../ica/x11/libvncserver/stats.c     (Revision 401)
4313
 
+++ ../ica/x11/libvncserver/stats.c     (Arbeitskopie)
4314
 
@@ -103,6 +103,7 @@
4315
 
     case rfbEncodingZlibHex:            snprintf(buf, len, "zlibhex");     break;
4316
 
     case rfbEncodingUltra:              snprintf(buf, len, "ultra");       break;
4317
 
     case rfbEncodingZRLE:               snprintf(buf, len, "ZRLE");        break;
4318
 
+    case rfbEncodingZYWRLE:             snprintf(buf, len, "ZYWRLE");      break;
4319
 
     case rfbEncodingCache:              snprintf(buf, len, "cache");       break;
4320
 
     case rfbEncodingCacheEnable:        snprintf(buf, len, "cacheEnable"); break;
4321
 
     case rfbEncodingXOR_Zlib:           snprintf(buf, len, "xorZlib");     break;
4322
 
Index: ../ica/x11/libvncserver/rfbregion.c
4323
 
===================================================================
4324
 
--- ../ica/x11/libvncserver/rfbregion.c (Revision 401)
4325
 
+++ ../ica/x11/libvncserver/rfbregion.c (Arbeitskopie)
4326
 
@@ -620,8 +620,8 @@
4327
 
 sraRgnPopRect(sraRegion *rgn, sraRect *rect, unsigned long flags) {
4328
 
   sraSpan *vcurr, *hcurr;
4329
 
   sraSpan *vend, *hend;
4330
 
-  rfbBool right2left = flags & 2;
4331
 
-  rfbBool bottom2top = flags & 1;
4332
 
+  rfbBool right2left = (flags & 2) == 2;
4333
 
+  rfbBool bottom2top = (flags & 1) == 1;
4334
 
 
4335
 
   /* - Pick correct order */
4336
 
   if (bottom2top) {
4337
 
Index: ../ica/x11/libvncserver/zywrletemplate.c
4338
 
===================================================================
4339
 
--- ../ica/x11/libvncserver/zywrletemplate.c    (Revision 401)
4340
 
+++ ../ica/x11/libvncserver/zywrletemplate.c    (Arbeitskopie)
4341
 
@@ -41,16 +41,23 @@
4342
 
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4343
 
  ********************************************************************/
4344
 
 
4345
 
+/* Change Log:
4346
 
+     V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline
4347
 
+                            (Thanks Johannes Schindelin, author of LibVNC
4348
 
+                                                 Server/Client)
4349
 
+     V0.01 : 2007/02/06 : Initial release
4350
 
+*/
4351
 
+
4352
 
 /* #define ZYWRLE_ENCODE */
4353
 
 /* #define ZYWRLE_DECODE */
4354
 
 #define ZYWRLE_QUANTIZE
4355
 
 
4356
 
 /*
4357
 
-  [References]
4358
 
-   PLHarr:
4359
 
-     Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380.
4360
 
-   EZW:
4361
 
-     Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
4362
 
+[References]
4363
 
+ PLHarr:
4364
 
+   Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380.
4365
 
+ EZW:
4366
 
+   Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
4367
 
 */
4368
 
 
4369
 
 
4370
 
@@ -67,8 +74,8 @@
4371
 
 #define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP)
4372
 
 #define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP)
4373
 
 
4374
 
-/* Packing/Unpacking pixel stuffs. */
4375
 
-/*   Endian conversion stuffs. */
4376
 
+/* Packing/Unpacking pixel stuffs.
4377
 
+   Endian conversion stuffs. */
4378
 
 #undef S_0
4379
 
 #undef S_1
4380
 
 #undef L_0
4381
 
@@ -147,11 +154,9 @@
4382
 
        {0x0000F000,0x00000000,0x00000000},
4383
 
        {0x0000C000,0x00F0F0F0,0x00000000},
4384
 
        {0x0000C000,0x00C0C0C0,0x00F0F0F0},
4385
 
-/*
4386
 
-       {0x0000FF00,0x00000000,0x00000000},
4387
 
+/*     {0x0000FF00,0x00000000,0x00000000},
4388
 
        {0x0000FF00,0x00FFFFFF,0x00000000},
4389
 
-       {0x0000FF00,0x00FFFFFF,0x00FFFFFF},
4390
 
-*/
4391
 
+       {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */
4392
 
 };
4393
 
 #  else
4394
 
 /* Type B:Non liner quantization filter. */
4395
 
@@ -305,8 +310,8 @@
4396
 
 {
4397
 
        /* Piecewise-Linear Harr(PLHarr) */
4398
 
        int X0 = (int)*pX0, X1 = (int)*pX1;
4399
 
-       int orgX0=X0, orgX1=X1;
4400
 
-       if ((X0^X1) & 0x80) {
4401
 
+       int orgX0 = X0, orgX1 = X1;
4402
 
+       if ((X0 ^ X1) & 0x80) {
4403
 
                /* differ sign */
4404
 
                X1 += X0;
4405
 
                if (((X1^orgX1)&0x80)==0) {
4406
 
@@ -316,7 +321,7 @@
4407
 
        } else {
4408
 
                /* same sign */
4409
 
                X0 -= X1;
4410
 
-               if (((X0^orgX0) & 0x80) == 0) {
4411
 
+               if (((X0 ^ orgX0) & 0x80) == 0) {
4412
 
                        /* |X0| > |X1| */
4413
 
                        X1 += X0;       /* L = A */
4414
 
                }
4415
 
@@ -325,27 +330,26 @@
4416
 
        *pX1 = (signed char)X0;
4417
 
 }
4418
 
 /*
4419
 
-   1D-Wavelet transform.
4420
 
+ 1D-Wavelet transform.
4421
 
 
4422
 
-   In coefficients array, the famous 'pyramid' decomposition is well used.
4423
 
+ In coefficients array, the famous 'pyramid' decomposition is well used.
4424
 
 
4425
 
-   1D Model:
4426
 
-     |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
4427
 
-     |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
4428
 
+ 1D Model:
4429
 
+   |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
4430
 
+   |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
4431
 
 
4432
 
-   But this method needs line buffer because H/L is different position from X0/X1.
4433
 
-   So, I used 'interleave' decomposition instead of it.
4434
 
+ But this method needs line buffer because H/L is different position from X0/X1.
4435
 
+ So, I used 'interleave' decomposition instead of it.
4436
 
 
4437
 
-   1D Model:
4438
 
-     |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
4439
 
-     |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
4440
 
+ 1D Model:
4441
 
+   |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
4442
 
+   |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
4443
 
 
4444
 
-   In this method, H/L and X0/X1 is always same position.
4445
 
-   This lead us to more speed and less memory.
4446
 
-   Of cause, the result of both method is quite same
4447
 
-   because it's only difference that coefficient position.
4448
 
+ In this method, H/L and X0/X1 is always same position.
4449
 
+ This lead us to more speed and less memory.
4450
 
+ Of cause, the result of both method is quite same
4451
 
+ because it's only difference that coefficient position.
4452
 
 */
4453
 
-
4454
 
 static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel)
4455
 
 {
4456
 
        int s, ofs;
4457
 
@@ -389,11 +393,11 @@
4458
 
                for (y = 0; y < height / s; y++) {
4459
 
                        for (x = 0; x < width / s; x++) {
4460
 
                                /*
4461
 
-                                  these are same following code.
4462
 
-                                      pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1);
4463
 
-                                      ( round pH[x] with pM[x] bit )
4464
 
-                                  '&' operator isn't 'round' but is 'floor'.
4465
 
-                                  So, we must offset when pH[x] is negative.
4466
 
+                                these are same following code.
4467
 
+                                    pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1);
4468
 
+                                    ( round pH[x] with pM[x] bit )
4469
 
+                                '&' operator isn't 'round' but is 'floor'.
4470
 
+                                So, we must offset when pH[x] is negative.
4471
 
                                */
4472
 
                                if (((signed char*)pH)[0] & 0x80)
4473
 
                                        ((signed char*)pH)[0] += ~((signed char*)pM)[0];
4474
 
@@ -410,36 +414,35 @@
4475
 
 }
4476
 
 #  else
4477
 
 /*
4478
 
-   Type B:Non liner quantization filter.
4479
 
+ Type B:Non liner quantization filter.
4480
 
 
4481
 
-   Coefficients have Gaussian curve and smaller value which is
4482
 
-   large part of coefficients isn't more important than larger value.
4483
 
-   So, I use filter of Non liner quantize/dequantize table.
4484
 
-   In general, Non liner quantize formula is explained as following.
4485
 
+ Coefficients have Gaussian curve and smaller value which is
4486
 
+ large part of coefficients isn't more important than larger value.
4487
 
+ So, I use filter of Non liner quantize/dequantize table.
4488
 
+ In general, Non liner quantize formula is explained as following.
4489
 
 
4490
 
-      y=f(x)   = sign(x)*round( ((abs(x)/(2^7))^ r   )* 2^(bo-1) )*2^(8-bo)
4491
 
-      x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
4492
 
-   ( r:power coefficient  bi:effective MSB in input  bo:effective MSB in output )
4493
 
+    y=f(x)   = sign(x)*round( ((abs(x)/(2^7))^ r   )* 2^(bo-1) )*2^(8-bo)
4494
 
+    x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
4495
 
+ ( r:power coefficient  bi:effective MSB in input  bo:effective MSB in output )
4496
 
 
4497
 
-     r < 1.0 : Smaller value is more important than larger value.
4498
 
-     r > 1.0 : Larger value is more important than smaller value.
4499
 
-     r = 1.0 : Liner quantization which is same with EZW style.
4500
 
+   r < 1.0 : Smaller value is more important than larger value.
4501
 
+   r > 1.0 : Larger value is more important than smaller value.
4502
 
+   r = 1.0 : Liner quantization which is same with EZW style.
4503
 
 
4504
 
-   r = 0.75 is famous non liner quantization used in MP3 audio codec.
4505
 
-   In contrast to audio data, larger value is important in wavelet coefficients.
4506
 
-   So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
4507
 
+ r = 0.75 is famous non liner quantization used in MP3 audio codec.
4508
 
+ In contrast to audio data, larger value is important in wavelet coefficients.
4509
 
+ So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
4510
 
 
4511
 
-   As compared with EZW style liner quantization, this filter tended to be
4512
 
-   more sharp edge and be more compression rate but be more blocking noise and be less quality.
4513
 
-   Especially, the surface of graphic objects has distinguishable noise in middle quality mode.
4514
 
+ As compared with EZW style liner quantization, this filter tended to be
4515
 
+ more sharp edge and be more compression rate but be more blocking noise and be less quality.
4516
 
+ Especially, the surface of graphic objects has distinguishable noise in middle quality mode.
4517
 
 
4518
 
-   We need only quantized-dequantized(filtered) value rather than quantized value itself
4519
 
-   because all values are packed or palette-lized in later ZRLE section.
4520
 
-   This lead us not to need to modify client decoder when we change
4521
 
-   the filtering procedure in future.
4522
 
-   Client only decodes coefficients given by encoder.
4523
 
+ We need only quantized-dequantized(filtered) value rather than quantized value itself
4524
 
+ because all values are packed or palette-lized in later ZRLE section.
4525
 
+ This lead us not to need to modify client decoder when we change
4526
 
+ the filtering procedure in future.
4527
 
+ Client only decodes coefficients given by encoder.
4528
 
 */
4529
 
-
4530
 
 static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l)
4531
 
 {
4532
 
        int r, s;
4533
 
@@ -485,7 +488,7 @@
4534
 
                pTop = pBuf;
4535
 
                pEnd = pBuf+width;
4536
 
                s = 1<<l;
4537
 
-               while(pTop < pEnd) {
4538
 
+               while (pTop < pEnd) {
4539
 
                        WaveletLevel(pTop, height,l, width);
4540
 
                        pTop += s;
4541
 
                }
4542
 
@@ -494,12 +497,13 @@
4543
 
 }
4544
 
 #endif
4545
 
 #ifdef ZYWRLE_DECODE
4546
 
-static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
4547
 
+static InlineX void InvWavelet(int* pBuf, int width, int height, int level)
4548
 
+{
4549
 
        int l, s;
4550
 
        int* pTop;
4551
 
        int* pEnd;
4552
 
 
4553
 
-       for (l = level-1; l >= 0; l--) {
4554
 
+       for (l = level - 1; l >= 0; l--) {
4555
 
                pTop = pBuf;
4556
 
                pEnd = pBuf+width;
4557
 
                s = 1<<l;
4558
 
@@ -518,8 +522,8 @@
4559
 
 }
4560
 
 #endif
4561
 
 
4562
 
-/* Load/Save coefficients stuffs. */
4563
 
-/* Coefficients manages as 24 bits little-endian pixel. */
4564
 
+/* Load/Save coefficients stuffs.
4565
 
+ Coefficients manages as 24 bits little-endian pixel. */
4566
 
 #define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \
4567
 
        R = ((signed char*)pSrc)[2];    \
4568
 
        G = ((signed char*)pSrc)[1];    \
4569
 
@@ -532,25 +536,22 @@
4570
 
 }
4571
 
 
4572
 
 /*
4573
 
-   RGB <=> YUV conversion stuffs.
4574
 
-   YUV coversion is explained as following formula in strict meaning:
4575
 
-     Y =  0.299R + 0.587G + 0.114B (   0<=Y<=255)
4576
 
-     U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
4577
 
-     V =  0.500R - 0.419G - 0.081B (-128<=V<=127)
4578
 
+ RGB <=> YUV conversion stuffs.
4579
 
+ YUV coversion is explained as following formula in strict meaning:
4580
 
+   Y =  0.299R + 0.587G + 0.114B (   0<=Y<=255)
4581
 
+   U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
4582
 
+   V =  0.500R - 0.419G - 0.081B (-128<=V<=127)
4583
 
 
4584
 
-   I use simple conversion RCT(reversible color transform) which is described
4585
 
-   in JPEG-2000 specification.
4586
 
-     Y = (R + 2G + B)/4 (   0<=Y<=255)
4587
 
-     U = B-G (-256<=U<=255)
4588
 
-     V = R-G (-256<=V<=255)
4589
 
+ I use simple conversion RCT(reversible color transform) which is described
4590
 
+ in JPEG-2000 specification.
4591
 
+   Y = (R + 2G + B)/4 (   0<=Y<=255)
4592
 
+   U = B-G (-256<=U<=255)
4593
 
+   V = R-G (-256<=V<=255)
4594
 
 */
4595
 
-
4596
 
 #define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x)))
4597
 
-       /*
4598
 
-          RCT is N-bit RGB to N-bit Y and N+1-bit UV.
4599
 
-          For make Same N-bit, UV is lossy.
4600
 
-          More exact PLHarr, we reduce to odd range(-127<=x<=127).
4601
 
-       */
4602
 
+       /* RCT is N-bit RGB to N-bit Y and N+1-bit UV.
4603
 
+        For make Same N-bit, UV is lossy.
4604
 
+        More exact PLHarr, we reduce to odd range(-127<=x<=127). */
4605
 
 #define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \
4606
 
        Y = (R+(G<<1)+B)>>2;    \
4607
 
        U =  B-G;       \
4608
 
@@ -581,71 +582,77 @@
4609
 
 }
4610
 
 
4611
 
 /*
4612
 
-   coefficient packing/unpacking stuffs.
4613
 
-   Wavelet transform makes 4 sub coefficient image from 1 original image.
4614
 
+ coefficient packing/unpacking stuffs.
4615
 
+ Wavelet transform makes 4 sub coefficient image from 1 original image.
4616
 
 
4617
 
-   model with pyramid decomposition:
4618
 
-     +------+------+
4619
 
-     |      |      |
4620
 
-     |  L   |  Hx  |
4621
 
-     |      |      |
4622
 
-     +------+------+
4623
 
-     |      |      |
4624
 
-     |  H   |  Hxy |
4625
 
-     |      |      |
4626
 
-     +------+------+
4627
 
+ model with pyramid decomposition:
4628
 
+   +------+------+
4629
 
+   |      |      |
4630
 
+   |  L   |  Hx  |
4631
 
+   |      |      |
4632
 
+   +------+------+
4633
 
+   |      |      |
4634
 
+   |  H   |  Hxy |
4635
 
+   |      |      |
4636
 
+   +------+------+
4637
 
 
4638
 
-   So, we must transfer each sub images individually in strict meaning.
4639
 
-   But at least ZRLE meaning, following one decompositon image is same as
4640
 
-   avobe individual sub image. I use this format.
4641
 
-   (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
4642
 
-    for simplified procedure for any wavelet level.)
4643
 
+ So, we must transfer each sub images individually in strict meaning.
4644
 
+ But at least ZRLE meaning, following one decompositon image is same as
4645
 
+ avobe individual sub image. I use this format.
4646
 
+ (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
4647
 
+  for simplified procedure for any wavelet level.)
4648
 
 
4649
 
-     +------+------+
4650
 
-     |      L      |
4651
 
-     +------+------+
4652
 
-     |      Hx     |
4653
 
-     +------+------+
4654
 
-     |      Hy     |
4655
 
-     +------+------+
4656
 
-     |      Hxy    |
4657
 
-     +------+------+
4658
 
+   +------+------+
4659
 
+   |      L      |
4660
 
+   +------+------+
4661
 
+   |      Hx     |
4662
 
+   +------+------+
4663
 
+   |      Hy     |
4664
 
+   +------+------+
4665
 
+   |      Hxy    |
4666
 
+   +------+------+
4667
 
 */
4668
 
+#define INC_PTR(data) \
4669
 
+       data++; \
4670
 
+       if( data-pData >= (w+uw) ){     \
4671
 
+               data += scanline-(w+uw);        \
4672
 
+               pData = data;   \
4673
 
+       }
4674
 
 
4675
 
-#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,TRANS)    \
4676
 
+#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS)    \
4677
 
        pH = pBuf;      \
4678
 
        s = 2<<level;   \
4679
 
        if (r & 0x01)   \
4680
 
                pH +=  s>>1;    \
4681
 
        if (r & 0x02)   \
4682
 
-               pH += (s>>1)*width;     \
4683
 
-       pEnd = pH+height*width; \
4684
 
+               pH += (s>>1)*w; \
4685
 
+       pEnd = pH+h*w;  \
4686
 
        while (pH < pEnd) {     \
4687
 
-               pLine = pH+width;       \
4688
 
+               pLine = pH+w;   \
4689
 
                while (pH < pLine) {    \
4690
 
                        TRANS   \
4691
 
-                       data++; \
4692
 
+                       INC_PTR(data)   \
4693
 
                        pH += s;        \
4694
 
                }       \
4695
 
-               pH += (s-1)*width;      \
4696
 
+               pH += (s-1)*w;  \
4697
 
        }
4698
 
 
4699
 
-#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,level)      \
4700
 
-       ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);)
4701
 
+#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level)     \
4702
 
+       ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);)
4703
 
 
4704
 
-#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,level)    \
4705
 
-       ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);)
4706
 
+#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level)   \
4707
 
+       ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);)
4708
 
 
4709
 
 #define ZYWRLE_SAVE_UNALIGN(data,TRANS)        \
4710
 
        pTop = pBuf+w*h;        \
4711
 
-       pEnd = pTop + (w+uw)*(h+uh)-w*h;        \
4712
 
+       pEnd = pBuf + (w+uw)*(h+uh);    \
4713
 
        while (pTop < pEnd) {   \
4714
 
                TRANS   \
4715
 
-               data++; \
4716
 
+               INC_PTR(data)   \
4717
 
                pTop++; \
4718
 
        }
4719
 
 
4720
 
-#define ZYWRLE_LOAD_UNALIGN(data,pData,TRANS)  \
4721
 
+#define ZYWRLE_LOAD_UNALIGN(data,TRANS)        \
4722
 
        pTop = pBuf+w*h;        \
4723
 
        if (uw) {       \
4724
 
                pData=         data + w;        \
4725
 
@@ -718,8 +725,7 @@
4726
 
 }
4727
 
 #endif
4728
 
 #ifdef ZYWRLE_DECODE
4729
 
-static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline)
4730
 
-{
4731
 
+static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) {
4732
 
        int R, G, B;
4733
 
        int Y, U, V;
4734
 
        int* pLine;
4735
 
@@ -740,15 +746,14 @@
4736
 
 #endif
4737
 
 
4738
 
 #ifdef ZYWRLE_ENCODE
4739
 
-PIXEL_T* ZYWRLE_ANALYZE (PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf)
4740
 
-{
4741
 
+PIXEL_T* ZYWRLE_ANALYZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) {
4742
 
        int l;
4743
 
        int uw = w;
4744
 
        int uh = h;
4745
 
        int* pTop;
4746
 
        int* pEnd;
4747
 
        int* pLine;
4748
 
-       PIXEL_T* pSrc;
4749
 
+       PIXEL_T* pData;
4750
 
        int R, G, B;
4751
 
        int s;
4752
 
        int* pH;
4753
 
@@ -759,15 +764,16 @@
4754
 
        uw -= w;
4755
 
        uh -= h;
4756
 
 
4757
 
-       ZYWRLE_LOAD_UNALIGN(src,pSrc,*(PIXEL_T*)pTop=*pSrc;)
4758
 
+       pData = dst;
4759
 
+       ZYWRLE_LOAD_UNALIGN(src,*(PIXEL_T*)pTop=*pData;)
4760
 
        ZYWRLE_RGBYUV(pBuf, src, w, h, scanline);
4761
 
        Wavelet(pBuf, w, h, level);
4762
 
        for (l = 0; l < level; l++) {
4763
 
-               ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, l);
4764
 
-               ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, l);
4765
 
-               ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, l);
4766
 
-               if (l == level-1) {
4767
 
-                       ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, l);
4768
 
+               ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, scanline, l);
4769
 
+               ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, scanline, l);
4770
 
+               ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, scanline, l);
4771
 
+               if (l == level - 1) {
4772
 
+                       ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, scanline, l);
4773
 
                }
4774
 
        }
4775
 
        ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;)
4776
 
@@ -783,7 +789,7 @@
4777
 
        int* pTop;
4778
 
        int* pEnd;
4779
 
        int* pLine;
4780
 
-       PIXEL_T* pDst;
4781
 
+       PIXEL_T* pData;
4782
 
        int R, G, B;
4783
 
        int s;
4784
 
        int* pH;
4785
 
@@ -794,18 +800,19 @@
4786
 
        uw -= w;
4787
 
        uh -= h;
4788
 
 
4789
 
+       pData = src;
4790
 
        for (l = 0; l < level; l++) {
4791
 
-               ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, l);
4792
 
-               ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, l);
4793
 
-               ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, l);
4794
 
-               if (l == level-1) {
4795
 
-                       ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, l);
4796
 
+               ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, scanline, l);
4797
 
+               ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, scanline, l);
4798
 
+               ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, scanline, l);
4799
 
+               if (l == level - 1) {
4800
 
+                       ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, scanline, l);
4801
 
                }
4802
 
        }
4803
 
        ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;)
4804
 
        InvWavelet(pBuf, w, h, level);
4805
 
        ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline);
4806
 
-       ZYWRLE_LOAD_UNALIGN(dst,pDst,*pDst=*(PIXEL_T*)pTop;)
4807
 
+       ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;)
4808
 
        return src;
4809
 
 }
4810
 
 #endif
4811
 
Index: ../ica/x11/libvncserver/rfbserver.c
4812
 
===================================================================
4813
 
--- ../ica/x11/libvncserver/rfbserver.c (Revision 401)
4814
 
+++ ../ica/x11/libvncserver/rfbserver.c (Arbeitskopie)
4815
 
@@ -2631,7 +2631,7 @@
4816
 
            rows = (h-1)/cl->correMaxHeight+1;
4817
 
            nUpdateRegionRects += rectsPerRow*rows;
4818
 
         }
4819
 
-       sraRgnReleaseIterator(i);
4820
 
+       sraRgnReleaseIterator(i); i=NULL;
4821
 
     } else if (cl->preferredEncoding == rfbEncodingUltra) {
4822
 
         nUpdateRegionRects = 0;
4823
 
         
4824
 
@@ -2645,7 +2645,7 @@
4825
 
                 rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate");
4826
 
             nUpdateRegionRects += (((h-1) / (ULTRA_MAX_SIZE( w ) / w)) + 1);
4827
 
           }
4828
 
-        sraRgnReleaseIterator(i);
4829
 
+        sraRgnReleaseIterator(i); i=NULL;
4830
 
 #ifdef LIBVNCSERVER_HAVE_LIBZ
4831
 
     } else if (cl->preferredEncoding == rfbEncodingZlib) {
4832
 
        nUpdateRegionRects = 0;
4833
 
@@ -2660,7 +2660,7 @@
4834
 
                 rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate");
4835
 
            nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1);
4836
 
        }
4837
 
-       sraRgnReleaseIterator(i);
4838
 
+       sraRgnReleaseIterator(i); i=NULL;
4839
 
 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
4840
 
     } else if (cl->preferredEncoding == rfbEncodingTight) {
4841
 
        nUpdateRegionRects = 0;
4842
 
@@ -2681,7 +2681,7 @@
4843
 
            }
4844
 
            nUpdateRegionRects += n;
4845
 
        }
4846
 
-       sraRgnReleaseIterator(i);
4847
 
+       sraRgnReleaseIterator(i); i=NULL;
4848
 
 #endif
4849
 
 #endif
4850
 
     } else {
4851
 
@@ -2806,6 +2806,10 @@
4852
 
 #endif
4853
 
         }
4854
 
     }
4855
 
+    if (i) {
4856
 
+        sraRgnReleaseIterator(i);
4857
 
+        i = NULL;
4858
 
+    }
4859
 
 
4860
 
     if ( nUpdateRegionRects == 0xFFFF &&
4861
 
         !rfbSendLastRectMarker(cl) )
4862
 
@@ -3062,12 +3066,20 @@
4863
 
                            int nColours)
4864
 
 {
4865
 
     char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];
4866
 
-    rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;
4867
 
-    uint16_t *rgb = (uint16_t *)(&buf[sz_rfbSetColourMapEntriesMsg]);
4868
 
+    char *wbuf = buf;
4869
 
+    rfbSetColourMapEntriesMsg *scme;
4870
 
+    uint16_t *rgb;
4871
 
     rfbColourMap* cm = &cl->screen->colourMap;
4872
 
-    
4873
 
     int i, len;
4874
 
 
4875
 
+    if (nColours > 256) {
4876
 
+       /* some rare hardware has, e.g., 4096 colors cells: PseudoColor:12 */
4877
 
+       wbuf = (char *) malloc(sz_rfbSetColourMapEntriesMsg + nColours * 3 * 2);
4878
 
+    }
4879
 
+
4880
 
+    scme = (rfbSetColourMapEntriesMsg *)wbuf;
4881
 
+    rgb = (uint16_t *)(&wbuf[sz_rfbSetColourMapEntriesMsg]);
4882
 
+
4883
 
     scme->type = rfbSetColourMapEntries;
4884
 
 
4885
 
     scme->firstColour = Swap16IfLE(firstColour);
4886
 
@@ -3091,13 +3103,15 @@
4887
 
 
4888
 
     len += nColours * 3 * 2;
4889
 
 
4890
 
-    if (rfbWriteExact(cl, buf, len) < 0) {
4891
 
+    if (rfbWriteExact(cl, wbuf, len) < 0) {
4892
 
        rfbLogPerror("rfbSendSetColourMapEntries: write");
4893
 
        rfbCloseClient(cl);
4894
 
+        if (wbuf != buf) free(wbuf);
4895
 
        return FALSE;
4896
 
     }
4897
 
 
4898
 
     rfbStatRecordMessageSent(cl, rfbSetColourMapEntries, len, len);
4899
 
+    if (wbuf != buf) free(wbuf);
4900
 
     return TRUE;
4901
 
 }
4902