Exemplo n.º 1
0
JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis,
							jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
{
	jclass					cls = (*pEnv)->GetObjectClass( pEnv, pThis);
	jfieldID				contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
	OpContext				*pContext = NULL;
	DNSServiceErrorType		err = kDNSServiceErr_NoError;

	if ( contextField != 0)
		pContext = NewContext( pEnv, pThis, "queryAnswered",
								"(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V");
	else
		err = kDNSServiceErr_BadParam;

	if ( pContext != NULL)
	{
		const char	*servStr = SafeGetUTFChars( pEnv, serviceName);

		err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr,
									rrtype, rrclass, ServiceQueryReply, pContext);
		if ( err == kDNSServiceErr_NoError)
		{
			(*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
		}

		SafeReleaseUTFChars( pEnv, serviceName, servStr);
	}
	else
		err = kDNSServiceErr_NoMemory;

	return err;
}
Exemplo n.º 2
0
static VALUE
dnssd_service_query_record(VALUE self, VALUE _flags, VALUE _interface,
    VALUE _fullname, VALUE _rrtype, VALUE _rrclass) {
  DNSServiceRef *client;
  DNSServiceFlags flags;
  DNSServiceErrorType e;
  char *fullname;
  uint32_t interface;
  uint16_t rrtype;
  uint16_t rrclass;

  flags = (DNSServiceFlags)NUM2ULONG(_flags);
  interface = (uint32_t)NUM2ULONG(_interface);
  dnssd_utf8_cstr(_fullname, fullname);
  rrtype = NUM2UINT(_rrtype);
  rrclass = NUM2UINT(_rrclass);

  get(cDNSSDService, self, DNSServiceRef, client);

  e = DNSServiceQueryRecord(client, flags, interface, fullname, rrtype,
      rrclass, dnssd_service_query_record_reply, (void *)self);

  dnssd_check_error_code(e);

  return self;
}
static void
resolve_reply (DNSServiceRef client,
               DNSServiceFlags flags,
               uint32_t ifIndex,
               DNSServiceErrorType errorCode,
               const char *fullname,
               const char *hosttarget,
               uint16_t opaqueport,
               uint16_t txtLen,
               const char *txtRecord,
               void *context)
{
	GMDNSUserData *ud = context;
	GMDNSUserData *ud2;
	DNSServiceErrorType err;
	gint i;
	union { guint16 s; guchar b[2]; } portu = { opaqueport };

	g_return_if_fail (ud);

	ud->server->port = ((guint16) portu.b[0]) << 8 | portu.b[1];
	ud->server->hostname = g_strdup (hosttarget);
	ud->server->txtvalues = g_hash_table_new_full (g_str_hash, g_str_equal,
	                                               g_free, g_free);

	for (i = 0; i < TXTRecordGetCount (txtLen, txtRecord); i++) {
		gchar key[256];
		const void *txt_value;
		gchar *value;
		guint8 vallen;

		err = TXTRecordGetItemAtIndex (txtLen, txtRecord, i, 256, key, &vallen, &txt_value);
		if (err != kDNSServiceErr_NoError) {
			g_warning ("error parsing TXT records!");
		}

		value = g_malloc (vallen + 1);
		g_strlcpy (value, txt_value, vallen + 1);
		g_hash_table_insert (ud->server->txtvalues, g_strdup (key), value);
	}

	ud2 = g_new0 (GMDNSUserData, 1);

	err = DNSServiceQueryRecord (&ud2->client, 0,
	                             kDNSServiceInterfaceIndexAny,
	                             ud->server->hostname,
	                             kDNSServiceType_A,
	                             kDNSServiceClass_IN,
	                             qr_reply, ud2);

	if (err != kDNSServiceErr_NoError) {
		g_warning ("Error from QueryRecord!");
	}

	g_mdns_poll_add (ud->mdns, ud2, ud2->client);
	ud2->server = ud->server;

	g_mdns_user_data_destroy (ud);
}
Exemplo n.º 4
0
int main(int argc, char **argv)
{
  struct dummy_struct ds;
  int c;
  int type = kDNSServiceType_ANY;
  int flags = 0;
  int ifindex = 0;

  memset (&ds, 0, sizeof(ds));
  while ((c = getopt(argc, argv, "f:t:i:")) != -1)
    switch (c)
      {
      case 't':
        type = atoi(optarg);
        break;
      case 'i':
        ifindex = if_nametoindex(optarg);
        break;
      case 'f':
        flags = atoi(optarg);
        break;
      }
  if (argc <= 1)
    {
      fprintf(stderr, "Usage: %s [-f <flags>] [-i <if>] [-t <type>] <name>\n",
              argv[0]);
      exit(1);
    }
  if (DNSServiceQueryRecord(&ds.service, flags, ifindex,
                            argv[1],
                            type,
                            kDNSServiceClass_IN,
                            dummy_callback,
                            NULL) != kDNSServiceErr_NoError)
    {
      fprintf(stderr, "Error initializing DNSServiceQueryRecord\n");
      exit(1);
    }

  if (uloop_init() < 0)
    {
      fprintf(stderr, "Error in uloop_init\n");
      exit(1);
    }
  ds.ufd.fd = DNSServiceRefSockFD(ds.service);
  printf("FD:%d\n", ds.ufd.fd);
  ds.ufd.cb = uloop_fd_callback;
  if (uloop_fd_add(&ds.ufd, ULOOP_READ) < 0)
    {
      fprintf(stderr, "Error in uloop_fd_add\n");
      exit(1);
    }
  printf("Entering event loop\n");
  uloop_run();
  return 0;
}
Exemplo n.º 5
0
STDMETHODIMP CDNSSD::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IQueryRecordListener *listener, IDNSSDService **service)
{
	CComObject<CDNSSDService>	*	object			= NULL;
	DNSServiceRef					sref			= NULL;
	std::string						fullNameUTF8;
	DNSServiceErrorType				err				= 0;
	HRESULT							hr				= 0;
	BOOL							ok;

	// Initialize
	*service = NULL;

	// Convert BSTR params to utf8
	ok = BSTRToUTF8( fullname, fullNameUTF8 );
	require_action( ok, exit, err = kDNSServiceErr_BadParam );

	try
	{
		object = new CComObject<CDNSSDService>();
	}
	catch ( ... )
	{
		object = NULL;
	}

	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
	hr = object->FinalConstruct();
	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
	object->AddRef();

	err = DNSServiceQueryRecord( &sref, flags, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );
	require_noerr( err, exit );

	object->SetServiceRef( sref );
	object->SetListener( listener );

	err = object->Run();
	require_noerr( err, exit );

	*service = object;

exit:

	if ( err && object )
	{
		object->Release();
	}

	return err;
}
Exemplo n.º 6
0
    bool Client::query( const std::string& hostname, int port )
    {
      m_port = port;
      m_qRef = 0;
      DNSServiceErrorType e = DNSServiceQueryRecord( &m_qRef, 0, m_interface, hostname.c_str(), kDNSServiceType_A,
                                                    kDNSServiceClass_IN, &handleQueryReply, this );
      if( e != kDNSServiceErr_NoError )
      {
        // printf( "Client::query() failed\n" );
        DNSServiceRefDeallocate( m_qRef );
        m_qRef = 0;
        return false;
      }
      m_currentRef = m_qRef;

      return true;
    }
