From 85ee6bdb696179980845a73aa279a2d1314ce289 Mon Sep 17 00:00:00 2001 From: Trent Lloyd Date: Sat, 11 Feb 2006 15:12:48 +0000 Subject: [PATCH] * Implement static hosts file for static host<->ip mappings git-svn-id: file:///home/lennart/svn/public/avahi/trunk@1133 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-daemon/Makefile.am | 6 +- avahi-daemon/hosts | 8 ++ avahi-daemon/main.c | 11 ++ avahi-daemon/static-hosts.c | 223 ++++++++++++++++++++++++++++++++++++ avahi-daemon/static-hosts.h | 30 +++++ 5 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 avahi-daemon/hosts create mode 100644 avahi-daemon/static-hosts.c create mode 100644 avahi-daemon/static-hosts.h diff --git a/avahi-daemon/Makefile.am b/avahi-daemon/Makefile.am index 6f27914..55207d0 100644 --- a/avahi-daemon/Makefile.am +++ b/avahi-daemon/Makefile.am @@ -34,6 +34,7 @@ AM_CFLAGS+= \ -DAVAHI_SOCKET=\"$(avahi_socket)\" \ -DAVAHI_SERVICE_DIR=\"$(servicedir)\" \ -DAVAHI_CONFIG_FILE=\"$(pkgsysconfdir)/avahi-daemon.conf\" \ + -DAVAHI_HOSTS_FILE=\"$(pkgsysconfdir)/hosts\" \ -DAVAHI_DBUS_INTROSPECTION_DIR=\"$(introspectiondir)\" \ -DAVAHI_CONFIG_DIR=\"$(pkgsysconfdir)\" @@ -49,6 +50,7 @@ avahi_daemon_SOURCES = \ main.c main.h \ simple-protocol.c simple-protocol.h \ static-services.c static-services.h \ + static-hosts.c static-hosts.h \ ini-file-parser.c ini-file-parser.h \ setproctitle.c setproctitle.h \ ../avahi-client/check-nss.c @@ -64,7 +66,8 @@ ini_file_parser_test_CFLAGS = $(AM_CFLAGS) ini_file_parser_test_LDADD = $(AM_LDADD) ../avahi-common/libavahi-common.la ../avahi-core/libavahi-core.la pkgsysconf_DATA = \ - avahi-daemon.conf + avahi-daemon.conf \ + hosts service_DATA = \ ssh.service @@ -145,6 +148,7 @@ EXTRA_DIST = \ HostNameResolver.introspect \ RecordBrowser.introspect \ ssh.service \ + hosts \ example.service \ introspect.dtd \ introspect.xsl diff --git a/avahi-daemon/hosts b/avahi-daemon/hosts new file mode 100644 index 0000000..53f412b --- /dev/null +++ b/avahi-daemon/hosts @@ -0,0 +1,8 @@ +# $Id$ +# +# This file contains static ip<-> host mappings. +# These can be usefull to publish services on behalf of a non-avahi enabled device. +# +# Examples: +# 192.168.0.1 router.local +# 2001::81:1 test.local diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c index 8327200..cd4a6dc 100644 --- a/avahi-daemon/main.c +++ b/avahi-daemon/main.c @@ -269,6 +269,7 @@ static void server_callback(AvahiServer *s, AvahiServerState state, void *userda avahi_set_proc_title("%s: running [%s]", argv0, avahi_server_get_host_name_fqdn(s)); static_service_add_to_server(); + static_hosts_add_to_server(); remove_dns_server_entry_groups(); @@ -285,6 +286,7 @@ static void server_callback(AvahiServer *s, AvahiServerState state, void *userda char *n; static_service_remove_from_server(); + static_hosts_remove_from_server(); remove_dns_server_entry_groups(); @@ -670,10 +672,13 @@ static void signal_callback(AvahiWatch *watch, AVAHI_GCC_UNUSED int fd, AVAHI_GC avahi_log_info("Got SIGHUP, reloading."); #ifdef ENABLE_CHROOT static_service_load(config.use_chroot); + static_hosts_load(config.use_chroot); #else static_service_load(0); + static_hosts_load(0); #endif static_service_add_to_server(); + static_service_remove_from_server(); if (resolv_conf_entry_group) avahi_s_entry_group_reset(resolv_conf_entry_group); @@ -769,8 +774,10 @@ static int run_server(DaemonConfig *c) { load_resolv_conf(); #ifdef ENABLE_CHROOT static_service_load(config.use_chroot); + static_hosts_load(config.use_chroot); #else static_service_load(0); + static_hosts_load(0); #endif if (!(avahi_server = avahi_server_new(poll_api, &c->server_config, server_callback, c, &error))) { @@ -804,6 +811,10 @@ finish: static_service_remove_from_server(); static_service_free_all(); + + static_hosts_remove_from_server(); + static_hosts_free_all(); + remove_dns_server_entry_groups(); simple_protocol_shutdown(); diff --git a/avahi-daemon/static-hosts.c b/avahi-daemon/static-hosts.c new file mode 100644 index 0000000..8b1eb58 --- /dev/null +++ b/avahi-daemon/static-hosts.c @@ -0,0 +1,223 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi 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 Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "main.h" +#include "static-hosts.h" + +typedef struct StaticHost StaticHost; + +struct StaticHost { + AvahiSEntryGroup *group; + + char *host, *ip; + + AVAHI_LLIST_FIELDS(StaticHost, hosts); +}; + +static AVAHI_LLIST_HEAD(StaticHost, hosts) = NULL; + +static void add_static_host_to_server(StaticHost *h); +static void remove_static_host_from_server(StaticHost *h); + +static void entry_group_callback(AvahiServer *s, AVAHI_GCC_UNUSED AvahiSEntryGroup *eg, AvahiEntryGroupState state, void* userdata) { + StaticHost *h; + + assert(s); + assert(eg); + + h = userdata; + + switch (state) { + + case AVAHI_ENTRY_GROUP_COLLISION: + avahi_log_error("Host name conflict for \"%s\", not established.", h->host); + break; + + case AVAHI_ENTRY_GROUP_ESTABLISHED: + avahi_log_notice ("Static Host \"%s\" successfully established.", h->host); + break; + + case AVAHI_ENTRY_GROUP_FAILURE: + avahi_log_notice ("Failed to establish Static Host \"%s\": %s.", h->host, avahi_strerror (avahi_server_errno (s))); + break; + + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + ; + } +} + +static StaticHost *static_host_new(void) { + StaticHost *s; + + s = avahi_new(StaticHost, 1); + + s->group = NULL; + s->host = NULL; + s->ip = NULL; + + AVAHI_LLIST_PREPEND(StaticHost, hosts, hosts, s); + + return s; +} + +static void static_host_free(StaticHost *s) { + assert(s); + + AVAHI_LLIST_REMOVE(StaticHost, hosts, hosts, s); + + avahi_s_entry_group_free (s->group); + + avahi_free(s->host); + avahi_free(s->ip); + + avahi_free(s); +} + +static void add_static_host_to_server(StaticHost *h) +{ + AvahiAddress a; + int err; + + if (!h->group) + h->group = avahi_s_entry_group_new (avahi_server, entry_group_callback, h); + + if (!avahi_address_parse (h->ip, AVAHI_PROTO_UNSPEC, &a)) { + avahi_log_error("Static host %s: avahi_address_parse failed", h->host); + return; + } + + if ((err = avahi_server_add_address(avahi_server, h->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, h->host, &a))) { + avahi_log_error ("Static host %s: avahi_server_add_address failure: %s", h->host, avahi_strerror(err)); + return; + } + + avahi_s_entry_group_commit (h->group); +} + +static void remove_static_host_from_server(StaticHost *h) +{ + avahi_s_entry_group_reset (h->group); +} + +void static_hosts_add_to_server(void) { + StaticHost *h; + + for (h = hosts; h; h = h->hosts_next) { + add_static_host_to_server(h); + } +} + +void static_hosts_remove_from_server(void) { + StaticHost *h; + + for (h = hosts; h; h = h->hosts_next) { + remove_static_host_from_server(h); + } +} + +void static_hosts_load(int in_chroot) { + FILE *f; + unsigned int line = 0; + const char *filename = (in_chroot ? "/hosts" : AVAHI_CONFIG_DIR "/hosts"); + + if (!(f = fopen(filename, "r"))) + { + avahi_log_error ("Failed to open static hosts file: %s", strerror (errno)); + return; + } + + while (!feof(f)) { + unsigned int len; + char ln[256], *s; + char *host, *ip; + StaticHost *h; + + if (!fgets(ln, sizeof (ln), f)) + break; + + line++; + + /* Find the start of the line, ignore whitespace */ + s = ln + strspn(ln, " \t"); + /* Set the end of the string to NULL */ + s[strcspn(s, "#\r\n")] = 0; + + /* Ignore comment (#) and blank lines (*/ + if (*s == '#' || *s == 0) + continue; + + /* Read the first string (ip) up to the next whitespace */ + len = strcspn(s, " \t"); + ip = avahi_strndup(s, len); + + /* Skip past it */ + s += len; + + /* Find the next token */ + s += strspn(s, " \t"); + len = strcspn(s, " \t"); + host = avahi_strndup(s, len); + + if (*host == 0) + { + avahi_log_error ("%s:%d: Error, unexpected end of line!", filename, line); + break; + } + + /* Skip past any more spaces */ + s += strspn(s+len, " \t"); + + /* Anything left? */ + if (*(s+len) != 0) { + avahi_log_error ("%s:%d: Junk on the end of the line!", filename, line); + break; + } + + h = static_host_new(); + h->host = host; + h->ip = ip; + } +} + +void static_hosts_free_all (void) +{ + StaticHost *h; + + for (h = hosts; h; h = hosts->hosts_next) + { + static_host_free (h); + } +} diff --git a/avahi-daemon/static-hosts.h b/avahi-daemon/static-hosts.h new file mode 100644 index 0000000..2fdb0bd --- /dev/null +++ b/avahi-daemon/static-hosts.h @@ -0,0 +1,30 @@ +#ifndef foostatichostshfoo +#define foostatichostshfoo + +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi 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 Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +void static_hosts_load(int in_chroot); +void static_hosts_free_all(void); +void static_hosts_add_to_server(void); +void static_hosts_remove_from_server(void); + +#endif -- 2.39.5