Exemple #1
0
int avahi_entry_group_add_service(
    AvahiEntryGroup *group,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiPublishFlags flags,
    const char *name,
    const char *type,
    const char *domain,
    const char *host,
    uint16_t port,
    ...) {

    va_list va;
    int r;
    AvahiStringList *txt;

    assert(group);

    va_start(va, port);
    txt = avahi_string_list_new_va(va);
    r = avahi_entry_group_add_service_strlst(group, interface, protocol, flags, name, type, domain, host, port, txt);
    avahi_string_list_free(txt);
    va_end(va);
    return r;
}
Exemple #2
0
const char *addAvahiGroup(AvahiThreadedPoll *threaded_poll, AvahiClient *client,
    AvahiEntryGroup **group, const char *service_name, unsigned short port, AvahiStringList *txt) {
  *group = avahi_entry_group_new(client, handleGroupStateChange, (void *)service_name);
  if (!*group) {
    return avahi_strerror(avahi_client_errno(client));
  }

  int error = avahi_entry_group_add_service_strlst(
      *group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, service_name,
      SERVICE_TYPE, NULL, NULL, port, txt);
  if (AVAHI_OK != error) {
    avahi_entry_group_free(*group);
    return avahi_strerror(error);
  }

  error = avahi_entry_group_add_service_subtype(*group, AVAHI_IF_UNSPEC,
      AVAHI_PROTO_UNSPEC, 0, service_name, SERVICE_TYPE, NULL, SERVICE_SUBTYPE);
  if (AVAHI_OK != error) {
    avahi_entry_group_free(*group);
    return avahi_strerror(error);
  }

  error = avahi_entry_group_commit(*group);
  if (AVAHI_OK != error) {
    avahi_entry_group_free(*group);
    return avahi_strerror(error);
  }
  return NULL;
}
Exemple #3
0
static void
_create_services(void)
{
  struct mdns_group_entry *pentry;
  int ret;

  DPRINTF(E_DBG, L_MDNS, "Creating service group\n");

  if (!group_entries)
    {
      DPRINTF(E_DBG, L_MDNS, "No entries yet... skipping service create\n");

      return;
    }

    if (mdns_group == NULL)
      {
        mdns_group = avahi_entry_group_new(mdns_client, entry_group_callback, NULL);
	if (!mdns_group)
	  {
            DPRINTF(E_WARN, L_MDNS, "Could not create Avahi EntryGroup: %s\n",
                    avahi_strerror(avahi_client_errno(mdns_client)));

            return;
	  }
      }

    pentry = group_entries;
    while (pentry)
      {
        DPRINTF(E_DBG, L_MDNS, "Re-registering %s/%s\n", pentry->name, pentry->type);

        ret = avahi_entry_group_add_service_strlst(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,
						   avahi_strdup(pentry->name), avahi_strdup(pentry->type),
						   NULL, NULL, pentry->port, pentry->txt);
	if (ret < 0)
	  {
	    DPRINTF(E_WARN, L_MDNS, "Could not add mDNS services: %s\n", avahi_strerror(ret));

	    return;
	  }

	pentry = pentry->next;
      }

    ret = avahi_entry_group_commit(mdns_group);
    if (ret < 0)
      {
	DPRINTF(E_WARN, L_MDNS, "Could not commit mDNS services: %s\n",
		avahi_strerror(avahi_client_errno(mdns_client)));
      }
}
static gboolean
create_service (struct DMAPMdnsPublisherService *service,
		DMAPMdnsPublisher * publisher, GError ** error)
{
	int ret;
	const char *password_record;
	AvahiStringList *txt_records;

	if (service->password_required) {
		password_record = "Password=true";
	} else {
		password_record = "Password=false";
	}

	txt_records = avahi_string_list_new (password_record, NULL);

	if (service->txt_records) {
		//g_debug("Number of txt records: %d", service->txt_records);
		gchar **txt_record = service->txt_records;

		while (*txt_record) {
			txt_records =
				avahi_string_list_add (txt_records,
						       *txt_record);
			txt_record++;
		}
	}

	ret = avahi_entry_group_add_service_strlst (publisher->
						    priv->entry_group,
						    AVAHI_IF_UNSPEC,
						    AVAHI_PROTO_UNSPEC, 0,
						    service->name,
						    service->type_of_service,
						    NULL, NULL, service->port,
						    txt_records);

	avahi_string_list_free (txt_records);

	if (ret < 0) {
		g_set_error (error,
			     DMAP_MDNS_PUBLISHER_ERROR,
			     DMAP_MDNS_PUBLISHER_ERROR_FAILED,
			     "%s: %s",
			     _("Could not add service"),
			     avahi_strerror (ret));
		return FALSE;
	}

	return TRUE;
}
Exemple #5
0
void CZeroconfAvahi::addService(tServiceMap::mapped_type fp_service_info, AvahiClient* fp_client)
{
  assert(fp_client);
  CLog::Log(LOGDEBUG, "CZeroconfAvahi::addService() named: %s type: %s port:%i", fp_service_info->m_name.c_str(), fp_service_info->m_type.c_str(), fp_service_info->m_port);
  //create the group if it doesn't exist
  if (!fp_service_info->mp_group)
  {
    if (!(fp_service_info->mp_group = avahi_entry_group_new(fp_client, &CZeroconfAvahi::groupCallback, this)))
    {
      CLog::Log(LOGDEBUG, "CZeroconfAvahi::addService() avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(fp_client)));
      fp_service_info->mp_group = 0;
      return;
    }
  }


  // add entries to the group if it's empty
  int ret;
  if (avahi_entry_group_is_empty(fp_service_info->mp_group))
  {
    if ((ret = avahi_entry_group_add_service_strlst(fp_service_info->mp_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0),
                                             fp_service_info->m_name.c_str(),
                                             fp_service_info->m_type.c_str(), NULL, NULL, fp_service_info->m_port, fp_service_info->mp_txt) < 0))
    {
      if (ret == AVAHI_ERR_COLLISION)
      {
        char* alt_name = avahi_alternative_service_name(fp_service_info->m_name.c_str());
        fp_service_info->m_name = alt_name;
        avahi_free(alt_name);
        CLog::Log(LOGNOTICE, "CZeroconfAvahi::addService: Service name collision. Renamed to: %s", fp_service_info->m_name.c_str());
        addService(fp_service_info, fp_client);
        return;
      }
      CLog::Log(LOGERROR, "CZeroconfAvahi::addService(): failed to add service named:%s@$(HOSTNAME) type:%s port:%i. Error:%s :/ FIXME!",
                fp_service_info->m_name.c_str(), fp_service_info->m_type.c_str(), fp_service_info->m_port,  avahi_strerror(ret));
      return;
    }
  }

  // Tell the server to register the service
  if ((ret = avahi_entry_group_commit(fp_service_info->mp_group)) < 0)
  {
    CLog::Log(LOGERROR, "CZeroconfAvahi::addService(): Failed to commit entry group! Error:%s",  avahi_strerror(ret));
    // TODO what now? reset the group? free it?
  }
}
static int publish_main_service(struct userdata *u) {
    AvahiStringList *txt = NULL;
    int r = -1;

    pa_assert(u);

    if (!u->main_entry_group) {
        if (!(u->main_entry_group = avahi_entry_group_new(u->client, main_entry_group_callback, u))) {
            pa_log("avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(u->client)));
            goto fail;
        }
    } else
        avahi_entry_group_reset(u->main_entry_group);

    txt = txt_record_server_data(u->core, txt);

    if (avahi_entry_group_add_service_strlst(
                u->main_entry_group,
                AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                0,
                u->service_name,
                SERVICE_TYPE_SERVER,
                NULL,
                NULL,
                compute_port(u),
                txt) < 0) {

        pa_log("avahi_entry_group_add_service_strlst() failed: %s", avahi_strerror(avahi_client_errno(u->client)));
        goto fail;
    }

    if (avahi_entry_group_commit(u->main_entry_group) < 0) {
        pa_log("avahi_entry_group_commit() failed: %s", avahi_strerror(avahi_client_errno(u->client)));
        goto fail;
    }

    r = 0;

fail:
    avahi_string_list_free(txt);

    return r;
}
void
Avahi::PresencePublisher::add_services ()
{
  Ekiga::CallManager::InterfaceList interfaces;
  AvahiStringList* txt_record = NULL;
  int ret;

  for (Ekiga::CallCore::const_iterator iter = call_core.begin ();
       iter != call_core.end ();
       ++iter) {

    Ekiga::CallManager::InterfaceList ints = (*iter)->get_interfaces ();
    interfaces.insert (interfaces.begin (), ints.begin (), ints.end ());

  }

  txt_record = prepare_txt_record ();

  for (Ekiga::CallManager::InterfaceList::const_iterator iter = interfaces.begin ();
       iter != interfaces.end ();
       ++iter) {

    gchar *typ = NULL;

    typ = g_strdup_printf ("_%s._%s",
			   iter->voip_protocol.c_str (),
			   iter->protocol.c_str ());

    /* FIXME: no collision checking here */
    ret = avahi_entry_group_add_service_strlst (group, AVAHI_IF_UNSPEC,
						AVAHI_PROTO_UNSPEC,
						(AvahiPublishFlags)0,
						name, typ,
						NULL, NULL,
						iter->port, txt_record);

    g_free (typ);
  }
  avahi_string_list_free (txt_record);
  ret = avahi_entry_group_commit (group);
}
static int register_stuff(Config *config) {
    assert(config);

    if (!entry_group) {
        if (!(entry_group = avahi_entry_group_new(client, entry_group_callback, config))) {
            fprintf(stderr, "Failed to create entry group: %s\n", avahi_strerror(avahi_client_errno(client)));
            return -1;
        }
    }

    assert(avahi_entry_group_is_empty(entry_group));

    if (config->command == COMMAND_PUBLISH_ADDRESS) {

        if (avahi_entry_group_add_address(entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, config->name, &config->address) < 0) {
            fprintf(stderr, "Failed to add address: %s\n", avahi_strerror(avahi_client_errno(client)));
            return -1;
        }
        
    } else {
        AvahiStringList *i;
        
        assert(config->command == COMMAND_PUBLISH_SERVICE);

        if (avahi_entry_group_add_service_strlst(entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, config->name, config->stype, config->domain, config->host, config->port, config->txt) < 0) {
            fprintf(stderr, "Failed to add service: %s\n", avahi_strerror(avahi_client_errno(client)));
            return -1;
        }

        for (i = config->subtypes; i; i = i->next)
            if (avahi_entry_group_add_service_subtype(entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, config->name, config->stype, config->domain, (char*) i->text) < 0) {
                fprintf(stderr, "Failed to add subtype '%s': %s\n", i->text, avahi_strerror(avahi_client_errno(client)));
                return -1;
            }
    }

    avahi_entry_group_commit(entry_group);

    return 0;
}
Exemple #9
0
static void
epc_service_publish (EpcService *self)
{
  if (self->group)
    {
      gint result;
      GList *iter;

      if (EPC_DEBUG_LEVEL (1))
        g_debug ("%s: Publishing service `%s' for `%s'...",
                 G_STRLOC, self->type, self->dispatcher->priv->name);

      result = avahi_entry_group_add_service_strlst (self->group,
                                                     AVAHI_IF_UNSPEC, self->protocol, 0,
                                                     self->dispatcher->priv->name,
                                                     self->type, self->domain,
                                                     self->host, self->port,
                                                     self->details);

      if (AVAHI_ERR_COLLISION == result)
        epc_dispatcher_handle_collision (self->dispatcher, self->domain);
      else if (AVAHI_OK != result)
        g_warning ("%s: Failed to publish service `%s' for `%s': %s (%d)",
                   G_STRLOC, self->type, self->dispatcher->priv->name,
                   avahi_strerror (result), result);
      else
        {
          for (iter = self->subtypes; iter; iter = iter->next)
            epc_service_publish_subtype (self, iter->data);

          epc_service_schedule_commit (self);
        }
    }
  else
    epc_service_run (self);
}
Exemple #10
0
gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) {
	int publish_result = 0;
	AvahiSessionImplData *idata = data->mdns_impl_data;
	AvahiStringList *lst = NULL;

	g_return_val_if_fail(idata != NULL, FALSE);

	if (!idata->group) {
		idata->group = avahi_entry_group_new(idata->client,
						     _entry_group_cb, idata);
		if (!idata->group) {
			purple_debug_error("bonjour",
				"Unable to initialize the data for the mDNS (%s).\n",
				avahi_strerror(avahi_client_errno(idata->client)));
			return FALSE;
		}
	}

	while (records) {
		PurpleKeyValuePair *kvp = records->data;
		lst = avahi_string_list_add_pair(lst, kvp->key, kvp->value);
		records = records->next;
	}

	/* Publish the service */
	switch (type) {
		case PUBLISH_START:
			publish_result = avahi_entry_group_add_service_strlst(
				idata->group, AVAHI_IF_UNSPEC,
				AVAHI_PROTO_UNSPEC, 0,
				purple_account_get_username(data->account),
				ICHAT_SERVICE, NULL, NULL, data->port_p2pj, lst);
			break;
		case PUBLISH_UPDATE:
			publish_result = avahi_entry_group_update_service_txt_strlst(
				idata->group, AVAHI_IF_UNSPEC,
				AVAHI_PROTO_UNSPEC, 0,
				purple_account_get_username(data->account),
				ICHAT_SERVICE, NULL, lst);
			break;
	}

	/* Free the memory used by temp data */
	avahi_string_list_free(lst);

	if (publish_result < 0) {
		purple_debug_error("bonjour",
			"Failed to add the " ICHAT_SERVICE " service. Error: %s\n",
			avahi_strerror(publish_result));
		return FALSE;
	}

	if (type == PUBLISH_START
			&& (publish_result = avahi_entry_group_commit(idata->group)) < 0) {
		purple_debug_error("bonjour",
			"Failed to commit " ICHAT_SERVICE " service. Error: %s\n",
			avahi_strerror(publish_result));
		return FALSE;
	}

	return TRUE;
}
JNIEXPORT jint JNICALL Java_avahi4j_EntryGroup_add_1service_1txt_1records
			(JNIEnv *e, jobject t, jlong ptr, jint interfaceNum, jint proto,
					jstring name, jstring type, jstring domain, jstring host,
					jint port, jarray txtRecord, jint length){
	dprint("[LOG] Entering %s\n", __PRETTY_FUNCTION__);

	struct avahi4j_entry_group *group = (struct avahi4j_entry_group *) (uintptr_t) ptr;

	AvahiIfIndex avahi_if;
	AvahiProtocol avahi_proto;
	const char *avahi_name=NULL, *avahi_type=NULL, *avahi_domain=NULL, *avahi_host=NULL;
	AvahiStringList *list = NULL;
	jstring current;
	const char* record;
	int result, i;
	uint16_t avahi_port = (uint16_t) port;

	// translate  interface num
	GET_AVAHI_IF_IDX(avahi_if, interfaceNum);

	// translate the Protocol Enum to an AvahiProtocol
	GET_AVAHI_PROTO(avahi_proto, proto);

	// go through the list of TXT  record and add them to the AvahiStringList
	for(i=0; i<length; i++) {
		current = (jstring) (*e)->GetObjectArrayElement(e, txtRecord, i);
		if(current==NULL)
		{
			dprint("error getting txt record %d\n",i);
			THROW_EXCEPTION(e, JNI_EXCP, "error getting record %d",i);
			return 0;
		}

		GET_UTF_STR(record, current, e, 0);
		dprint("Adding '%s' to TXT record\n", record);
		list = avahi_string_list_add(list, record);
		PUT_UTF_STR(record, current, e);
	}

	// get UTF string from name, type, domain (can be NULL) and host (can be NULL)
	GET_UTF_STR_JUMP(avahi_name, name, e, bail);
	GET_UTF_STR_JUMP(avahi_type, type,e ,bail);
	GET_UTF_STR_JUMP(avahi_domain, domain, e, bail);
	GET_UTF_STR_JUMP(avahi_host, host,e ,bail);

	result = avahi_entry_group_add_service_strlst(group->group, avahi_if,
			avahi_proto, 0, avahi_name, avahi_type, avahi_domain, avahi_host,
			avahi_port, list);

bail:
	// free UTF string
	PUT_UTF_STR(avahi_name, name, e);
	PUT_UTF_STR(avahi_type, type,e);
	PUT_UTF_STR(avahi_domain, domain, e);
	PUT_UTF_STR(avahi_host, host,e);

	// free string list
	avahi_string_list_free(list);

	CHECK_N_RET(avahi_entry_group_add_service_strlst, result);
}
Exemple #12
0
int
dnssd_register(AvahiClient *c)
{
  AvahiStringList *ipp_txt;             /* DNS-SD IPP TXT record */
  char            temp[256];            /* Subtype service string */
  char            dnssd_name[1024];
  char            *dev_id = NULL;
  const char      *make;                /* I - Manufacturer */
  const char      *model;               /* I - Model name */
  const char      *serial = NULL;
  const char      *cmd;
  int             pwgraster = 0,
                  appleraster = 0,
                  pclm = 0,
                  pdf = 0,
                  jpeg = 0;
  char            formats[1024];        /* I - Supported formats */
  char            *ptr;
  int             error;

 /*
  * Parse the device ID for MFG, MDL, and CMD
  */

  dev_id = strdup(g_options.device_id);
  if ((ptr = strcasestr(dev_id, "MFG:")) == NULL)
    if ((ptr = strcasestr(dev_id, "MANUFACTURER:")) == NULL) {
      ERR("No manufacturer info in device ID");
      free(dev_id);
      return -1;
    }
  make = strchr(ptr, ':') + 1;
  if ((ptr = strcasestr(dev_id, "MDL:")) == NULL)
    if ((ptr = strcasestr(dev_id, "MODEL:")) == NULL) {
      ERR("No model info in device ID");
      free(dev_id);
      return -1;
    }
  model = strchr(ptr, ':') + 1;
  if ((ptr = strcasestr(dev_id, "SN:")) == NULL)
    if ((ptr = strcasestr(dev_id, "SERN:")) == NULL) {
      if ((ptr = strcasestr(dev_id, "SERIALNUMBER:")) == NULL) {
	NOTE("No serial number info in device ID");
      }
    }
  if (ptr)
    serial = strchr(ptr, ':') + 1;
  if ((ptr = strcasestr(dev_id, "CMD:")) == NULL)
    if ((ptr = strcasestr(dev_id, "COMMAND SET:")) == NULL) {
      ERR("No page description language info in device ID");
      free(dev_id);
      return -1;
    }
  cmd = strchr(ptr, ':') + 1;
  ptr = strchr(make, ';');
  if (ptr) *ptr = '\0';
  ptr = strchr(model, ';');
  if (ptr) *ptr = '\0';
  if (serial) {
    ptr = strchr(serial, ';');
    if (ptr) *ptr = '\0';
  }
  ptr = strchr(cmd, ';');
  if (ptr) *ptr = '\0';

  if ((ptr = strcasestr(cmd, "pwg")) != NULL &&
      (ptr = strcasestr(ptr, "raster")) != NULL)
    pwgraster = 1;
  if (((ptr = strcasestr(cmd, "apple")) != NULL &&
       (ptr = strcasestr(ptr, "raster")) != NULL) ||
      ((ptr = strcasestr(cmd, "urf")) != NULL))
    appleraster = 1;
  if ((ptr = strcasestr(cmd, "pclm")) != NULL)
    pclm = 1;
  if ((ptr = strcasestr(cmd, "pdf")) != NULL)
    pdf = 1;
  if ((ptr = strcasestr(cmd, "jpeg")) != NULL ||
      (ptr = strcasestr(cmd, "jpg")) != NULL)
    jpeg = 1;
  snprintf(formats, sizeof(formats),"%s%s%s%s%s",
	   (pdf ? "application/pdf," : ""),
	   (pwgraster ? "image/pwg-raster," : ""),
	   (appleraster ? "image/urf," : ""),
	   (pclm ? "application/PCLm," : ""),
	   (jpeg ? "image/jpeg," : ""));
  formats[strlen(formats) - 1] = '\0';

 /*
  * Additional printer properties
  */

  snprintf(temp, sizeof(temp), "http://localhost:%d/", g_options.real_port);
  if (serial)
    snprintf(dnssd_name, sizeof(dnssd_name), "%s [%s]", model, serial);
  else
    snprintf(dnssd_name, sizeof(dnssd_name), "%s", model);

 /*
  * Create the TXT record...
  */

  ipp_txt = NULL;
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "rp=ipp/print");
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "ty=%s %s", make, model);
  if (strcasecmp(g_options.interface, "lo") == 0)
    ipp_txt = avahi_string_list_add_printf(ipp_txt, "adminurl=%s", temp);
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "product=(%s)", model);
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "pdl=%s", formats);
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "Color=U");
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "Duplex=U");
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "usb_MFG=%s", make);
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "usb_MDL=%s", model);
  if (appleraster)
    ipp_txt = avahi_string_list_add_printf(ipp_txt, "URF=CP1,IS1-5-7,MT1-2-3-4-5-6-8-9-10-11-12-13,RS300,SRGB24,V1.4,W8,DM1");
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "priority=60");
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "txtvers=1");
  ipp_txt = avahi_string_list_add_printf(ipp_txt, "qtotal=1");
  free(dev_id);

 /*
  * Register _printer._tcp (LPD) with port 0 to reserve the service name...
  */

  NOTE("Registering printer %s on interface %s for DNS-SD broadcasting ...",
       dnssd_name, g_options.interface);

  if (g_options.dnssd_data->ipp_ref == NULL)
    g_options.dnssd_data->ipp_ref =
      avahi_entry_group_new((c ? c : g_options.dnssd_data->DNSSDClient),
			    dnssd_callback, NULL);

  if (g_options.dnssd_data->ipp_ref == NULL) {
    ERR("Could not establish Avahi entry group");
    avahi_string_list_free(ipp_txt);
    return -1;
  }

  error =
    avahi_entry_group_add_service_strlst(g_options.dnssd_data->ipp_ref,
					 (g_options.interface ?
					  (int)if_nametoindex(g_options.interface) :
					  AVAHI_IF_UNSPEC),
					 AVAHI_PROTO_UNSPEC, 0,
					 dnssd_name,
					 "_printer._tcp", NULL, NULL, 0,
					 NULL);
  if (error)
    ERR("Error registering %s as Unix printer (_printer._tcp): %d", dnssd_name,
	error);
  else
    NOTE("Registered %s as Unix printer (_printer._tcp).", dnssd_name);

 /*
  * Then register the _ipp._tcp (IPP)...
  */

  error =
    avahi_entry_group_add_service_strlst(g_options.dnssd_data->ipp_ref,
					 (g_options.interface ?
					  (int)if_nametoindex(g_options.interface) :
					  AVAHI_IF_UNSPEC),
					 AVAHI_PROTO_UNSPEC, 0,
					 dnssd_name,
					 "_ipp._tcp", NULL, NULL, g_options.real_port,
					 ipp_txt);
  if (error)
    ERR("Error registering %s as IPP printer (_ipp._tcp): %d", dnssd_name,
	error);
  else {
    NOTE("Registered %s as IPP printer (_ipp._tcp).", dnssd_name);
    error =
      avahi_entry_group_add_service_subtype(g_options.dnssd_data->ipp_ref,
					    (g_options.interface ?
					     (int)if_nametoindex(g_options.interface) :
					     AVAHI_IF_UNSPEC),
					    AVAHI_PROTO_UNSPEC, 0,
					    dnssd_name,
					    "_ipp._tcp", NULL,
					    (appleraster && !pwgraster ?
					     "_universal._sub._ipp._tcp" :
					     "_print._sub._ipp._tcp"));
    if (error)
      ERR("Error registering subtype for IPP printer %s (_print._sub._ipp._tcp or _universal._sub._ipp._tcp): %d",
	  dnssd_name, error);
    else
      NOTE("Registered subtype for IPP printer %s (_print._sub._ipp._tcp or _universal._sub._ipp._tcp).",
	   dnssd_name);
  }

 /*
  * Finally _http.tcp (HTTP) for the web interface...
  */

  error =
    avahi_entry_group_add_service_strlst(g_options.dnssd_data->ipp_ref,
					 (g_options.interface ?
					  (int)if_nametoindex(g_options.interface) :
					  AVAHI_IF_UNSPEC),
					 AVAHI_PROTO_UNSPEC, 0,
					 dnssd_name,
					 "_http._tcp", NULL, NULL, g_options.real_port,
					 NULL);
  if (error)
    ERR("Error registering web interface of %s (_http._tcp): %d", dnssd_name,
	error);
  else {
    NOTE("Registered web interface of %s (_http._tcp).", dnssd_name);
    error =
      avahi_entry_group_add_service_subtype(g_options.dnssd_data->ipp_ref,
					    (g_options.interface ?
					     (int)if_nametoindex(g_options.interface) :
					     AVAHI_IF_UNSPEC),
					    AVAHI_PROTO_UNSPEC, 0,
					    dnssd_name,
					    "_http._tcp", NULL,
					    "_printer._sub._http._tcp");
    if (error)
      ERR("Error registering subtype for web interface of %s (_printer._sub._http._tcp): %d",
	  dnssd_name, error);
    else
      NOTE("Registered subtype for web interface of %s (_printer._sub._http._tcp).",
	   dnssd_name);
  }

 /*
  * Commit it...
  */

  avahi_entry_group_commit(g_options.dnssd_data->ipp_ref);

  avahi_string_list_free(ipp_txt);

  return 0;
}
Exemple #13
0
/*
 * This function tries to register the AFP DNS
 * SRV service type.
 */