Exemplo n.º 7
0
    address bonjour_resolve_policy::resolve (std::string const& s)
    {
        address result;

        DNSServiceRef sd_ref;

        DNSServiceErrorType error = 
            DNSServiceQueryRecord (&sd_ref, 0, 0, s.c_str (),
                                  kDNSServiceType_SRV, kDNSServiceClass_IN,
                                  callback, static_cast<void*> (&result)
                    );

        if (error == kDNSServiceErr_NoError)
            DNSServiceProcessResult (sd_ref);
        else
            result = address::from_string ("::1");

        DNSServiceRefDeallocate (sd_ref);
        
        return result;
    }
Exemplo n.º 8
0
static void FoundInstanceInfo(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
	DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t notAnIntPort,
	uint16_t txtLen, const char *txtRecord, void *context)
	{
	linkedServiceInfo *info = (linkedServiceInfo *)context;
	SearcherServices *services = info->services;
	(void)sdRef;			// Unused
	(void)flags;			// Unused
	(void)interfaceIndex;	// Unused
	(void)errorCode;		// Unused
	(void)fullname;			// Unused
	strcpy(info->host, hosttarget);
	if (txtLen == 0) info->text[0] = 0;
	else
		{
		strncpy(info->text, txtRecord+1, txtRecord[0]);
		info->text[txtRecord[0]] = 0;
		}
	info->notAnIntPort.NotAnInteger = notAnIntPort;
	DNSServiceRefDeallocate(info->sdRef);
	DNSServiceQueryRecord(&info->sdRef, 0, 0, info->host, ns_t_a, ns_c_in, FoundInstanceAddress, info);
	}
