dbus_connection_unref(client->bus);
client->bus = NULL;
}
-
+
/* Fall through */
-
+
case AVAHI_CLIENT_S_COLLISION:
case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_S_FAILURE:
/* Clear cached strings */
avahi_free(client->host_name);
} else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged")) {
int32_t state;
+ char *e;
+ int c;
if (!(dbus_message_get_args(
message, &error,
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);
goto fail;
}
-
+
+ if ((c = avahi_error_dbus_to_number(e)) != AVAHI_OK)
+ avahi_client_set_errno(client, c);
+
client_set_state(client, (AvahiClientState) state);
} else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "StateChanged")) {
if (g) {
int32_t state;
- if (!(dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID)) ||
+ char *e;
+ int c;
+
+ if (!(dbus_message_get_args(
+ message, &error,
+ DBUS_TYPE_INT32, &state,
+ 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);
goto fail;
}
+
+ if ((c = avahi_error_dbus_to_number(e)) != AVAHI_OK)
+ avahi_client_set_errno(client, c);
avahi_entry_group_set_state(g, state);
}
AVAHI_CLIENT_S_REGISTERING = AVAHI_SERVER_REGISTERING,
AVAHI_CLIENT_S_RUNNING = AVAHI_SERVER_RUNNING,
AVAHI_CLIENT_S_COLLISION = AVAHI_SERVER_COLLISION,
+ AVAHI_CLIENT_S_FAILURE = AVAHI_SERVER_FAILURE,
AVAHI_CLIENT_DISCONNECTED = 100 /**< Lost DBUS connection to the Avahi daemon */
} AvahiClientState;
#include <avahi-common/dbus.h>
static const char * const table[- AVAHI_ERR_MAX] = {
- NULL, /* OK */
+ AVAHI_DBUS_ERR_OK,
AVAHI_DBUS_ERR_FAILURE,
AVAHI_DBUS_ERR_BAD_STATE,
AVAHI_DBUS_ERR_INVALID_HOST_NAME,
AVAHI_DBUS_ERR_NO_NETWORK,
AVAHI_DBUS_ERR_INVALID_TTL,
AVAHI_DBUS_ERR_IS_PATTERN,
- AVAHI_DBUS_ERR_LOCAL_COLLISION,
+ AVAHI_DBUS_ERR_COLLISION,
AVAHI_DBUS_ERR_INVALID_RECORD,
AVAHI_DBUS_ERR_INVALID_SERVICE_NAME,
AVAHI_DBUS_ERR_INVALID_SERVICE_TYPE,
#define AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER AVAHI_DBUS_NAME".HostNameResolver"
#define AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER AVAHI_DBUS_NAME".ServiceResolver"
+#define AVAHI_DBUS_ERR_OK "org.freedesktop.Avahi.Success"
#define AVAHI_DBUS_ERR_FAILURE "org.freedesktop.Avahi.Failure"
#define AVAHI_DBUS_ERR_BAD_STATE "org.freedesktop.Avahi.BadStateError"
#define AVAHI_DBUS_ERR_INVALID_HOST_NAME "org.freedesktop.Avahi.InvalidHostNameError"
#define AVAHI_DBUS_ERR_NO_NETWORK "org.freedesktop.Avahi.NoNetworkError"
#define AVAHI_DBUS_ERR_INVALID_TTL "org.freedesktop.Avahi.InvalidTTLError"
#define AVAHI_DBUS_ERR_IS_PATTERN "org.freedesktop.Avahi.IsPatternError"
-#define AVAHI_DBUS_ERR_LOCAL_COLLISION "org.freedesktop.Avahi.LocalCollisionError"
+#define AVAHI_DBUS_ERR_COLLISION "org.freedesktop.Avahi.CollisionError"
#define AVAHI_DBUS_ERR_INVALID_RECORD "org.freedesktop.Avahi.InvalidRecordError"
#define AVAHI_DBUS_ERR_INVALID_SERVICE_NAME "org.freedesktop.Avahi.InvalidServiceNameError"
#define AVAHI_DBUS_ERR_INVALID_SERVICE_TYPE "org.freedesktop.Avahi.InvalidServiceTypeError"
AVAHI_ENTRY_GROUP_UNCOMMITED, /**< The group has not yet been commited, the user must still call avahi_entry_group_commit() */
AVAHI_ENTRY_GROUP_REGISTERING, /**< The entries of the group are currently being registered */
AVAHI_ENTRY_GROUP_ESTABLISHED, /**< The entries have successfully been established */
- AVAHI_ENTRY_GROUP_COLLISION /**< A name collision for one of the entries in the group has been detected, the entries have been withdrawn */
+ AVAHI_ENTRY_GROUP_COLLISION, /**< A name collision for one of the entries in the group has been detected, the entries have been withdrawn */
+ AVAHI_ENTRY_GROUP_FAILURE /**< Some kind of failure happened, the entries have been withdrawn */
} AvahiEntryGroupState;
/** The type of domain to browse for */
AVAHI_SERVER_INVALID, /**< Invalid state (initial) */
AVAHI_SERVER_REGISTERING, /**< Host RRs are being registered */
AVAHI_SERVER_RUNNING, /**< All host RRs have been established */
- AVAHI_SERVER_COLLISION /**< There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name() */
+ AVAHI_SERVER_COLLISION, /**< There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name() */
+ AVAHI_SERVER_FAILURE /**< Some fatal failure happened, the server is unable to proceed */
} AvahiServerState;
/** For every service a special TXT item is implicitly added, which
AVAHI_ERR_NO_NETWORK = -5, /**< No suitable network protocol available */
AVAHI_ERR_INVALID_TTL = -6, /**< Invalid DNS TTL */
AVAHI_ERR_IS_PATTERN = -7, /**< RR key is pattern */
- AVAHI_ERR_LOCAL_COLLISION = -8, /**< Local name collision */
+ AVAHI_ERR_COLLISION = -8, /**< Name collision */
AVAHI_ERR_INVALID_RECORD = -9, /**< Invalid RR */
AVAHI_ERR_INVALID_SERVICE_NAME = -10, /**< Invalid service name */
return;
switch (state) {
+ case AVAHI_CLIENT_S_FAILURE:
case AVAHI_CLIENT_DISCONNECTED:
reg_report_status(data, SW_DISCOVERY_PUBLISH_INVALID);
break;
case AVAHI_ENTRY_GROUP_UNCOMMITED:
/* Ignore */
break;
+
+ case AVAHI_ENTRY_GROUP_FAILURE:
+ reg_report_status(data, SW_DISCOVERY_PUBLISH_INVALID);
+ break;
+
}
}
return kDNSServiceErr_BadParam;
- case AVAHI_ERR_LOCAL_COLLISION:
+ case AVAHI_ERR_COLLISION:
return kDNSServiceErr_NameConflict;
case AVAHI_ERR_TOO_MANY_CLIENTS:
static void generic_client_callback(AvahiClient *s, AvahiClientState state, void* userdata) {
DNSServiceRef sdref = userdata;
-
+ int error = kDNSServiceErr_Unknown;
+
assert(s);
assert(sdref);
assert(sdref->n_ref >= 1);
switch (state) {
- case AVAHI_CLIENT_DISCONNECTED: {
+ case AVAHI_CLIENT_S_FAILURE:
+
+ error = map_error(avahi_client_errno(s));
+
+ /* Fall through */
+
+ case AVAHI_CLIENT_DISCONNECTED:
if (sdref->service_browser_callback)
- sdref->service_browser_callback(sdref, 0, 0, kDNSServiceErr_Unknown, NULL, NULL, NULL, sdref->context);
+ sdref->service_browser_callback(sdref, 0, 0, error, NULL, NULL, NULL, sdref->context);
else if (sdref->service_resolver_callback)
- sdref->service_resolver_callback(sdref, 0, 0, kDNSServiceErr_Unknown, NULL, NULL, 0, 0, NULL, sdref->context);
+ sdref->service_resolver_callback(sdref, 0, 0, error, NULL, NULL, 0, 0, NULL, sdref->context);
else if (sdref->domain_browser_callback)
- sdref->domain_browser_callback(sdref, 0, 0, kDNSServiceErr_Unknown, NULL, sdref->context);
+ sdref->domain_browser_callback(sdref, 0, 0, error, NULL, sdref->context);
break;
- }
case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION:
return;
switch (state) {
- case AVAHI_CLIENT_DISCONNECTED:
+ case AVAHI_CLIENT_DISCONNECTED:
+ reg_report_error(sdref, kDNSServiceErr_Unknown);
+ break;
- reg_report_error(sdref, kDNSServiceErr_NoError);
+ case AVAHI_CLIENT_S_FAILURE:
+ reg_report_error(sdref, map_error(avahi_client_errno(s)));
break;
case AVAHI_CLIENT_S_RUNNING: {
case AVAHI_ENTRY_GROUP_UNCOMMITED:
/* Ignore */
break;
+
+ case AVAHI_ENTRY_GROUP_FAILURE:
+ /* Inform the user */
+ reg_report_error(sdref, map_error(avahi_client_errno(sdref->client)));
+ break;
+
}
}
/* Add a new record */
if (check_record_conflict(s, interface, protocol, r, flags) < 0) {
- avahi_server_set_errno(s, AVAHI_ERR_LOCAL_COLLISION);
+ avahi_server_set_errno(s, AVAHI_ERR_COLLISION);
return NULL;
}
<method name="GetState">
<arg name="state" type="i" direction="out"/>
</method>
+
<signal name="StateChanged">
<arg name="state" type="i"/>
+ <arg name="error" type="s"/>
</signal>
<method name="IsEmpty">
<method name="GetState">
<arg name="state" type="i" direction="out"/>
</method>
+
<signal name="StateChanged">
<arg name="state" type="i"/>
+ <arg name="error" type="s"/>
</signal>
<method name="GetLocalServiceCookie">
EntryGroupInfo *i = userdata;
DBusMessage *m;
int32_t t;
+ const char *e;
assert(s);
assert(g);
assert(i);
m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "StateChanged");
+
t = (int32_t) state;
- dbus_message_append_args(m, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
+ if (state == AVAHI_ENTRY_GROUP_FAILURE)
+ e = avahi_error_number_to_dbus(avahi_server_errno(s));
+ else if (state == AVAHI_ENTRY_GROUP_COLLISION)
+ e = AVAHI_DBUS_ERR_COLLISION;
+ else
+ e = AVAHI_DBUS_ERR_OK;
+
+ dbus_message_append_args(
+ m,
+ DBUS_TYPE_INT32, &t,
+ DBUS_TYPE_STRING, &e,
+ DBUS_TYPE_INVALID);
dbus_message_set_destination(m, i->client->name);
dbus_connection_send(server->bus, m, NULL);
dbus_message_unref(m);
void dbus_protocol_server_state_changed(AvahiServerState state) {
DBusMessage *m;
int32_t t;
+ const char *e;
if (!server)
return;
m = dbus_message_new_signal(AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged");
t = (int32_t) state;
+
+ if (state == AVAHI_SERVER_COLLISION)
+ e = AVAHI_DBUS_ERR_COLLISION;
+ else if (state == AVAHI_SERVER_FAILURE)
+ e = avahi_error_number_to_dbus(avahi_server_errno(avahi_server));
+ else
+ e = AVAHI_DBUS_ERR_OK;
+
dbus_message_append_args(m, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
dbus_connection_send(server->bus, m, NULL);
dbus_message_unref(m);
#endif
AvahiServer *avahi_server = NULL;
+AvahiSimplePoll *simple_poll_api = NULL;
typedef enum {
DAEMON_RUN,
}
avahi_server_set_wide_area_servers(avahi_server, a, n);
-
}
static void server_callback(AvahiServer *s, AvahiServerState state, void *userdata) {
assert(s);
assert(c);
- /** This function is possibly called before the global variable
+ /* This function is possibly called before the global variable
* avahi_server has been set, therefore we do it explicitly */
avahi_server = s;
dbus_protocol_server_state_changed(state);
#endif
- if (state == 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));
- static_service_add_to_server();
-
- remove_dns_server_entry_groups();
-
- if (c->publish_resolv_conf && resolv_conf && resolv_conf[0])
- resolv_conf_entry_group = add_dns_servers(s, resolv_conf_entry_group, resolv_conf);
-
- 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();
-
- } else if (state == AVAHI_SERVER_COLLISION) {
- char *n;
+ 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));
+ static_service_add_to_server();
+
+ remove_dns_server_entry_groups();
+
+ if (c->publish_resolv_conf && resolv_conf && resolv_conf[0])
+ resolv_conf_entry_group = add_dns_servers(s, resolv_conf_entry_group, resolv_conf);
+
+ 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();
+ break;
+
+ case AVAHI_SERVER_COLLISION: {
+ char *n;
+
+ static_service_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_server_set_host_name(s, n);
+ avahi_free(n);
+ break;
+ }
- static_service_remove_from_server();
+ case AVAHI_SERVER_FAILURE:
- remove_dns_server_entry_groups();
+ avahi_log_error("Server error: %s", avahi_strerror(avahi_server_errno(s)));
+ avahi_simple_poll_quit(simple_poll_api);
+ break;
- n = avahi_alternative_host_name(avahi_server_get_host_name(s));
- avahi_log_warn("Host name conflict, retrying with <%s>", n);
- avahi_server_set_host_name(s, n);
- avahi_free(n);
+ case AVAHI_SERVER_REGISTERING:
+ case AVAHI_SERVER_INVALID:
+ break;
+
}
}
static void signal_callback(AvahiWatch *watch, int fd, AvahiWatchEvent event, void *userdata) {
int sig;
- AvahiSimplePoll *simple_poll_api = userdata;
const AvahiPoll *poll_api;
assert(watch);
static int run_server(DaemonConfig *c) {
int r = -1;
int error;
- AvahiSimplePoll *simple_poll_api;
const AvahiPoll *poll_api;
AvahiWatch *sig_watch;
dbus_protocol_shutdown();
#endif
- if (avahi_server)
+ if (avahi_server) {
avahi_server_free(avahi_server);
+ avahi_server = NULL;
+ }
daemon_signal_done();
if (sig_watch)
poll_api->watch_free(sig_watch);
- if (simple_poll_api)
+ if (simple_poll_api) {
avahi_simple_poll_free(simple_poll_api);
+ simple_poll_api = NULL;
+ }
if (r != 0 && c->daemonize)
daemon_retval_send(1);
***/
#include <avahi-core/core.h>
+#include <avahi-common/simple-watch.h>
extern AvahiServer *avahi_server;
+extern AvahiSimplePoll *simple_poll_api;
+
#endif
* add support for subtypes in static services
* Add static host configuration like static services [lathiat]
* wrap avahi_server_add_record() via DBUS and in avahi-client [lathiat]
+* make sure that all limit definitions end with _MAX
+* unify argument oder of functions returning a string in a user supplied buffer
later:
* add simplification routine for adding services
/* Called whenever the entry group state changes */
- if (state == AVAHI_ENTRY_GROUP_ESTABLISHED)
- /* The entry group has been established successfully */
- fprintf(stderr, "Service '%s' successfully established.\n", name);
-
- else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
- char *n;
+ switch (state) {
+ case AVAHI_ENTRY_GROUP_ESTABLISHED :
+ /* The entry group has been established successfully */
+ fprintf(stderr, "Service '%s' successfully established.\n", name);
+ break;
+
+ case AVAHI_ENTRY_GROUP_COLLISION : {
+ char *n;
+
+ /* A service name collision happened. Let's pick a new name */
+ n = avahi_alternative_service_name(name);
+ avahi_free(name);
+ name = n;
+
+ fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
+
+ /* And recreate the services */
+ create_services(avahi_entry_group_get_client(g));
+ break;
+ }
- /* A service name collision happened. Let's pick a new name */
- n = avahi_alternative_service_name(name);
- avahi_free(name);
- name = n;
+ case AVAHI_ENTRY_GROUP_FAILURE :
- fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
+ /* Some kind of failure happened while we were registering our services */
+ avahi_simple_poll_quit(simple_poll);
+ break;
- /* And recreate the services */
- create_services(avahi_entry_group_get_client(g));
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ ;
}
}
fail:
avahi_simple_poll_quit(simple_poll);
- return;
}
static void client_callback(AvahiClient *c, AvahiClientState state, void * userdata) {
/* Called whenever the client or server state changes */
- if (state == AVAHI_CLIENT_S_RUNNING) {
+ switch (state) {
+ case AVAHI_CLIENT_S_RUNNING:
- /* The server has startup successfully and registered its host
- * name on the network, so it's time to create our services */
- if (group)
- create_services(c);
-
- } else if (state == AVAHI_CLIENT_S_COLLISION) {
-
- /* Let's drop our registered services. When the server is back
- * in AVAHI_SERVER_RUNNING state we will register them
- * again with the new host name. */
- if (group)
- avahi_entry_group_reset(group);
-
- } else if (state == AVAHI_CLIENT_DISCONNECTED) {
+ /* The server has startup successfully and registered its host
+ * name on the network, so it's time to create our services */
+ if (!group)
+ create_services(c);
+ break;
- fprintf(stderr, "Server connection terminated.\n");
- avahi_simple_poll_quit(simple_poll);
+ case AVAHI_CLIENT_S_COLLISION:
+
+ /* Let's drop our registered services. When the server is back
+ * in AVAHI_SERVER_RUNNING state we will register them
+ * again with the new host name. */
+ if (group)
+ avahi_entry_group_reset(group);
+ break;
+
+ case AVAHI_CLIENT_DISCONNECTED:
+
+ fprintf(stderr, "Server connection terminated.\n");
+ avahi_simple_poll_quit(simple_poll);
+
+ break;
+
+ case AVAHI_CLIENT_S_FAILURE:
+ case AVAHI_CLIENT_S_INVALID:
+ case AVAHI_CLIENT_S_REGISTERING:
+ ;
}
}
/* Called whenever the entry group state changes */
- if (state == AVAHI_ENTRY_GROUP_ESTABLISHED)
- /* The entry group has been established successfully */
- fprintf(stderr, "Service '%s' successfully established.\n", name);
-
- else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
- char *n;
-
- /* A service name collision happened. Let's pick a new name */
- n = avahi_alternative_service_name(name);
- avahi_free(name);
- name = n;
+ switch (state) {
+
+ case AVAHI_ENTRY_GROUP_ESTABLISHED:
+
+ /* The entry group has been established successfully */
+ fprintf(stderr, "Service '%s' successfully established.\n", name);
+ break;
+
+ case AVAHI_ENTRY_GROUP_COLLISION: {
+ char *n;
+
+ /* A service name collision happened. Let's pick a new name */
+ n = avahi_alternative_service_name(name);
+ avahi_free(name);
+ name = n;
+
+ fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
+
+ /* And recreate the services */
+ create_services(s);
+ break;
+ }
+
+ case AVAHI_ENTRY_GROUP_FAILURE :
- fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
+ /* Some kind of failure happened while we were registering our services */
+ avahi_simple_poll_quit(simple_poll);
+ break;
- /* And recreate the services */
- create_services(s);
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ ;
}
}
fail:
avahi_simple_poll_quit(simple_poll);
- return;
}
static void server_callback(AvahiServer *s, AvahiServerState state, void * userdata) {
/* Called whenever the server state changes */
- if (state == AVAHI_SERVER_RUNNING) {
- /* The serve has startup successfully and registered its host
- * name on the network, so it's time to create our services */
-
- if (group)
- create_services(s);
-
- } else if (state == AVAHI_SERVER_COLLISION) {
- char *n;
- int r;
-
- /* A host name collision happened. Let's pick a new name for the server */
- n = avahi_alternative_host_name(avahi_server_get_host_name(s));
- fprintf(stderr, "Host name collision, retrying with '%s'\n", n);
- r = avahi_server_set_host_name(s, n);
- avahi_free(n);
-
- if (r < 0) {
- fprintf(stderr, "Failed to set new host name: %s\n", avahi_strerror(r));
+ switch (state) {
+
+ case AVAHI_SERVER_RUNNING:
+ /* The serve has startup successfully and registered its host
+ * name on the network, so it's time to create our services */
+
+ if (group)
+ create_services(s);
+
+ break;
+
+ case AVAHI_SERVER_COLLISION: {
+ char *n;
+ int r;
+
+ /* A host name collision happened. Let's pick a new name for the server */
+ n = avahi_alternative_host_name(avahi_server_get_host_name(s));
+ fprintf(stderr, "Host name collision, retrying with '%s'\n", n);
+ r = avahi_server_set_host_name(s, n);
+ avahi_free(n);
+
+ if (r < 0) {
+ fprintf(stderr, "Failed to set new host name: %s\n", avahi_strerror(r));
+
+ avahi_simple_poll_quit(simple_poll);
+ return;
+ }
+
+ /* Let's drop our registered services. When the server is back
+ * in AVAHI_SERVER_RUNNING state we will register them
+ * again with the new host name. */
+ if (group)
+ avahi_s_entry_group_reset(group);
+
+ break;
+ }
+ case AVAHI_SERVER_FAILURE:
+
+ /* Terminate on failure */
+
+ fprintf(stderr, "Server failure: %s\n", avahi_strerror(avahi_server_errno(s)));
avahi_simple_poll_quit(simple_poll);
- return;
- }
+ break;
- /* Let's drop our registered services. When the server is back
- * in AVAHI_SERVER_RUNNING state we will register them
- * again with the new host name. */
- if (group)
- avahi_s_entry_group_reset(group);
+ case AVAHI_SERVER_INVALID:
+ case AVAHI_SERVER_REGISTERING:
+ ;
}
}