AVAHI_DBUS_ERR_INVALID_FLAGS,
AVAHI_DBUS_ERR_NOT_FOUND,
AVAHI_DBUS_ERR_INVALID_CONFIG,
- AVAHI_DBUS_ERR_VERSION_MISMATCH
+ AVAHI_DBUS_ERR_VERSION_MISMATCH,
+ AVAHI_DBUS_ERR_INVALID_SERVICE_SUBTYPE
};
int avahi_error_dbus_to_number(const char *s) {
#define AVAHI_DBUS_ERR_NOT_FOUND "org.freedesktop.Avahi.NotFoundError"
#define AVAHI_DBUS_ERR_INVALID_CONFIG "org.freedesktop.Avahi.InvalidConfigurationError"
#define AVAHI_DBUS_ERR_VERSION_MISMATCH "org.freedesktop.Avahi.VersionMismatchError"
+#define AVAHI_DBUS_ERR_INVALID_SERVICE_SUBTYPE "org.freedesktop.Avahi.InvalidServiceSubtypeError"
/** Convert a DBus error string into an Avahi error number */
int avahi_error_dbus_to_number(const char *s);
"Invalid flags",
"Not found",
"Invalid configuration",
- "Version mismatch"
+ "Version mismatch",
+ "Invalid service subtype"
};
if (-error < 0 || -error >= -AVAHI_ERR_MAX)
/** Error codes used by avahi */
enum {
- AVAHI_OK = 0, /**< OK */
- AVAHI_ERR_FAILURE = -1, /**< Generic error code */
- AVAHI_ERR_BAD_STATE = -2, /**< Object was in a bad state */
- AVAHI_ERR_INVALID_HOST_NAME = -3, /**< Invalid host name */
- AVAHI_ERR_INVALID_DOMAIN_NAME = -4, /**< Invalid domain name */
- 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_INVALID_RECORD = -9, /**< Invalid RR */
- AVAHI_ERR_INVALID_SERVICE_NAME = -10, /**< Invalid service name */
- AVAHI_ERR_INVALID_SERVICE_TYPE = -11, /**< Invalid service type */
- AVAHI_ERR_INVALID_PORT = -12, /**< Invalid port number */
- AVAHI_ERR_INVALID_KEY = -13, /**< Invalid key */
- AVAHI_ERR_INVALID_ADDRESS = -14, /**< Invalid address */
- AVAHI_ERR_TIMEOUT = -15, /**< Timeout reached */
- AVAHI_ERR_TOO_MANY_CLIENTS = -16, /**< Too many clients */
- AVAHI_ERR_TOO_MANY_OBJECTS = -17, /**< Too many objects */
- AVAHI_ERR_TOO_MANY_ENTRIES = -18, /**< Too many entries */
- AVAHI_ERR_OS = -19, /**< OS error */
- AVAHI_ERR_ACCESS_DENIED = -20, /**< Access denied */
- AVAHI_ERR_INVALID_OPERATION = -21, /**< Invalid operation */
- AVAHI_ERR_DBUS_ERROR = -22, /**< An unexpected DBUS error occured */
- AVAHI_ERR_NOT_CONNECTED = -23, /**< Could not get a connection to the daemon */
- AVAHI_ERR_NO_MEMORY = -24, /**< Memory exhausted */
- AVAHI_ERR_INVALID_OBJECT = -25, /**< The object passed to this function was invalid */
- AVAHI_ERR_NO_DAEMON = -26, /**< Daemon not running */
- AVAHI_ERR_INVALID_INTERFACE = -27, /**< Invalid interface */
- AVAHI_ERR_INVALID_PROTOCOL = -28, /**< Invalid protocol */
- AVAHI_ERR_INVALID_FLAGS = -29, /**< Invalid flags */
- AVAHI_ERR_NOT_FOUND = -30, /**< Not found */
- AVAHI_ERR_INVALID_CONFIG = -31, /**< Configuration error */
- AVAHI_ERR_VERSION_MISMATCH = -32, /**< Verson mismatch */
+ AVAHI_OK = 0, /**< OK */
+ AVAHI_ERR_FAILURE = -1, /**< Generic error code */
+ AVAHI_ERR_BAD_STATE = -2, /**< Object was in a bad state */
+ AVAHI_ERR_INVALID_HOST_NAME = -3, /**< Invalid host name */
+ AVAHI_ERR_INVALID_DOMAIN_NAME = -4, /**< Invalid domain name */
+ 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_INVALID_RECORD = -9, /**< Invalid RR */
+ AVAHI_ERR_INVALID_SERVICE_NAME = -10, /**< Invalid service name */
+ AVAHI_ERR_INVALID_SERVICE_TYPE = -11, /**< Invalid service type */
+ AVAHI_ERR_INVALID_PORT = -12, /**< Invalid port number */
+ AVAHI_ERR_INVALID_KEY = -13, /**< Invalid key */
+ AVAHI_ERR_INVALID_ADDRESS = -14, /**< Invalid address */
+ AVAHI_ERR_TIMEOUT = -15, /**< Timeout reached */
+ AVAHI_ERR_TOO_MANY_CLIENTS = -16, /**< Too many clients */
+ AVAHI_ERR_TOO_MANY_OBJECTS = -17, /**< Too many objects */
+ AVAHI_ERR_TOO_MANY_ENTRIES = -18, /**< Too many entries */
+ AVAHI_ERR_OS = -19, /**< OS error */
+ AVAHI_ERR_ACCESS_DENIED = -20, /**< Access denied */
+ AVAHI_ERR_INVALID_OPERATION = -21, /**< Invalid operation */
+ AVAHI_ERR_DBUS_ERROR = -22, /**< An unexpected DBUS error occured */
+ AVAHI_ERR_NOT_CONNECTED = -23, /**< Could not get a connection to the daemon */
+ AVAHI_ERR_NO_MEMORY = -24, /**< Memory exhausted */
+ AVAHI_ERR_INVALID_OBJECT = -25, /**< The object passed to this function was invalid */
+ AVAHI_ERR_NO_DAEMON = -26, /**< Daemon not running */
+ AVAHI_ERR_INVALID_INTERFACE = -27, /**< Invalid interface */
+ AVAHI_ERR_INVALID_PROTOCOL = -28, /**< Invalid protocol */
+ AVAHI_ERR_INVALID_FLAGS = -29, /**< Invalid flags */
+ AVAHI_ERR_NOT_FOUND = -30, /**< Not found */
+ AVAHI_ERR_INVALID_CONFIG = -31, /**< Configuration error */
+ AVAHI_ERR_VERSION_MISMATCH = -32, /**< Verson mismatch */
+ AVAHI_ERR_INVALID_SERVICE_SUBTYPE = -33, /**< Invalid service subtype */
/****
**** IF YOU ADD A NEW ERROR CODE HERE, PLEASE DON'T FORGET TO ADD
**** Also remember to update the MAX value below.
****/
- AVAHI_ERR_MAX = -33
+ AVAHI_ERR_MAX = -34
};
/** Return a human readable error string for the specified error code */
case AVAHI_ERR_INVALID_PORT:
case AVAHI_ERR_INVALID_KEY:
case AVAHI_ERR_INVALID_ADDRESS:
+ case AVAHI_ERR_INVALID_SERVICE_SUBTYPE:
return kDNSServiceErr_BadParam;
uint16_t port,
AvahiStringList *strlst);
+/** Add a subtype for an already existing service */
+int avahi_server_add_service_subtype(
+ AvahiServer *s,
+ AvahiSEntryGroup *g,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiPublishFlags flags,
+ const char *name, /**< Specify the name of main service you already added here */
+ const char *type, /**< Specify the main type of the service you already added here */
+ const char *domain, /**< Specify the main type of the service you already added here */
+ const char *subtype /**< The new subtype for the specified service */ );
+
/** The type of DNS server */
typedef enum {
AVAHI_DNS_SERVER_RESOLVE, /**< Unicast DNS servers for normal resolves (_domain._udp)*/
assert(type);
assert(name);
- if (!AVAHI_IF_VALID(interface)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_INTERFACE);
- goto fail;
- }
-
- if (!AVAHI_PROTO_VALID(protocol)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_PROTOCOL);
- goto fail;
- }
-
- if (!AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_FLAGS);
- goto fail;
- }
-
- if (!avahi_is_valid_service_name(name)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME);
- goto fail;
- }
-
- if (!avahi_is_valid_service_type(type)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE);
- goto fail;
- }
-
- if (domain && !avahi_is_valid_domain_name(domain)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
- goto fail;
- }
-
- if (host && !avahi_is_valid_domain_name(host)) {
- ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
- goto fail;
- }
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(interface), AVAHI_ERR_INVALID_PROTOCOL);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY), AVAHI_ERR_INVALID_FLAGS);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !host || avahi_is_valid_domain_name(host), AVAHI_ERR_INVALID_HOST_NAME);
if (!domain)
domain = s->domain_name;
if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 ||
(ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, type, domain)) < 0 ||
- (ret = avahi_service_name_join(enum_ptr, sizeof(enum_ptr), NULL, "_services._dns-sd._udp", domain)) < 0)
+ (ret = avahi_service_name_join(enum_ptr, sizeof(enum_ptr), NULL, "_services._dns-sd._udp", domain)) < 0) {
+ avahi_server_set_errno(s, ret);
goto fail;
+ }
+ /* Add service enumeration PTR record */
+
if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
goto fail;
+ /* Add SRV record */
+
if (!(r = avahi_record_new_full(svc_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV, AVAHI_DEFAULT_TTL_HOST_NAME))) {
ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
goto fail;
if (ret < 0)
goto fail;
+ /* Add TXT record */
+
if (!(flags & AVAHI_PUBLISH_NO_COOKIE))
strlst = add_magic_cookie(s, strlst);
if (ret < 0)
goto fail;
+ /* Add service type enumeration record */
+
ret = avahi_server_add_ptr(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY), AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
fail:
return ret;
}
+
+
int avahi_server_add_service_strlst(
AvahiServer *s,
AvahiSEntryGroup *g,
return ret;
}
+int avahi_server_add_service_subtype(
+ AvahiServer *s,
+ AvahiSEntryGroup *g,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiPublishFlags flags,
+ const char *name,
+ const char *type,
+ const char *domain,
+ const char *subtype) {
+
+ int ret = AVAHI_OK;
+ char svc_name[AVAHI_DOMAIN_NAME_MAX], ptr_name[AVAHI_DOMAIN_NAME_MAX];
+
+ assert(name);
+ assert(type);
+ assert(subtype);
+
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(interface), AVAHI_ERR_INVALID_PROTOCOL);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY), AVAHI_ERR_INVALID_FLAGS);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(subtype), AVAHI_ERR_INVALID_SERVICE_SUBTYPE);
+
+ if (!domain)
+ domain = s->domain_name;
+
+ if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 ||
+ (ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, subtype, domain)) < 0) {
+ avahi_server_set_errno(s, ret);
+ goto fail;
+ }
+
+ if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
+ goto fail;
+
+fail:
+
+ return ret;
+}
+
static void hexstring(char *s, size_t sl, const void *p, size_t pl) {
static const char hex[] = "0123456789abcdef";
int b = 0;
} \
}
+#define AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(server, expression, error) {\
+ if (!(expression)) { \
+ ret = avahi_server_set_errno((server), (error)); \
+ goto fail; \
+ } \
+}
+
#endif
goto fail;
}
+ /* Add an additional (hypothetic) subtype */
+ if ((ret = avahi_server_add_service_subtype(s, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL, "_magic._sub._printer._tcp") < 0)) {
+ fprintf(stderr, "Failed to add subtype _magic._sub._printer._tcp: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
/* Tell the server to register the service */
if ((ret = avahi_s_entry_group_commit(group)) < 0) {
fprintf(stderr, "Failed to commit entry_group: %s\n", avahi_strerror(ret));