diff options
Diffstat (limited to 'x11vnc/avahi.c')
-rw-r--r-- | x11vnc/avahi.c | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/x11vnc/avahi.c b/x11vnc/avahi.c index 3d60388..830fabd 100644 --- a/x11vnc/avahi.c +++ b/x11vnc/avahi.c @@ -7,18 +7,122 @@ void avahi_advertise(const char *name, const char *host, const 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) { + kill(avahi_pid, SIGTERM); + avahi_pid = 0; + } +} + +static int try_avahi_helper(const char *name, const char *host, const uint16_t port) { +#if LIBVNCSERVER_HAVE_FORK + char *cmd, *p, *path = getenv("PATH"), portstr[32]; + int i; + + /* 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(const char *name, const char *host, const uint16_t port) { - if (!name || !host || !port) {} - rfbLog("avahi_advertise: no Avahi support at buildtime.\n"); + if (!try_avahi_helper(name, host, port)) { + rfbLog("avahi_advertise: no Avahi support at buildtime.\n"); + } } + 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 |