Exemplo n.º 9
0
DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo(
    DNSServiceRef *             outRef,
    DNSServiceFlags inFlags,
    uint32_t inInterfaceIndex,
    DNSServiceProtocol inProtocol,
    const char *                inHostName,
    DNSServiceGetAddrInfoReply inCallback,
    void *                      inContext )
{
    const char *                    errormsg = "Unknown";
    DNSServiceErrorType err;
    mDNS_DirectOP_GetAddrInfo *     x;

    // Allocate memory, and handle failure
    x = (mDNS_DirectOP_GetAddrInfo *)mDNSPlatformMemAllocate(sizeof(*x));
    if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

    // Set up object
    x->disposefn = DNSServiceGetAddrInfoDispose;
    x->callback  = inCallback;
    x->context   = inContext;
    x->aQuery    = mDNSNULL;

    // Start the query.
    // (It would probably be more efficient to code this using mDNS_StartQuery directly,
    // instead of wrapping DNSServiceQueryRecord, which then unnecessarily allocates
    // more memory and then just calls through to mDNS_StartQuery. -- SC June 2010)
    err = DNSServiceQueryRecord(&x->aQuery, inFlags, inInterfaceIndex, inHostName, kDNSServiceType_A,
                                kDNSServiceClass_IN, DNSServiceGetAddrInfoResponse, x);
    if (err) { DNSServiceGetAddrInfoDispose((mDNS_DirectOP*)x); errormsg = "DNSServiceQueryRecord"; goto fail; }

    *outRef = (DNSServiceRef)x;
    return(mStatus_NoError);

fail:
    LogMsg("DNSServiceGetAddrInfo(\"%s\", %d) failed: %s (%ld)", inHostName, inProtocol, errormsg, err);
    return(err);
}
Exemplo n.º 10
0
void DNSSD_API
CSecondPage::OnResolve(
				DNSServiceRef			inRef,
				DNSServiceFlags			inFlags,
				uint32_t				inInterfaceIndex,
				DNSServiceErrorType		inErrorCode,
				const char *			inFullName,	
				const char *			inHostName, 
				uint16_t 				inPort,
				uint16_t 				inTXTSize,
				const char *			inTXT,
				void *					inContext )
{
	DEBUG_UNUSED(inFullName);
	DEBUG_UNUSED(inInterfaceIndex);
	DEBUG_UNUSED(inFlags);
	DEBUG_UNUSED(inRef);

	CSecondPage	*	self;
	Service		*	service;
	Queue		*	q;
	bool			qtotalDefined = false;
	uint32_t		qpriority = kDefaultPriority;
	CString			qname;
	int				idx;
	OSStatus		err;

	require_noerr( inErrorCode, exit );

	service = reinterpret_cast<Service*>( inContext );
	require_quiet( service, exit);

	check( service->refs != 0 );

	self = service->printer->window;
	require_quiet( self, exit );

	err = self->StopOperation( service->serviceRef );
	require_noerr( err, exit );
	
	//
	// hold on to the hostname...
	//
	err = UTF8StringToStringObject( inHostName, service->hostname );
	require_noerr( err, exit );

	//
	// <rdar://problem/3739200> remove the trailing dot on hostname
	//
	idx = service->hostname.ReverseFind('.');

	if ((idx > 1) && ((service->hostname.GetLength() - 1) == idx))
	{
		service->hostname.Delete(idx, 1);
	}

	//
	// hold on to the port
	//
	service->portNumber = ntohs(inPort);

	//
	// parse the text record.
	//

	err = self->ParseTextRecord( service, inTXTSize, inTXT, qtotalDefined, qname, qpriority );
	require_noerr( err, exit );

	if ( service->qtotal == 1 )
	{	
		//
		// create a new queue
		//
		try
		{
			q = new Queue;
		}
		catch (...)
		{
			q = NULL;
		}

		require_action( q, exit, err = E_OUTOFMEMORY );

		if ( qtotalDefined )
		{
			q->name = qname;
		}

		q->priority = qpriority;
		
		service->queues.push_back( q );

		//
		// we've completely resolved this service
		//

		self->OnResolveService( service );
	}
	else
	{
		//
		// if qtotal is more than 1, then we need to get additional
		// text records.  if not, then this service is considered
		// resolved
		//

		err = DNSServiceQueryRecord(&service->serviceRef, 0, inInterfaceIndex, inFullName, kDNSServiceType_TXT, kDNSServiceClass_IN, OnQuery, (void*) service );
		require_noerr( err, exit );

		err = self->StartOperation( service->serviceRef );
		require_noerr( err, exit );
	}

exit:

	return;
}
Exemplo n.º 11
0
Arquivo: dnssd.c Projeto: zdohnal/cups
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  const char	*name;			/* Backend name */
  cups_array_t	*devices;		/* Device array */
  cups_device_t	*device;		/* Current device */
  char		uriName[1024];		/* Unquoted fullName for URI */
