-/* $Id$ */
-
/***
This file is part of avahi.
#include <avahi-core/publish.h>
#include <avahi-core/dns-srv-rr.h>
#include <avahi-core/log.h>
+#include <avahi-core/util.h>
#ifdef ENABLE_CHROOT
#include "chroot.h"
#include "static-services.h"
#include "static-hosts.h"
#include "ini-file-parser.h"
+#include "sd-daemon.h"
#ifdef HAVE_DBUS
#include "dbus-protocol.h"
#ifdef HAVE_DBUS
int enable_dbus;
int fail_on_missing_dbus;
+ unsigned n_clients_max;
+ unsigned n_objects_per_client_max;
+ unsigned n_entries_per_entry_group_max;
#endif
int drop_root;
int set_rlimits;
l = filter_duplicate_domains(l);
avahi_server_set_browse_domains(avahi_server, l);
+ avahi_string_list_free(l);
}
static void server_callback(AvahiServer *s, AvahiServerState state, void *userdata) {
switch (state) {
case AVAHI_SERVER_RUNNING:
avahi_log_info("Server startup complete. Host name is %s. Local service cookie is %u.", avahi_server_get_host_name_fqdn(s), avahi_server_get_local_service_cookie(s));
-
+ sd_notifyf(0, "STATUS=Server startup complete. Host name is %s. Local service cookie is %u.", avahi_server_get_host_name_fqdn(s), avahi_server_get_local_service_cookie(s));
avahi_set_proc_title(argv0, "%s: running [%s]", argv0, avahi_server_get_host_name_fqdn(s));
static_service_add_to_server();
case AVAHI_SERVER_COLLISION: {
char *n;
- avahi_set_proc_title(argv0, "%s: collision", argv0);
-
static_service_remove_from_server();
static_hosts_remove_from_server();
remove_dns_server_entry_groups();
n = avahi_alternative_host_name(avahi_server_get_host_name(s));
- avahi_log_warn("Host name conflict, retrying with <%s>", n);
+
+ avahi_log_warn("Host name conflict, retrying with %s", n);
+ sd_notifyf(0, "STATUS=Host name conflict, retrying with %s", n);
+ avahi_set_proc_title(argv0, "%s: collision [%s]", argv0, n);
+
avahi_server_set_host_name(s, n);
avahi_free(n);
case AVAHI_SERVER_FAILURE:
avahi_log_error("Server error: %s", avahi_strerror(avahi_server_errno(s)));
+ sd_notifyf(0, "STATUS=Server error: %s", avahi_strerror(avahi_server_errno(s)));
+
avahi_simple_poll_quit(simple_poll_api);
break;
case AVAHI_SERVER_REGISTERING:
+ sd_notifyf(0, "STATUS=Registering host name %s", avahi_server_get_host_name_fqdn(s));
avahi_set_proc_title(argv0, "%s: registering [%s]", argv0, avahi_server_get_host_name_fqdn(s));
static_service_remove_from_server();
return *s == 'y' || *s == 'Y' || *s == '1' || *s == 't' || *s == 'T';
}
+static int parse_unsigned(const char *s, unsigned *u) {
+ char *e = NULL;
+ unsigned long ul;
+ unsigned k;
+
+ errno = 0;
+ ul = strtoul(s, &e, 0);
+
+ if (!e || *e || errno != 0)
+ return -1;
+
+ k = (unsigned) ul;
+
+ if ((unsigned long) k != ul)
+ return -1;
+
+ *u = k;
+ return 0;
+}
+
+static int parse_usec(const char *s, AvahiUsec *u) {
+ char *e = NULL;
+ unsigned long long ull;
+ AvahiUsec k;
+
+ errno = 0;
+ ull = strtoull(s, &e, 0);
+
+ if (!e || *e || errno != 0)
+ return -1;
+
+ k = (AvahiUsec) ull;
+
+ if ((unsigned long long) k != ull)
+ return -1;
+
+ *u = k;
+ return 0;
+}
+
+static char *get_machine_id(void) {
+ int fd;
+ char buf[32];
+
+ fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd == -1 && errno == ENOENT)
+ fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd == -1)
+ return NULL;
+
+ /* File is on a filesystem so we never get EINTR or partial reads */
+ if (read(fd, buf, sizeof buf) != sizeof buf) {
+ close(fd);
+ return NULL;
+ }
+ close(fd);
+
+ /* Contents can be lower, upper and even mixed case so normalize */
+ avahi_strdown(buf);
+
+ return avahi_strndup(buf, sizeof buf);
+}
+
static int load_config_file(DaemonConfig *c) {
int r = -1;
AvahiIniFile *f;
c->server_config.use_iff_running = is_yes(p->value);
else if (strcasecmp(p->key, "disallow-other-stacks") == 0)
c->server_config.disallow_other_stacks = is_yes(p->value);
+ else if (strcasecmp(p->key, "host-name-from-machine-id") == 0) {
+ if (*(p->value) == 'y' || *(p->value) == 'Y') {
+ char *machine_id = get_machine_id();
+ if (machine_id != NULL) {
+ avahi_free(c->server_config.host_name);
+ c->server_config.host_name = machine_id;
+ }
+ }
+ }
#ifdef HAVE_DBUS
else if (strcasecmp(p->key, "enable-dbus") == 0) {
c->server_config.deny_interfaces = avahi_string_list_add(c->server_config.deny_interfaces, *t);
avahi_strfreev(e);
+ } else if (strcasecmp(p->key, "ratelimit-interval-usec") == 0) {
+ AvahiUsec k;
+
+ if (parse_usec(p->value, &k) < 0) {
+ avahi_log_error("Invalid ratelimit-interval-usec setting %s", p->value);
+ goto finish;
+ }
+
+ c->server_config.ratelimit_interval = k;
+
+ } else if (strcasecmp(p->key, "ratelimit-burst") == 0) {
+ unsigned k;
+
+ if (parse_unsigned(p->value, &k) < 0) {
+ avahi_log_error("Invalid ratelimit-burst setting %s", p->value);
+ goto finish;
+ }
+
+ c->server_config.ratelimit_burst = k;
+
+ } else if (strcasecmp(p->key, "cache-entries-max") == 0) {
+ unsigned k;
+
+ if (parse_unsigned(p->value, &k) < 0) {
+ avahi_log_error("Invalid cache-entries-max setting %s", p->value);
+ goto finish;
+ }
+
+ c->server_config.n_cache_entries_max = k;
+#ifdef HAVE_DBUS
+ } else if (strcasecmp(p->key, "clients-max") == 0) {
+ unsigned k;
+
+ if (parse_unsigned(p->value, &k) < 0) {
+ avahi_log_error("Invalid clients-max setting %s", p->value);
+ goto finish;
+ }
+
+ c->n_clients_max = k;
+ } else if (strcasecmp(p->key, "objects-per-client-max") == 0) {
+ unsigned k;
+
+ if (parse_unsigned(p->value, &k) < 0) {
+ avahi_log_error("Invalid objects-per-client-max setting %s", p->value);
+ goto finish;
+ }
+
+ c->n_objects_per_client_max = k;
+ } else if (strcasecmp(p->key, "entries-per-entry-group-max") == 0) {
+ unsigned k;
+
+ if (parse_unsigned(p->value, &k) < 0) {
+ avahi_log_error("Invalid entries-per-entry-group-max setting %s", p->value);
+ goto finish;
+ }
+
+ c->n_entries_per_entry_group_max = k;
+#endif
} else {
avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
goto finish;
switch (sig) {
case SIGINT:
- case SIGQUIT:
case SIGTERM:
avahi_log_info(
"Got %s, quitting.",
- sig == SIGINT ? "SIGINT" :
- (sig == SIGQUIT ? "SIGQUIT" : "SIGTERM"));
+ sig == SIGINT ? "SIGINT" : "SIGTERM");
avahi_simple_poll_quit(simple_poll_api);
break;
/* Imported from ../avahi-client/nss-check.c */
int avahi_nss_support(void);
+static void ignore_signal(int sig) {
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = SA_RESTART;
+
+ sigaction(sig, &sa, NULL);
+}
+
static int run_server(DaemonConfig *c) {
int r = -1;
int error;
assert(c);
+ ignore_signal(SIGPIPE);
+
if (!(nss_support = avahi_nss_support()))
avahi_log_warn("WARNING: No NSS support for mDNS detected, consider installing nss-mdns!");
poll_api = avahi_simple_poll_get(simple_poll_api);
- if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, SIGTERM, SIGUSR1, 0) < 0) {
+ if (daemon_signal_init(SIGINT, SIGHUP, SIGTERM, SIGUSR1, 0) < 0) {
avahi_log_error("Could not register signal handlers (%s).", strerror(errno));
goto finish;
}
#ifdef HAVE_DBUS
if (c->enable_dbus) {
- if (dbus_protocol_setup(poll_api, config.disable_user_service_publishing, !c->fail_on_missing_dbus
+ if (dbus_protocol_setup(poll_api,
+ config.disable_user_service_publishing,
+ config.n_clients_max,
+ config.n_objects_per_client_max,
+ config.n_entries_per_entry_group_max,
+ !c->fail_on_missing_dbus
#ifdef ENABLE_CHROOT
&& !config.use_chroot
#endif
break;
}
+ r = 0;
finish:
#endif
/* the sysctl() call from iface-pfroute.c needs locked memory on FreeBSD */
-#if defined(RLIMIT_MEMLOCK) && !defined(__FreeBSD__)
+#if defined(RLIMIT_MEMLOCK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
/* We don't need locked memory */
set_one_rlimit(RLIMIT_MEMLOCK, 0, "RLIMIT_MEMLOCK");
#endif
#ifdef HAVE_DBUS
config.enable_dbus = 1;
config.fail_on_missing_dbus = 1;
+ config.n_clients_max = 0;
+ config.n_objects_per_client_max = 0;
+ config.n_entries_per_entry_group_max = 0;
#endif
config.drop_root = 1;
if (config.use_syslog || config.daemonize)
daemon_log_use = DAEMON_LOG_SYSLOG;
- if (daemon_close_all(-1) < 0) {
- avahi_log_error("Failed to close remaining file descriptors: %s", strerror(errno));
- goto finish;
- }
+ if (sd_listen_fds(0) <= 0)
+ if (daemon_close_all(-1) < 0)
+ avahi_log_warn("Failed to close all remaining file descriptors: %s", strerror(errno));
+
+ daemon_reset_sigs(-1);
+ daemon_unblock_sigs(-1);
if (make_runtime_dir() < 0)
goto finish;
}
#endif
avahi_log_info("%s "PACKAGE_VERSION" starting up.", argv0);
-
+ sd_notifyf(0, "STATUS=%s "PACKAGE_VERSION" starting up.", argv0);
avahi_set_proc_title(argv0, "%s: starting up", argv0);
if (run_server(&config) == 0)
r = 0;
+
+ avahi_log_info("%s "PACKAGE_VERSION" exiting.", argv0);
+ sd_notifyf(0, "STATUS=%s "PACKAGE_VERSION" exiting.", argv0);
}
finish: