dbus_error_init (&error);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, db);
- parse_environment(db);
- parse_domain_file(db);
+ if (!(client->flags & AVAHI_CLIENT_IGNORE_USER_CONFIG)) {
+ parse_environment(db);
+ parse_domain_file(db);
+ }
db->static_browse_domains = avahi_string_list_reverse(db->static_browse_domains);
client = b->client;
- if (b->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (b->path && avahi_client_is_connected(b->client))
r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free");
AVAHI_LLIST_REMOVE(AvahiDomainBrowser, domain_browsers, client->domain_browsers, b);
dbus_error_init(&error);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
assert(b);
client = b->client;
- if (b->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (b->path && avahi_client_is_connected(b->client))
r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free");
AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, service_type_browsers, b->client->service_type_browsers, b);
dbus_error_init(&error);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
assert(b);
client = b->client;
- if (b->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (b->path && avahi_client_is_connected(b->client))
r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free");
AVAHI_LLIST_REMOVE(AvahiServiceBrowser, service_browsers, b->client->service_browsers, b);
simple_poll = avahi_simple_poll_new();
poll_api = avahi_simple_poll_get(simple_poll);
- if (!(avahi = avahi_client_new(poll_api, avahi_client_callback, "omghai2u", &error))) {
+ if (!(avahi = avahi_client_new(poll_api, 0, avahi_client_callback, "omghai2u", &error))) {
fprintf(stderr, "Client failed: %s\n", avahi_strerror(error));
goto fail;
}
cookie = avahi_client_get_local_service_cookie(avahi);
printf("Local service cookie: %u (Error Return: %s)\n", cookie, cookie != AVAHI_SERVICE_COOKIE_INVALID ? "OK" : avahi_strerror(avahi_client_errno(avahi)));
- group = avahi_entry_group_new (avahi, avahi_entry_group_callback, "omghai");
+ group = avahi_entry_group_new(avahi, avahi_entry_group_callback, "omghai");
printf("Creating entry group: %s\n", group ? "OK" : avahi_strerror(avahi_client_errno (avahi)));
assert(group);
#include "client.h"
#include "internal.h"
+static int init_server(AvahiClient *client, int *ret_error);
+
int avahi_client_set_errno (AvahiClient *client, int error) {
assert(client);
break;
case AVAHI_CLIENT_S_RUNNING:
+ case AVAHI_CLIENT_CONNECTING:
break;
}
assert(bus);
assert(message);
- dbus_error_init (&error);
+ dbus_error_init(&error);
/* fprintf(stderr, "dbus: interface=%s, path=%s, member=%s\n", */
/* dbus_message_get_interface (message), */
/* dbus_message_get_path (message), */
/* dbus_message_get_member (message)); */
- if (client->state == AVAHI_CLIENT_FAILURE)
- goto fail;
-
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
/* The DBUS server died or kicked us */
avahi_client_set_errno(client, AVAHI_ERR_DISCONNECTED);
- client_set_state(client, AVAHI_CLIENT_FAILURE);
+ goto fail;
} if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
char *name, *old, *new;
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &old,
DBUS_TYPE_STRING, &new,
- DBUS_TYPE_INVALID) || dbus_error_is_set (&error)) {
+ DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
fprintf(stderr, "WARNING: Failed to parse NameOwnerChanged signal: %s\n", error.message);
+ avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
goto fail;
}
if (strcmp(name, AVAHI_DBUS_NAME) == 0) {
- /* Regardless if the server lost or acquired its name or
- * if the name was transfered: our services are no longer
- * available, so we disconnect ourselves */
+ if (avahi_client_is_connected(client)) {
- avahi_client_set_errno(client, AVAHI_ERR_DISCONNECTED);
- client_set_state(client, AVAHI_CLIENT_FAILURE);
+ /* Regardless if the server lost or acquired its name or
+ * if the name was transfered: our services are no longer
+ * available, so we disconnect ourselves */
+ avahi_client_set_errno(client, AVAHI_ERR_DISCONNECTED);
+ goto fail;
+
+ } else if (client->state == AVAHI_CLIENT_CONNECTING && (!old || *old == 0)) {
+ int ret;
+
+ /* Server appeared */
+
+ if ((ret = init_server(client, NULL)) < 0) {
+ avahi_client_set_errno(client, ret);
+ goto fail;
+ }
+ }
}
+ } else if (!avahi_client_is_connected(client)) {
+
+ /* Ignore messages, we get in unconnected state */
+
} else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged")) {
int32_t state;
char *e = NULL;
DBUS_TYPE_INT32, &state,
DBUS_TYPE_STRING, &e,
DBUS_TYPE_INVALID) || dbus_error_is_set (&error)) {
+
fprintf(stderr, "WARNING: Failed to parse Server.StateChanged signal: %s\n", error.message);
+ avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
goto fail;
}
DBUS_TYPE_STRING, &e,
DBUS_TYPE_INVALID) ||
dbus_error_is_set(&error)) {
+
fprintf(stderr, "WARNING: Failed to parse EntryGroup.StateChanged signal: %s\n", error.message);
+ avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
goto fail;
}
return avahi_address_resolver_event (client, AVAHI_RESOLVER_FOUND, message);
else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Failure"))
return avahi_address_resolver_event (client, AVAHI_RESOLVER_FAILURE, message);
+ else {
+
+ fprintf(stderr, "WARNING: Unhandled message: interface=%s, path=%s, member=%s\n",
+ dbus_message_get_interface(message),
+ dbus_message_get_path(message),
+ dbus_message_get_member(message));
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
return DBUS_HANDLER_RESULT_HANDLED;
fail:
- dbus_error_free (&error);
+ if (dbus_error_is_set(&error)) {
+ avahi_client_set_errno(client, avahi_error_dbus_to_number(error.name));
+ dbus_error_free(&error);
+ }
+
+ client_set_state(client, AVAHI_CLIENT_FAILURE);
+
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
return e;
}
+static int init_server(AvahiClient *client, int *ret_error) {
+ int r;
+
+ if ((r = check_version(client, ret_error)) < 0)
+ return r;
-/* This function acts like dbus_bus_get but creates a private
- * connection instead */
-static DBusConnection*
-avahi_dbus_bus_get (DBusError *error)
-{
- DBusConnection *conn;
- const char *env_addr;
-
- env_addr = getenv ("DBUS_SYSTEM_BUS_ADDRESS");
+ if ((r = get_server_state(client, ret_error)) < 0)
+ return r;
- if (env_addr == NULL || (*env_addr == 0))
- {
- env_addr = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
- }
+ return AVAHI_OK;
+}
- conn = dbus_connection_open_private (env_addr, error);
+/* This function acts like dbus_bus_get but creates a private
+ * connection instead */
+static DBusConnection* avahi_dbus_bus_get(DBusError *error) {
+ DBusConnection *c;
+ const char *a;
- if (!conn)
+ if (!(a = getenv("DBUS_SYSTEM_BUS_ADDRESS")) || !*a)
+ a = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
+
+ if (!(c = dbus_connection_open_private(a, error)))
return NULL;
- dbus_connection_set_exit_on_disconnect (conn, FALSE);
-
- if (!dbus_bus_register (conn, error))
- {
- dbus_connection_close (conn);
- dbus_connection_unref (conn);
+ dbus_connection_set_exit_on_disconnect(c, FALSE);
+ if (!dbus_bus_register(c, error)) {
+ dbus_connection_close(c);
+ dbus_connection_unref(c);
return NULL;
}
- return conn;
+ return c;
}
-AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback callback, void *userdata, int *ret_error) {
+AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientFlags flags, AvahiClientCallback callback, void *userdata, int *ret_error) {
AvahiClient *client = NULL;
DBusError error;
- dbus_error_init (&error);
+ dbus_error_init(&error);
if (!(client = avahi_new(AvahiClient, 1))) {
if (ret_error)
client->error = AVAHI_OK;
client->callback = callback;
client->userdata = userdata;
- client->state = AVAHI_CLIENT_FAILURE;
-
+ client->state = (AvahiClientState) -1;
+ client->flags = flags;
+
client->host_name = NULL;
client->host_name_fqdn = NULL;
client->domain_name = NULL;
AVAHI_LLIST_HEAD_INIT(AvahiHostNameResolver, client->host_name_resolvers);
AVAHI_LLIST_HEAD_INIT(AvahiAddressResolver, client->address_resolvers);
- if (!(client->bus = avahi_dbus_bus_get(&error)) ||
- dbus_error_is_set (&error))
+ if (!(client->bus = avahi_dbus_bus_get(&error)) || dbus_error_is_set(&error)) {
+ if (ret_error)
+ *ret_error = AVAHI_ERR_DBUS_ERROR;
goto fail;
+ }
if (avahi_dbus_connection_glue(client->bus, poll_api) < 0) {
if (ret_error)
"path='" AVAHI_DBUS_PATH_SERVER "'",
&error);
- if (dbus_error_is_set (&error))
+ if (dbus_error_is_set(&error))
goto fail;
dbus_bus_add_match (
"path='" DBUS_PATH_DBUS "'",
&error);
- if (dbus_error_is_set (&error))
+ if (dbus_error_is_set(&error))
goto fail;
- dbus_bus_add_match (
+ dbus_bus_add_match (
client->bus,
"type='signal', "
"interface='" DBUS_INTERFACE_LOCAL "'",
&error);
- if (dbus_error_is_set (&error))
+ if (dbus_error_is_set(&error))
goto fail;
+
if (!(dbus_bus_name_has_owner(client->bus, AVAHI_DBUS_NAME, &error)) ||
dbus_error_is_set(&error)) {
/* We free the error so its not set, that way the fail target
* will return the NO_DAEMON error rather than a DBUS error */
- dbus_error_free (&error);
+ dbus_error_free(&error);
- if (ret_error)
- *ret_error = AVAHI_ERR_NO_DAEMON;
+ if (!(flags & AVAHI_CLIENT_NO_FAIL)) {
+
+ if (ret_error)
+ *ret_error = AVAHI_ERR_NO_DAEMON;
- goto fail;
- }
+ goto fail;
+ }
- if (check_version(client, ret_error) < 0)
- goto fail;
+ /* The user doesn't want this call to fail if the daemon is not
+ * available, so let's return succesfully */
+ client_set_state(client, AVAHI_CLIENT_CONNECTING);
+
+ } else {
- if (get_server_state(client, ret_error) < 0)
- goto fail;
+ if (init_server(client, ret_error) < 0)
+ goto fail;
+ }
return client;
return NULL;
}
-const char* avahi_client_get_version_string (AvahiClient *client) {
+const char* avahi_client_get_version_string(AvahiClient *client) {
assert(client);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
return NULL;
}
return client->version_string;
}
-const char* avahi_client_get_domain_name (AvahiClient *client) {
+const char* avahi_client_get_domain_name(AvahiClient *client) {
assert(client);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
return NULL;
}
return client->domain_name;
}
-const char* avahi_client_get_host_name (AvahiClient *client) {
+const char* avahi_client_get_host_name(AvahiClient *client) {
assert(client);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
return NULL;
}
const char* avahi_client_get_host_name_fqdn (AvahiClient *client) {
assert(client);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
return NULL;
}
DBusError error;
assert(client);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
return AVAHI_SERVICE_COOKIE_INVALID;
}
return AVAHI_SERVICE_COOKIE_INVALID;
}
+
+int avahi_client_is_connected(AvahiClient *client) {
+ assert(client);
+
+ return client->state == AVAHI_CLIENT_S_RUNNING || client->state == AVAHI_CLIENT_S_REGISTERING || client->state == AVAHI_CLIENT_S_COLLISION;
+}
AVAHI_CLIENT_S_REGISTERING = AVAHI_SERVER_REGISTERING, /**< Server state: REGISTERING */
AVAHI_CLIENT_S_RUNNING = AVAHI_SERVER_RUNNING, /**< Server state: RUNNING */
AVAHI_CLIENT_S_COLLISION = AVAHI_SERVER_COLLISION, /**< Server state: COLLISION */
- AVAHI_CLIENT_FAILURE = 100 /**< Some kind of error happened on the client side */
+ AVAHI_CLIENT_FAILURE = 100, /**< Some kind of error happened on the client side */
+ AVAHI_CLIENT_CONNECTING = 101 /**< We're still connecting. This state is only entered when AVAHI_CLIENT_NO_FAIL has been passed to avahi_client_new() and the daemon is not yet available. */
} AvahiClientState;
+typedef enum {
+ AVAHI_CLIENT_IGNORE_USER_CONFIG = 1, /**< Don't read user configuration */
+ AVAHI_CLIENT_NO_FAIL = 2 /**< Don't fail if the daemon is not available when avahi_client_new() is called, instead enter AVAHI_CLIENT_CONNECTING state and wait for the daemon to appear */
+} AvahiClientFlags;
+
/** The function prototype for the callback of an AvahiClient */
typedef void (*AvahiClientCallback) (AvahiClient *s, AvahiClientState state, void* userdata);
/** Creates a new client instance */
-AvahiClient* avahi_client_new (const AvahiPoll *poll_api, AvahiClientCallback callback, void *userdata, int *error);
+AvahiClient* avahi_client_new (const AvahiPoll *poll_api, AvahiClientFlags flags, AvahiClientCallback callback, void *userdata, int *error);
/** Free a client instance */
void avahi_client_free(AvahiClient *client);
dbus_error_init (&error);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
assert(group);
- if (group->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (group->path && !avahi_client_is_connected(client))
r = entry_group_simple_method_call(group, "Free");
AVAHI_LLIST_REMOVE(AvahiEntryGroup, groups, client->groups, group);
int avahi_entry_group_commit(AvahiEntryGroup *group) {
assert(group);
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
return entry_group_simple_method_call(group, "Commit");
int avahi_entry_group_reset(AvahiEntryGroup *group) {
assert(group);
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
return entry_group_simple_method_call(group, "Reset");
assert(group);
client = group->client;
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
dbus_error_init(&error);
client = group->client;
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
if (!domain)
client = group->client;
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
if (!domain)
client = group->client;
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
if (!domain)
client = group->client;
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
dbus_error_init(&error);
client = group->client;
- if (!group->path || group->client->state == AVAHI_CLIENT_FAILURE)
+ if (!group->path || !avahi_client_is_connected(group->client))
return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);
dbus_error_init(&error);
DBusConnection *bus;
int error;
AvahiClientState state;
+ AvahiClientFlags flags;
/* Cache for some seldom changing server data */
char *version_string, *host_name, *host_name_fqdn, *domain_name;
int avahi_client_simple_method_call(AvahiClient *client, const char *path, const char *interface, const char *method);
+int avahi_client_is_connected(AvahiClient *client);
+
#endif
dbus_error_init (&error);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
assert(r);
client = r->client;
- if (r->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (r->path && avahi_client_is_connected(client))
ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free");
AVAHI_LLIST_REMOVE(AvahiServiceResolver, service_resolvers, client->service_resolvers, r);
dbus_error_init (&error);
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
assert(r);
client = r->client;
- if (r->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (r->path && avahi_client_is_connected(client))
ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Free");
AVAHI_LLIST_REMOVE(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r);
return NULL;
}
- if (client->state == AVAHI_CLIENT_FAILURE) {
+ if (!avahi_client_is_connected(client)) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
}
assert(r);
client = r->client;
- if (r->path && client->state != AVAHI_CLIENT_FAILURE)
+ if (r->path && avahi_client_is_connected(client))
ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Free");
AVAHI_LLIST_REMOVE(AvahiAddressResolver, address_resolvers, client->address_resolvers, r);
poll_api = avahi_simple_poll_get(simple_poll);
assert(poll_api);
- client = avahi_client_new(poll_api, NULL, NULL, NULL);
+ client = avahi_client_new(poll_api, 0, NULL, NULL, NULL);
assert(client);
r = avahi_service_resolver_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, "_domain._udp", "0pointer.de", AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_TXT, callback, simple_poll);
assert(r);
- for (;;)
- if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
- break;
+ avahi_simple_poll_loop(simple_poll);
avahi_client_free(client);
avahi_simple_poll_free(simple_poll);
avahi_simple_poll_set_func((*self)->simple_poll, poll_func, *self);
- if (!((*self)->client = avahi_client_new(avahi_simple_poll_get((*self)->simple_poll), client_callback, *self, &error))) {
+ if (!((*self)->client = avahi_client_new(avahi_simple_poll_get((*self)->simple_poll), 0, client_callback, *self, &error))) {
result = map_error(error);
goto fail;
}
avahi_entry_group_reset(data->object);
break;
+ case AVAHI_CLIENT_CONNECTING:
case AVAHI_CLIENT_S_REGISTERING:
/* Ignore */
break;
case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION:
case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_CONNECTING:
break;
}
}
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), generic_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), generic_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), generic_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
break;
+ case AVAHI_CLIENT_CONNECTING:
case AVAHI_CLIENT_S_REGISTERING:
/* Ignore */
break;
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), reg_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, reg_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
int ignore_local;
Command command;
int resolve;
+ int no_fail;
#ifdef HAVE_GDBM
int no_db_lookup;
#endif
static AvahiStringList *browsed_types = NULL;
static ServiceInfo *services = NULL;
static int n_columns = 80;
+static int browsing = 0;
static void check_terminate(Config *c) {
n_all_for_now++;
}
+static int start(Config *config) {
+
+ assert(!browsing);
+
+ if (config->verbose) {
+ const char *version, *hn;
+
+ if (!(version = avahi_client_get_version_string(client))) {
+ fprintf(stderr, "Failed to query version string: %s\n", avahi_strerror(avahi_client_errno(client)));
+ return -1;
+ }
+
+ if (!(hn = avahi_client_get_host_name_fqdn(client))) {
+ fprintf(stderr, "Failed to query host name: %s\n", avahi_strerror(avahi_client_errno(client)));
+ return -1;
+ }
+
+ fprintf(stderr, "Server version: %s; Host name: %s\n", version, hn);
+
+ if (config->command == COMMAND_BROWSE_DOMAINS)
+ fprintf(stderr, "E Ifce Prot Domain\n");
+ else
+ fprintf(stderr, "E Ifce Prot %-*s %-20s Domain\n", n_columns-35, "Name", "Type");
+ }
+
+ if (config->command == COMMAND_BROWSE_SERVICES)
+ browse_service_type(config, config->stype, config->domain);
+ else if (config->command == COMMAND_BROWSE_ALL_SERVICES)
+ browse_all(config);
+ else {
+ assert(config->command == COMMAND_BROWSE_DOMAINS);
+ browse_domains(config);
+ }
+
+ browsing = 1;
+ return 0;
+}
+
static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
+ Config *config = userdata;
+
+ /* This function might be called when avahi_client_new() has not
+ * returned yet.*/
+ client = c;
+
switch (state) {
case AVAHI_CLIENT_FAILURE:
- fprintf(stderr, "Client failure, exiting: %s\n", avahi_strerror(avahi_client_errno(c)));
- avahi_simple_poll_quit(simple_poll);
+
+ if (config->no_fail && avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) {
+ int error;
+
+ /* We have been disconnected, so let reconnect */
+
+ fprintf(stderr, "Disconnected, reconnecting ...\n");
+
+ avahi_client_free(client);
+ client = NULL;
+
+ avahi_string_list_free(browsed_types);
+ browsed_types = NULL;
+
+ while (services)
+ remove_service(config, services);
+
+ browsing = 0;
+
+ if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), AVAHI_CLIENT_NO_FAIL, client_callback, config, &error))) {
+ fprintf(stderr, "Failed to create client object: %s\n", avahi_strerror(error));
+ avahi_simple_poll_quit(simple_poll);
+ }
+
+ } else {
+ fprintf(stderr, "Client failure, exiting: %s\n", avahi_strerror(avahi_client_errno(c)));
+ avahi_simple_poll_quit(simple_poll);
+ }
+
break;
case AVAHI_CLIENT_S_REGISTERING:
case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION:
- ;
+
+ if (!browsing)
+ if (start(config) < 0)
+ avahi_simple_poll_quit(simple_poll);
+
+ break;
+
+ case AVAHI_CLIENT_CONNECTING:
+
+ if (config->verbose)
+ fprintf(stderr, "Waiting for daemon ...\n");
+
+ break;
}
}
" -c --cache Terminate after dumping all entries from the cache\n"
" -l --ignore-local Ignore local services\n"
" -r --resolve Resolve services found\n"
+ " -f --no-fail Don't fail if the server is not available\n"
#ifdef HAVE_GDBM
" -k --no-db-lookup Don't lookup service types\n"
#endif
{ "cache", no_argument, NULL, 'c' },
{ "ignore-local", no_argument, NULL, 'l' },
{ "resolve", no_argument, NULL, 'r' },
+ { "no-fail", no_argument, NULL, 'f' },
#ifdef HAVE_GDBM
{ "no-db-lookup", no_argument, NULL, 'k' },
#endif
c->terminate_on_cache_exhausted =
c->terminate_on_all_for_now =
c->ignore_local =
- c->resolve = 0;
+ c->resolve =
+ c->no_fail = 0;
c->domain = c->stype = NULL;
#ifdef HAVE_GDBM
#endif
opterr = 0;
- while ((o = getopt_long(argc, argv, "hVd:avtclrD"
+ while ((o = getopt_long(argc, argv, "hVd:avtclrDf"
#ifdef HAVE_GDBM
"k"
#endif
case 'r':
c->resolve = 1;
break;
+ case 'f':
+ c->no_fail = 1;
+ break;
#ifdef HAVE_GDBM
case 'k':
c->no_db_lookup = 1;
if (sigint_install(simple_poll) < 0)
goto fail;
- if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), client_callback, NULL, &error))) {
+ if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), config.no_fail ? AVAHI_CLIENT_NO_FAIL : 0, client_callback, &config, &error))) {
fprintf(stderr, "Failed to create client object: %s\n", avahi_strerror(error));
goto fail;
}
-
- if (config.verbose) {
- const char *version, *hn;
-
- if (!(version = avahi_client_get_version_string(client))) {
- fprintf(stderr, "Failed to query version string: %s\n", avahi_strerror(avahi_client_errno(client)));
- goto fail;
- }
-
- if (!(hn = avahi_client_get_host_name_fqdn(client))) {
- fprintf(stderr, "Failed to query host name: %s\n", avahi_strerror(avahi_client_errno(client)));
- goto fail;
- }
-
- fprintf(stderr, "Server version: %s; Host name: %s\n", version, hn);
-
- if (config.command == COMMAND_BROWSE_DOMAINS)
- fprintf(stderr, "E Ifce Prot Domain\n");
- else
- fprintf(stderr, "E Ifce Prot %-*s %-20s Domain\n", n_columns-35, "Name", "Type");
- }
-
- if (config.command == COMMAND_BROWSE_SERVICES)
- browse_service_type(&config, config.stype, config.domain);
- else if (config.command == COMMAND_BROWSE_ALL_SERVICES)
- browse_all(&config);
- else {
- assert(config.command == COMMAND_BROWSE_DOMAINS);
- browse_domains(&config);
- }
avahi_simple_poll_loop(simple_poll);
ret = 0;
case AVAHI_CLIENT_S_REGISTERING:
case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION:
+ case AVAHI_CLIENT_CONNECTING:
;
}
}
if (sigint_install(simple_poll) < 0)
goto fail;
- if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), client_callback, NULL, &error))) {
+ if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error))) {
fprintf(stderr, "Failed to create client object: %s\n", avahi_strerror(error));
goto fail;
}
}
/* Allocate a new client */
- client = avahi_client_new(avahi_simple_poll_get(simple_poll), client_callback, NULL, &error);
+ client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
/* Check wether creating the client object succeeded */
if (!client) {
break;
+ case AVAHI_CLIENT_CONNECTING:
case AVAHI_CLIENT_S_REGISTERING:
;
}
name = avahi_strdup("MegaPrinter");
/* Allocate a new client */
- client = avahi_client_new(avahi_simple_poll_get(simple_poll), client_callback, NULL, &error);
+ client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
/* Check wether creating the client object succeeded */
if (!client) {
/* Create a new AvahiClient instance */
client = avahi_client_new (poll_api, /* AvahiPoll object from above */
+ 0,
avahi_client_callback, /* Callback function for Client state changes */
loop, /* User data */
&error); /* Error return */