home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
netnwscd.sit
/
tcpio.c
< prev
next >
Wrap
Text File
|
1990-10-15
|
4KB
|
197 lines
/* tcp I/O */
#include <MacTCPCommonTypes.h>
#include <TCPPB.h>
#include <GetMyIPAddr.h>
#include <AddressXlation.h>
/* prototypes */
OSErr tcp_open(char *host, int port);
OSErr tcp_create(short size);
OSErr tcp_write(char *buf, int cnt);
OSErr tcp_read(char *buf, int *cnt);
OSErr tcp_close(void);
OSErr tcp_release(void);
void tcp_shutdown(void);
#define TCP_BUFSIZ (16*1024L)
#define NULL 0L
short driver = 0;
struct hostInfo hp;
Ptr IOBuffer;
wdsEntry wds[2];
TCPiopb iopb;
/*
* needed for host resolution.
*/
pascal void dnrDone(struct hostInfo *hostInfoPtr, char *userDataPtr)
{
*userDataPtr = 1;
}
static
delay(int n) {
long cur = TickCount();
while (TickCount() - cur < n)
;
}
/*
* Open - open a tcp connection
*/
OSErr
tcp_open(char *host, int port)
{
OSErr err;
Boolean dnrdoneflag;
if (driver == 0) { /* first open */
if ((err=OpenDriver("\p.ipp", &driver)) != noErr)
return (err);
if ((err = OpenResolver(NULL)) != noErr)
return (err);
}
/* lookup hostname */
err = StrToAddr(host, &hp, &dnrDone, &dnrdoneflag);
if (err == cacheFault) {
while (!dnrdoneflag) {
/* SystemTask? WaitNextEvent ? */
}
}
if ((err = err = tcp_create(TCP_BUFSIZ)) != noErr)
return (err);
delay(20); /* hack: wait for server */
iopb.ioCompletion = NULL;
iopb.csCode = TCPActiveOpen;
iopb.ioCRefNum = driver;
iopb.csParam.open.validityFlags = timeoutValue | timeoutAction;
iopb.csParam.open.ulpTimeoutValue = 60 /* seconds */;
iopb.csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
iopb.csParam.open.commandTimeoutValue = 0;
iopb.csParam.open.remoteHost = hp.addr[0];
iopb.csParam.open.remotePort = port;
iopb.csParam.open.localHost = 0;
iopb.csParam.open.localPort = 0;
iopb.csParam.open.dontFrag = 0;
iopb.csParam.open.timeToLive = 0;
iopb.csParam.open.security = 0;
iopb.csParam.open.optionCnt = 0;
iopb.csParam.open.userDataPtr = "TCPActiveOpen";
err = PBControl((ParmBlkPtr)&iopb, FALSE);
atexit(tcp_shutdown);
return (err);
}
/*
* create a tcp stream
*/
OSErr
tcp_create(short size)
{
OSErr err;
IOBuffer = NewPtr(size); /* allocate a buffer for the connection */
if (IOBuffer == NULL)
err = MemError();
iopb.csCode = TCPCreate;
iopb.ioCompletion = NULL;
iopb.ioCRefNum = driver;
iopb.csParam.create.notifyProc = NULL;
iopb.csParam.create.rcvBuffLen = size;
iopb.csParam.create.rcvBuff = IOBuffer;
iopb.csParam.create.userDataPtr = "TCPCreate";
return PBControl((ParmBlkPtr)&iopb, FALSE);
}
OSErr
tcp_write(char *buf, int cnt)
{
int err;
iopb.csCode = TCPSend;
iopb.ioCRefNum = driver;
iopb.csParam.send.ulpTimeoutValue = 10;
iopb.csParam.send.ulpTimeoutAction = 1;
/* build write-data structure */
wds[0].length = cnt;
wds[0].ptr = buf;
wds[1].length = 0;
iopb.csParam.send.wdsPtr = (Ptr)&wds;
iopb.csParam.send.sendLength = 0;
iopb.csParam.send.userDataPtr = "TCPWrite";
err = PBControl((ParmBlkPtr)&iopb, FALSE);
}
OSErr
tcp_read(char *buf, int *cnt)
{
int err;
iopb.csCode = TCPRcv;
iopb.ioCRefNum = driver;
iopb.csParam.receive.commandTimeoutValue = 10; /* */
iopb.csParam.receive.secondTimeStamp = 0; /* must be zero */
iopb.csParam.receive.rcvBuff = buf;
iopb.csParam.receive.rcvBuffLen = *cnt;
iopb.csParam.receive.userDataPtr = "TCPRead";
err = PBControl((ParmBlkPtr)&iopb, FALSE);
if (err == noErr)
*cnt = iopb.csParam.receive.rcvBuffLen;
return (err);
}
OSErr
tcp_close()
{
OSErr err;
iopb.ioCompletion = NULL;
iopb.csCode = TCPClose;
iopb.ioCRefNum = driver;
iopb.csParam.close.validityFlags = timeoutValue | timeoutAction;
iopb.csParam.close.ulpTimeoutValue = 60 /* seconds */;
iopb.csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
iopb.csParam.create.userDataPtr = "TCPClose";
err = PBControl((ParmBlkPtr)&iopb, FALSE);
}
/*
* close down a TCP stream (aborting a connection, if necessary)
*/
OSErr
tcp_release()
{
OSErr err;
iopb.ioCompletion = NULL;
iopb.csCode = TCPRelease;
iopb.ioCRefNum = driver;
err = PBControl((ParmBlkPtr)&iopb, FALSE);
if (err == noErr)
DisposPtr(iopb.csParam.create.rcvBuff); /* there is no release pb */
return(err);
}
void
tcp_shutdown() {
tcp_release();
CloseResolver();
}