static void register_stuff(void) {
    uint port;
    const struct vol *volume;
    DSI *dsi;
    char name[MAXINSTANCENAMELEN+1];
    AvahiStringList *strlist = NULL;
    AvahiStringList *strlist2 = NULL;
    char tmpname[256];

    assert(ctx->client);

    if (!ctx->group) {
        if (!(ctx->group = avahi_entry_group_new(ctx->client, publish_reply, ctx))) {
            LOG(log_error, logtype_afpd, "Failed to create entry group: %s",
                avahi_strerror(avahi_client_errno(ctx->client)));
            goto fail;
        }
    }

    if (avahi_entry_group_is_empty(ctx->group)) {
        /* Register our service */

        /* Build AFP volumes list */
        int i = 0;
        strlist = avahi_string_list_add_printf(strlist, "sys=waMa=0,adVF=0x100");

        for (volume = getvolumes(); volume; volume = volume->v_next) {

            if (convert_string(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, -1, tmpname, 255) <= 0) {
                LOG ( log_error, logtype_afpd, "Could not set Zeroconf volume name for TimeMachine");
                goto fail;
            }

            if (volume->v_flags & AFPVOL_TM) {
                if (volume->v_uuid) {
                    LOG(log_info, logtype_afpd, "Registering volume '%s' with UUID: '%s' for TimeMachine",
                        volume->v_localname, volume->v_uuid);
                    strlist = avahi_string_list_add_printf(strlist, "dk%u=adVN=%s,adVF=0xa1,adVU=%s",
                                                           i++, tmpname, volume->v_uuid);
                } else {
                    LOG(log_warning, logtype_afpd, "Registering volume '%s' for TimeMachine. But UUID is invalid.",
                        volume->v_localname);
                    strlist = avahi_string_list_add_printf(strlist, "dk%u=adVN=%s,adVF=0xa1",
                                                           i++, tmpname);
                }
            }
        }

        /* AFP server */
        for (dsi = ctx->obj->dsi; dsi; dsi = dsi->next) {
            port = getip_port((struct sockaddr *)&dsi->server);

            LOG(log_info, logtype_afpd, "hostname: %s", ctx->obj->options.hostname);

            if (convert_string(ctx->obj->options.unixcharset,
                               CH_UTF8,
                               ctx->obj->options.hostname,
                               -1,
                               name,
                               MAXINSTANCENAMELEN) <= 0) {
                LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name: %s", ctx->obj->options.hostname);
                goto fail;
            }
            if ((dsi->bonjourname = strdup(name)) == NULL) {
                LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name");
                goto fail;

            }
            LOG(log_info, logtype_afpd, "Registering server '%s' with Bonjour",
                dsi->bonjourname);

            if (avahi_entry_group_add_service(ctx->group,
                                              AVAHI_IF_UNSPEC,
                                              AVAHI_PROTO_UNSPEC,
                                              0,
                                              dsi->bonjourname,
                                              AFP_DNS_SERVICE_TYPE,
                                              NULL,
                                              NULL,
                                              port,
                                              NULL) < 0) {
                LOG(log_error, logtype_afpd, "Failed to add service: %s",
                    avahi_strerror(avahi_client_errno(ctx->client)));
                goto fail;
            }

            if (i && avahi_entry_group_add_service_strlst(ctx->group,
                    AVAHI_IF_UNSPEC,
                    AVAHI_PROTO_UNSPEC,
                    0,
                    dsi->bonjourname,
                    ADISK_SERVICE_TYPE,
                    NULL,
                    NULL,
                    9, /* discard */
                    strlist) < 0) {
                LOG(log_error, logtype_afpd, "Failed to add service: %s",
                    avahi_strerror(avahi_client_errno(ctx->client)));
                goto fail;
            }	/* if */

            if (ctx->obj->options.mimicmodel) {
                strlist2 = avahi_string_list_add_printf(strlist2, "model=%s", ctx->obj->options.mimicmodel);
                if (avahi_entry_group_add_service_strlst(ctx->group,
                        AVAHI_IF_UNSPEC,
                        AVAHI_PROTO_UNSPEC,
                        0,
                        dsi->bonjourname,
                        DEV_INFO_SERVICE_TYPE,
                        NULL,
                        NULL,
                        0,
                        strlist2) < 0) {
                    LOG(log_error, logtype_afpd, "Failed to add service: %s",
                        avahi_strerror(avahi_client_errno(ctx->client)));
                    goto fail;
                }
            } /* if (config->obj.options.mimicmodel) */

        }	/* for config*/

        if (avahi_entry_group_commit(ctx->group) < 0) {
            LOG(log_error, logtype_afpd, "Failed to commit entry group: %s",
                avahi_strerror(avahi_client_errno(ctx->client)));
            goto fail;
        }

    }	/* if avahi_entry_group_is_empty*/

    return;

fail:
    time(NULL);
//    avahi_threaded_poll_quit(ctx->threaded_poll);
}
Exemple #14
0
static void create_services(AvahiClient * c, Game * game)
{
	gchar *hostname;
	gchar *servicename;
	AvahiStringList *sl;
	int ret;

	g_assert(c != NULL);

	/* If this is the first time we're called, let's create a new entry group */
	if (!group) {
		if (!
		    (group =
		     avahi_entry_group_new(c, entry_group_callback,
					   NULL))) {
			log_message(MSG_ERROR, _("Avahi error: %s, %s\n"),
				    "avahi_entry_group_new() failed",
				    avahi_strerror(avahi_client_errno(c)));
			avahi_glib_poll_free(glib_poll);
			return;
		}
	}

	sl = avahi_string_list_new(NULL, NULL);
	sl = avahi_string_list_add_printf(sl, "version=%s",
					  PROTOCOL_VERSION);
	sl = avahi_string_list_add_printf(sl, "title=%s",
					  game->params->title);

	/* Add the service for IPP */
	hostname =
	    game->hostname ? g_strdup(game->hostname) : get_my_hostname();
	servicename =
	    g_strdup_printf("%s [%s]", hostname, game->server_port);
	g_free(hostname);
	ret = avahi_entry_group_add_service_strlst(group,
						   AVAHI_IF_UNSPEC,
						   AVAHI_NETWORK_PROTOCOL,
						   0,
						   servicename,
						   AVAHI_ANNOUNCE_NAME,
						   NULL,
						   NULL,
						   atoi(game->server_port),
						   sl);
	g_free(servicename);
	if (ret < 0) {
		gchar *msg = g_strdup_printf("Failed to add '%s' service",
					     AVAHI_ANNOUNCE_NAME);
		log_message(MSG_ERROR, _("Avahi error: %s, %s\n"), msg,
			    avahi_strerror(ret));
		g_free(msg);
		avahi_string_list_free(sl);
		avahi_glib_poll_free(glib_poll);
		return;
	}

	/* Tell the server to register the service */
	if ((ret = avahi_entry_group_commit(group)) < 0) {
		log_message(MSG_ERROR, _("Avahi error: %s, %s\n"),
			    "Failed to commit entry_group",
			    avahi_strerror(ret));
		avahi_string_list_free(sl);
		avahi_glib_poll_free(glib_poll);
		return;
	}

	avahi_string_list_free(sl);
	return;
}
static int publish_service(struct service *s) {
    int r = -1;
    AvahiStringList *txt = NULL;
    const char *name = NULL, *t;
    pa_proplist *proplist = NULL;
    pa_sample_spec ss;
    pa_channel_map map;
    char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
    enum service_subtype subtype;

    const char * const subtype_text[] = {
        [SUBTYPE_HARDWARE] = "hardware",
        [SUBTYPE_VIRTUAL] = "virtual",
        [SUBTYPE_MONITOR] = "monitor"
    };

    pa_assert(s);

    if (!s->userdata->client || avahi_client_get_state(s->userdata->client) != AVAHI_CLIENT_S_RUNNING)
        return 0;

    if (!s->entry_group) {
        if (!(s->entry_group = avahi_entry_group_new(s->userdata->client, service_entry_group_callback, s))) {
            pa_log("avahi_entry_group_new(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
            goto finish;
        }
    } else
        avahi_entry_group_reset(s->entry_group);

    txt = txt_record_server_data(s->userdata->core, txt);

    get_service_data(s, &ss, &map, &name, &proplist, &subtype);
    txt = avahi_string_list_add_pair(txt, "device", name);
    txt = avahi_string_list_add_printf(txt, "rate=%u", ss.rate);
    txt = avahi_string_list_add_printf(txt, "channels=%u", ss.channels);
    txt = avahi_string_list_add_pair(txt, "format", pa_sample_format_to_string(ss.format));
    txt = avahi_string_list_add_pair(txt, "channel_map", pa_channel_map_snprint(cm, sizeof(cm), &map));
    txt = avahi_string_list_add_pair(txt, "subtype", subtype_text[subtype]);

    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_DESCRIPTION)))
        txt = avahi_string_list_add_pair(txt, "description", t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_ICON_NAME)))
        txt = avahi_string_list_add_pair(txt, "icon-name", t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_VENDOR_NAME)))
        txt = avahi_string_list_add_pair(txt, "vendor-name", t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_PRODUCT_NAME)))
        txt = avahi_string_list_add_pair(txt, "product-name", t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_CLASS)))
        txt = avahi_string_list_add_pair(txt, "class", t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_FORM_FACTOR)))
        txt = avahi_string_list_add_pair(txt, "form-factor", t);

    if (avahi_entry_group_add_service_strlst(
                s->entry_group,
                AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                0,
                s->service_name,
                pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE,
                NULL,
                NULL,
                compute_port(s->userdata),
                txt) < 0) {

        pa_log("avahi_entry_group_add_service_strlst(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
        goto finish;
    }

    if (avahi_entry_group_add_service_subtype(
                s->entry_group,
                AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                0,
                s->service_name,
                pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE,
                NULL,
                pa_sink_isinstance(s->device) ? (subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SINK_HARDWARE : SERVICE_SUBTYPE_SINK_VIRTUAL) :
                (subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SOURCE_HARDWARE : (subtype == SUBTYPE_VIRTUAL ? SERVICE_SUBTYPE_SOURCE_VIRTUAL : SERVICE_SUBTYPE_SOURCE_MONITOR))) < 0) {

        pa_log("avahi_entry_group_add_service_subtype(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
        goto finish;
    }

    if (pa_source_isinstance(s->device) && subtype != SUBTYPE_MONITOR) {
        if (avahi_entry_group_add_service_subtype(
                    s->entry_group,
                    AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                    0,
                    s->service_name,
                    SERVICE_TYPE_SOURCE,
                    NULL,
                    SERVICE_SUBTYPE_SOURCE_NON_MONITOR) < 0) {

            pa_log("avahi_entry_group_add_service_subtype(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
            goto finish;
        }
    }

    if (avahi_entry_group_commit(s->entry_group) < 0) {
        pa_log("avahi_entry_group_commit(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
        goto finish;
    }

    r = 0;
    pa_log_debug("Successfully created entry group for %s.", s->service_name);

finish:

    /* Remove this service */
    if (r < 0)
        service_free(s);

    avahi_string_list_free(txt);

    return r;
}
Exemple #16
0
static int				/* O - 1 on success, 0 on failure */
dnssdRegisterInstance(
    cupsd_srv_t     *srv,		/* O - Service */
    cupsd_printer_t *p,			/* I - Printer */
    char            *name,		/* I - DNS-SD service name */
    const char      *type,		/* I - DNS-SD service type */
    const char      *subtypes,		/* I - Subtypes to register or NULL */
    int             port,		/* I - Port number or 0 */
    cupsd_txt_t     *txt,		/* I - TXT record */
    int             commit,		/* I - Commit registration? */
    int             from_callback)	/* I - Called from callback? */
{
  char	temp[256],			/* Temporary string */
	*ptr;				/* Pointer into string */
  int	error;				/* Any error */


#  ifdef HAVE_DNSSD
  (void)from_callback;
#  endif /* HAVE_DNSSD */

  cupsdLogMessage(CUPSD_LOG_DEBUG, "Registering \"%s\" with DNS-SD type \"%s\".", name, type);

  if (p && !srv)
  {
   /*
    * Assign the correct pointer for "srv"...
    */

#  ifdef HAVE_DNSSD
    if (!strcmp(type, "_printer._tcp"))
      srv = &p->printer_srv;		/* Target LPD service */
#    ifdef HAVE_SSL
    else if (!strcmp(type, "_ipps._tcp"))
      srv = &p->ipps_srv;		/* Target IPPS service */
#    endif /* HAVE_SSL */
    else
      srv = &p->ipp_srv;		/* Target IPP service */

#  else /* HAVE_AVAHI */
    srv = &p->ipp_srv;			/* Target service group */
#  endif /* HAVE_DNSSD */
  }

#  ifdef HAVE_DNSSD
  (void)commit;

#  else /* HAVE_AVAHI */
  if (!from_callback)
    avahi_threaded_poll_lock(DNSSDMaster);

  if (!*srv)
    *srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL);
  if (!*srv)
  {
    if (!from_callback)
      avahi_threaded_poll_unlock(DNSSDMaster);

    cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
                    name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
    return (0);
  }
#  endif /* HAVE_DNSSD */

 /*
  * Make sure the name is <= 63 octets, and when we truncate be sure to
  * properly truncate any UTF-8 characters...
  */

  ptr = name + strlen(name);
  while ((ptr - name) > 63)
  {
    do
    {
      ptr --;
    }
    while (ptr > name && (*ptr & 0xc0) == 0x80);

    if (ptr > name)
      *ptr = '\0';
  }

 /*
  * Register the service...
  */

#  ifdef HAVE_DNSSD
  if (subtypes)
    snprintf(temp, sizeof(temp), "%s,%s", type, subtypes);
  else
    strlcpy(temp, type, sizeof(temp));

  *srv  = DNSSDMaster;
  error = DNSServiceRegister(srv, kDNSServiceFlagsShareConnection,
			     0, name, temp, NULL, NULL, htons(port),
			     txt ? TXTRecordGetLength(txt) : 0,
			     txt ? TXTRecordGetBytesPtr(txt) : NULL,
			     dnssdRegisterCallback, p);

#  else /* HAVE_AVAHI */
  if (txt)
  {
    AvahiStringList *temptxt;
    for (temptxt = *txt; temptxt; temptxt = temptxt->next)
      cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS_SD \"%s\" %s", name, temptxt->text);
  }

  error = avahi_entry_group_add_service_strlst(*srv, AVAHI_IF_UNSPEC,
                                               AVAHI_PROTO_UNSPEC, 0, name,
                                               type, NULL, NULL, port,
                                               txt ? *txt : NULL);
  if (error)
    cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD service add for \"%s\" failed.",
                    name);

  if (!error && subtypes)
  {
   /*
    * Register all of the subtypes...
    */

    char	*start,			/* Start of subtype */
		subtype[256];		/* Subtype string */

    strlcpy(temp, subtypes, sizeof(temp));

    for (start = temp; *start; start = ptr)
    {
     /*
      * Skip leading whitespace...
      */

      while (*start && isspace(*start & 255))
        start ++;

     /*
      * Grab everything up to the next comma or the end of the string...
      */

      for (ptr = start; *ptr && *ptr != ','; ptr ++);

      if (*ptr)
        *ptr++ = '\0';

      if (!*start)
        break;

     /*
      * Register the subtype...
      */

      snprintf(subtype, sizeof(subtype), "%s._sub.%s", start, type);

      error = avahi_entry_group_add_service_subtype(*srv, AVAHI_IF_UNSPEC,
                                                    AVAHI_PROTO_UNSPEC, 0,
                                                    name, type, NULL, subtype);
      if (error)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
                        "DNS-SD subtype %s registration for \"%s\" failed." ,
                        subtype, name);
        break;
      }
    }
  }

  if (!error && commit)
  {
    if ((error = avahi_entry_group_commit(*srv)) != 0)
      cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
                      name);
  }

  if (!from_callback)
    avahi_threaded_poll_unlock(DNSSDMaster);