#ifdef HAVE_DNSSD
  int		fd;			/* Main file descriptor */
  fd_set	input;			/* Input set for select() */
  struct timeval timeout;		/* Timeout for select() */
  DNSServiceRef	main_ref,		/* Main service reference */
		fax_ipp_ref,		/* IPP fax service reference */
		ipp_ref,		/* IPP service reference */
		ipp_tls_ref,		/* IPP w/TLS service reference */
		ipps_ref,		/* IPP service reference */
		local_fax_ipp_ref,	/* Local IPP fax service reference */
		local_ipp_ref,		/* Local IPP service reference */
		local_ipp_tls_ref,	/* Local IPP w/TLS service reference */
		local_ipps_ref,		/* Local IPP service reference */
		local_printer_ref,	/* Local LPD service reference */
		pdl_datastream_ref,	/* AppSocket service reference */
		printer_ref,		/* LPD service reference */
		riousbprint_ref;	/* Remote IO service reference */
#endif /* HAVE_DNSSD */
#ifdef HAVE_AVAHI
  AvahiClient	*client;		/* Client information */
  int		error;			/* Error code, if any */
#endif /* HAVE_AVAHI */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */


 /*
  * Don't buffer stderr, and catch SIGTERM...
  */

  setbuf(stderr, NULL);

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
  sigset(SIGTERM, sigterm_handler);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));

  sigemptyset(&action.sa_mask);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */

 /*
  * Check command-line...
  */

  if (argc >= 6)
    exec_backend(argv);
  else if (argc != 1)
  {
    _cupsLangPrintf(stderr,
                    _("Usage: %s job-id user title copies options [file]"),
		    argv[0]);
    return (1);
  }

 /*
  * Only do discovery when run as "dnssd"...
  */

  if ((name = strrchr(argv[0], '/')) != NULL)
    name ++;
  else
    name = argv[0];

  if (strcmp(name, "dnssd"))
    return (0);

 /*
  * Create an array to track devices...
  */

  devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL);

 /*
  * Browse for different kinds of printers...
  */

