diff options
Diffstat (limited to 'x11vnc/avahi.c')
-rw-r--r-- | x11vnc/avahi.c | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/x11vnc/avahi.c b/x11vnc/avahi.c deleted file mode 100644 index 939a34f..0000000 --- a/x11vnc/avahi.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com> - All rights reserved. - -This file is part of x11vnc. - -x11vnc is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at -your option) any later version. - -x11vnc is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with x11vnc; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -or see <http://www.gnu.org/licenses/>. - -In addition, as a special exception, Karl J. Runge -gives permission to link the code of its release of x11vnc with the -OpenSSL project's "OpenSSL" library (or with modified versions of it -that use the same license as the "OpenSSL" library), and distribute -the linked executables. You must obey the GNU General Public License -in all respects for all of the code used other than "OpenSSL". If you -modify this file, you may extend this exception to your version of the -file, but you are not obligated to do so. If you do not wish to do -so, delete this exception statement from your version. -*/ - -/* -- avahi.c -- */ - -#include "x11vnc.h" -#include "connections.h" -#include "cleanup.h" - -void avahi_initialise(void); -void avahi_advertise(char *name, char *host, uint16_t port); -void avahi_reset(void); -void avahi_cleanup(void); - -static pid_t avahi_pid = 0; - -static void kill_avahi_pid(void) { - if (avahi_pid != 0) { - rfbLog("kill_avahi_pid: %d\n", (int) avahi_pid); - kill(avahi_pid, SIGTERM); - avahi_pid = 0; - } -} - -static int try_avahi_helper(char *name, char *host, uint16_t port) { -#if LIBVNCSERVER_HAVE_FORK - char *cmd, *p, *path = getenv("PATH"), portstr[32]; - int i; - - if (!name || !host || !port) {} - - /* avahi-publish */ - if (no_external_cmds || !cmd_ok("zeroconf")) { - return 0; - } - - if (!path) { - return 0; - } - - path = strdup(path); - cmd = (char *) malloc(strlen(path) + 100); - sprintf(portstr, "%d", (int) port); - - p = strtok(path, ":"); - while (p) { - struct stat sbuf; - - sprintf(cmd, "%s/avahi-publish", p); - if (stat(cmd, &sbuf) == 0) { - break; - } - sprintf(cmd, "%s/dns-sd", p); - if (stat(cmd, &sbuf) == 0) { - break; - } - sprintf(cmd, "%s/mDNS", p); - if (stat(cmd, &sbuf) == 0) { - break; - } - cmd[0] = '\0'; - - p = strtok(NULL, ":"); - } - free(path); - - if (!strcmp(cmd, "")) { - free(cmd); - rfbLog("Could not find an external avahi/zeroconf helper program.\n"); - return 0; - } - - avahi_pid = fork(); - - if (avahi_pid < 0) { - rfbLogPerror("fork"); - avahi_pid = 0; - free(cmd); - return 0; - } - - if (avahi_pid != 0) { - int status; - - usleep(500 * 1000); - waitpid(avahi_pid, &status, WNOHANG); - if (kill(avahi_pid, 0) != 0) { - waitpid(avahi_pid, &status, WNOHANG); - avahi_pid = 0; - free(cmd); - return 0; - } - if (! quiet) { - rfbLog("%s helper pid is: %d\n", cmd, (int) avahi_pid); - } - free(cmd); - return 1; - } - - for (i=3; i<256; i++) { - close(i); - } - - if (strstr(cmd, "/avahi-publish")) { - execlp(cmd, cmd, "-s", name, "_rfb._tcp", portstr, (char *) NULL); - } else { - execlp(cmd, cmd, "-R", name, "_rfb._tcp", ".", portstr, (char *) NULL); - } - exit(1); -#else - if (!name || !host || !port) {} - return 0; -#endif -} - -#if !defined(LIBVNCSERVER_HAVE_AVAHI) || !defined(LIBVNCSERVER_HAVE_LIBPTHREAD) -void avahi_initialise(void) { - rfbLog("avahi_initialise: no Avahi support at buildtime.\n"); -} - -void avahi_advertise(char *name, char *host, uint16_t port) { - char *t; - t = getenv("X11VNC_AVAHI_NAME"); if (t) name = t; - t = getenv("X11VNC_AVAHI_HOST"); if (t) host = t; - t = getenv("X11VNC_AVAHI_PORT"); if (t) port = atoi(t); - - if (!try_avahi_helper(name, host, port)) { - rfbLog("avahi_advertise: no Avahi support at buildtime.\n"); - avahi = 0; - } -} - -void avahi_reset(void) { - kill_avahi_pid(); - rfbLog("avahi_reset: no Avahi support at buildtime.\n"); -} - -void avahi_cleanup(void) { - kill_avahi_pid(); - rfbLog("avahi_cleanup: no Avahi support at buildtime.\n"); -} -#else - -#include <avahi-common/thread-watch.h> -#include <avahi-common/alternative.h> -#include <avahi-client/client.h> -#include <avahi-client/publish.h> - -#include <avahi-common/malloc.h> -#include <avahi-common/error.h> - - -static AvahiThreadedPoll *_poll = NULL; -static AvahiClient *_client = NULL; -static AvahiEntryGroup *_group = NULL; - -static int db = 0; - -typedef struct { - const char *name; - const char *host; - uint16_t port; -} avahi_service_t; - -typedef struct { - char *name; - char *host; - uint16_t port; -} avahi_reg_t; - -#define NREG 16 -static avahi_reg_t registered[NREG]; - -void avahi_initialise(void) { - int ret; - static int first = 1; - - if (getenv("AVAHI_DEBUG")) { - db = 1; - } - if (first) { - int i; - for (i=0; i<NREG; i++) { - registered[i].name = NULL; - registered[i].host = NULL; - } - first = 0; - } - -if (db) fprintf(stderr, "in avahi_initialise\n"); - if (_poll) { -if (db) fprintf(stderr, " avahi_initialise: poll not null\n"); - return; - } - - if (! (_poll = avahi_threaded_poll_new()) ) { - rfbLog("warning: unable to open Avahi poll.\n"); - return; - } - - _client = avahi_client_new(avahi_threaded_poll_get(_poll), - 0, NULL, NULL, &ret); - if (! _client) { - rfbLog("warning: unable to open Avahi client: %s\n", - avahi_strerror(ret)); - - avahi_threaded_poll_free(_poll); - _poll = NULL; - return; - } - - if (avahi_threaded_poll_start(_poll) < 0) { - rfbLog("warning: unable to start Avahi poll.\n"); - avahi_client_free(_client); - _client = NULL; - avahi_threaded_poll_free(_poll); - _poll = NULL; - return; - } -if (db) fprintf(stderr, "out avahi_initialise\n"); -} - -static void _avahi_create_services(char *name, char *host, - uint16_t port); - -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 _avahi_create_services(char *name, char *host, uint16_t port) { - avahi_service_t *svc = (avahi_service_t *)malloc(sizeof(avahi_service_t)); - int ret = 0; - -if (db) fprintf(stderr, "in _avahi_create_services '%s' '%s' %d\n", name, host, port); - svc->name = name; - svc->host = host; - svc->port = port; - - if (!_group) { -if (db) fprintf(stderr, " _avahi_create_services create group\n"); - _group = avahi_entry_group_new(_client, - _avahi_entry_group_callback, svc); - } - if (!_group) { - rfbLog("avahi_entry_group_new() failed: %s\n", - avahi_strerror(avahi_client_errno(_client))); - return; - } - - ret = avahi_entry_group_add_service(_group, AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, 0, name, "_rfb._tcp", NULL, NULL, port, NULL); - if (ret < 0) { - rfbLog("Failed to add _rfb._tcp service: %s\n", - avahi_strerror(ret)); - return; - } - - ret = avahi_entry_group_commit(_group); - if (ret < 0) { - rfbLog("Failed to commit entry_group:: %s\n", - avahi_strerror(ret)); - return; - } -if (db) fprintf(stderr, "out _avahi_create_services\n"); -} - -void avahi_advertise(char *name, char *host, uint16_t port) { - int i; - char *t; - t = getenv("X11VNC_AVAHI_NAME"); if (t) name = t; - t = getenv("X11VNC_AVAHI_HOST"); if (t) host = t; - t = getenv("X11VNC_AVAHI_PORT"); if (t) port = atoi(t); - -if (db) fprintf(stderr, "in avahi_advertise: '%s' '%s' %d\n", name, host, port); - if (!_client) { -if (db) fprintf(stderr, " avahi_advertise client null\n"); - return; - } - if (_poll == NULL) { - rfbLog("Avahi poll not initialized.\n"); - return; - } - /* well, we just track it ourselves... */ - for (i=0; i<NREG; i++) { - if (!registered[i].name) { - continue; - } - if (strcmp(registered[i].name, name)) { - continue; - } - if (strcmp(registered[i].host, host)) { - continue; - } - if (registered[i].port != port) { - continue; - } -if (db) fprintf(stderr, " avahi_advertise already did this one\n"); - return; - } - for (i=0; i<NREG; i++) { - if (!registered[i].name) { - registered[i].name = strdup(name); - registered[i].host = strdup(host); - registered[i].port = port; - break; - } - } - - avahi_threaded_poll_lock(_poll); - _avahi_create_services(name, host, port >= 5900 ? port : 5900+port); - avahi_threaded_poll_unlock(_poll); -if (db) fprintf(stderr, "out avahi_advertise\n"); -} - -void avahi_reset(void) { - int i; -if (db) fprintf(stderr, "in avahi_reset\n"); - for (i=0; i<NREG; i++) { - if (registered[i].name) { - free(registered[i].name); - registered[i].name = NULL; - } - if (registered[i].host) { - free(registered[i].host); - registered[i].host = NULL; - } - } - if (!_client || !_group) { -if (db) fprintf(stderr, " avahi_reset client/group null\n"); - return; - } - avahi_entry_group_reset(_group); - rfbLog("Avahi resetting group.\n"); -if (db) fprintf(stderr, "out avahi_reset\n"); -} - -static void avahi_timeout (int sig) { - rfbLog("sig: %d, avahi_cleanup timed out.\n", sig); - exit(1); -} - - -void avahi_cleanup(void) { -if (db) fprintf(stderr, "in avahi_cleanup\n"); - if (!_client) { -if (db) fprintf(stderr, " avahi_cleanup client null\n"); - return; - } -if (db) fprintf(stderr, " avahi_cleanup poll_lock\n"); - avahi_threaded_poll_lock(_poll); -if (db) fprintf(stderr, " avahi_cleanup poll_stop\n"); - - signal(SIGALRM, avahi_timeout); - alarm(3); - avahi_threaded_poll_stop(_poll); - alarm(0); - signal(SIGALRM, SIG_DFL); - -if (db) fprintf(stderr, " avahi_cleanup client_free\n"); - avahi_client_free(_client); - _client = NULL; - -if (db) fprintf(stderr, " avahi_cleanup poll_free\n"); - avahi_threaded_poll_free(_poll); - _poll = NULL; -if (db) fprintf(stderr, "out avahi_cleanup\n"); -} - -#endif - |