46836e | 2005-04-09 | Jonas Wallden | | reason = "Bad interface index";
break;
default:
reason = "Unknown error";
break;
}
Pike_error("DNS_SD: %s Reason: %s (%d)\n", msg, reason, err);
}
static void start_service_callback(DNSServiceRef ref,
DNSServiceFlags flags,
DNSServiceErrorType error,
const char *name,
const char *regtype,
const char *domain,
void *context)
{
}
static DNSServiceErrorType start_service(struct service *svc,
char *name,
char *service,
char *domain,
int port,
char *txt,
int txtlen)
{
DNSServiceErrorType err;
DNSServiceRef ref;
if (name && !strlen(name))
name = NULL;
if (domain && !strlen(domain))
domain = NULL;
if (txt && !txtlen)
txt = NULL;
|
46836e | 2005-04-09 | Jonas Wallden | | return err;
}
static void stop_service(struct service *svc)
{
if (svc->service_ref) {
DNSServiceRefDeallocate(svc->service_ref);
svc->service_ref = NULL;
}
}
static DNSServiceErrorType update_txt_record(struct service *svc,
char *txt, int txtlen)
{
if (svc->service_ref) {
int ttl = 0;
return DNSServiceUpdateRecord(svc->service_ref, NULL, 0,
txtlen, txt, ttl);
}
return kDNSServiceErr_Invalid;
}
#endif /* HAVE_DNS_SD */
#if defined(HAVE_HOWL) && !defined(HAVE_DNS_SD)
#ifdef HAVE_HOWL_H
#include <howl.h>
#endif
#define IS_ERR(x) ((x) != SW_OKAY)
static sw_discovery service_session = NULL;
static THREAD_T service_thread;
struct service {
sw_discovery_oid service_ref;
};
static void raise_error(char *msg, sw_result err)
{
char *reason;
if (err == SW_OKAY)
return;
switch (err) {
case SW_DISCOVERY_E_NO_MEM:
reason = "No memory";
break;
case SW_DISCOVERY_E_BAD_PARAM:
reason = "Bad parameter";
break;
case SW_DISCOVERY_E_UNKNOWN:
default:
reason = "Unknown error";
break;
}
Pike_error("DNS_SD: %s Reason: %s (%d)\n", msg, reason, err);
}
static sw_result start_reply_fn(sw_discovery discovery,
sw_discovery_publish_status status,
sw_discovery_oid oid,
sw_opaque extra)
{
return SW_OKAY;
}
static sw_result start_service(struct service *svc,
char *name,
char *service,
char *domain,
int port,
char *txt,
int txtlen)
{
sw_result err = SW_DISCOVERY_E_UNKNOWN;
if (domain && !strlen(domain))
domain = NULL;
if (txt && !txtlen)
txt = NULL;
err = sw_discovery_publish(service_session,
0, name, service, domain, NULL, port,
txt, txtlen, start_reply_fn, NULL,
&svc->service_ref);
return err;
}
static void stop_service(struct service *svc)
{
if (svc->service_ref) {
sw_discovery_cancel(service_session, svc->service_ref);
}
}
static sw_result update_txt_record(struct service *svc, char *txt, int txtlen)
{
if (svc->service_ref) {
return sw_discovery_publish_update(service_session,
svc->service_ref,
txt, txtlen);
}
return SW_DISCOVERY_E_UNKNOWN;
}
static void * howl_thread(void *arg)
{
sw_discovery_run(service_session);
return NULL;
}
static void init_howl_module()
{
if (sw_discovery_init(&service_session) == SW_OKAY) {
th_create_small(&service_thread, howl_thread, NULL);
}
}
static void exit_howl_module()
{
if (service_session)
sw_discovery_fina(service_session);
if (service_thread)
th_kill(service_thread, SIGCHLD);
}
#endif /* defined(HAVE_HOWL) && !defined(HAVE_DNS_SD) */
static void f_update_txt(INT32 args)
{
check_all_args("Service->update_txt", args,
BIT_STRING,
0);
if (THIS->service_ref) {
char *txt = sp[0 - args].u.string->str;
int txtlen = sp[0 - args].u.string->len;
int err = update_txt_record(THIS, txt, txtlen);
if (IS_ERR(err))
raise_error("Could not update TXT record.", err);
}
pop_n_elems(args);
}
static void f_create(INT32 args)
{
char *name, *service, *domain, *txt;
int port, txtlen, err;
check_all_args("Service->create", args,
BIT_STRING,
BIT_STRING,
BIT_STRING,
BIT_INT,
BIT_STRING | BIT_VOID,
0);
stop_service(THIS);
name = sp[0 - args].u.string->str;
service = sp[1 - args].u.string->str;
domain = sp[2 - args].u.string->str;
port = sp[3 - args].u.integer;
txt = (args == 5) ? sp[4 - args].u.string->str : NULL;
txtlen = txt ? sp[4 - args].u.string->len : 0;
err = start_service(THIS, name, service, domain, port, txt, txtlen);
if (IS_ERR(err))
raise_error("Could not register service.", err);
pop_n_elems(args);
}
static void init_service_struct(struct object *o)
{
THIS->service_ref = 0;
}
static void exit_service_struct(struct object *o)
{
stop_service(THIS);
}
PIKE_MODULE_INIT
{
start_new_program();
ADD_STORAGE(struct service);
set_init_callback(init_service_struct);
set_exit_callback(exit_service_struct);
ADD_FUNCTION("create", f_create,
tFunc(tStr tStr tStr tInt tOr(tStr, tVoid), tVoid), 0);
ADD_FUNCTION("update_txt", f_update_txt, tFunc(tStr, tVoid), 0);
end_class("Service", 0);
#ifdef HAVE_HOWL
init_howl_module();
#endif
}
PIKE_MODULE_EXIT
{
#ifdef HAVE_HOWL
exit_howl_module();
#endif
}
#else /* defined(HAVE_DNS_SD) || defined(HAVE_HOWL) */
PIKE_MODULE_INIT {}
PIKE_MODULE_EXIT {}
#endif /* defined(HAVE_DNS_SD) || defined(HAVE_HOWL) */
|