#ifdef HAVE_DNSSD
  if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError)
  {
    perror("ERROR: Unable to create service connection");
    return (1);
  }

  fd = DNSServiceRefSockFD(main_ref);

  fax_ipp_ref = main_ref;
  DNSServiceBrowse(&fax_ipp_ref, kDNSServiceFlagsShareConnection, 0,
                   "_fax-ipp._tcp", NULL, browse_callback, devices);

  ipp_ref = main_ref;
  DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0,
                   "_ipp._tcp", NULL, browse_callback, devices);

  ipp_tls_ref = main_ref;
  DNSServiceBrowse(&ipp_tls_ref, kDNSServiceFlagsShareConnection, 0,
                   "_ipp-tls._tcp", NULL, browse_callback, devices);

  ipps_ref = main_ref;
  DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0,
                   "_ipps._tcp", NULL, browse_callback, devices);

  local_fax_ipp_ref = main_ref;
  DNSServiceBrowse(&local_fax_ipp_ref, kDNSServiceFlagsShareConnection,
                   kDNSServiceInterfaceIndexLocalOnly,
		   "_fax-ipp._tcp", NULL, browse_local_callback, devices);

  local_ipp_ref = main_ref;
  DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection,
                   kDNSServiceInterfaceIndexLocalOnly,
		   "_ipp._tcp", NULL, browse_local_callback, devices);

  local_ipp_tls_ref = main_ref;
  DNSServiceBrowse(&local_ipp_tls_ref, kDNSServiceFlagsShareConnection,
                   kDNSServiceInterfaceIndexLocalOnly,
                   "_ipp-tls._tcp", NULL, browse_local_callback, devices);

  local_ipps_ref = main_ref;
  DNSServiceBrowse(&local_ipps_ref, kDNSServiceFlagsShareConnection,
                   kDNSServiceInterfaceIndexLocalOnly,
		   "_ipps._tcp", NULL, browse_local_callback, devices);

  local_printer_ref = main_ref;
  DNSServiceBrowse(&local_printer_ref, kDNSServiceFlagsShareConnection,
                   kDNSServiceInterfaceIndexLocalOnly,
                   "_printer._tcp", NULL, browse_local_callback, devices);

  pdl_datastream_ref = main_ref;
  DNSServiceBrowse(&pdl_datastream_ref, kDNSServiceFlagsShareConnection, 0,
                   "_pdl-datastream._tcp", NULL, browse_callback, devices);

  printer_ref = main_ref;
  DNSServiceBrowse(&printer_ref, kDNSServiceFlagsShareConnection, 0,
                   "_printer._tcp", NULL, browse_callback, devices);

  riousbprint_ref = main_ref;
  DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0,
                   "_riousbprint._tcp", NULL, browse_callback, devices);
#endif /* HAVE_DNSSD */

#ifdef HAVE_AVAHI
  if ((simple_poll = avahi_simple_poll_new()) == NULL)
  {
    fputs("DEBUG: Unable to create Avahi simple poll object.\n", stderr);
    return (0);
  }

  avahi_simple_poll_set_func(simple_poll, poll_callback, NULL);

  client = avahi_client_new(avahi_simple_poll_get(simple_poll),
			    0, client_callback, simple_poll, &error);
  if (!client)
  {
    fputs("DEBUG: Unable to create Avahi client.\n", stderr);
    return (0);
  }

  browsers = 6;
  avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
			    AVAHI_PROTO_UNSPEC,
			    "_fax-ipp._tcp", NULL, 0,
			    browse_callback, devices);
  avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
			    AVAHI_PROTO_UNSPEC,
			    "_ipp._tcp", NULL, 0,
			    browse_callback, devices);
  avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
			    AVAHI_PROTO_UNSPEC,
			    "_ipp-tls._tcp", NULL, 0,
			    browse_callback, devices);
  avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
			    AVAHI_PROTO_UNSPEC,
			    "_ipps._tcp", NULL, 0,
			    browse_callback, devices);
  avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
			    AVAHI_PROTO_UNSPEC,
			    "_pdl-datastream._tcp",
			    NULL, 0,
			    browse_callback,
			    devices);
  avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
			    AVAHI_PROTO_UNSPEC,
			    "_printer._tcp", NULL, 0,
			    browse_callback, devices);
