summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--avahi-core/avahi-reflector.c8
-rw-r--r--avahi-core/core.h12
-rw-r--r--avahi-core/iface.c4
-rw-r--r--avahi-core/server.c22
-rw-r--r--avahi-daemon/Makefile.am7
-rw-r--r--avahi-daemon/avahi.conf18
-rw-r--r--avahi-daemon/main.c346
-rw-r--r--avahi-discover/main.c2
8 files changed, 364 insertions, 55 deletions
diff --git a/avahi-core/avahi-reflector.c b/avahi-core/avahi-reflector.c
index 60e19b6..7af0dd4 100644
--- a/avahi-core/avahi-reflector.c
+++ b/avahi-core/avahi-reflector.c
@@ -36,10 +36,10 @@ int main(int argc, char*argv[]) {
GMainLoop *loop;
avahi_server_config_init(&config);
- config.register_hinfo = FALSE;
- config.register_addresses = FALSE;
- config.register_workstation = FALSE;
- config.announce_domain = FALSE;
+ config.publish_hinfo = FALSE;
+ config.publish_addresses = FALSE;
+ config.publish_workstation = FALSE;
+ config.publish_domain = FALSE;
config.use_ipv6 = FALSE;
config.enable_reflector = TRUE;
diff --git a/avahi-core/core.h b/avahi-core/core.h
index 6e8d9dd..c9274c4 100644
--- a/avahi-core/core.h
+++ b/avahi-core/core.h
@@ -75,14 +75,14 @@ typedef struct AvahiServerConfig {
gchar *domain_name; /**< Default domain name. If left empty defaults to .local */
gboolean use_ipv4; /**< Enable IPv4 support */
gboolean use_ipv6; /**< Enable IPv6 support */
- gboolean register_hinfo; /**< Register a HINFO record for the host containing the local OS and CPU type */
- gboolean register_addresses; /**< Register A, AAAA and PTR records for all local IP addresses */
- gboolean register_workstation; /**< Register a _workstation._tcp service */
+ gboolean publish_hinfo; /**< Register a HINFO record for the host containing the local OS and CPU type */
+ gboolean publish_addresses; /**< Register A, AAAA and PTR records for all local IP addresses */
+ gboolean publish_workstation; /**< Register a _workstation._tcp service */
+ gboolean publish_domain; /**< Announce the local domain for browsing */
gboolean check_response_ttl; /**< If enabled the server ignores all incoming responses with IP TTL != 255 */
- gboolean announce_domain; /**< Announce the local domain for browsing */
- gboolean use_iff_running; /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */
+ gboolean use_iff_running; /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */
gboolean enable_reflector; /**< Reflect incoming mDNS traffic to all local networks. This allows mDNS based network browsing beyond ethernet borders */
- gboolean ipv_reflect; /**< if enable_reflector is TRUE, enable/disable reflecting between IPv4 and IPv6 */
+ gboolean reflect_ipv; /**< if enable_reflector is TRUE, enable/disable reflecting between IPv4 and IPv6 */
} AvahiServerConfig;
/** Allocate a new mDNS responder object. */
diff --git a/avahi-core/iface.c b/avahi-core/iface.c
index 73f4cdf..7972a5c 100644
--- a/avahi-core/iface.c
+++ b/avahi-core/iface.c
@@ -45,7 +45,7 @@ static void update_address_rr(AvahiInterfaceMonitor *m, AvahiInterfaceAddress *a
if (avahi_interface_address_relevant(a) &&
!remove &&
- m->server->config.register_addresses &&
+ m->server->config.publish_addresses &&
(m->server->state == AVAHI_SERVER_RUNNING ||
m->server->state == AVAHI_SERVER_REGISTERING)) {
@@ -87,7 +87,7 @@ static void update_hw_interface_rr(AvahiInterfaceMonitor *m, AvahiHwInterface *h
update_interface_rr(m, i, remove);
if (!remove &&
- m->server->config.register_workstation &&
+ m->server->config.publish_workstation &&
(m->server->state == AVAHI_SERVER_RUNNING ||
m->server->state == AVAHI_SERVER_REGISTERING)) {
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 1630b29..0c00658 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -484,7 +484,7 @@ static void reflect_response(AvahiServer *s, AvahiInterface *i, AvahiRecord *r,
return;
for (j = s->monitor->interfaces; j; j = j->interface_next)
- if (j != i && (s->config.ipv_reflect || j->protocol == i->protocol))
+ if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol))
avahi_interface_post_response(j, r, flush_cache, NULL, TRUE);
}
@@ -511,7 +511,7 @@ static void reflect_query(AvahiServer *s, AvahiInterface *i, AvahiKey *k) {
return;
for (j = s->monitor->interfaces; j; j = j->interface_next)
- if (j != i && (s->config.ipv_reflect || j->protocol == i->protocol)) {
+ if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol)) {
/* Post the query to other networks */
avahi_interface_post_query(j, k, TRUE);
@@ -533,7 +533,7 @@ static void reflect_probe(AvahiServer *s, AvahiInterface *i, AvahiRecord *r) {
return;
for (j = s->monitor->interfaces; j; j = j->interface_next)
- if (j != i && (s->config.ipv_reflect || j->protocol == i->protocol))
+ if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol))
avahi_interface_post_probe(j, r, TRUE);
}
@@ -775,7 +775,7 @@ static void reflect_legacy_unicast_query_packet(AvahiServer *s, AvahiDnsPacket *
for (j = s->monitor->interfaces; j; j = j->interface_next)
if (avahi_interface_relevant(j) &&
j != i &&
- (s->config.ipv_reflect || j->protocol == i->protocol)) {
+ (s->config.reflect_ipv || j->protocol == i->protocol)) {
if (j->protocol == AF_INET && s->fd_legacy_unicast_ipv4 >= 0) {
avahi_send_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, j->hardware->index, p, NULL, 0);
@@ -1105,7 +1105,7 @@ static void register_hinfo(AvahiServer *s) {
g_assert(s);
- if (!s->config.register_hinfo || s->hinfo_entry_group)
+ if (!s->config.publish_hinfo || s->hinfo_entry_group)
return;
s->hinfo_entry_group = avahi_entry_group_new(s, avahi_host_rr_entry_group_callback, NULL);
@@ -1136,7 +1136,7 @@ static void register_localhost(AvahiServer *s) {
static void register_browse_domain(AvahiServer *s) {
g_assert(s);
- if (!s->config.announce_domain || s->browse_domain_entry_group)
+ if (!s->config.publish_domain || s->browse_domain_entry_group)
return;
s->browse_domain_entry_group = avahi_entry_group_new(s, NULL, NULL);
@@ -1870,18 +1870,18 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) {
g_assert(c);
memset(c, 0, sizeof(AvahiServerConfig));
- c->register_hinfo = TRUE;
- c->register_addresses = TRUE;
c->use_ipv6 = TRUE;
c->use_ipv4 = TRUE;
c->host_name = NULL;
c->domain_name = NULL;
c->check_response_ttl = TRUE;
- c->announce_domain = TRUE;
+ c->publish_hinfo = TRUE;
+ c->publish_addresses = TRUE;
+ c->publish_workstation = TRUE;
+ c->publish_domain = TRUE;
c->use_iff_running = FALSE;
c->enable_reflector = FALSE;
- c->ipv_reflect = FALSE;
- c->register_workstation = TRUE;
+ c->reflect_ipv = FALSE;
return c;
}
diff --git a/avahi-daemon/Makefile.am b/avahi-daemon/Makefile.am
index f90b16d..bb983a3 100644
--- a/avahi-daemon/Makefile.am
+++ b/avahi-daemon/Makefile.am
@@ -17,13 +17,18 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA.
-AM_CFLAGS=-I$(top_srcdir) -D_GNU_SOURCE -DAVAHI_SERVICE_DIRECTORY=\"`pwd`\"
+AM_CFLAGS=-I$(top_srcdir) -D_GNU_SOURCE -DAVAHI_SERVICE_DIRECTORY=\"`pwd`\" -DAVAHI_CONFIG_FILE=\"avahi.conf\"
AM_LDADD=-lexpat
# GLIB 2.0
AM_CFLAGS+=$(GLIB20_CFLAGS)
AM_LDADD+=$(GLIB20_LIBS)
+# libdaemon
+AM_CFLAGS+=$(LIBDAEMON_CFLAGS)
+AM_LDADD+=$(LIBDAEMON_LIBS)
+
+
if ENABLE_DBUS
# DBUS
AM_CFLAGS+=$(DBUS_CFLAGS)
diff --git a/avahi-daemon/avahi.conf b/avahi-daemon/avahi.conf
new file mode 100644
index 0000000..900d04b
--- /dev/null
+++ b/avahi-daemon/avahi.conf
@@ -0,0 +1,18 @@
+[server]
+#host-name=foo
+#domain-name=local
+use-ipv4=yes
+use-ipv6=no
+check-response-ttl=yes
+use-iff-running=yes
+enable-dbus=yes
+
+[publish]
+publish-addresses=yes
+publish-hinfo=yes
+publish-workstation=yes
+publish-domain=yes
+
+[reflector]
+enable-reflector=no
+reflect-ipv=no
diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c
index d59e9fb..4373f9a 100644
--- a/avahi-daemon/main.c
+++ b/avahi-daemon/main.c
@@ -23,19 +23,45 @@
#include <config.h>
#endif
+#include <getopt.h>
+#include <string.h>
+#include <signal.h>
+
+#include <libdaemon/dfork.h>
+#include <libdaemon/dsignal.h>
+#include <libdaemon/dlog.h>
+#include <libdaemon/dpid.h>
+
#include <avahi-core/core.h>
+#include <avahi-core/log.h>
#include "main.h"
#include "simple-protocol.h"
+#include "dbus-protocol.h"
#include "static-services.h"
AvahiServer *avahi_server = NULL;
+typedef enum {
+ DAEMON_RUN,
+ DAEMON_KILL,
+ DAEMON_VERSION,
+ DAEMON_HELP
+} DaemonCommand;
+
+typedef struct {
+ AvahiServerConfig server_config;
+ DaemonCommand command;
+ gboolean daemonize;
+ gchar *config_file;
+ gboolean enable_dbus;
+} DaemonConfig;
+
static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) {
g_assert(s);
if (state == AVAHI_SERVER_RUNNING) {
- g_message("Server startup complete. Host name is <%s>", avahi_server_get_host_name_fqdn(s));
+ avahi_log_info("Server startup complete. Host name is <%s>", avahi_server_get_host_name_fqdn(s));
static_service_add_to_server();
} else if (state == AVAHI_SERVER_COLLISION) {
gchar *n;
@@ -43,7 +69,7 @@ static void server_callback(AvahiServer *s, AvahiServerState state, gpointer use
static_service_remove_from_server();
n = avahi_alternative_host_name(avahi_server_get_host_name(s));
- g_message("Host name conflict, retrying with <%s>", n);
+ avahi_log_warn("Host name conflict, retrying with <%s>", n);
avahi_server_set_host_name(s, n);
g_free(n);
}
@@ -52,64 +78,227 @@ static void server_callback(AvahiServer *s, AvahiServerState state, gpointer use
static void help(FILE *f, const gchar *argv0) {
fprintf(f,
"%s [options]\n"
- " -h --help Show this help\n"
- " -D --daemon Daemonize after startup\n"
- " -k --kill Kill a running daemon\n"
- " -v --version Show version\n",
+ " -h --help Show this help\n"
+ " -D --daemonize Daemonize after startup\n"
+ " -k --kill Kill a running daemon\n"
+ " -V --version Show version\n"
+ " -f --file=FILE Load the specified configuration file instead of the default\n",
argv0);
}
-static gint parse_command_line(AvahiServerConfig *config, int argc, char *argv[]) {
+static gint parse_command_line(DaemonConfig *config, int argc, char *argv[]) {
+ gint c;
+
+ static const struct option const long_options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "daemonize", no_argument, NULL, 'D' },
+ { "kill", no_argument, NULL, 'k' },
+ { "version", no_argument, NULL, 'V' },
+ { "file", required_argument, NULL, 'f' },
+ };
- return 0;
-}
+ g_assert(config);
-static gint load_config_file(AvahiServerConfig *config) {
+ opterr = 0;
+ while ((c = getopt_long(argc, argv, "hDkVf:", long_options, NULL)) >= 0) {
+ switch(c) {
+ case 'h':
+ config->command = DAEMON_HELP;
+ break;
+ case 'D':
+ config->daemonize = TRUE;
+ break;
+ case 'k':
+ config->command = DAEMON_KILL;
+ break;
+ case 'V':
+ config->command = DAEMON_VERSION;
+ break;
+ case 'f':
+ g_free(config->config_file);
+ config->config_file = g_strdup(optarg);
+ break;
+ default:
+ fprintf(stderr, "Invalid command line argument: %c\n", c);
+ return -1;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr, "Too many arguments\n");
+ return -1;
+ }
+
return 0;
}
-int main(int argc, char *argv[]) {
- GMainLoop *loop = NULL;
- gint r = 255;
- AvahiServerConfig config;
+static gboolean is_yes(const gchar *s) {
+ g_assert(s);
+
+ return *s == 'y' || *s == 'Y';
+}
- avahi_server_config_init(&config);
+static gint load_config_file(DaemonConfig *config) {
+ int r = -1;
+ GKeyFile *f = NULL;
+ GError *err = NULL;
+ gchar **groups = NULL, **g, **keys = NULL;
- if (load_config_file(&config) < 0)
+ g_assert(config);
+
+ f = g_key_file_new();
+
+ if (!g_key_file_load_from_file(f, config->config_file ? config->config_file : AVAHI_CONFIG_FILE, G_KEY_FILE_NONE, &err)) {
+ fprintf(stderr, "Unable to read config file: %s\n", err->message);
goto finish;
+ }
- if (parse_command_line(&config, argc, argv) < 0)
- goto finish;
+ groups = g_key_file_get_groups(f, NULL);
+
+ for (g = groups; *g; g++) {
+ if (g_strcasecmp(*g, "server") == 0) {
+ gchar **k;
+
+ keys = g_key_file_get_keys(f, *g, NULL, NULL);
+
+ for (k = keys; *k; k++) {
+ if (g_strcasecmp(*k, "host-name") == 0) {
+ g_free(config->server_config.host_name);
+ config->server_config.host_name = g_strdup(g_key_file_get_string(f, *g, *k, NULL));
+ } else if (g_strcasecmp(*k, "domain-name") == 0) {
+ g_free(config->server_config.domain_name);
+ config->server_config.domain_name = g_strdup(g_key_file_get_string(f, *g, *k, NULL));
+ } else if (g_strcasecmp(*k, "use-ipv4") == 0)
+ config->server_config.use_ipv4 = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "use-ipv6") == 0)
+ config->server_config.use_ipv6 = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "check-response-ttl") == 0)
+ config->server_config.check_response_ttl = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "use-iff-running") == 0)
+ config->server_config.use_iff_running = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "enable-dbus") == 0)
+ config->enable_dbus = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else {
+ fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
+ goto finish;
+ }
+ }
+
+ } else if (g_strcasecmp(*g, "publish") == 0) {
+ gchar **k;
+
+ keys = g_key_file_get_keys(f, *g, NULL, NULL);
+
+ for (k = keys; *k; k++) {
+ if (g_strcasecmp(*k, "publish-addresses") == 0)
+ config->server_config.publish_addresses = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "publish-hinfo") == 0)
+ config->server_config.publish_hinfo = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "publish-workstation") == 0)
+ config->server_config.publish_workstation = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "publish-domain") == 0)
+ config->server_config.publish_domain = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else {
+ fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
+ goto finish;
+ }
+ }
+
+ } else if (g_strcasecmp(*g, "reflector") == 0) {
+ gchar **k;
+
+ keys = g_key_file_get_keys(f, *g, NULL, NULL);
+
+ for (k = keys; *k; k++) {
+ if (g_strcasecmp(*k, "enable-reflector") == 0)
+ config->server_config.enable_reflector = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else if (g_strcasecmp(*k, "reflect-ipv") == 0)
+ config->server_config.reflect_ipv = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+ else {
+ fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
+ goto finish;
+ }
+ }
- loop = g_main_loop_new(NULL, FALSE);
+ } else {
+ fprintf(stderr, "Invalid configuration file group \"%s\".\n", *g);
+ goto finish;
+ }
+ }
+
+ r = 0;
+
+finish:
+
+ g_strfreev(groups);
+ g_strfreev(keys);
+
+ if (err)
+ g_error_free (err);
+
+ if (f)
+ g_key_file_free(f);
+
+ return r;
+}
+
+static void log_function(AvahiLogLevel level, const gchar *txt) {
+
+ static const int const log_level_map[] = {
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG
+ };
+
+ g_assert(level < AVAHI_LOG_LEVEL_MAX);
+ g_assert(txt);
+ daemon_log(log_level_map[level], "%s", txt);
+}
+
+static gint run_server(DaemonConfig *config) {
+ GMainLoop *loop = NULL;
+ gint r = -1;
+
+ g_assert(config);
+
+ loop = g_main_loop_new(NULL, FALSE);
+
if (simple_protocol_setup(NULL) < 0)
goto finish;
-
+
#ifdef ENABLE_DBUS
- if (dbus_protocol_setup (loop) < 0)
- goto finish;
+ if (config->enable_dbus)
+ if (dbus_protocol_setup(loop) < 0)
+ goto finish;
#endif
-
- if (!(avahi_server = avahi_server_new(NULL, &config, server_callback, NULL)))
+
+ if (!(avahi_server = avahi_server_new(NULL, &config->server_config, server_callback, NULL)))
goto finish;
-
+
static_service_load();
+ if (config->daemonize) {
+ daemon_retval_send(0);
+ r = 0;
+ }
+
g_main_loop_run(loop);
- r = 0;
-
-finish:
+finish:
+
static_service_remove_from_server();
static_service_free_all();
simple_protocol_shutdown();
#ifdef ENABLE_DBUS
- dbus_protocol_shutdown();
+ if (config->enable_dbus)
+ dbus_protocol_shutdown();
#endif
if (avahi_server)
@@ -118,7 +307,104 @@ finish:
if (loop)
g_main_loop_unref(loop);
- avahi_server_config_free(&config);
+ if (r != 0 && config->daemonize)
+ daemon_retval_send(0);
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ gint r = 255;
+ DaemonConfig config;
+ const gchar *argv0;
+ gboolean wrote_pid_file = FALSE;
+
+ avahi_set_log_function(log_function);
+
+ avahi_server_config_init(&config.server_config);
+ config.command = DAEMON_RUN;
+ config.daemonize = FALSE;
+ config.config_file = NULL;
+ config.enable_dbus = TRUE;
+
+ if ((argv0 = strrchr(argv[0], '/')))
+ argv0++;
+ else
+ argv0 = argv[0];
+ daemon_pid_file_ident = daemon_log_ident = (char *) argv0;
+
+ if (parse_command_line(&config, argc, argv) < 0)
+ goto finish;
+
+ if (load_config_file(&config) < 0)
+ goto finish;
+
+ if (config.command == DAEMON_HELP) {
+ help(stdout, argv0);
+ r = 0;
+ } else if (config.command == DAEMON_VERSION) {
+ printf("%s "PACKAGE_VERSION"\n", argv0);
+
+ } else if (config.command == DAEMON_KILL) {
+ if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) {
+ avahi_log_warn("Failed to kill daemon");
+ goto finish;
+ }
+
+ r = 0;
+
+ } else if (config.command == DAEMON_RUN) {
+ pid_t pid;
+
+ if ((pid = daemon_pid_file_is_running()) >= 0) {
+ avahi_log_error("Daemon already running on PID %u", pid);
+ goto finish;
+ }
+
+ if (config.daemonize) {
+
+ daemon_retval_init();
+
+ if ((pid = daemon_fork()) < 0)
+ goto finish;
+ else if (pid != 0) {
+ int ret;
+ /** Parent **/
+
+ if ((ret = daemon_retval_wait(20)) < 0) {
+ avahi_log_error("Could not recieve return value from daemon process.");
+ goto finish;
+ }
+
+ r = ret;
+ goto finish;
+ }
+
+ /* Child */
+ }
+
+ if (daemon_pid_file_create() < 0) {
+ avahi_log_error("Failed to create PID file.");
+ daemon_retval_send(1);
+ goto finish;
+ } else
+ wrote_pid_file = TRUE;
+
+ if (run_server(&config) == 0)
+ r = 0;
+ }
+
+finish:
+
+ if (config.daemonize)
+ daemon_retval_done();
+
+ avahi_server_config_free(&config.server_config);
+ g_free(config.config_file);
+
+ if (wrote_pid_file)
+ daemon_pid_file_remove();
+
return r;
}
diff --git a/avahi-discover/main.c b/avahi-discover/main.c
index f8cb953..557ad41 100644
--- a/avahi-discover/main.c
+++ b/avahi-discover/main.c
@@ -270,7 +270,7 @@ int main(int argc, char *argv[]) {
service_type_hash_table = g_hash_table_new((GHashFunc) avahi_domain_hash, (GEqualFunc) avahi_domain_equal);
avahi_server_config_init(&config);
- config.register_hinfo = config.register_addresses = config.announce_domain = config.register_workstation = FALSE;
+ config.publish_hinfo = config.publish_addresses = config.publish_domain = config.publish_workstation = FALSE;
server = avahi_server_new(NULL, &config, NULL, NULL);
avahi_server_config_free(&config);