Q: How do I obtain a list of volumes from a server programmatically, given that I
have the atalk-internet address of that server?
A: To obtain a list of volumes from a server programatically, you use an
AFPCommand called afpGetSParms . This command requires you to log in (as either
a guest or a user) and create a session, and then issue the afpGetSParms . The
string returned by afpGetSParms , which is described on page 13-98 of
Inside AppleTalk,looks like this:
[0-3] long Current Date-time on Server's clock
[4] byte Number of Volumes that follow
---->
byte NumVol Structure...
Msb = HasPassword (bit)
Lsb = HasConfigInfo (appleII stuff, ignore it)
P-String Volume Name
<----
|
The string is repeated for each volume.
There is also an example in the February 1995 Developer CD:
Dev.CD Feb 95:Sample Code:Snippets:Networking:AppleTalk Libraries
The string from this example looks like this:
short LogOnAsGuest(AddrBlock *serverAddress,Ptr SCBBlock)
{
AFPLoginPrm *XPPBlock; /* to build parameter blocks for AFP */
short cbsize;
char XPPReply[quantumSize*8];
/* used to get AFP replies (max. size 8 ATP packet) */
char XPPCmd[quantumSize]; /* used to send AFP commands */
OSErr error;
short result;
- /* information used by Login function */
char AFPVersion[30];
char AuthentMethod[30];
strcpy(AFPVersion, "AFPVersion 2.0");
strcpy(AuthentMethod, "No User Authent");
if (!(XPPBlock = (AFPLoginPrm *)NewPtrClear(sizeof(AFPLoginPrm))))
return MemError();
XPPBlock->ioRefNum = xppRefNum;
XPPBlock->ioCompletion = nil;
XPPBlock->aspTimeout = 1; /* Timeout for ATP */
XPPBlock->aspRetry = 2; /* Retry count for ATP */
XPPBlock->afpAddrBlock = *serverAddress;
/* AppleTalk address of the server */
XPPBlock->afpAttnRoutine = nil ;
XPPBlock->rbPtr = (Ptr)XPPReply; /* Reply buffer pointer */
XPPBlock->rbSize = quantumSize; /* Reply buffer size */
/* prepare command information :
1st byte : command (login)
2nd Pascal string : AFP version
3rd Pascal string : Authentication
Method - see Inside AppleTalk 13-104 */
XPPCmd[0] = afpLogin;
XPPCmd[1] = strlen(AFPVersion);
strcpy(XPPCmd+2,AFPVersion);
cbsize = strlen(XPPCmd);
XPPCmd[cbsize] = strlen(AuthentMethod);
strcpy(XPPCmd+cbsize+1,AuthentMethod);
cbsize = strlen(XPPCmd);
XPPBlock->cbPtr = (Ptr)XPPCmd; /* Command block pointer */
XPPBlock->cbSize = cbsize;
XPPBlock->afpSCBPtr = (Ptr) SCBBlock; /* SCB pointer in AFP login */
if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) != noErr)
result = error;
else
if (XPPBlock->cmdResult != noErr)
result = XPPBlock->cmdResult ;
else result = XPPBlock->sessRefnum;
/* return session number */
DisposPtr((Ptr)XPPBlock);
return result;
} /* LogOnAsGuest */
OSErr GetServerParams(short sessNum,Ptr replyBuffer,short buffLength)
{
XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
char XPPCmd[quantumSize];/* used to send AFP commands */
OSErr error;
if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
return MemError();
XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
/* prepare command information :
no input provided except command - see IA 13-98 */
XPPCmd[0] = afpGetSParms;
XPPBlock->sessRefnum = sessNum;
XPPBlock->aspTimeout = 2; /* Timeout for ATP */
XPPBlock->aspRetry = 2;
XPPBlock->cbPtr = (Ptr)XPPCmd;
XPPBlock->cbSize = 1; /* Command block size */
XPPBlock->rbPtr = replyBuffer; /* Reply buffer pointer */
XPPBlock->rbSize = buffLength;
XPPBlock->wdSize = 0; /* Write Data size */
XPPBlock->wdPtr = nil; /* Write Data pointer */
error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync);
DisposPtr((Ptr)XPPBlock);
return error;
}
main()
{
Str32 theServer;
Ptr buffer;
AddrBlock serverAddress;
char SCBBlock[scbMemSize]; /* used by AFP to manage a session */
short sessionNum;
OSErr ErrNo;
short refNum;
/* allocate a buffer to retrieve info */
if (!(buffer = NewPtr(buffSize))) return;
/* open .XPP driver */
ErrNo = OpenXPP(&refNum);
// hard coded address cause I'm lazy
serverAddress.aNet = 41107;
serverAddress.aNode = 87;
serverAddress.aSocket = 250;
// simple login as guest
if ((sessionNum = LogOnAsGuest(
&serverAddress,&SCBBlock)) <= 0) {
DisposePtr(buffer);
return;
}
// get server params
if ((ErrNo = GetServerParams(sessionNum,
buffer,buffSize)) != noErr) {
DisposePtr(buffer);
return;
}
// buffer has server string
// be a good citizen
LogOut(sessionNum,&SCBBlock);
DisposePtr(buffer);
}
|
|