#endif /* HAVE_AVAHI */

 /*
  * Loop until we are killed...
  */

  while (!job_canceled)
  {
    int announce = 0;			/* Announce printers? */

#ifdef HAVE_DNSSD
    FD_ZERO(&input);
    FD_SET(fd, &input);

    timeout.tv_sec  = 0;
    timeout.tv_usec = 500000;

    if (select(fd + 1, &input, NULL, NULL, &timeout) < 0)
      continue;

    if (FD_ISSET(fd, &input))
    {
     /*
      * Process results of our browsing...
      */

      DNSServiceProcessResult(main_ref);
    }
    else
      announce = 1;

#elif defined(HAVE_AVAHI)
    got_data = 0;

    if ((error = avahi_simple_poll_iterate(simple_poll, 500)) > 0)
    {
     /*
      * We've been told to exit the loop.  Perhaps the connection to
      * Avahi failed.
      */

      break;
    }

    if (!got_data)
      announce = 1;
#endif /* HAVE_DNSSD */

/*    fprintf(stderr, "DEBUG: announce=%d\n", announce);*/

    if (announce)
    {
     /*
      * Announce any devices we've found...
      */

#ifdef HAVE_DNSSD
      DNSServiceErrorType status;	/* DNS query status */
#endif /* HAVE_DNSSD */
      cups_device_t *best;		/* Best matching device */
      char	device_uri[1024];	/* Device URI */
      int	count;			/* Number of queries */
      int	sent;			/* Number of sent */

      for (device = (cups_device_t *)cupsArrayFirst(devices),
               best = NULL, count = 0, sent = 0;
           device;
	   device = (cups_device_t *)cupsArrayNext(devices))
      {
        if (device->sent)
	  sent ++;

        if (device->ref)
	  count ++;

        if (!device->ref && !device->sent)
	{
	 /*
	  * Found the device, now get the TXT record(s) for it...
	  */

          if (count < 50)
	  {
	    fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName);

#ifdef HAVE_DNSSD
	    device->ref = main_ref;

	    status = DNSServiceQueryRecord(&(device->ref),
				           kDNSServiceFlagsShareConnection,
				           0, device->fullName,
					   kDNSServiceType_TXT,
				           kDNSServiceClass_IN, query_callback,
				           device);
            if (status != kDNSServiceErr_NoError)
	      fprintf(stderr,
	              "ERROR: Unable to query \"%s\" for TXT records: %d\n",
	              device->fullName, status);
	              			/* Users never see this */
	    else
	      count ++;

#else
	    if ((device->ref = avahi_record_browser_new(client, AVAHI_IF_UNSPEC,
	                                                AVAHI_PROTO_UNSPEC,
	                                                device->fullName,
	                                                AVAHI_DNS_CLASS_IN,
	                                                AVAHI_DNS_TYPE_TXT,
	                                                0,
				                        query_callback,
				                        device)) == NULL)
	      fprintf(stderr,
	              "ERROR: Unable to query \"%s\" for TXT records: %s\n",
	              device->fullName,
	              avahi_strerror(avahi_client_errno(client)));
	              			/* Users never see this */
	    else
	      count ++;
#endif /* HAVE_AVAHI */
          }
	}
	else if (!device->sent)
	{
#ifdef HAVE_DNSSD
	 /*
	  * Got the TXT records, now report the device...
	  */

	  DNSServiceRefDeallocate(device->ref);
#else
          avahi_record_browser_free(device->ref);
#endif /* HAVE_DNSSD */

	  device->ref = NULL;

          if (!best)
	    best = device;
	  else if (_cups_strcasecmp(best->name, device->name) ||
	           _cups_strcasecmp(best->domain, device->domain))
          {
	    unquote(uriName, best->fullName, sizeof(uriName));

            if (best->uuid)
	      httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri,
	                       sizeof(device_uri), "dnssd", NULL, uriName, 0,
			       best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s",
			       best->uuid);
	    else
	      httpAssembleURI(HTTP_URI_CODING_ALL, device_uri,
	                      sizeof(device_uri), "dnssd", NULL, uriName, 0,
			      best->cups_shared ? "/cups" : "/");

	    cupsBackendReport("network", device_uri, best->make_and_model,
	                      best->name, best->device_id, NULL);
	    best->sent = 1;
	    best       = device;

	    sent ++;
	  }
	  else if (best->priority > device->priority ||
	           (best->priority == device->priority &&
		    best->type < device->type))
          {
	    best->sent = 1;
	    best       = device;

	    sent ++;
	  }
	  else
	  {
	    device->sent = 1;

	    sent ++;
	  }
        }
      }

      if (best)
      {
	unquote(uriName, best->fullName, sizeof(uriName));

	if (best->uuid)
	  httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri,
			   sizeof(device_uri), "dnssd", NULL, uriName, 0,
			   best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s",
			   best->uuid);
	else
	  httpAssembleURI(HTTP_URI_CODING_ALL, device_uri,
			  sizeof(device_uri), "dnssd", NULL, uriName, 0,
			  best->cups_shared ? "/cups" : "/");

	cupsBackendReport("network", device_uri, best->make_and_model,
			  best->name, best->device_id, NULL);
	best->sent = 1;
	sent ++;
      }

      fprintf(stderr, "DEBUG: sent=%d, count=%d\n", sent, count);

