void mDNS_CFMTerm(void)
{
    extern pascal void __terminate(void);
    LogMsg("mDNS_CFMTerm");
    mDNS_Close(&mDNSStorage);
    __terminate();
}
Esempio n. 2
0
int		main(int argc, char **argv)
	{
	#define mDNSRecord mDNSStorage
	mDNS_PlatformSupport	platformStorage;
	mStatus					err;

	bzero(&mDNSRecord, sizeof mDNSRecord);
	bzero(&platformStorage, sizeof platformStorage);

	ParseCmdLinArgs(argc, argv);

	LogMsgIdent(mDNSResponderVersionString, "starting");

	err = mDNS_Init(&mDNSRecord, &platformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, 
					mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext); 

	if (mStatus_NoError == err)
		err = udsserver_init();
		
	Reconfigure(&mDNSRecord);

	// Now that we're finished with anything privileged, switch over to running as "nobody"
	if (mStatus_NoError == err)
		{
		const struct passwd *pw = getpwnam(MDNSD_USER);
		if (pw != NULL)
			setuid(pw->pw_uid);
		else 
#ifdef MDNSD_NOROOT
		     {
			LogMsg("WARNING: mdnsd exiting because user \""MDNSD_USER"\" does not exist");
			err = mStatus_Invalid;
		     }
#else
			LogMsg("WARNING: mdnsd continuing as root because user \""MDNSD_USER"\" does not exist");
#endif
		}

	if (mStatus_NoError == err)
		err = MainLoop(&mDNSRecord);
 
	LogMsgIdent(mDNSResponderVersionString, "stopping");

	mDNS_Close(&mDNSRecord);

	if (udsserver_exit() < 0)
		LogMsg("ExitCallback: udsserver_exit failed");
 
 #if MDNS_DEBUGMSGS > 0
	printf("mDNSResponder exiting normally with %ld\n", err);
 #endif
 
	return err;
	}
