From: Stuart Cheshire <cheshire@cs.stanford.edu>
Subject: Re: Looking for some sample appletalk ATP code... 
Date: Wed, 2 Sep 92 18:11:08 GMT 

In article <1992Sep1.033635.28604@sunb10.cs.uiuc.edu> Alex Bratton,
bratton@sparc3.cs.uiuc.edu writes:
>If you have some sample code (ATP) that opens, registers, and dumps some
>data, I'd really appreciate seeing it.  This has been bugging me for a
while
>and I think I need to look at some working code to see what I'm missing.

Here is some more sample code, which opens and registers an ATP socket.
It is from the Macintosh User Authenticator mentioned in a previous post
be me.

The code is written for Think C 5.

#include <Traps.h>
#include <GestaltEqu.h>
#include <Folders.h>
#include <AppleTalk.h>

#define local static
#define export
#define import extern
typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
#define until(A) while (!(A))

typedef struct
	{
	BYTE sysLAPAddr;
	BYTE destnode;
	BYTE srcnode;
	BYTE ALAPproto;
	WORD length;
	union
		{
		struct
			{
			BYTE destsocket;
			BYTE srcsocket;
			BYTE DPPproto;
			BYTE userdata[15];
			} shortheader;
		struct
			{
			WORD checksum;
			WORD destnet;
			WORD srcnet;
			BYTE destnode;
			BYTE srcnode;
			BYTE destsocket;
			BYTE srcsocket;
			BYTE DPPproto;
			BYTE userdata[7];
			} longheader;
		} u;
	BYTE unused;
	BYTE sysABridge;
	WORD sysNetNum;
	WORD vSCCEnable;
	} MPPglobals;

extern MPPglobals *ABusVars : 0x2D8;

typedef struct
	{
	ATPParamBlock p;
	long *myglobals;
	} myATPParamBlock;

local NamesTableEntry myNTE;	/* DONT TOUCH THIS -- IT'S USED CONTINUOUSLY
BY NBP */

// name must be 8 characters long
local void construct_name(AddrBlock addr, unsigned char *name)
	{
	static unsigned char hextable[] = "0123456789ABCDEF";
	name[0] = 7;
	name[1] = hextable[(addr.aNet  >> 12) & 0xF];
	name[2] = hextable[(addr.aNet  >>  8) & 0xF];
	name[3] = hextable[(addr.aNet  >>  4) & 0xF];
	name[4] = hextable[(addr.aNet  >>  0) & 0xF];
	name[5] = '.';
	name[6] = hextable[(addr.aNode >>  4) & 0xF];
	name[7] = hextable[(addr.aNode >>  0) & 0xF];
	}

local void awaitrequest(void);
local void acceptrequest(void)
	{
	static char dummy;
	static BDSElement bds;
	
	myATPParamBlock *atp_pb;
	long *saveGptr;
	asm	{	move.l	GLOBREG, saveGptr
			move.l	a0, atp_pb
			move.l	myATPParamBlock.myglobals(a0), GLOBREG
		}
	
	// if (atp_pb->p.ATPioResult) What to do if error?

// do whatever you want here to prepare your response...
	
	bds.buffSize  = sizeof(dummy);
	bds.buffPtr   = (Ptr)&dummy;
	bds.dataSize  = 0;
	bds.userBytes = 0;
	
	atp_pb->p.ATPioCompletion = awaitrequest;
	atp_pb->p.ATPatpFlags   = atpEOMvalue;
	atp_pb->p.ATPbdsPointer = (Ptr)&bds;
	atp_pb->p.ATPnumOfBuffs = 1;
	atp_pb->p.ATPbdsSize    = 1;
	
	PSendResponse(&atp_pb->p, TRUE);

	asm { move.l saveGptr, GLOBREG }
	}

local void awaitrequest(void)
	{
	static MACAUTH_REQUEST req;
	myATPParamBlock *atp_pb;
	long *saveGptr;
	asm	{	move.l	GLOBREG, saveGptr
			move.l	a0, atp_pb
			move.l	myATPParamBlock.myglobals(a0), GLOBREG
		}
	atp_pb->p.ATPioCompletion = acceptrequest;
	atp_pb->p.ATPatpSocket    = myNTE.nt.nteAddress.aSocket;
	atp_pb->p.ATPreqLength    = sizeof(req);
	atp_pb->p.ATPreqPointer   = (Ptr)&req;
	PGetRequest(&atp_pb->p, TRUE);
	asm { move.l saveGptr, GLOBREG }
	}

local OSErr AppleTalkInit(void)	// returns non-zero if init failed
	{
	OSErr retcode;
	short MPPRefNum;
	MPPParamBlock p;
	ATPParamBlock atp;
	static myATPParamBlock req_pb;
	static AddrBlock zeroaddress;
	static unsigned char regname[8];
	
	if (retcode = OpenDriver("\p.MPP", &MPPRefNum))
		{ DebugStr("\pCouldn't open AppleTalk driver"); return(retcode); }

	p.SETSELF.newSelfFlag = TRUE;
	PSetSelfSend(&p, FALSE);     // no need to abort if this fails
	
	atp.ATPatpSocket = 0;
	atp.ATPaddrBlock = zeroaddress;
	if (retcode = POpenATPSkt(&atp, FALSE))
		{ DebugStr("\pCouldn't open ATP socket"); return(retcode); }

	myNTE.nt.nteAddress.aNet    = ABusVars->sysNetNum;
	myNTE.nt.nteAddress.aNode   = ABusVars->sysLAPAddr;
	myNTE.nt.nteAddress.aSocket = atp.ATPatpSocket;
	
	construct_name(myNTE.nt.nteAddress, regname);

	NBPSetNTE((Ptr)&myNTE,
		(Ptr)regname, (Ptr)"\pMacintosh Authenticator", (Ptr)"\p*",
		myNTE.nt.nteAddress.aSocket);
	
	p.NBPinterval    = 2;
	p.NBPcount       = 2;
	p.NBPntQElPtr    = (Ptr)&myNTE;
	p.NBPverifyFlag  = TRUE;
	if (retcode = PRegisterName(&p, FALSE))
		{ DebugStr("\pCouldn't Register name"); return(retcode); }

	asm	{	move.l	GLOBREG, req_pb.myglobals
			lea		req_pb, a0
			bsr		awaitrequest
		}
	}


Stuart Cheshire <cheshire@cs.stanford.edu>
 * Liliore Green Rains Houses Resident Computer Coordinator
 * Stanford Distributed Systems Group Research Assistant
 * Macintosh Programmer