From: Stuart Cheshire <[email protected]>
Subject: Re: Looking for some sample appletalk ATP code...
Date: Wed, 2 Sep 92 18:11:08 GMT

In article <[email protected]> Alex Bratton,
[email protected] 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 <[email protected]>
* Liliore Green Rains Houses Resident Computer Coordinator
* Stanford Distributed Systems Group Research Assistant
* Macintosh Programmer