#ifdef HAVE_AVAHI
      if (sent == cupsArrayCount(devices) && browsers == 0)
#else
      if (sent == cupsArrayCount(devices))
#endif /* HAVE_AVAHI */
	break;
    }
  }

  return (CUPS_BACKEND_OK);
}
Exemplo n.º 12
0
static int
_nss_mdns_queryrecord(const char *rrname, int rrclass, int rrtype,
		DNSServiceQueryRecordReply callback,
		struct mdns_querydata *data)
{
	int sockfd;
	int flags = kDNSServiceFlagsForceMulticast;  /* Multicast only */
	int opinterface = kDNSServiceInterfaceIndexAny;
	DNSServiceErrorType err;
	DNSServiceRef ref = NULL;
	int ret;
	struct fd_set readfds;
	struct timeval tv;

	data->status = NSS_NOTFOUND;
#ifdef DEBUG
	syslog(LOG_DEBUG, "nss_mdns: query called rrname:%s rrtype:%d",
	    rrname, rrtype);
#endif
	err = DNSServiceQueryRecord(&ref, flags, opinterface,
	    rrname, rrtype, rrclass, callback, data);
	if (err != kDNSServiceErr_NoError || ref == NULL ||
	    (sockfd = DNSServiceRefSockFD(ref)) == NULL) {
		DNSServiceRefDeallocate(ref);
		data->status = NSS_UNAVAIL;
		return (NSS_UNAVAIL);
	}

	do {
		FD_ZERO(&readfds);
		FD_SET(sockfd, &readfds);
		tv.tv_sec = NSSMDNS_MAXQRYTMO;
		tv.tv_usec = 0;

		/* Wait until response received from mDNS daemon */
		ret = select(sockfd + 1, &readfds, NULL, NULL, &tv);
		if (!((ret > 0) && FD_ISSET(sockfd, &readfds) &&
		    (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError))) {
			data->status = NSS_NOTFOUND;
			if (errno != EINTR)
				data->qrydone = B_TRUE;
		}
	} while (data->qrydone != B_TRUE);

