static int handle_subwin_resize(char *msg) { int new_x, new_y; int i, check = 10, ms = 250; /* 2.5 secs total... */ if (msg) {} /* unused vars warning: */ if (! subwin) { return 0; /* hmmm... */ } if (! valid_window(subwin, NULL, 0)) { rfbLogEnable(1); rfbLog("subwin 0x%lx went away!\n", subwin); X_UNLOCK; clean_up_exit(1); } if (! get_window_size(subwin, &new_x, &new_y)) { rfbLogEnable(1); rfbLog("could not get size of subwin 0x%lx\n", subwin); X_UNLOCK; clean_up_exit(1); } if (wdpy_x == new_x && wdpy_y == new_y) { /* no change */ return 0; } /* window may still be changing (e.g. drag resize) */ for (i=0; i < check; i++) { int newer_x, newer_y; usleep(ms * 1000); if (! get_window_size(subwin, &newer_x, &newer_y)) { rfbLogEnable(1); rfbLog("could not get size of subwin 0x%lx\n", subwin); clean_up_exit(1); } if (new_x == newer_x && new_y == newer_y) { /* go for it... */ break; } else { rfbLog("subwin 0x%lx still changing size...\n", subwin); new_x = newer_x; new_y = newer_y; } } rfbLog("subwin 0x%lx new size: x: %d -> %d, y: %d -> %d\n", subwin, wdpy_x, new_x, wdpy_y, new_y); rfbLog("calling handle_xrandr_change() for resizing\n"); X_UNLOCK; handle_xrandr_change(new_x, new_y); return 1; }
void check_stunnel(void) { static time_t last_check = 0; time_t now = time(NULL); if (last_check + 3 >= now) { return; } last_check = now; /* double check that stunnel is still running: */ if (stunnel_pid > 0) { int status; #ifdef SSLCMDS waitpid(stunnel_pid, &status, WNOHANG); #endif if (kill(stunnel_pid, 0) != 0) { #ifdef SSLCMDS waitpid(stunnel_pid, &status, WNOHANG); #endif rfbLog("stunnel subprocess %d died.\n", stunnel_pid); stunnel_pid = 0; clean_up_exit(1); } } }
static void _avahi_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { char *new_name; avahi_service_t *svc = (avahi_service_t *)userdata; if (db) fprintf(stderr, "in _avahi_entry_group_callback %d 0x%p\n", state, svc); if (g != _group && _group != NULL) { rfbLog("avahi_entry_group_callback fatal error (group).\n"); clean_up_exit(1); } if (userdata == NULL) { rfbLog("avahi_entry_group_callback fatal error (userdata).\n"); clean_up_exit(1); } switch(state) { case AVAHI_ENTRY_GROUP_ESTABLISHED: rfbLog("Avahi group %s established.\n", svc->name); #if 0 /* is this the segv problem? */ free(svc); #endif break; case AVAHI_ENTRY_GROUP_COLLISION: new_name = avahi_alternative_service_name(svc->name); _avahi_create_services(new_name, svc->host, svc->port); rfbLog("Avahi Entry group collision\n"); avahi_free(new_name); break; case AVAHI_ENTRY_GROUP_FAILURE: rfbLog("Avahi Entry group failure: %s\n", avahi_strerror(avahi_client_errno( avahi_entry_group_get_client(g)))); break; default: break; } if (db) fprintf(stderr, "out _avahi_entry_group_callback\n"); }
static void handle_xrandr_change(int new_x, int new_y) { rfbClientIteratorPtr iter; rfbClientPtr cl; RAWFB_RET_VOID /* assumes no X_LOCK */ /* sanity check xrandr_mode */ if (! xrandr_mode) { xrandr_mode = strdup("default"); } else if (! known_xrandr_mode(xrandr_mode)) { free(xrandr_mode); xrandr_mode = strdup("default"); } rfbLog("xrandr_mode: %s\n", xrandr_mode); if (!strcmp(xrandr_mode, "exit")) { close_all_clients(); rfbLog(" shutting down due to XRANDR event.\n"); clean_up_exit(0); } if (!strcmp(xrandr_mode, "newfbsize") && screen) { iter = rfbGetClientIterator(screen); while( (cl = rfbClientIteratorNext(iter)) ) { if (cl->useNewFBSize) { continue; } rfbLog(" closing client %s (no useNewFBSize" " support).\n", cl->host); rfbCloseClient(cl); rfbClientConnectionGone(cl); } rfbReleaseClientIterator(iter); } /* default, resize, and newfbsize create a new fb: */ rfbLog("check_xrandr_event: trying to create new framebuffer...\n"); if (new_x < wdpy_x || new_y < wdpy_y) { check_black_fb(); } do_new_fb(1); rfbLog("check_xrandr_event: fb WxH: %dx%d\n", wdpy_x, wdpy_y); }
static void init_freqtab(char *file) { char *p, *q, *dir, *file2; char line[1024], inc[1024]; char *text, *str; int size = 0, maxn, extra, currn; FILE *in1, *in2; static int v = 1; if (quiet) { v = 0; } /* YUCK */ dir = strdup(file); q = strrchr(dir, '/'); if (q) { *(q+1) = '\0'; } else { free(dir); dir = strdup("./"); } file2 = (char *) malloc(strlen(dir) + 1024 + 1); in1 = fopen(file, "r"); if (in1 == NULL) { rfbLog("error opening freqtab: %s\n", file); clean_up_exit(1); } if (v) fprintf(stderr, "loading frequencies from: %s\n", file); while (fgets(line, 1024, in1) != NULL) { char *lb; char line2[1024]; size += strlen(line); lb = lblanks(line); if (strstr(lb, "#include") == lb && sscanf(lb, "#include %s", inc) == 1) { char *q, *s = inc; if (s[0] == '"') { s++; } q = strrchr(s, '"'); if (q) { *q = '\0'; } sprintf(file2, "%s%s", dir, s); in2 = fopen(file2, "r"); if (in2 == NULL) { rfbLog("error opening freqtab include: %s %s\n", line, file2); clean_up_exit(1); } if (v) fprintf(stderr, "loading frequencies from: %s\n", file2); while (fgets(line2, 1024, in2) != NULL) { size += strlen(line2); } fclose(in2); } } fclose(in1); size = 4*(size + 10000); text = (char *) malloc(size); text[0] = '\0'; in1 = fopen(file, "r"); if (in1 == NULL) { rfbLog("error opening freqtab: %s\n", file); clean_up_exit(1); } while (fgets(line, 1024, in1) != NULL) { char *lb; char line2[1024]; lb = lblanks(line); if (lb[0] == '[') { strcat(text, lb); } else if (strstr(lb, "freq")) { strcat(text, lb); } else if (strstr(lb, "#include") == lb && sscanf(lb, "#include %s", inc) == 1) { char *lb2; char *q, *s = inc; if (s[0] == '"') { s++; } q = strrchr(s, '"'); if (q) { *q = '\0'; } sprintf(file2, "%s%s", dir, s); in2 = fopen(file2, "r"); if (in2 == NULL) { rfbLog("error opening freqtab include: %s %s\n", line, file2); clean_up_exit(1); } while (fgets(line2, 1024, in2) != NULL) { lb2 = lblanks(line2); if (lb2[0] == '[') { strcat(text, lb2); } else if (strstr(lb2, "freq")) { strcat(text, lb2); } if ((int) strlen(text) > size/2) { break; } } fclose(in2); } if ((int) strlen(text) > size/2) { break; } } fclose(in1); if (0) fprintf(stderr, "%s", text); str = strdup(text); p = strtok(str, "\n"); maxn = -1; extra = 0; while (p) { if (p[0] == '[') { int ok = 1; q = p+1; while (*q) { if (*q == ']') { break; } if (! isdigit((unsigned char) (*q))) { if (0) fprintf(stderr, "extra: %s\n", p); extra++; ok = 0; break; } q++; } if (ok) { int n; if (sscanf(p, "[%d]", &n) == 1) { if (n > maxn) { maxn = n; } if (0) fprintf(stderr, "maxn: %d %d\n", maxn, n); } } } p = strtok(NULL, "\n"); } free(str); str = strdup(text); p = strtok(str, "\n"); extra = 0; currn = 0; if (v) fprintf(stderr, "\nname\tstation\tfreq (KHz)\n"); while (p) { if (p[0] == '[') { int ok = 1; strncpy(line, p, 100); q = p+1; while (*q) { if (*q == ']') { break; } if (! isdigit((unsigned char) (*q))) { extra++; currn = maxn + extra; ok = 0; break; } q++; } if (ok) { int n; if (sscanf(p, "[%d]", &n) == 1) { currn = n; } } } if (strstr(p, "freq") && (q = strchr(p, '=')) != NULL) { int n; q = lblanks(q+1); if (sscanf(q, "%d", &n) == 1) { if (currn >= 0 && currn < CHANNEL_MAX) { if (v) fprintf(stderr, "%s\t%d\t%d\n", line, currn, n); custom_freq[currn] = (unsigned long) n; if (last_freq == 0) { last_freq = custom_freq[currn]; } } } } p = strtok(NULL, "\n"); } if (v) fprintf(stderr, "\n"); v = 0; free(str); free(text); free(dir); free(file2); }
static int XIOerr(Display *d) { static int reopen = 0, rmax = 1; X_UNLOCK; if (getenv("X11VNC_REOPEN_DISPLAY")) { rmax = atoi(getenv("X11VNC_REOPEN_DISPLAY")); } #if !NO_X11 if (reopen < rmax && getenv("X11VNC_REOPEN_DISPLAY")) { int db = getenv("X11VNC_REOPEN_DEBUG") ? 1 : 0; int sleepmax = 10, i; Display *save_dpy = dpy; char *dstr = strdup(DisplayString(save_dpy)); reopen++; if (getenv("X11VNC_REOPEN_SLEEP_MAX")) { sleepmax = atoi(getenv("X11VNC_REOPEN_SLEEP_MAX")); } rfbLog("*** XIO error: Trying to reopen[%d/%d] display '%s'\n", reopen, rmax, dstr); rfbLog("*** XIO error: Note the reopened state may be unstable.\n"); for (i=0; i < sleepmax; i++) { usleep (1000 * 1000); dpy = XOpenDisplay_wr(dstr); rfbLog("dpy[%d/%d]: %p\n", i+1, sleepmax, dpy); if (dpy) { break; } } last_open_xdisplay = time(NULL); if (dpy) { rfbLog("*** XIO error: Reopened display '%s' successfully.\n", dstr); if (db) rfbLog("*** XIO error: '%s' 0x%x\n", dstr, dpy); scr = DefaultScreen(dpy); rootwin = RootWindow(dpy, scr); if (db) rfbLog("*** XIO error: disable_grabserver\n"); disable_grabserver(dpy, 0); if (db) rfbLog("*** XIO error: xrecord\n"); zerodisp_xrecord(); initialize_xrecord(); if (db) rfbLog("*** XIO error: xdamage\n"); create_xdamage_if_needed(1); if (db) rfbLog("*** XIO error: do_new_fb\n"); if (using_shm) { if (db) rfbLog("*** XIO error: clean_shm\n"); clean_shm(1); } do_new_fb(1); if (db) rfbLog("*** XIO error: check_xevents\n"); check_xevents(1); /* sadly, we can never return... */ if (db) rfbLog("*** XIO error: watch_loop\n"); watch_loop(); clean_up_exit(1); } } #endif interrupted(-1); if (d) {} /* unused vars warning: */ return (*XIOerr_def)(d); }
int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport) { #ifdef SSLCMDS char extra[] = ":/usr/sbin:/usr/local/sbin:/dist/sbin"; char *path, *p, *exe; char *stunnel_path = NULL; struct stat verify_buf; struct stat crl_buf; int status, tmp_pem = 0; if (stunnel_pid) { stop_stunnel(); } stunnel_pid = 0; path = getenv("PATH"); if (! path) { path = strdup(extra+1); } else { char *pt = path; path = (char *) malloc(strlen(path)+strlen(extra)+1); if (! path) { return 0; } strcpy(path, pt); strcat(path, extra); } exe = (char *) malloc(strlen(path) + 1 + strlen("stunnel4") + 1); p = strtok(path, ":"); exe[0] = '\0'; while (p) { struct stat sbuf; sprintf(exe, "%s/%s", p, "stunnel4"); if (! stunnel_path && stat(exe, &sbuf) == 0) { if (! S_ISDIR(sbuf.st_mode)) { stunnel_path = exe; break; } } sprintf(exe, "%s/%s", p, "stunnel"); if (! stunnel_path && stat(exe, &sbuf) == 0) { if (! S_ISDIR(sbuf.st_mode)) { stunnel_path = exe; break; } } p = strtok(NULL, ":"); } if (path) { free(path); } if (getenv("STUNNEL_PROG")) { free(exe); exe = strdup(getenv("STUNNEL_PROG")); stunnel_path = exe; } if (! stunnel_path) { free(exe); return 0; } if (stunnel_path[0] == '\0') { free(exe); return 0; } /* stunnel */ if (no_external_cmds || !cmd_ok("stunnel")) { rfbLogEnable(1); rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n"); rfbLog(" \"%s\"\n", stunnel_path); rfbLog(" exiting.\n"); clean_up_exit(1); } if (! quiet) { rfbLog("\n"); rfbLog("starting ssl tunnel: %s %d -> %d\n", stunnel_path, stunnel_port, x11vnc_port); } if (stunnel_pem && strstr(stunnel_pem, "SAVE") == stunnel_pem) { stunnel_pem = get_saved_pem(stunnel_pem, 1); if (! stunnel_pem) { rfbLog("start_stunnel: could not create or open" " saved PEM.\n"); clean_up_exit(1); } } else if (!stunnel_pem) { stunnel_pem = create_tmp_pem(NULL, 0); if (! stunnel_pem) { rfbLog("start_stunnel: could not create temporary," " self-signed PEM.\n"); clean_up_exit(1); } tmp_pem = 1; if (getenv("X11VNC_SHOW_TMP_PEM")) { FILE *in = fopen(stunnel_pem, "r"); if (in != NULL) { char line[128]; fprintf(stderr, "\n"); while (fgets(line, 128, in) != NULL) { fprintf(stderr, "%s", line); } fprintf(stderr, "\n"); fclose(in); } } } if (ssl_verify) { char *file = get_ssl_verify_file(ssl_verify); if (file) { ssl_verify = file; } if (stat(ssl_verify, &verify_buf) != 0) { rfbLog("stunnel: %s does not exist.\n", ssl_verify); clean_up_exit(1); } } if (ssl_crl) { if (stat(ssl_crl, &crl_buf) != 0) { rfbLog("stunnel: %s does not exist.\n", ssl_crl); clean_up_exit(1); } } stunnel_pid = fork(); if (stunnel_pid < 0) { stunnel_pid = 0; free(exe); return 0; } if (stunnel_pid == 0) { FILE *in; char fd[20]; int i; char *st_if = getenv("STUNNEL_LISTEN"); if (st_if == NULL) { st_if = ""; } else { st_if = (char *) malloc(strlen(st_if) + 2); sprintf(st_if, "%s:", getenv("STUNNEL_LISTEN")); } for (i=3; i<256; i++) { close(i); } if (use_stunnel == 3) { char sp[30], xp[30], *a = NULL; char *st = stunnel_path; char *pm = stunnel_pem; char *sv = ssl_verify; sprintf(sp, "%d", stunnel_port); sprintf(xp, "%d", x11vnc_port); if (ssl_verify) { if(S_ISDIR(verify_buf.st_mode)) { a = "-a"; } else { a = "-A"; } } if (ssl_crl) { rfbLog("stunnel: stunnel3 does not support CRL. %s\n", ssl_crl); clean_up_exit(1); } if (stunnel_pem && ssl_verify) { /* XXX double check -v 2 */ execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", "-p", pm, a, sv, "-v", "2", (char *) NULL); } else if (stunnel_pem && !ssl_verify) { execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", "-p", pm, (char *) NULL); } else if (!stunnel_pem && ssl_verify) { execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", a, sv, "-v", "2", (char *) NULL); } else { execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", (char *) NULL); } exit(1); } in = tmpfile(); if (! in) { exit(1); } fprintf(in, "foreground = yes\n"); fprintf(in, "pid =\n"); if (stunnel_pem) { fprintf(in, "cert = %s\n", stunnel_pem); } if (ssl_crl) { if(S_ISDIR(crl_buf.st_mode)) { fprintf(in, "CRLpath = %s\n", ssl_crl); } else { fprintf(in, "CRLfile = %s\n", ssl_crl); } } if (ssl_verify) { if(S_ISDIR(verify_buf.st_mode)) { fprintf(in, "CApath = %s\n", ssl_verify); } else { fprintf(in, "CAfile = %s\n", ssl_verify); } fprintf(in, "verify = 2\n"); } fprintf(in, ";debug = 7\n\n"); fprintf(in, "[x11vnc_stunnel]\n"); fprintf(in, "accept = %s%d\n", st_if, stunnel_port); fprintf(in, "connect = %d\n", x11vnc_port); if (hport > 0 && x11vnc_hport > 0) { fprintf(in, "\n[x11vnc_http]\n"); fprintf(in, "accept = %s%d\n", st_if, hport); fprintf(in, "connect = %d\n", x11vnc_hport); } fflush(in); rewind(in); if (getenv("STUNNEL_DEBUG")) { char line[1000]; fprintf(stderr, "\nstunnel config contents:\n\n"); while (fgets(line, sizeof(line), in) != NULL) { fprintf(stderr, "%s", line); } fprintf(stderr, "\n"); rewind(in); } sprintf(fd, "%d", fileno(in)); execlp(stunnel_path, stunnel_path, "-fd", fd, (char *) NULL); exit(1); } free(exe); usleep(750 * 1000); waitpid(stunnel_pid, &status, WNOHANG); if (ssl_verify && strstr(ssl_verify, "/sslverify-tmp-load-")) { /* temporary file */ usleep(1000 * 1000); unlink(ssl_verify); } if (tmp_pem) { /* temporary cert */ usleep(1500 * 1000); unlink(stunnel_pem); } if (kill(stunnel_pid, 0) != 0) { waitpid(stunnel_pid, &status, WNOHANG); stunnel_pid = 0; return 0; } if (! quiet) { rfbLog("stunnel pid is: %d\n", (int) stunnel_pid); } return 1; #else return 0; #endif }
void setup_stunnel(int rport, int *argc, char **argv) { int i, xport = 0, hport = 0, xhport = 0; if (! rport && argc && argv) { for (i=0; i< *argc; i++) { if (argv[i] && !strcmp(argv[i], "-rfbport")) { if (i < *argc - 1) { rport = atoi(argv[i+1]); } } } } if (! rport) { /* we do our own autoprobing then... */ rport = find_free_port(5900, 5999); if (! rport) { goto stunnel_fail; } } xport = find_free_port(5950, 5999); if (! xport) { goto stunnel_fail; } if (https_port_num > 0) { hport = https_port_num; } if (! hport && argc && argv) { for (i=0; i< *argc; i++) { if (argv[i] && !strcmp(argv[i], "-httpport")) { if (i < *argc - 1) { hport = atoi(argv[i+1]); } } } } if (! hport && http_try_it) { hport = find_free_port(rport-100, rport-1); if (! hport) { goto stunnel_fail; } } if (hport) { xhport = find_free_port(5850, 5899); if (! xhport) { goto stunnel_fail; } stunnel_http_port = hport; } if (start_stunnel(rport, xport, hport, xhport)) { int tweaked = 0; char tmp[30]; sprintf(tmp, "%d", xport); if (argc && argv) { for (i=0; i < *argc; i++) { if (argv[i] && !strcmp(argv[i], "-rfbport")) { if (i < *argc - 1) { /* replace orig value */ argv[i+i] = strdup(tmp); tweaked = 1; break; } } } if (! tweaked) { i = *argc; argv[i] = strdup("-rfbport"); argv[i+1] = strdup(tmp); *argc += 2; got_rfbport = 1; got_rfbport_val = atoi(tmp); } } stunnel_port = rport; ssl_initialized = 1; return; } stunnel_fail: rfbLog("failed to start stunnel.\n"); clean_up_exit(1); }