#  endif /* HAVE_DNSSD */

  if (error)
  {
    cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
                    name, dnssdErrorString(error));
    cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD type: %s", type);
    if (subtypes)
      cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD sub-types: %s", subtypes);
  }

  return (!error);
}
Exemple #17
0
static int
create_group_entry(struct mdns_group_entry *ge, int commit)
{
  char hostname[HOST_NAME_MAX + 1];
  char rdata[HOST_NAME_MAX + 6 + 1]; // Includes room for ".local" and 0-terminator
  int count;
  int i;
  int ret;

  if (!mdns_group)
    {
      mdns_group = avahi_entry_group_new(mdns_client, entry_group_callback, NULL);
      if (!mdns_group)
	{
	  DPRINTF(E_WARN, L_MDNS, "Could not create Avahi EntryGroup: %s\n", MDNSERR);
	  return -1;
	}
    }

  if (ge->publish == MDNS_PUBLISH_SERVICE)
    {
      DPRINTF(E_DBG, L_MDNS, "Adding service %s/%s\n", ge->name, ge->type);

      ret = avahi_entry_group_add_service_strlst(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,
						 ge->name, ge->type,
						 NULL, NULL, ge->port, ge->txt);
      if (ret < 0)
	{
	  DPRINTF(E_LOG, L_MDNS, "Could not add mDNS service %s/%s: %s\n", ge->name, ge->type, avahi_strerror(ret));
	  return -1;
	}
    }
  else if (ge->publish == MDNS_PUBLISH_CNAME)
    {
      DPRINTF(E_DBG, L_MDNS, "Adding CNAME record %s\n", ge->name);

      ret = gethostname(hostname, HOST_NAME_MAX);
      if (ret < 0)
	{
	  DPRINTF(E_LOG, L_MDNS, "Could not add CNAME %s, gethostname failed\n", ge->name);
	  return -1;
	}
      // Note, gethostname does not guarantee 0-termination
      hostname[HOST_NAME_MAX] = 0;

      ret = snprintf(rdata, sizeof(rdata), ".%s.local", hostname);
      if (!(ret > 0 && ret < sizeof(rdata)))
        {
	  DPRINTF(E_LOG, L_MDNS, "Could not add CNAME %s, hostname is invalid\n", ge->name);
	  return -1;
        }

      // Convert to dns string: .forked-daapd.local -> \12forked-daapd\6local
      count = 0;
      for (i = ret - 1; i >= 0; i--)
        {
	  if (rdata[i] == '.')
	    {
	      rdata[i] = count;
	      count = 0;
	    }
	  else
	    count++;
        }

      // ret + 1 should be the string length of rdata incl. 0-terminator
      ret = avahi_entry_group_add_record(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                                         AVAHI_PUBLISH_USE_MULTICAST | AVAHI_PUBLISH_ALLOW_MULTIPLE,
                                         ge->name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME,
                                         AVAHI_DEFAULT_TTL, rdata, ret + 1);
      if (ret < 0)
	{
	  DPRINTF(E_LOG, L_MDNS, "Could not add CNAME record %s: %s\n", ge->name, avahi_strerror(ret));
	  return -1;
	}
    }

  if (!commit)
    return 0;

  ret = avahi_entry_group_commit(mdns_group);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_MDNS, "Could not commit mDNS services: %s\n", MDNSERR);
      return -1;
    }

  return 0;
}
Exemple #18
0
void announcer::async_announce(const aware::contact& contact,
                               async_announce_handler h)
{
    assert(ptr != 0);

    handler = h;

    const AvahiPublishFlags flags = AvahiPublishFlags(0);
    const aware::contact::endpoint_type endpoint = contact.get_endpoint();
    // Use all network interfaces
    const AvahiIfIndex interface_index = AVAHI_IF_UNSPEC;
    // Use only a specific protocol
    const AvahiProtocol protocol =
        contact.get_endpoint().protocol() == boost::asio::ip::tcp::v6()
        ? AVAHI_PROTO_INET6
        : AVAHI_PROTO_INET;
    std::string name = contact.get_name();
    // FIXME: from contact (endpoint.protocol())
    std::string type = "_" + contact.get_type() + "._tcp";
    // Use .local
    const char *domain = 0;
    // Host name
    boost::asio::ip::address address = endpoint.address();
    std::string host = address.is_unspecified()
        ? "" // Use default host name
        : address.to_string();

    property_list properties;
    if (!contact.get_properties().empty())
    {
        properties = contact.get_properties();
        if (properties == 0)
        {
            boost::system::error_code error(boost::system::errc::not_enough_memory,
                                            boost::system::system_category());
            handler(error);
            return;
        }
    }

    while (true)
    {
        int rc = avahi_entry_group_add_service_strlst(ptr,
                                                      interface_index,
                                                      protocol,
                                                      flags,
                                                      name.c_str(),
                                                      type.c_str(),
                                                      domain,
                                                      host.empty() ? 0 : host.c_str(),
                                                      endpoint.port(),
                                                      properties);
        if (rc == AVAHI_ERR_COLLISION)
        {
            char *alternative = avahi_alternative_service_name(name.c_str());
            name = alternative;
            avahi_free(alternative);
        }
        else if (rc != AVAHI_OK)
        {
            handler(convert_error(rc));
            return;
        }
        else
        {
            break;
        }
    }
    commit(ptr);
}
Exemple #19
0
static void create_service(struct service_data *j) {
    apr_pool_t *t;
    const char *n;
    char *p;
    struct runtime_data *r = j->runtime;
    char **type, **txt_record;
    AvahiStringList *strlist = NULL;


    if (!j->group)
        if (!(j->group = avahi_entry_group_new(r->client, service_callback, j))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(r->client)));
            return;
        }

    ap_assert(j->group);
    ap_assert(avahi_entry_group_is_empty(j->group));

    apr_pool_create(&t, r->pool);

