/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>						// For printf()
#include <string.h>						// For strcpy()

#include <Events.h>						// For WaitNextEvent()

#include <OpenTransport.h>
#include <OpenTptInternet.h>

#include <SIOUX.h>						// For SIOUXHandleOneEvent()

#include "dns_sd.h"

typedef union { UInt8 b[2]; UInt16 NotAnInteger; } mDNSOpaque16;
static UInt16 mDNSVal16(mDNSOpaque16 x) { return((UInt16)(x.b[0]<<8 | x.b[1])); }
static mDNSOpaque16 mDNSOpaque16fromIntVal(UInt16 v)
	{ mDNSOpaque16 x; x.b[0] = (UInt8)(v >> 8); x.b[1] = (UInt8)(v & 0xFF); return(x); }

typedef struct RegisteredService_struct RegisteredService;
struct RegisteredService_struct
	{
	RegisteredService *next;
	DNSServiceRef sdRef;
	Boolean gotresult;
	DNSServiceErrorType errorCode;
	char namestr[64];
	char typestr[kDNSServiceMaxDomainName];
	char domstr [kDNSServiceMaxDomainName];
	};

static RegisteredService p1, p2, afp, http, njp;
static RegisteredService *services = NULL, **nextservice = &services;

static void RegCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
						const char *name, const char *regtype, const char *domain, void *context)
    {
    RegisteredService *rs = (RegisteredService *)context;
    (void)sdRef;	// Unused
    (void)flags;	// Unused
    rs->gotresult = true;
    rs->errorCode = errorCode;
    strcpy(rs->namestr, name);
    strcpy(rs->typestr, regtype);
    strcpy(rs->domstr,  domain);
    }

static DNSServiceErrorType RegisterService(RegisteredService *rs, mDNSOpaque16 OpaquePort,
	const char name[], const char type[], const char domain[], const char txtinfo[])
	{
	DNSServiceErrorType err;
	unsigned char txtbuffer[257];
	strncpy((char*)txtbuffer+1, txtinfo, 255);
	txtbuffer[256] = 0;
	txtbuffer[0] = (unsigned char)strlen((char*)txtbuffer);
	rs->gotresult = 0;
	rs->errorCode = kDNSServiceErr_NoError;
	err = DNSServiceRegister(&rs->sdRef, /* kDNSServiceFlagsAutoRename*/ 0, 0,
		name, type, domain, NULL, OpaquePort.NotAnInteger, (unsigned short)(1+txtbuffer[0]), txtbuffer, RegCallback, rs);
	if (err)
		printf("RegisterService(%s %s %s) failed %d\n", name, type, domain, err);
	else
		{ *nextservice = rs; nextservice = &rs->next; }
	return(err);
	}

// RegisterFakeServiceForTesting() simulates the effect of services being registered on
// dynamically-allocated port numbers. No real service exists on that port -- this is just for testing.
static DNSServiceErrorType RegisterFakeServiceForTesting(RegisteredService *rs,
	const char name[], const char type[], const char domain[], const char txtinfo[])
	{
	static UInt16 NextPort = 0xF000;
	return RegisterService(rs, mDNSOpaque16fromIntVal(NextPort++), name, type, domain, txtinfo);
	}

// CreateProxyRegistrationForRealService() checks to see if the given port is currently
// in use, and if so, advertises the specified service as present on that port.
// This is useful for advertising existing real services (Personal Web Sharing, Personal
// File Sharing, etc.) that currently don't register with mDNS Service Discovery themselves.
static DNSServiceErrorType CreateProxyRegistrationForRealService(RegisteredService *rs,
	const char *servicetype, UInt16 PortAsNumber, const char txtinfo[])
	{
	mDNSOpaque16 OpaquePort = mDNSOpaque16fromIntVal(PortAsNumber);
	InetAddress ia;
	TBind bindReq;
	OSStatus err;
	TEndpointInfo endpointinfo;
	EndpointRef ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &endpointinfo, &err);
	if (!ep || err) { printf("OTOpenEndpoint (CreateProxyRegistrationForRealService) failed %d", err); return(err); }

	ia.fAddressType = AF_INET;
	ia.fPort        = OpaquePort.NotAnInteger;
	ia.fHost        = 0;
	bindReq.addr.maxlen = sizeof(ia);
	bindReq.addr.len    = sizeof(ia);
	bindReq.addr.buf    = (UInt8*)&ia;
	bindReq.qlen        = 0;
	err = OTBind(ep, &bindReq, NULL);

	if (err == kOTBadAddressErr)
		err = RegisterService(rs, OpaquePort, "", servicetype, "local.", txtinfo);
	else if (err)
		printf("OTBind failed %d", err);

	OTCloseProvider(ep);
	return(err);
	}

// YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
static Boolean YieldSomeTime(UInt32 milliseconds)
	{
	extern Boolean SIOUXQuitting;
	EventRecord e;
	WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
	SIOUXHandleOneEvent(&e);
	return(SIOUXQuitting);
	}

int main()
	{
	OSStatus err;
	RegisteredService *s;
	
	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\n");

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

	printf("Advertising Services...\n");

#define SRSET 0
#if SRSET==0
	RegisterFakeServiceForTesting(&p1, "Web Server One", "_http._tcp.", "local.", "path=/index.html");
	RegisterFakeServiceForTesting(&p2, "Web Server Two", "_http._tcp.", "local.", "path=/path.html");
#elif SRSET==1
	RegisterFakeServiceForTesting(&p1, "Epson Stylus 900N", "_printer._tcp.", "local.", "rn=lpq1");
	RegisterFakeServiceForTesting(&p2, "HP LaserJet",       "_printer._tcp.", "local.", "rn=lpq2");
#else
	RegisterFakeServiceForTesting(&p1, "My Printer",        "_printer._tcp.", "local.", "rn=lpq3");
	RegisterFakeServiceForTesting(&p2, "My Other Printer",  "_printer._tcp.", "local.", "lrn=pq4");
#endif

	// If AFP Server is running, register a record for it
	CreateProxyRegistrationForRealService(&afp, "_afpovertcp._tcp.", 548, "");

	// If Web Server is running, register a record for it
	CreateProxyRegistrationForRealService(&http, "_http._tcp.",       80, "path=/index.html");

	while (!YieldSomeTime(35))
		for (s = services; s; s = s->next)
			if (s->gotresult)
				{
				printf("%s %s %s registered\n", s->namestr, s->typestr, s->domstr);
				s->gotresult = false;
				}
	
	for (s = services; s; s = s->next)
		if (s->sdRef) DNSServiceRefDeallocate(s->sdRef);

	CloseOpenTransport();
	return(0);
	}
