home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
clintsrc.sit
/
TCPNameToAddr.c
< prev
next >
Wrap
Text File
|
1990-01-29
|
6KB
|
218 lines
/*
TCPNameToAddr(hostName,timeOut,hostFile) -- Return a list of alternative addresses for the host
name specified. If the name can't be resolved locally, go ask a name server. If it can't be resolved
within timeOut ticks, give up. The hostFile parameter gives the file name of a local name table
file. The last two parameters are optional. timeOut defaults to 1800. hostFile defaults to none.
To compile and link this file using Macintosh Programmer's Workshop,
c -b TCPNameToAddr.p
link -m ENTRYPOINT -o "TCP XCMD Example" -rt XFCN=7870 -sn Main=TCPNameToAddr ╢
TCPNameToAddr.c.o "{Libraries}HyperXLib.o" "{Libraries}Interface.o" "{CLibraries}CInterface.o" ╢
"{CLibraries}StdCLib.o"
⌐ Copyright 1989 by Apple Computer, Inc.
Initial coding 3/89 by Harry R. Chesley.
Un-XCMD'ed 10/89 by Greg Anderson
*/
#include <OSUtils.h>
#include <Errors.h>
#include <Files.h>
#include <Resources.h>
#include <Memory.h>
#include <Events.h>
#include <HyperXCmd.h>
#include <String.h>
#include "MacTCPCommonTypes.h"
/* DNR resource function IDs. */
#define OPENRESOLVER 1
#define CLOSERESOLVER 2
#define STRTOADDR 3
#define ADDRTOSTR 4
#define ENUMCACHE 5
#define ADDRTONAME 6
/* Default time-out. */
#define DEFAULTTICK 3600
/* Minimum time-out (to fix bug in MacTCP). */
#define MINTICK 2400
/* Number of addresses returned by DNR. */
#define NUM_ALT_ADDRS 4
/* DNR return structure. */
typedef struct hostInfo {
int rtnCode; /* Result code. */
char cname[255]; /* Standard name. */
unsigned long addr[NUM_ALT_ADDRS]; /* Addresses. */
};
typedef OSErr (*OSErrProcPtr)();
short NameToAddr(host_name,inet_addr,timeout)
char *host_name;
long *inet_addr,
timeout;
{
Handle codeHndl; /* DNR code resource handle. */
OSErrProcPtr dnr; /* Pointer to code resource. */
SysEnvRec info; /* System info record (to find the system volume). */
HParamBlockRec fi; /* Parameter block (to find the MacTCP file). */
Str255 filename; /* File name (for MacTCP file search). */
char str[256]; /* Scratch string. */
short refnum; /* Resource file refnum. */
OSErr rc; /* Result code return. */
struct hostInfo rtnStruct; /* Answer from DNR. */
struct hostInfo cacheFltRtn; /* Place to return the answer if there's a cache fault. */
long lastTick; /* When to time-out. */
pascal void resultProc();
short ntaErr = 0; /* GA NameToAdr error */
*inet_addr = 0; /* GA */
*filename = 0; /* GA */
/* Get the system volume. */
SysEnvirons(1, &info);
/* Prepare to scan for the MacTCP file (where we'll find the DNR code resource). */
fi.fileParam.ioCompletion = nil;
fi.fileParam.ioNamePtr = &filename;
fi.fileParam.ioVRefNum = info.sysVRefNum;
fi.fileParam.ioDirID = 0;
fi.fileParam.ioFDirIndex = 1;
refnum = -1;
/* Scan for MacTCP file. */
while (PBHGetFInfo(&fi, false) == noErr) {
/* scan system folder for driver resource files of specific type & creator */
if (fi.fileParam.ioFlFndrInfo.fdType == 'cdev' &&
fi.fileParam.ioFlFndrInfo.fdCreator == 'mtcp') {
/* Found the MacTCP driver file. */
SetVol(nil,fi.fileParam.ioVRefNum);
refnum = OpenResFile(&filename);
break;
};
/* Check next file in system folder. */
fi.fileParam.ioFDirIndex++;
fi.fileParam.ioDirID = 0;
};
/* Ignore failures since the resource may have been installed in the
System file if running on a Mac 512Ke. */
/* Load in the DNR resource package. */
codeHndl = GetIndResource('dnrp', 1);
if (codeHndl == nil) {
if (refnum != -1) CloseResFile(refnum);
/* errAbort(paramPtr,"ñññ couldn't open resource ñññ"); */
return(-1);
};
DetachResource(codeHndl);
if (refnum != -1) CloseResFile(refnum);
/* Lock the DNR resource so it cannot be relocated while opened. */
HLock(codeHndl);
dnr = (OSErrProcPtr) *codeHndl;
if( !dnr ) return( -2 ); /* GA -- just checking */
/* Call open resolver. */
*str = 0; /* Fill in path/filename of HOST file here */
/***
*** THIS CALL OFTEN DIES UNDER MULTIFINDER!!! Out of Mr. Memory error.
***/
rc = (*dnr)(OPENRESOLVER, str);
/***/
if (rc != noErr) {
/* Problem with open resolver, flush it. */
HUnlock(codeHndl);
DisposHandle(codeHndl);
/* errAbort(paramPtr,"ñññ domain name resolver failed ñññ"); */
return(-2);
};
/* Get the address. */
strcpy(str,host_name);
cacheFltRtn.rtnCode = 1;
rc = (*dnr)(STRTOADDR, str, &rtnStruct, resultProc, &cacheFltRtn);
/* If we couldn't get it right away, wait for it. */
if (rc == cacheFault)
{
/* GA */
if( timeout == 0 ) timeout = DEFAULTTICK;
if( timeout < MINTICK ) timeout = MINTICK;
lastTick = TickCount() + timeout;
/**** XCMD version:
if ((paramPtr->paramCount < 2) || (paramPtr->params[1] == nil)) lastTick = TickCount() + DEFAULTTICK;
else if (**paramPtr->params[1] == 0) lastTick = TickCount() + DEFAULTTICK;
else {
ZeroToPas(paramPtr,*(paramPtr->params[1]),str);
if ((lastTick = StrToNum(paramPtr,str)) > MINTICK) lastTick = MINTICK;
lastTick = lastTick + TickCount();
};
******/
while ((TickCount() < lastTick) && (cacheFltRtn.rtnCode > 0));
rtnStruct = cacheFltRtn;
} else rtnStruct.rtnCode = rc;
/* Check if we got it OK or not. */
if (rtnStruct.rtnCode == noErr)
{
*inet_addr = rtnStruct.addr[0]; /* GA */
/* We did, so build the result string. */
/**** Don't return a string
for (i = 0; i < NUM_ALT_ADDRS; i++) {
if (rtnStruct.addr[i] == 0) break;
if (i > 0) strcat(resultStr,",");
NumToStr(paramPtr,rtnStruct.addr[i],str);
p2cstr(str);
strcat(resultStr,str);
};
*****/
/* Make the handle to return. */
/****** Only needed in XCMD
resultHand = NewHandle((long) strlen(resultStr)+1);
if (resultHand != nil) {
strcpy(*resultHand,resultStr);
paramPtr->returnValue = resultHand;
} else errAbort(paramPtr,"ñññ couldn't make result string ñññ");
*******/
}
else if (rtnStruct.rtnCode == 1)
{
/* errAbort("ñññ time-out ñññ"); */
ntaErr = -3;
}
else
{
/* errAbort(paramPtr,"ñññ couldn't get address ñññ"); */
ntaErr = -4;
}
/* Call close resolver. */
(void) (*dnr)(CLOSERESOLVER);
/* Release the DNR resource package. */
HUnlock(codeHndl);
DisposHandle(codeHndl);
return( ntaErr );
}
/* Async routine called when name is found from name server. We just copy the result
and let the main loop process it. */
pascal void resultProc(struct hostInfo *hostInfoPtr, struct hostInfo *userDataPtr)
{
*userDataPtr = *hostInfoPtr;
}