home *** CD-ROM | disk | FTP | other *** search
- /* 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();
- }