#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
+#include <stdio.h>
#include <libdaemon/dfork.h>
#include <libdaemon/dsignal.h>
DAEMON_KILL,
DAEMON_VERSION,
DAEMON_HELP,
- DAEMON_RELOAD
+ DAEMON_RELOAD,
+ DAEMON_CHECK
} DaemonCommand;
typedef struct {
#define MAX_NAME_SERVERS 10
-static gint load_resolv_conf(const DaemonConfig *config) {
+static gint load_resolv_conf(const DaemonConfig *c) {
gint ret = -1;
FILE *f;
gint i = 0;
g_strfreev(resolv_conf);
resolv_conf = NULL;
- if (!config->publish_resolv_conf)
+ if (!c->publish_resolv_conf)
return 0;
if (!(f = fopen(RESOLV_CONF, "r"))) {
return ret;
}
-static AvahiEntryGroup* add_dns_servers(AvahiServer *s, gchar **l) {
+static AvahiEntryGroup* add_dns_servers(AvahiServer *s, AvahiEntryGroup* g, gchar **l) {
gchar **p;
- AvahiEntryGroup *g;
g_assert(s);
g_assert(l);
- g = avahi_entry_group_new(s, NULL, NULL);
+ if (!g)
+ g = avahi_entry_group_new(s, NULL, NULL);
+
+ g_assert(avahi_entry_group_is_empty(g));
for (p = l; *p; p++) {
AvahiAddress a;
avahi_entry_group_commit(g);
return g;
-
}
static void remove_dns_server_entry_groups(void) {
- if (resolv_conf_entry_group) {
- avahi_entry_group_free(resolv_conf_entry_group);
- resolv_conf_entry_group = NULL;
- }
+
+ if (resolv_conf_entry_group)
+ avahi_entry_group_reset(resolv_conf_entry_group);
- if (dns_servers_entry_group) {
- avahi_entry_group_free(dns_servers_entry_group);
- dns_servers_entry_group = NULL;
- }
+ if (dns_servers_entry_group)
+ avahi_entry_group_reset(dns_servers_entry_group);
}
static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) {
- DaemonConfig *config = userdata;
+ DaemonConfig *c = userdata;
g_assert(s);
- g_assert(config);
+ g_assert(c);
+
+#ifdef ENABLE_DBUS
+ if (c->enable_dbus)
+ dbus_protocol_server_state_changed(state);
+#endif
if (state == AVAHI_SERVER_RUNNING) {
avahi_log_info("Server startup complete. Host name is <%s>", avahi_server_get_host_name_fqdn(s));
remove_dns_server_entry_groups();
if (resolv_conf && resolv_conf[0])
- resolv_conf_entry_group = add_dns_servers(s, resolv_conf);
+ resolv_conf_entry_group = add_dns_servers(s, resolv_conf_entry_group, resolv_conf);
- if (config->publish_dns_servers && config->publish_dns_servers[0])
- dns_servers_entry_group = add_dns_servers(s, config->publish_dns_servers);
+ if (c->publish_dns_servers && c->publish_dns_servers[0])
+ dns_servers_entry_group = add_dns_servers(s, dns_servers_entry_group, c->publish_dns_servers);
simple_protocol_restart_queries();
" -D --daemonize Daemonize after startup\n"
" -k --kill Kill a running daemon\n"
" -r --reload Request a running daemon to reload static services\n"
+ " -c --check Return 0 if a daemon is already running\n"
" -V --version Show version\n"
" -f --file=FILE Load the specified configuration file instead of\n"
" "AVAHI_CONFIG_FILE"\n",
argv0);
}
-static gint parse_command_line(DaemonConfig *config, int argc, char *argv[]) {
- gint c;
+static gint parse_command_line(DaemonConfig *c, int argc, char *argv[]) {
+ gint o;
static const struct option const long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "file", required_argument, NULL, 'f' },
{ "reload", no_argument, NULL, 'r' },
+ { "check", no_argument, NULL, 'c' },
};
- g_assert(config);
+ g_assert(c);
opterr = 0;
- while ((c = getopt_long(argc, argv, "hDkVf:r", long_options, NULL)) >= 0) {
+ while ((o = getopt_long(argc, argv, "hDkVf:rc", long_options, NULL)) >= 0) {
- switch(c) {
+ switch(o) {
case 'h':
- config->command = DAEMON_HELP;
+ c->command = DAEMON_HELP;
break;
case 'D':
- config->daemonize = TRUE;
+ c->daemonize = TRUE;
break;
case 'k':
- config->command = DAEMON_KILL;
+ c->command = DAEMON_KILL;
break;
case 'V':
- config->command = DAEMON_VERSION;
+ c->command = DAEMON_VERSION;
break;
case 'f':
- g_free(config->config_file);
- config->config_file = g_strdup(optarg);
+ g_free(c->config_file);
+ c->config_file = g_strdup(optarg);
break;
case 'r':
- config->command = DAEMON_RELOAD;
+ c->command = DAEMON_RELOAD;
+ break;
+ case 'c':
+ c->command = DAEMON_CHECK;
break;
default:
- fprintf(stderr, "Invalid command line argument: %c\n", c);
+ fprintf(stderr, "Invalid command line argument: %c\n", o);
return -1;
}
}
return *s == 'y' || *s == 'Y';
}
-static gint load_config_file(DaemonConfig *config) {
+static gint load_config_file(DaemonConfig *c) {
int r = -1;
GKeyFile *f = NULL;
GError *err = NULL;
gchar **groups = NULL, **g, **keys = NULL, *v = NULL;
- g_assert(config);
+ g_assert(c);
f = g_key_file_new();
g_key_file_set_list_separator(f, ',');
- if (!g_key_file_load_from_file(f, config->config_file ? config->config_file : AVAHI_CONFIG_FILE, G_KEY_FILE_NONE, &err)) {
+ if (!g_key_file_load_from_file(f, c->config_file ? c->config_file : AVAHI_CONFIG_FILE, G_KEY_FILE_NONE, &err)) {
fprintf(stderr, "Unable to read config file: %s\n", err->message);
goto finish;
}
v = g_key_file_get_value(f, *g, *k, NULL);
if (g_strcasecmp(*k, "host-name") == 0) {
- g_free(config->server_config.host_name);
- config->server_config.host_name = v;
+ g_free(c->server_config.host_name);
+ c->server_config.host_name = v;
v = NULL;
} else if (g_strcasecmp(*k, "domain-name") == 0) {
- g_free(config->server_config.domain_name);
- config->server_config.domain_name = v;
+ g_free(c->server_config.domain_name);
+ c->server_config.domain_name = v;
v = NULL;
} else if (g_strcasecmp(*k, "use-ipv4") == 0)
- config->server_config.use_ipv4 = is_yes(v);
+ c->server_config.use_ipv4 = is_yes(v);
else if (g_strcasecmp(*k, "use-ipv6") == 0)
- config->server_config.use_ipv6 = is_yes(v);
+ c->server_config.use_ipv6 = is_yes(v);
else if (g_strcasecmp(*k, "check-response-ttl") == 0)
- config->server_config.check_response_ttl = is_yes(v);
+ c->server_config.check_response_ttl = is_yes(v);
else if (g_strcasecmp(*k, "use-iff-running") == 0)
- config->server_config.use_iff_running = is_yes(v);
+ c->server_config.use_iff_running = is_yes(v);
else if (g_strcasecmp(*k, "enable-dbus") == 0)
- config->enable_dbus = is_yes(v);
+ c->enable_dbus = is_yes(v);
else if (g_strcasecmp(*k, "drop-root") == 0)
- config->drop_root = is_yes(v);
+ c->drop_root = is_yes(v);
else {
fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
goto finish;
v = g_key_file_get_string(f, *g, *k, NULL);
if (g_strcasecmp(*k, "publish-addresses") == 0)
- config->server_config.publish_addresses = is_yes(v);
+ c->server_config.publish_addresses = is_yes(v);
else if (g_strcasecmp(*k, "publish-hinfo") == 0)
- config->server_config.publish_hinfo = is_yes(v);
+ c->server_config.publish_hinfo = is_yes(v);
else if (g_strcasecmp(*k, "publish-workstation") == 0)
- config->server_config.publish_workstation = is_yes(v);
+ c->server_config.publish_workstation = is_yes(v);
else if (g_strcasecmp(*k, "publish-domain") == 0)
- config->server_config.publish_domain = is_yes(v);
+ c->server_config.publish_domain = is_yes(v);
else if (g_strcasecmp(*k, "publish-resolv-conf-dns-servers") == 0)
- config->publish_resolv_conf = is_yes(v);
+ c->publish_resolv_conf = is_yes(v);
else if (g_strcasecmp(*k, "publish-dns-servers") == 0) {
- g_strfreev(config->publish_dns_servers);
- config->publish_dns_servers = g_key_file_get_string_list(f, *g, *k, NULL, NULL);
+ g_strfreev(c->publish_dns_servers);
+ c->publish_dns_servers = g_key_file_get_string_list(f, *g, *k, NULL, NULL);
} else {
fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
goto finish;
v = g_key_file_get_string(f, *g, *k, NULL);
if (g_strcasecmp(*k, "enable-reflector") == 0)
- config->server_config.enable_reflector = is_yes(v);
+ c->server_config.enable_reflector = is_yes(v);
else if (g_strcasecmp(*k, "reflect-ipv") == 0)
- config->server_config.reflect_ipv = is_yes(v);
+ c->server_config.reflect_ipv = is_yes(v);
else {
fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
goto finish;
daemon_log(log_level_map[level], "%s", txt);
}
+static void dump(const gchar *text, gpointer userdata) {
+ avahi_log_info("%s", text);
+}
+
static gboolean signal_callback(GIOChannel *source, GIOCondition condition, gpointer data) {
gint sig;
GMainLoop *loop = data;
static_service_load();
static_service_add_to_server();
- if (resolv_conf_entry_group) {
- avahi_entry_group_free(resolv_conf_entry_group);
- resolv_conf_entry_group = NULL;
- }
+ if (resolv_conf_entry_group)
+ avahi_entry_group_reset(resolv_conf_entry_group);
load_resolv_conf(&config);
if (resolv_conf && resolv_conf[0])
- resolv_conf_entry_group = add_dns_servers(avahi_server, resolv_conf);
+ resolv_conf_entry_group = add_dns_servers(avahi_server, resolv_conf_entry_group, resolv_conf);
+
+ break;
+ case SIGUSR1:
+ avahi_log_info("Got SIGUSR1, dumping record data.");
+ avahi_server_dump(avahi_server, dump, NULL);
break;
default:
return TRUE;
}
-static gint run_server(DaemonConfig *config) {
+static gint run_server(DaemonConfig *c) {
GMainLoop *loop = NULL;
gint r = -1;
GIOChannel *io = NULL;
guint watch_id = (guint) -1;
- g_assert(config);
+ g_assert(c);
loop = g_main_loop_new(NULL, FALSE);
- if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, SIGTERM, 0) < 0) {
+ if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, SIGTERM, SIGUSR1, 0) < 0) {
avahi_log_error("Could not register signal handlers (%s).", strerror(errno));
goto finish;
}
goto finish;
#ifdef ENABLE_DBUS
- if (config->enable_dbus)
+ if (c->enable_dbus)
if (dbus_protocol_setup(loop) < 0)
goto finish;
#endif
- if (!(avahi_server = avahi_server_new(NULL, &config->server_config, server_callback, config)))
+ if (!(avahi_server = avahi_server_new(NULL, &c->server_config, server_callback, c)))
goto finish;
- load_resolv_conf(config);
+ load_resolv_conf(c);
static_service_load();
- if (config->daemonize) {
+ if (c->daemonize) {
daemon_retval_send(0);
r = 0;
}
simple_protocol_shutdown();
#ifdef ENABLE_DBUS
- if (config->enable_dbus)
+ if (c->enable_dbus)
dbus_protocol_shutdown();
#endif
if (loop)
g_main_loop_unref(loop);
- if (r != 0 && config->daemonize)
+ if (r != 0 && c->daemonize)
daemon_retval_send(1);
return r;
}
static const char* pid_file_proc(void) {
- return AVAHI_RUNTIME_DIR"/avahi-daemon.pid";
+ return AVAHI_DAEMON_RUNTIME_DIR"/pid";
}
static gint make_runtime_dir(void) {
u = umask(0000);
reset_umask = TRUE;
- if (mkdir(AVAHI_RUNTIME_DIR, 0755) < 0 && errno != EEXIST) {
- avahi_log_error("mkdir(\""AVAHI_RUNTIME_DIR"\"): %s", strerror(errno));
+ if (mkdir(AVAHI_DAEMON_RUNTIME_DIR, 0755) < 0 && errno != EEXIST) {
+ avahi_log_error("mkdir(\""AVAHI_DAEMON_RUNTIME_DIR"\"): %s", strerror(errno));
goto fail;
}
- chown(AVAHI_RUNTIME_DIR, pw->pw_uid, gr->gr_gid);
+ chown(AVAHI_DAEMON_RUNTIME_DIR, pw->pw_uid, gr->gr_gid);
- if (stat(AVAHI_RUNTIME_DIR, &st) < 0) {
+ if (stat(AVAHI_DAEMON_RUNTIME_DIR, &st) < 0) {
avahi_log_error("stat(): %s\n", strerror(errno));
goto fail;
}
if (!S_ISDIR(st.st_mode) || st.st_uid != pw->pw_uid || st.st_gid != gr->gr_gid) {
- avahi_log_error("Failed to create runtime directory "AVAHI_RUNTIME_DIR".");
+ avahi_log_error("Failed to create runtime directory "AVAHI_DAEMON_RUNTIME_DIR".");
goto fail;
}
else
argv0 = argv[0];
- daemon_pid_file_ident = daemon_log_ident = (char *) argv0;
+ daemon_pid_file_ident = (const char *) argv0;
+ daemon_log_ident = (char*) argv0;
daemon_pid_file_proc = pid_file_proc;
if (parse_command_line(&config, argc, argv) < 0)
}
r = 0;
-
+
} else if (config.command == DAEMON_RELOAD) {
if (daemon_pid_file_kill(SIGHUP) < 0) {
avahi_log_warn("Failed to kill daemon: %s", strerror(errno));
r = 0;
- } else if (config.command == DAEMON_RUN) {
+ } else if (config.command == DAEMON_CHECK)
+ r = (daemon_pid_file_is_running() >= 0) ? 0 : 1;
+ else if (config.command == DAEMON_RUN) {
pid_t pid;
if (getuid() != 0) {
/* Child */
}
+
+ printf("%s "PACKAGE_VERSION" starting up.\n", argv0);
+
chdir("/");
if (make_runtime_dir() < 0)