Esempio n. 3
0
mDNSexport void embedded_mDNSExit() {
#ifdef WIN32
	struct timeval tv;
	tv.tv_sec  = 0;
	tv.tv_usec = 0;
//	mDNS_StartExit(&mDNSStorage);
//	embedded_mDNSmainLoop(tv);
//	mDNS_FinalExit(&mDNSStorage);
#else
	mDNS_Close(&mDNSStorage);
#endif
}
Esempio n. 4
0
int main(int argc, char **argv)
// The program's main entry point.  The program does a trivial
// mDNS query, looking for all AFP servers in the local domain.
{
    int     result;
    mStatus     status;
    DNSQuestion question;
    domainname  type;
    domainname  domain;

    // Parse our command line arguments.  This won't come back if there's an error.
    ParseArguments(argc, argv);

    // Initialise the mDNS core.
    status = mDNS_Init(&mDNSStorage, &PlatformStorage,
                       gRRCache, RR_CACHE_SIZE,
                       mDNS_Init_DontAdvertiseLocalAddresses,
                       mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
    if (status == mStatus_NoError) {

        // Construct and start the query.

        MakeDomainNameFromDNSNameString(&type, gServiceType);
        MakeDomainNameFromDNSNameString(&domain, gServiceDomain);

        status = mDNS_StartBrowse(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, BrowseCallback, NULL);

        // Run the platform main event loop until the user types ^C.
        // The BrowseCallback routine is responsible for printing
        // any results that we find.

        if (status == mStatus_NoError) {
            fprintf(stderr, "Hit ^C when you're bored waiting for responses.\n");
            ExampleClientEventLoop(&mDNSStorage);
            mDNS_StopQuery(&mDNSStorage, &question);
            mDNS_Close(&mDNSStorage);
        }
    }

    if (status == mStatus_NoError) {
        result = 0;
    } else {
        result = 2;
    }
    if ( (result != 0) || (gMDNSPlatformPosixVerboseLevel > 0) ) {
        fprintf(stderr, "%s: Finished with status %d, result %d\n", gProgramName, (int)status, result);
    }

    return 0;
}
Esempio n. 5
0
static void HandleSigQuit(int sigraised)
// If we get a SIGQUIT the user is desperate and we 
// just call mDNS_Close directly.  This is definitely 
// not safe (because it could reenter mDNS), but 
// we presume that the user has already tried the safe 
// alternatives.
{
    assert(sigraised == SIGQUIT);

    DPRINTF(E_INF,L_REND,"SIGQUIT\n");

    mDNS_Close(&mDNSStorage);
    exit(0);
}
Esempio n. 6
0
static void HandleSigQuit(int sigraised)
    // If we get a SIGQUIT the user is desperate and we 
    // just call mDNS_Close directly.  This is definitely 
    // not safe (because it could reenter mDNS), but 
    // we presume that the user has already tried the safe 
    // alternatives.
{
    assert(sigraised == SIGQUIT);

    if (gMDNSPlatformPosixVerboseLevel > 0) {
        fprintf(stderr, "\nSIGQUIT\n");
    }
    mDNS_Close(&mDNSStorage);
    exit(0);
}
int main()
	{
	mStatus err;
	Boolean DoneSetup = false;

	SIOUXSettings.asktosaveonclose = false;
	SIOUXSettings.userwindowtitle = "\pMulticast DNS Responder";

	printf("Multicast DNS Responder\n\n");
	printf("This software reports errors using MacsBug breaks,\n");
	printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
	printf("******************************************************************************\n");

	err = InitOpenTransport();
	if (err) { debugf("InitOpenTransport failed %d", err); return(err); }

	err = mDNS_Init(&m, &p, mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
		mDNS_Init_AdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
	if (err) return(err);

	while (!YieldSomeTime(35))
		{
#if MDNS_ONLYSYSTEMTASK
		// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
		// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
		extern void mDNSPlatformIdle(mDNS *const m);
		mDNSPlatformIdle(&m);	// Only needed for debugging version
#endif
		if (m.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
			{
			DoneSetup = true;
			printf("\nListening for mDNS queries...\n");
			mDNSResponderTestSetup(&m);
			}
		}
	
	if (p1.RR_SRV.resrec.RecordType  ) mDNS_DeregisterService(&m, &p1);
	if (p2.RR_SRV.resrec.RecordType  ) mDNS_DeregisterService(&m, &p2);
	if (afp.RR_SRV.resrec.RecordType ) mDNS_DeregisterService(&m, &afp);
	if (http.RR_SRV.resrec.RecordType) mDNS_DeregisterService(&m, &http);
	if (njp.RR_SRV.resrec.RecordType ) mDNS_DeregisterService(&m, &njp);

	mDNS_Close(&m);
	
	return(0);
	}
mDNSexport int main(int argc, char **argv)
{
    mStatus status;
    sigset_t signals;

    if (argc < 3) goto usage;

    status = mDNS_Init(&mDNSStorage, &PlatformStorage,
                       mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
                       mDNS_Init_DontAdvertiseLocalAddresses,
                       mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
    if (status) { fprintf(stderr, "Daemon start: mDNS_Init failed %d\n", (int)status); return(status); }

    mDNSPosixListenForSignalInEventLoop(SIGINT);
    mDNSPosixListenForSignalInEventLoop(SIGTERM);

    if (!strcmp(argv[1], "-"))
    {
        domainname proxyhostname;
        AuthRecord proxyrecord;
        if (argc < 5) goto usage;
        proxyhostname.c[0] = 0;
        AppendLiteralLabelString(&proxyhostname, argv[2]);
        AppendLiteralLabelString(&proxyhostname, "local");
        RegisterNoSuchService(&mDNSStorage, &proxyrecord, &proxyhostname, argv[3], argv[4], "local.");
    }
    else
    {
        ProxyHost proxyhost;
        ServiceRecordSet proxyservice;

        proxyhost.ip.NotAnInteger = inet_addr(argv[1]);
        if (proxyhost.ip.NotAnInteger == INADDR_NONE)   // INADDR_NONE is 0xFFFFFFFF
        {
            struct hostent *h = gethostbyname(argv[1]);
            if (h) proxyhost.ip.NotAnInteger = *(long*)h->h_addr;
        }
        if (proxyhost.ip.NotAnInteger == INADDR_NONE)   // INADDR_NONE is 0xFFFFFFFF
        {
            fprintf(stderr, "%s is not valid host address\n", argv[1]);
            return(-1);
        }

        MakeDomainLabelFromLiteralString(&proxyhost.hostlabel, argv[2]);

        mDNS_RegisterProxyHost(&mDNSStorage, &proxyhost);

        if (argc >=6)
            RegisterService(&mDNSStorage, &proxyservice, argv[3], argv[4], "local.",
                            proxyhost.RR_A.resrec.name, atoi(argv[5]), argc-6, &argv[6]);
    }

    do
    {
        struct timeval timeout = { 0x3FFFFFFF, 0 };     // wait until SIGINT or SIGTERM
        mDNSBool gotSomething;
        mDNSPosixRunEventLoopOnce(&mDNSStorage, &timeout, &signals, &gotSomething);
    }
    while ( !( sigismember( &signals, SIGINT) || sigismember( &signals, SIGTERM)));

    mDNS_Close(&mDNSStorage);

    return(0);

usage:
    fprintf(stderr, "%s ip hostlabel [srvname srvtype port txt [txt ...]]\n", argv[0]);
    fprintf(stderr, "ip        Real IP address (or valid host name) of the host where the service actually resides\n");
    fprintf(stderr, "hostlabel First label of the dot-local host name to create for this host, e.g. \"foo\" for \"foo.local.\"\n");
    fprintf(stderr, "srvname   Descriptive name of service, e.g. \"Stuart's Ink Jet Printer\"\n");
    fprintf(stderr, "srvtype   IANA service type, e.g. \"_ipp._tcp\" or \"_ssh._tcp\", etc.\n");
    fprintf(stderr, "port      Port number where the service resides (1-65535)\n");
    fprintf(stderr, "txt       Additional name/value pairs specified in service definition, e.g. \"pdl=application/postscript\"\n");
    fprintf(stderr, "e.g. %s 169.254.12.34 thehost                                (just create a dot-local host name)\n", argv[0]);
    fprintf(stderr, "or   %s 169.254.12.34 thehost \"My Printer\" _printer._tcp. 515 rp=lpt1 pdl=application/postscript\n", argv[0]);
    fprintf(stderr, "or   %s -             thehost \"My Printer\" _printer._tcp.           (assertion of non-existence)\n", argv[0]);
    return(-1);
}
Esempio n. 9
0
int rend_private_init(char *user) {
    mStatus status;
    mDNSBool result;

    status = mDNS_Init(&mDNSStorage, &PlatformStorage,
                       mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
                       mDNS_Init_AdvertiseLocalAddresses,
                       mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
    
    if (status != mStatus_NoError) {
        DPRINTF(E_FATAL,L_REND,"mDNS Error %d\n",status);
        return(-1);
    }

    if(os_drop_privs(user))
        return -1;

    signal(SIGINT,  HandleSigInt);      // SIGINT is what you get for a Ctrl-C
    signal(SIGQUIT, HandleSigQuit);     // SIGQUIT is what you get for a Ctrl-\ (indeed)
    signal(SIGHUP,  SIG_IGN);           // SIGHUP might happen from a request to reload the daap server

    while (!gStopNow) {
        int nfds = 1;
        fd_set readfds;
        struct timeval timeout;
        int result;
        
        // 1. Set up the fd_set as usual here.
        // This example client has no file descriptors of its own,
        // but a real application would call FD_SET to add them to the set here
        FD_ZERO(&readfds);
        FD_SET(rend_pipe_to[RD_SIDE],&readfds);
        
        // 2. Set up the timeout.
        // This example client has no other work it needs to be doing,
        // so we set an effectively infinite timeout
        timeout.tv_sec = 0x3FFFFFFF;
        timeout.tv_usec = 0;
        
        // 3. Give the mDNSPosix layer a chance to add its information to the fd_set and timeout
        mDNSPosixGetFDSet(&mDNSStorage, &nfds, &readfds, &timeout);
        
        // 4. Call select as normal
        DPRINTF(E_SPAM,L_REND,"select(%d, %d.%06d)\n", nfds, 
                timeout.tv_sec, timeout.tv_usec);
        
        result = select(nfds, &readfds, NULL, NULL, &timeout);
        
        if (result < 0) {
            if (errno != EINTR) gStopNow = mDNStrue;
            DPRINTF(E_WARN,L_REND,"select() returned %d errno %d\n", result, errno);
        } else {
            // 5. Call mDNSPosixProcessFDSet to let the mDNSPosix layer do its work
            mDNSPosixProcessFDSet(&mDNSStorage, &readfds);
            
            // 6. This example client has no other work it needs to be doing,
            // but a real client would do its work here
            // ... (do work) ...
            if(FD_ISSET(rend_pipe_to[RD_SIDE],&readfds)) {
                rend_callback();
            }
        }
    }
    
    DPRINTF(E_DBG,L_REND,"Exiting\n");
    
    DeregisterOurServices();
    mDNS_Close(&mDNSStorage);
    
    if (status == mStatus_NoError) {
        result = 0;
    } else {
        result = 2;
    }
    DPRINTF(E_DBG,L_REND, "Finished with status %ld, result %d\n", 
            status, result);

    exit(result);
}
Esempio n. 10
0
int main(int argc, char **argv)
{
    mStatus status;
    int     result;

    // Parse our command line arguments.  This won't come back if there's an error.
    
    ParseArguments(argc, argv);

    // If we're told to run as a daemon, then do that straight away.
    // Note that we don't treat the inability to create our PID 
    // file as an error.  Also note that we assign getpid to a long 
    // because printf has no format specified for pid_t.
    
    if (gDaemon) {
        if (gMDNSPlatformPosixVerboseLevel > 0) {
            fprintf(stderr, "%s: Starting in daemon mode\n", gProgramName);
        }
        daemon(0,0);
        {
            FILE *fp;
            int  junk;
            
            fp = fopen(gPIDFile, "w");
            if (fp != NULL) {
                fprintf(fp, "%ld\n", (long) getpid());
                junk = fclose(fp);
                assert(junk == 0);
            }
        }
    } else {
        if (gMDNSPlatformPosixVerboseLevel > 0) {
            fprintf(stderr, "%s: Starting in foreground mode, PID %ld\n", gProgramName, (long) getpid());
        }
    }

    status = mDNS_Init(&mDNSStorage, &PlatformStorage,
    	mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
    	mDNS_Init_AdvertiseLocalAddresses,
    	mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
    if (status != mStatus_NoError) return(2);

	status = RegisterOurServices();
    if (status != mStatus_NoError) return(2);
    
    signal(SIGHUP,  HandleSigHup);      // SIGHUP has to be sent by kill -HUP <pid>
    signal(SIGINT,  HandleSigInt);      // SIGINT is what you get for a Ctrl-C
    signal(SIGQUIT, HandleSigQuit);     // SIGQUIT is what you get for a Ctrl-\ (indeed)
    signal(SIGUSR1, HandleSigUsr1);     // SIGUSR1 has to be sent by kill -USR1 <pid>

	while (!gStopNow)
		{
		int nfds = 0;
		fd_set readfds;
		struct timeval timeout;
		int result;
		
		// 1. Set up the fd_set as usual here.
		// This example client has no file descriptors of its own,
		// but a real application would call FD_SET to add them to the set here
		FD_ZERO(&readfds);
		
		// 2. Set up the timeout.
		// This example client has no other work it needs to be doing,
		// so we set an effectively infinite timeout
		timeout.tv_sec = 0x3FFFFFFF;
		timeout.tv_usec = 0;
		
		// 3. Give the mDNSPosix layer a chance to add its information to the fd_set and timeout
		mDNSPosixGetFDSet(&mDNSStorage, &nfds, &readfds, &timeout);
		
		// 4. Call select as normal
		verbosedebugf("select(%d, %d.%06d)", nfds, timeout.tv_sec, timeout.tv_usec);
		result = select(nfds, &readfds, NULL, NULL, &timeout);
		
		if (result < 0)
			{
			verbosedebugf("select() returned %d errno %d", result, errno);
			if (errno != EINTR) gStopNow = mDNStrue;
			else
				{
				if (gReceivedSigUsr1)
					{
					gReceivedSigUsr1 = mDNSfalse;
					gMDNSPlatformPosixVerboseLevel += 1;
					if (gMDNSPlatformPosixVerboseLevel > 2)
						gMDNSPlatformPosixVerboseLevel = 0;
					if ( gMDNSPlatformPosixVerboseLevel > 0 )
						fprintf(stderr, "\nVerbose level %d\n", gMDNSPlatformPosixVerboseLevel);
					}
				if (gReceivedSigHup)
					{
					if (gMDNSPlatformPosixVerboseLevel > 0)
						fprintf(stderr, "\nSIGHUP\n");
					gReceivedSigHup = mDNSfalse;
					DeregisterOurServices();
					status = mDNSPlatformPosixRefreshInterfaceList(&mDNSStorage);
					if (status != mStatus_NoError) break;
					status = RegisterOurServices();
					if (status != mStatus_NoError) break;
					}
				}
			}
		else
			{
			// 5. Call mDNSPosixProcessFDSet to let the mDNSPosix layer do its work
			mDNSPosixProcessFDSet(&mDNSStorage, &readfds);
			
			// 6. This example client has no other work it needs to be doing,
			// but a real client would do its work here
			// ... (do work) ...
			}
		}

	debugf("Exiting");
    
	DeregisterOurServices();
	mDNS_Close(&mDNSStorage);

    if (status == mStatus_NoError) {
        result = 0;
    } else {
        result = 2;
    }
    if ( (result != 0) || (gMDNSPlatformPosixVerboseLevel > 0) ) {
        fprintf(stderr, "%s: Finished with status %ld, result %d\n", gProgramName, status, result);
    }
    
    return result;
}
Esempio n. 11
0
int main(void)
    // The program's main entry point.  The program does a trivial 
    // mDNS query, looking for mDNS service & device in the local domain.
{
    	int     result;
    	mStatus     status;
    	DNSQuestion question;
    	domainname  type;
    	domainname  domain;
	char DeviceName[64];

    	// Initialise the mDNS core.
	status = mDNS_Init(&mDNSStorage, &PlatformStorage,
    	gRRCache, RR_CACHE_SIZE,
    	mDNS_Init_DontAdvertiseLocalAddresses,
    	mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);

    if (status == mStatus_NoError) {
#if 1 /* Query service type */
        // Construct and start the query.
        MakeDomainNameFromDNSNameString(&type, gServiceType);
        MakeDomainNameFromDNSNameString(&domain, gServiceDomain);

        status = mDNS_StartBrowse(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, BrowseCallback, NULL);
    
	//return;
        // Run the platform main event loop. 
        // The BrowseCallback routine is responsible for printing 
        // any results that we find.
        
        if (status == mStatus_NoError) {
            	fprintf(stderr, "* Query: %s\n", gServiceType);
        	EventLoop(&mDNSStorage);
            	mDNS_StopQuery(&mDNSStorage, &question);
                //Parse all service type and query detail
                //fprintf(stderr, "===== Parse all service type and query detail...\n");
                callback = 0;
                event = 0;
		StopNow = 0;
	}
	return 0;
#endif

#if 0 /* Query device name */
		Service_tmp = Service_list;
		while(Service_tmp!=NULL) {
			printf("\n======= Queried Service: %s.%s\n", Service_tmp->service, Service_tmp->type);
			sprintf(Query_type, "%s.%s", Service_tmp->service, Service_tmp->type);
			//Device_found = Service_tmp->sup_device;
			gServiceType = Query_type;
			MakeDomainNameFromDNSNameString(&type, gServiceType);
			status = mDNS_StartBrowse(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, QueryCallback, NULL);
			if (status == mStatus_NoError) {
		                EventLoop(&mDNSStorage);
        		        mDNS_StopQuery(&mDNSStorage, &question);
			}
                        callback = 0;
                        event = 0;
                        StopNow = 0;
                        Service_tmp = Service_tmp->next;
                }
		printf("===============\n\n");
#endif

#if 0 /* Query IP of device */
		DeviceIP_cur = Device_list;
		printf("%d,%d,%d  ", callback, event, StopNow);
		printf("QUERY DEVICE: %s/%s\n", Device_cur->name, Device_cur->IPv4Addr);
		char *cc = Device_cur->IPv4Addr;
		int x =0;
		for(; x<16; x++) {
			printf("%",*cc);
			cc++;
		}
		printf("\n");
		//if(DeviceIP_cur->IPv4Addr == NULL)
		if(!strcmp(DeviceIP_cur->IPv4Addr, ""))
			printf("    DeviceIP_cur->IPv4Addr == NULL\n");

		while(DeviceIP_cur && (!strcmp(DeviceIP_cur->IPv4Addr, ""))) {
			memset(DeviceName, 0, 64);
			strcpy(DeviceName, DeviceIP_cur->name);
			HostnameParse(DeviceName);
			gServiceType = DeviceName;
        		printf("Query IP of %s\n", gServiceType);
		        // Construct and start the query.
		       	MakeDomainNameFromDNSNameString(&type, gServiceType);
		        status = mDNS_GetAddrInfo(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, IPInfoCallback, NULL);
		        if (status == mStatus_NoError) {
		       	        EventLoop(&mDNSStorage);
                		mDNS_StopQuery(&mDNSStorage, &question);
		        }
			else {
				printf("Error= %ld\n", status);
			}
			DeviceIP_cur = DeviceIP_cur->next;
        	               callback = 0;
                        event = 0;
                       	StopNow = 0;
		}

		printf("===============\n");
#endif
int nvram_size, i = 0;
char *nvram_info;
char device_name_ascii[256], service_type_list[512];
struct mDNS_service_handler *handler;

nvram_size = device_count*64 + service_count*4;
nvram_info = malloc(nvram_size);
memset(nvram_info, 0, nvram_size);
printf("nvram_size= %d\n", nvram_size);

    	//Print all info
    	Service_tmp = Service_list;
    	while(Service_tmp!=NULL) {
		printf("\n=== %s.%s ===\n", Service_tmp->service, Service_tmp->type);
		Service_tmp = Service_tmp->next;
    	}

printf("\n===== Print device ========\n");
        Device_tmp = Device_list;
        while(Device_tmp!=NULL) {
                //printf("    %s:%s->", Device_tmp->name, Device_tmp->IPv4Addr);
		memset(device_name_ascii, 0, 256);
		char_to_ascii(device_name_ascii, Device_tmp->name);
		strcat(nvram_info, "<");
		sprintf(nvram_info, "%s%s>%s>", nvram_info, Device_tmp->IPv4Addr, device_name_ascii);
printf("    %s\n", nvram_info);
		Sup_service_tmp = Device_tmp->sup_service;
		memset(service_type_list, 0, 512);
		while(Sup_service_tmp!=NULL) {
			for(handler = &service_handler[0], i=0; handler->service; handler++, i++) {
				if(strstr(Sup_service_tmp->name, handler->service)) {
					sprintf(service_type_list, "%s#%d", service_type_list, i);
					break;
				}	
			}

			printf("%s ", Sup_service_tmp->name);
			Sup_service_tmp = Sup_service_tmp->next;
		}
		printf("\n");
		printf("Service_type= %s\n", service_type_list);
		sprintf(nvram_info, "%s%s", nvram_info, service_type_list);
printf("-> %s\n", nvram_info);
                Device_tmp = Device_tmp->next;
        }
	printf("\n==> %s\n", nvram_info);

	free(nvram_info);
	mDNS_Close(&mDNSStorage);
    }//Endof Initialise the mDNS core.
    
    if (status == mStatus_NoError) {
        result = 0;
    } else {
        result = 2;
    }
    if ( (result != 0) || (gMDNSPlatformPosixVerboseLevel > 0) ) {
        fprintf(stderr, "%s: Finished with status %d, result %d\n", gProgramName, (int)status, result);
    }

    return 0;
}
int main()
	{
	mStatus err;
	Boolean DoneSetup = false;
	void *tempmem;

	SIOUXSettings.asktosaveonclose = false;
	SIOUXSettings.userwindowtitle  = "\pMulticast DNS Searcher";
	SIOUXSettings.rows             = 40;
	SIOUXSettings.columns          = 132;

	printf("Multicast DNS Searcher\n\n");
	printf("This software reports errors using MacsBug breaks,\n");
	printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
	printf("******************************************************************************\n");

	err = InitOpenTransport();
	if (err) { debugf("InitOpenTransport failed %d", err); return(err); }

	err = mDNS_Init(&mDNSStorage, &PlatformSupportStorage, rrcachestorage, RR_CACHE_SIZE,
		mDNS_Init_DontAdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
	if (err) return(err);

	// Make sure OT has a large enough memory pool for us to draw from at OTNotifier (interrupt) time
	tempmem = OTAllocMem(0x10000);
	if (tempmem) OTFreeMem(tempmem);
	else printf("**** Warning: OTAllocMem couldn't pre-allocate 64K for us.\n");

	services.serviceinfolist.fHead = NULL;
	services.headerPrinted         = false;
	services.lostRecords           = false;

	while (!YieldSomeTime(35))
		{
#if MDNS_ONLYSYSTEMTASK
		// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
		// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
		extern void mDNSPlatformIdle(mDNS *const m);
		mDNSPlatformIdle(&mDNSStorage);	// Only needed for debugging version
#endif
		if (mDNSStorage.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
			{
			domainname srvtype, srvdom;
			DoneSetup = true;
			printf("\nSending mDNS service lookup queries and waiting for responses...\n\n");
			MakeDomainNameFromDNSNameString(&srvtype, "_http._tcp.");
			MakeDomainNameFromDNSNameString(&srvdom, "local.");
			err = mDNS_StartBrowse(&mDNSStorage, &browsequestion, &srvtype, &srvdom, mDNSInterface_Any, mDNSfalse, FoundInstance, &services);
			if (err) break;
			err = mDNS_GetDomains(&mDNSStorage, &domainquestion, mDNS_DomainTypeBrowse, NULL, mDNSInterface_Any, FoundDomain, &services);
			if (err) break;
			}

		if (services.serviceinfolist.fHead)
			PrintServiceInfo(&services);

		if (services.lostRecords)
			{
			services.lostRecords = false;
			printf("**** Warning: Out of memory: Records have been missed.\n");
			}
		}

	mDNS_StopBrowse(&mDNSStorage, &browsequestion);
	mDNS_Close(&mDNSStorage);
	return(0);
	}
int main()
	{
	mStatus err;
	Boolean DoneSetup = false;
	mDNSs32 nextAvail, nextBusy;

	SIOUXSettings.asktosaveonclose = false;
	SIOUXSettings.userwindowtitle = "\pMulticast DNS Responder";

	printf("Multicast DNS Responder\n\n");
	printf("This software reports errors using MacsBug breaks,\n");
	printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
	printf("******************************************************************************\n");

	err = InitOpenTransport();
	if (err) { debugf("InitOpenTransport failed %d", err); return(err); }

	err = mDNS_Init(&m, &p, mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
		mDNS_Init_AdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
	if (err) return(err);

	while (!YieldSomeTime(35))
		{
#if MDNS_ONLYSYSTEMTASK
		// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
		// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
		extern void mDNSPlatformIdle(mDNS *const m);
		mDNSPlatformIdle(&m);	// Only needed for debugging version
#endif
		if (m.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
			{
			DoneSetup = true;
			printf("\nListening for mDNS queries...\n");
			mDNSResponderTestSetup(&m);
			mDNSResponderSetAvail(&m, &availRec1, &p1);
			availRec2Active = false;
			nextAvail = mDNS_TimeNow(&m) + mDNSPlatformOneSecond * 10;
			nextBusy  = mDNS_TimeNow(&m) + mDNSPlatformOneSecond * 15;
			}

		if (DoneSetup)
			{
			// We check availRec2.RecordType because we don't want to re-register this record
			// if the previous mDNS_Deregister() has not yet completed
			if (mDNS_TimeNow(&m) - nextAvail > 0 && !availRec2Active)
				{
				printf("Setting Two now available\n");
				availRec2Active = true;
				mDNSResponderSetAvail(&m, &availRec2, &p2);
				nextAvail = nextBusy + mDNSPlatformOneSecond * 10;
				}
			else if (mDNS_TimeNow(&m) - nextBusy > 0)
				{
				printf("Setting Two now busy\n");
				mDNS_Deregister(&m, &availRec2);
				nextBusy = nextAvail + mDNSPlatformOneSecond * 5;
				}
			}
		}
	
	if (p1.RR_SRV.resrec.RecordType) mDNS_DeregisterService(&m, &p1);
	if (p2.RR_SRV.resrec.RecordType) mDNS_DeregisterService(&m, &p2);
	if (availRec1.resrec.RecordType) mDNS_Deregister(&m, &availRec1);
	if (availRec2Active)             mDNS_Deregister(&m, &availRec2);

	mDNS_Close(&m);
	
	return(0);
	}