	if (data->status == NSS_SUCCESS && (data->withttlbuffer == NULL)) {
		nss_XbyY_args_t *argp = data->argp;
		if (argp->buf.result != NULL) {
			int stat;

			if (data->buffer == NULL) {
				data->status = NSS_NOTFOUND;
				DNSServiceRefDeallocate(ref);
				return (data->status);
			}
			stat = (*argp->str2ent)(data->buffer,
			    strlen(data->buffer),
			    argp->buf.result, argp->buf.buffer,
			    argp->buf.buflen);
			if (stat == NSS_STR_PARSE_SUCCESS) {
				argp->returnval = argp->buf.result;
				argp->returnlen = 1;
			} else {
				data->status = NSS_NOTFOUND;
				if (stat == NSS_STR_PARSE_ERANGE)
					argp->erange = 1;
			}
			free(data->buffer);
		} else {
			argp->returnval = argp->buf.buffer;
			argp->returnlen = strlen(argp->buf.buffer);
		}
		data->buffer = NULL;
		data->buflen = 0;
	}

	if (data->status != NSS_SUCCESS)
		data->argp->h_errno = HOST_NOT_FOUND;

	DNSServiceRefDeallocate(ref);
	return (data->status);
}
Exemplo n.º 13
0
void DNSServiceResolveReplyCallback ( 
										 DNSServiceRef sdRef, 
										 DNSServiceFlags flags, 
										 uint32_t interfaceIndex, 
										 DNSServiceErrorType errorCode, 
										 const char *fullname, 
										 const char *hosttarget, 
										 uint16_t port, 
										 uint16_t txtLen, 
										 const unsigned char *txtRecord, 
										 void *context ) {
	(void)sdRef;
	(void)errorCode;
	(void)port;
	(void)txtLen;
	(void)txtRecord;
	(void)context;
	
	char	interfaceName[IF_NAMESIZE];
	if_indextoname( interfaceIndex, interfaceName );
	printf( "Resolve: interfaceIndex [%i]=%s : %s @ %s\n", interfaceIndex, interfaceName, fullname, hosttarget );
	callbackFlags = flags;
	
#if 0	
	struct hostent * host = gethostbyname( hosttarget );
	if ( host ) {
		printf( "h_name: %s\n", host->h_name );
		if ( host->h_aliases ) {	// this can be NULL
			for ( char **list = host->h_aliases ; *list ; list++ ) {
				printf( "h_alias: %s\n", *list );
			}
		}
		printf( "h_addrtype: %i\n", host->h_addrtype );
		printf( "h_length: %i\n", host->h_length );
		if ( !host->h_addr_list ) {	// I doubt this would ever be NULL...
			return;
		}
		for ( char **list = host->h_addr_list ; *list ; list++ ) {
			printf( "addr: %i.%i.%i.%i\n", ((byte *)*list)[0], ((byte *)*list)[1], ((byte *)*list)[2], ((byte *)*list)[3] );
		}
		
		memset( &resolvedServerAddress, 0, sizeof( resolvedServerAddress ) );
		resolvedServerAddress.sin_len = sizeof( resolvedServerAddress );
		resolvedServerAddress.sin_family = host->h_addrtype;
		resolvedServerAddress.sin_port = htons( DOOM_PORT );
		assert( host->h_length == 4 );
		memcpy( &resolvedServerAddress.sin_addr, *host->h_addr_list, host->h_length );

		gotServerAddress = true;
	}	
#else
	DNSServiceRef	queryRef;
	
	// look up the name for this host
	DNSServiceErrorType err = DNSServiceQueryRecord ( 
													 &queryRef, 
													 kDNSServiceFlagsForceMulticast, 
													 interfaceIndex, 
													 hosttarget, 
													 kDNSServiceType_A,		// we want the host address
													 kDNSServiceClass_IN, 
													 DNSServiceQueryRecordReplyCallback, 
													 NULL /* may be NULL */
													 );  	
	if ( err != kDNSServiceErr_NoError ) {
		printf( "DNSServiceQueryRecord error\n" );
	} else {
		// block until we get a response, process it, and run the callback
		err = DNSServiceProcessResult( queryRef );
		if ( err != kDNSServiceErr_NoError ) {
			printf( "DNSServiceProcessResult error\n" );
		}
		DNSServiceRefDeallocate( queryRef );
	}
#endif	
}