/*         ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "Service <%s>, host <%s>, port <%u>, location <%s>", j->name, j->host_name, j->port, j->location); */

    if (j->chosen_name)
        n = j->chosen_name;
    else if (!j->name)
        n = avahi_client_get_host_name(r->client);
    else if (j->append_host_name)
        n = apr_pstrcat(t, j->name, avahi_client_get_host_name(r->client), NULL);
    else
        n = j->name;

    if (!j->pool)
        apr_pool_create(&j->pool, r->pool);

    if (n != j->chosen_name) {
        apr_pool_clear(j->pool);
        j->chosen_name = apr_pstrdup(j->pool, n);
    }

    p = j->location ? apr_pstrcat(t, "path=", j->location, NULL) : NULL;

/*         ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "%s, %s", p, n); */

    txt_record = (char **) j->txt_record->elts;

    for ( ; *txt_record ; txt_record++)
       strlist =  avahi_string_list_add(strlist, *txt_record);

    if (p)
        strlist = avahi_string_list_add(strlist, p);

    if (apr_is_empty_array(j->types)) {

        if (avahi_entry_group_add_service_strlst(
                j->group,
                AVAHI_IF_UNSPEC,
                AVAHI_PROTO_UNSPEC,
                0,
                n,
                j->port == 443 ? "_https._tcp" : "_http._tcp",
                NULL,
                j->host_name,
                j->port,
                strlist) < 0) {

            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_entry_group_add_service_strlst(\"%s\") failed: %s", n, avahi_strerror(avahi_client_errno(r->client)));
        }

        const char * cnames = {j->host_name, NULL};
        PublishAvahiCNames(cnames);

    } else {

        for (type = (char**) j->types->elts; *type; type++) {

            if (avahi_entry_group_add_service_strlst(
                    j->group,
                    AVAHI_IF_UNSPEC,
                    AVAHI_PROTO_UNSPEC,
                    0,
                    n,
                    *type,
                    NULL,
                    j->host_name,
                    j->port,
                    strlist) < 0) {

                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_entry_group_add_service_strlst(\"%s\") failed: %s", n, avahi_strerror(avahi_client_errno(r->client)));
            }

            const char * cnames = {j->host_name, NULL};
            PublishAvahiCNames(cnames);
        }
    }

    avahi_string_list_free(strlist);

    if (avahi_entry_group_is_empty(j->group)) {
        avahi_entry_group_free(j->group);
        j->group = NULL;
    } else
        avahi_entry_group_commit(j->group);

    apr_pool_destroy(t);
}