home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / iplow / iplow.c next >
Encoding:
C/C++ Source or Header  |  1994-11-08  |  16.5 KB  |  779 lines  |  [TEXT/MPCC]

  1. /*
  2.  * iplow.c
  3.  *
  4.  * Low routines for MacTCP.  This file contains the code that talks
  5.  * directly to the MacTCP driver.  I hope that when Apple changes
  6.  * the IP interface around in system 8, this will be the only file
  7.  * that requires modification.
  8.  *
  9.  * This should vaguely approximate socket_like calls. Only asynch-
  10.  * ronous calls will be used.
  11.  *
  12.  * This library was strongly patterned after NewsWatcher, with the
  13.  * blessing of John Norstad.
  14.  *
  15.  * Mike Trent 8/94
  16.  *
  17.  */
  18.  
  19. /* Additional Mac Includes */
  20.  
  21. #include <MacTCPCommonTypes.h>
  22. #include <AddressXlation.h>
  23. #include <MiscIPPB.h>
  24. #include <UDPPB.h>
  25. #include <TCPPB.h>
  26. #include <GetMyIPAddr.h>
  27.  
  28. /* Local Includes */
  29.  
  30. //#include "ip.h"     Go make your own.
  31. #include "iplow.h"
  32.  
  33. /* constants for this module */
  34.  
  35. #define kBufferLength 32767             /*  32 k  */
  36. //#define kBufferLength 65535            /* unsigned short */
  37.  
  38.  
  39. /* Global to this Module */
  40.  
  41. static short gRefNum;                   /* refnum for talking to MacTCP */
  42. Spin gSpin;                                /* chosen spin routine */
  43.  
  44. /* Private Function headers */
  45.  
  46. pascal void myResultProc (hostInfo *hi, char *data);    /*private*/
  47. pascal void MyTCPNotifyProc(StreamPtr stream, unsigned short eventCode, Ptr data, 
  48.                             unsigned short termr, struct ICMPReport *icmpMsg);
  49. pascal void MyUDPNotifyProc(StreamPtr stream, unsigned short eventCode, Ptr data, 
  50.                             struct ICMPReport *icmpMsg);
  51. OSErr SpinDefault (void);
  52.  
  53.  
  54.  
  55. /**
  56.  **
  57.  **  GENERIC MacTCP ROUTINES
  58.  **
  59.  **/
  60.  
  61.  
  62. /* LowInitMacTCP 
  63.  * - Inits the MacTCP driver. It should be called once near the 
  64.  *     beginning of the program. 
  65.  * Returns OSErr: from OpenDriver
  66.  */
  67.  
  68. OSErr LowInitMacTCP (void)
  69. {
  70.     OSErr    err;
  71.     
  72.     err = OpenDriver("\p.IPP",&gRefNum);
  73.     return(err);
  74. }
  75.  
  76. void LowSetSpin(Spin spinRoutine)
  77. {
  78.     if (spinRoutine == nil)
  79.         gSpin = SpinDefault;
  80.     else
  81.         gSpin = spinRoutine;
  82. }
  83.  
  84. /* SpinDefault
  85.  * - a routine that handles events while waiting for a connection or
  86.  *   somesuch.  Currently, it should just call some event routine
  87.  *   so that other processes can function properly.
  88.  *
  89.  *     Strongly patterned after GiveTime() in NewsWatcher.
  90.  */
  91.  
  92. OSErr SpinDefault (void)
  93. {
  94.     EventRecord ev;
  95.     Boolean gotEvt;
  96.     short part;
  97.     WindowPtr theWindow;
  98.  
  99.     gotEvt = WaitNextEvent(everyEvent,&ev,0,nil);
  100.     if ( gotEvt )
  101.         switch (ev.what) {
  102.             case mouseDown:
  103.                 part = FindWindow(ev.where, &theWindow);
  104.                 if (part == inSysWindow) 
  105.                     SystemClick(&ev, theWindow);
  106.                 break;
  107.             case activateEvt:
  108.                 break;
  109.             case updateEvt:
  110.                 break;
  111.             case app4Evt:
  112.                 break;
  113.             case keyDown:
  114.             case autoKey:
  115.                 break;
  116.         }
  117. }
  118.  
  119.  
  120. /* LowStringToAddr
  121.  * - Performs a DNS lookup for the host 'name'.
  122.  *        *name  - the name of the host. This can be in DNS name form
  123.  *                 or in "dot notation". The "official" name of the
  124.  *                 host will be returned.
  125.  *        *ipNum - returned ip number.
  126.  * Returns OSErr: StrToAddr call.
  127.  */
  128.  
  129. OSErr LowStringToAddr(char *name, unsigned long *ipNum)
  130. {
  131.     hostInfo hi;
  132.     char done = 0x00;
  133.     ResultUPP myResultUPP;
  134.     OSErr err;
  135.     
  136.     if ((err = OpenResolver(nil)) != noErr)    
  137.         return err;
  138.  
  139.     myResultUPP = NewResultProc(myResultProc);
  140.  
  141.     err = StrToAddr(name, &hi, myResultUPP, &done) ;
  142.     if (err == cacheFault) {
  143.         while (!done) (*gSpin)();
  144.     } else if (err != noErr) goto foo;
  145.     
  146.     if ((hi.rtnCode == noErr) || (hi.rtnCode == cacheFault)) {
  147.         *ipNum = hi.addr[0];
  148.         strcpy(name, hi.cname);
  149.         name[strlen(name) -1] = '\0';
  150.     }
  151.     err = hi.rtnCode;
  152.         
  153. foo:
  154.     (void) CloseResolver();
  155.     return err;
  156. }
  157.  
  158. /* LowAddrToName
  159.  * - Provided an ipNum, LowAddrToName will look up the DNS name for
  160.  *   that address; if said name exists.
  161.  *        ipNum - ip address.
  162.  *        *name - returned DNS name.
  163.  * Returns OSErr: AddrToName call
  164.  */
  165.  
  166. OSErr LowAddrToName(unsigned long ipNum, char *name)
  167. {    
  168.     hostInfo hi;
  169.     char done = 0x00;
  170.     ResultUPP myResultUPP;
  171.     OSErr err;
  172.     
  173.     if ((err = OpenResolver(nil)) != noErr)    
  174.         return err;
  175.  
  176.     myResultUPP = NewResultProc(myResultProc);
  177.  
  178.     err = AddrToName(ipNum, &hi, myResultUPP, &done);
  179.     if (err == cacheFault) {
  180.         while(!done) (*gSpin)();
  181.     } else if (err != noErr) goto foo;
  182.     
  183.     if ((hi.rtnCode == noErr) || (hi.rtnCode == cacheFault)) {
  184.         strcpy(name, hi.cname);
  185.         name[strlen(name)-1] = '\0';
  186.         err = noErr;
  187.     } else  err = hi.rtnCode;
  188.     
  189. foo:
  190.     (void) CloseResolver();
  191.     return err;
  192. }
  193.  
  194.  
  195. /* myResultProc
  196.  * - ProcPtr (UPP) called when DNS routines cacheFault.
  197.  *   See MacTCP Dev Kit.
  198.  *         *hi   - hostInfo record returned by driver.
  199.  *        *data - user pointer ... used to flag when data is
  200.  *                valid.
  201.  */ 
  202.  
  203. pascal void myResultProc(hostInfo *hi, char *data)
  204. {
  205. #pragma unused (hi)
  206.     *data = 0xff;
  207. }
  208.  
  209.  
  210. /* LowGetMyIP
  211.  * - Returns local machines IP Number.
  212.  *        *ipNum - returned IP Number
  213.  * Returns OSErr: PBControl
  214.  */
  215.  
  216. OSErr LowGetMyIP (unsigned long *ipNum)
  217. {
  218.     OSErr err;
  219.     struct GetAddrParamBlock ippb;
  220.     
  221.     bzero ((char *)&ippb, sizeof(struct GetAddrParamBlock));
  222.  
  223.     ippb.csCode = ipctlGetAddr;
  224.     ippb.ioCRefNum = gRefNum;
  225.     
  226.     err = PBControl((ParmBlkPtr)&ippb, true);
  227.     if (err != noErr) return err;
  228.     
  229.     while (ippb.ioResult > 0) (*gSpin)();
  230.     if ((err = ippb.ioResult) != noErr) return err;
  231.     
  232.     *ipNum = ippb.ourAddress;
  233.     
  234.     return err;
  235. }
  236.  
  237.  
  238. /**
  239.  **
  240.  **  UDP/IP MacTCP ROUTINES
  241.  **
  242.  **/
  243.  
  244.  
  245.  
  246. /* InitUDPPB
  247.  * - A utility routine to zero a UDPiopb structure, and set some
  248.  *     global initializations.
  249.  *        *pb - UDPiopb to be initialized
  250.  */
  251.  
  252. void InitUDPPB (UDPiopb *pb)
  253. {
  254.     bzero (pb, sizeof(UDPiopb));
  255.     pb->ioResult = 1;
  256.     pb->ioCRefNum = gRefNum;
  257. }
  258.  
  259.  
  260. OSErr LowUDPCreate (StreamPtr *stream, unsigned short *port, mac_socket *sockets)
  261. {
  262.     UDPiopb pb;
  263.     OSErr err = noErr;
  264.     Ptr buffer;
  265.         
  266.     buffer = NewPtr(kBufferLength);
  267.     if ((err = MemError()) != noErr) {
  268.         return (err);
  269.     }
  270.     
  271.     InitUDPPB(&pb);
  272.     
  273.     pb.csCode = UDPCreate;
  274.     pb.csParam.create.rcvBuff = buffer;
  275.     pb.csParam.create.rcvBuffLen = kBufferLength;
  276. //    pb.csParam.create.notifyProc = (UDPNotifyProc)NewUDPNotifyProc(MyUDPNotifyProc);
  277.     pb.csParam.create.notifyProc = (UDPNotifyProc)NewUDPNotifyProc(nil);
  278.     pb.csParam.create.localPort = *port;
  279.     pb.csParam.create.userDataPtr = (Ptr)sockets;
  280.     
  281.     err = PBControl((ParmBlkPtr)&pb,true);
  282.     while (pb.ioResult > 0) (*gSpin)();
  283.     *stream = pb.udpStream;
  284.     if (*port == 0) *port = pb.csParam.create.localPort;
  285.     err = pb.ioResult;
  286.     
  287.     return err;
  288. }
  289.  
  290. OSErr LowUDPRead (StreamPtr stream, char timeout, Ptr buf, int *buflen, 
  291.                     unsigned long *remoteHost, unsigned short *remotePort)
  292. {
  293.     UDPiopb pb;
  294.     OSErr err = noErr;
  295.  
  296.     InitUDPPB(&pb);
  297.     
  298.     pb.csCode = UDPRead;
  299.     pb.udpStream = stream;
  300.     pb.csParam.receive.timeOut = timeout;
  301.     
  302.     if ((err = PBControl((ParmBlkPtr)&pb,true)) != noErr)
  303.         return err;
  304.     
  305.     while (pb.ioResult > 0) (*gSpin)();
  306.     
  307.     *buflen = pb.csParam.receive.rcvBuffLen;
  308.     bcopy ((char *)pb.csParam.receive.rcvBuff, (char *)buf, (long)*buflen);
  309.     *remoteHost = pb.csParam.receive.remoteHost;
  310.     *remotePort = pb.csParam.receive.remotePort;
  311.     
  312.     err = pb.ioResult;
  313.     
  314.     pb.csCode = UDPBfrReturn;                // Instead of returning right away,
  315.     pb.ioResult = 1;                        // we need to return the buffer ptr
  316.     (void)PBControl((ParmBlkPtr)&pb, true);    // to the driver.
  317.     while (pb.ioResult>0) (*gSpin)();
  318.     
  319.     return err;
  320. }
  321.  
  322. OSErr LowUDPWrite (StreamPtr stream, Ptr wdsPtr, unsigned long remoteHost, 
  323.                     unsigned short remotePort)
  324. {
  325.     UDPiopb pb;
  326.     OSErr err = noErr;
  327.  
  328.     InitUDPPB(&pb);
  329.     
  330.     pb.csCode = UDPWrite;
  331.     pb.udpStream = stream;
  332.     pb.csParam.send.remoteHost = remoteHost;
  333.     pb.csParam.send.remotePort = remotePort;
  334.     pb.csParam.send.wdsPtr = wdsPtr;
  335.     pb.csParam.send.checkSum = 0; /* MDT FIX */
  336.     
  337.     if ((err = PBControl((ParmBlkPtr)&pb,true)) != noErr)
  338.         return err;
  339.     
  340.     while (pb.ioResult > 0) (*gSpin)();
  341.     return pb.ioResult;
  342. }
  343.  
  344. OSErr LowUDPRelease (StreamPtr stream)
  345. {
  346.     UDPiopb pb;
  347.     OSErr err = noErr;
  348.  
  349.     InitUDPPB(&pb);
  350.     
  351.     pb.csCode = UDPRelease;
  352.     pb.udpStream = stream;
  353.  
  354.     if ((err = PBControl((ParmBlkPtr)&pb, true)) != noErr)
  355.         return err;
  356.     while (pb.ioResult >0) (*gSpin)();
  357.     if (pb.ioResult != noErr) return pb.ioResult;
  358.     
  359.     DisposPtr(pb.csParam.create.rcvBuff);
  360.     return MemError();
  361. }
  362.  
  363. OSErr LowUDPMTU (StreamPtr stream, unsigned long remoteHost, unsigned short *MTU)
  364. {
  365.     UDPiopb pb;
  366.     OSErr err = noErr;
  367.  
  368.     InitUDPPB(&pb);
  369.     
  370.     pb.csCode = UDPMaxMTUSize;
  371.     pb.udpStream = stream;
  372.     pb.csParam.mtu.remoteHost = remoteHost;
  373.  
  374.     if ((err = PBControl((ParmBlkPtr)&pb, true)) != noErr)
  375.         return err;
  376.     while (pb.ioResult >0) (*gSpin)();
  377.  
  378.     *MTU = pb.csParam.mtu.mtuSize;
  379.         
  380.     return (pb.ioResult);
  381.  
  382. }
  383.  
  384. /* multiport UDP commands have been ignored */
  385.  
  386.  
  387.  
  388.  
  389. /**
  390.  **
  391.  **  TCP/IP MacTCP ROUTINES
  392.  **
  393.  **/
  394.  
  395.  
  396. /* InitTCPPB
  397.  * - A utility routine to zero a TCPiopb structure, and set some
  398.  *     global initializations.
  399.  *        *pb - TCPiopb to be initialized
  400.  */
  401.  
  402. void InitTCPPB (TCPiopb *pb)
  403. {
  404.     bzero (pb, sizeof(TCPiopb));
  405.     pb->ioResult = 1;
  406.     pb->ioCRefNum = gRefNum;
  407. }
  408.     
  409.     
  410.  
  411. /* LowTCPCreate
  412.  * - Creates TCP stream asynchronously.
  413.  *     *stream - returns the TCP stream pointer.
  414.  * Returns OSErr: MemErr and PBControl
  415.  */
  416.  
  417. OSErr LowTCPCreate (StreamPtr *stream, mac_socket *sockets)
  418. {    
  419.     TCPiopb pb;
  420.     OSErr err = noErr;
  421.     Ptr buffer;
  422.         
  423.     buffer = NewPtr(kBufferLength);
  424.     if ((err = MemError()) != noErr) {
  425.         return (err);
  426.     }
  427.     
  428.     InitTCPPB(&pb);
  429.     
  430.     pb.csCode = TCPCreate;
  431.     pb.csParam.create.rcvBuff = buffer;
  432.     pb.csParam.create.rcvBuffLen = kBufferLength;
  433. //    pb.csParam.create.notifyProc = (TCPNotifyProc) NewTCPNotifyProc (MyTCPNotifyProc); 
  434.     pb.csParam.create.notifyProc = (TCPNotifyProc) NewTCPNotifyProc (nil); 
  435.     pb.csParam.create.userDataPtr = (Ptr)sockets;
  436.     
  437.     err = PBControl((ParmBlkPtr)&pb,true);
  438.     if (err != noErr ) return err;
  439.     
  440.     while (pb.ioResult > 0) (*gSpin)();
  441.     *stream = pb.tcpStream;
  442.     
  443.     err = pb.ioResult;
  444.     return err;
  445. }
  446.  
  447.  
  448. /* LowTCPPassiveOpen
  449.  * - waits on a stream for an incomming connection. This procedure
  450.  *   will block until a connection is received.
  451.  *      stream       - socket descriptor
  452.  *      char           - time out value in seconds
  453.  *      *remoteHost - registers the address connections may be received
  454.  *                    from. Passing 0 allows any address to connect. 
  455.  *                    Returns remoteHost IPNumber if 0 was passed to it.
  456.  *      *remotePort - as above for *remoteHost
  457.  *      *localhost  - returns local host IP
  458.  *      *localPort  - port to listen to; 0 specifies any port. Returns the
  459.  *                    port connected to.
  460.  * Returns OSErr: PBControl
  461.  */
  462. OSErr LowTCPPassiveOpen (StreamPtr stream, char timeout,
  463.     unsigned long *remoteHost, unsigned short *remotePort, unsigned long *localHost,
  464.     unsigned short *localPort)
  465. {
  466.     OSErr err = noErr;
  467.     TCPiopb pb;
  468.     
  469.     InitTCPPB(&pb);
  470.  
  471.     pb.csCode = TCPPassiveOpen;
  472.     pb.tcpStream = stream;
  473.     pb.csParam.open.ulpTimeoutValue = timeout;
  474.     pb.csParam.open.ulpTimeoutAction = 1;
  475.     pb.csParam.open.validityFlags = 0xC0;        /* timeout flags */
  476.     pb.csParam.open.commandTimeoutValue = timeout;
  477.     pb.csParam.open.remoteHost = *remoteHost;
  478.     pb.csParam.open.remotePort = *remotePort;
  479.     pb.csParam.open.localPort = *localPort;
  480.     
  481.     err = PBControl((ParmBlkPtr)&pb,true);
  482.     if (err != noErr) return err;
  483.     
  484.     while (pb.ioResult > 0 ) (*gSpin)();
  485.     err = pb.ioResult;
  486.     
  487.     *remoteHost = pb.csParam.open.remoteHost;
  488.     *remotePort = pb.csParam.open.remotePort;
  489.     return err;
  490. }
  491.  
  492.  
  493.  
  494.  
  495. /* LowTCPActiveOpen
  496.  * - Actively connects with a server on the specified remoteHost and
  497.  *     remotePort
  498.  *      stream       - socket descriptor
  499.  *      char           - time out value in seconds
  500.  *      remoteHost  - IPAddress unsigned long notation. (can't be 0)
  501.  *      remotePort  - port to connect to. (can't be 0)
  502.  *      *localhost  - returns local host IP
  503.  *      *localPort  - port to use; 0 specifies any port. Returns the
  504.  *                    port connected to.
  505.  * Returns OSErr: StrToAddr or PBControl
  506.  */
  507.  
  508. OSErr LowTCPActiveOpen (StreamPtr stream, char timeout,
  509.     unsigned long remoteHost, unsigned short remotePort, unsigned long *localHost,
  510.     unsigned short *localPort)
  511. {
  512.     OSErr err = noErr;
  513.     TCPiopb pb;
  514.                 
  515.     InitTCPPB(&pb);
  516.  
  517.     pb.csCode = TCPActiveOpen;
  518.     pb.tcpStream = stream;
  519.     pb.csParam.open.ulpTimeoutValue = timeout;
  520.     pb.csParam.open.ulpTimeoutAction = 1;
  521.     pb.csParam.open.validityFlags = 0xC0;        /* timeout flags */
  522.     pb.csParam.open.commandTimeoutValue = timeout;
  523.     pb.csParam.open.remoteHost = remoteHost;
  524.     pb.csParam.open.remotePort = remotePort;
  525.     pb.csParam.open.localPort = *localPort;
  526.     
  527.     err = PBControl((ParmBlkPtr)&pb,true);
  528.     if (err != noErr) return err;
  529.  
  530.     while (pb.ioResult > 0 ) (*gSpin)();
  531.     err = pb.ioResult;
  532.     *localPort = pb.csParam.open.localPort;
  533.     *localHost = pb.csParam.open.localHost;
  534.     return err;
  535. }
  536.  
  537.  
  538. /* LowTCPSend
  539.  * - Sends data over the stream
  540.  *    stream - stream descriptor
  541.  *    char   - time out in seconds
  542.  *    wdsPtr - write structure
  543.  * Returns OSErr: PBControl
  544.  */
  545. OSErr LowTCPSend (StreamPtr stream, char timeout, Ptr wdsPtr)
  546. {
  547.     OSErr err = noErr;
  548.     TCPiopb pb;
  549.     
  550.     InitTCPPB(&pb);
  551.  
  552.     pb.csCode = TCPSend;
  553.     pb.tcpStream = stream;
  554.     pb.csParam.send.ulpTimeoutValue = timeout;
  555.     pb.csParam.send.ulpTimeoutAction = 1;
  556.     pb.csParam.send.validityFlags = 0xC0;
  557.     pb.csParam.send.wdsPtr = wdsPtr;
  558.     
  559.     err = PBControl((ParmBlkPtr)&pb,true);
  560.     if (err != noErr) return err;
  561.     
  562.     while (pb.ioResult>0) (*gSpin)();
  563.     err = pb.ioResult;
  564.     return err;
  565. }
  566.  
  567. /* I'm going to ignore the NoCopy routines, because I don't understand them */
  568.  
  569.  
  570. /* LowTCPRcv
  571.  * - receives data over the stream
  572.  *    stream  - stream descriptor
  573.  *    char    - time out in seconds
  574.  *    rbuf      - memory buffer
  575.  *      *buflen - length of memory buffer. Returns # of bytes received.
  576.  * Returns OSErr: PBControl
  577.  */
  578. OSErr LowTCPRcv (StreamPtr stream, char timeout, Ptr rbuf, int *buflen)
  579. {
  580.     OSErr err = noErr;
  581.     TCPiopb pb;
  582.     
  583.     InitTCPPB(&pb);
  584.  
  585.     pb.csCode = TCPRcv;
  586.     pb.tcpStream = stream;
  587.     pb.csParam.receive.commandTimeoutValue = timeout;
  588.     pb.csParam.receive.rcvBuff = rbuf;
  589.     pb.csParam.receive.rcvBuffLen = *buflen;
  590.     
  591.     err = PBControl((ParmBlkPtr)&pb,true);
  592.     if (err != noErr) return err;
  593.     
  594.     while (pb.ioResult>0) (*gSpin)();
  595.  
  596.     *buflen = pb.csParam.receive.rcvBuffLen;
  597.     err = pb.ioResult;
  598.     
  599.     return err;
  600. }
  601.  
  602.  
  603. /* LowTCPClose
  604.  * - Closes a stream.
  605.  *      stream - stream descriptor
  606.  *      char     - timeout in seconds
  607.  * Returns OSErr: PBControl
  608.  */
  609.  
  610. OSErr LowTCPClose (StreamPtr stream, char timeout)
  611. {
  612.     OSErr err = noErr;
  613.     TCPiopb pb;
  614.     
  615.     InitTCPPB(&pb);
  616.  
  617.     pb.csCode = TCPClose;
  618.     pb.tcpStream = stream;
  619.     pb.csParam.close.ulpTimeoutValue = timeout;
  620.     pb.csParam.close.ulpTimeoutAction = 1;
  621.     pb.csParam.close.validityFlags = 0xC0;
  622.     
  623.     err = PBControl((ParmBlkPtr)&pb,true);
  624.     if (err != noErr) return err;
  625.     
  626.     while (pb.ioResult>0) (*gSpin)();
  627.  
  628.     err = pb.ioResult;
  629.     
  630.     return err;
  631. }
  632.  
  633.  
  634. /* LowTCPAbort
  635.  * - Abruptly closes a stream.
  636.  *      stream - stream descriptor
  637.  * Returns OSErr: PBControl
  638.  */
  639.  
  640. OSErr LowTCPAbort(StreamPtr stream)
  641. {
  642.     OSErr err = noErr;
  643.     TCPiopb pb;
  644.     
  645.     InitTCPPB(&pb);
  646.  
  647.     pb.csCode = TCPAbort;
  648.     pb.tcpStream = stream;
  649.     
  650.     err = PBControl((ParmBlkPtr)&pb,true);
  651.     if (err != noErr) return err;
  652.     
  653.     while (pb.ioResult>0) (*gSpin)();
  654.  
  655.     err = pb.ioResult;
  656.     
  657.     return err;
  658. }
  659.  
  660. /* TCP Status - skipped */
  661.  
  662. /* LowTCPRelease
  663.  * - Releases memory reserved for a stream. If the stream is still
  664.  *      connected, the stream will be aborted.
  665.  *      stream - stream descriptor
  666.  * Returns OSErr: PBControl and MemError
  667.  */
  668.  
  669. OSErr LowTCPRelease(StreamPtr stream)
  670. {
  671.     OSErr err = noErr;
  672.     TCPiopb pb;
  673.     Ptr buffer;
  674.     
  675.     InitTCPPB(&pb);
  676.  
  677.     pb.csCode = TCPRelease;
  678.     pb.tcpStream = stream;
  679.     
  680.     err = PBControl((ParmBlkPtr)&pb,true);
  681.     if (err != noErr) return err;
  682.     
  683.     while (pb.ioResult>0) (*gSpin)();
  684.  
  685.     if ((err = pb.ioResult) != noErr) return err;
  686.     buffer = pb.csParam.create.rcvBuff;
  687.  
  688.     DisposPtr(buffer);
  689.     err = MemError();
  690.     return err;
  691. }
  692.  
  693. /* LowGlobalInfo - skip */
  694.  
  695.  
  696.  
  697.  
  698. /* LowTCPSelect
  699.  * - Reports if there is unread data on a stream.
  700.  *        stream - stream descriptor
  701.  *        *ans   - 0 if no data waiting , 1 if data waiting.
  702.  * Returns OSErr: PBControl
  703.  */
  704.  
  705. /* OBSOLETE - Moved to a higher level because of ASR */
  706.  
  707. OSErr LowTCPSelect (StreamPtr stream, int *ans)
  708. {
  709.     OSErr err;
  710.     TCPiopb pb;
  711.     
  712.     InitTCPPB(&pb);
  713.  
  714.     pb.csCode = TCPStatus;
  715.     pb.tcpStream = stream;
  716.     
  717.     err = PBControl((ParmBlkPtr)&pb,true);
  718.     if (err != noErr) return err;
  719.     
  720.     while (pb.ioResult>0) (*gSpin)();
  721.     err = pb.ioResult;
  722.  
  723.     if (pb.csParam.status.amtUnreadData > 0) {
  724.         *ans = 1;
  725.     } else {
  726.         *ans = 0;
  727.     }
  728.     
  729.     return err;
  730. }
  731.  
  732.  
  733. /* Specifically for my socket ip.c. This will show you how to write your own though */
  734.  
  735. /*
  736. pascal void MyUDPNotifyProc(StreamPtr stream, unsigned short eventCode, Ptr data, 
  737.                             struct ICMPReport *icmpMsg)
  738. {
  739. #pragma unused (icmpMsg)
  740.     short i,s = -1;
  741.     
  742.     for (i=1; i<kNumSockets; i++){
  743.         if (((mac_socket *) data)[i].stream == stream) 
  744.         break;
  745.     }
  746.     if (s < 0) return;
  747.  
  748.     switch (eventCode) {
  749.     case UDPDataArrival:
  750.         ((mac_socket *)data)[s].hasData = 1;
  751.         break;
  752.     default:
  753.         ;
  754.     }
  755. }
  756.  
  757.  
  758.  
  759. pascal void MyTCPNotifyProc(StreamPtr stream, unsigned short eventCode, Ptr data, 
  760.                             unsigned short termr, struct ICMPReport *icmpMsg)
  761. {
  762. #pragma unused (icmpMsg)
  763. #pragma unused (termr)
  764.     short i,s = -1;
  765.     
  766.     for (i=1; i<kNumSockets; i++){
  767.         if (((mac_socket *) data)[i].stream == stream) 
  768.         break;
  769.     }
  770.     if (s < 0) return;
  771.  
  772.     switch (eventCode) {
  773.     case TCPDataArrival:
  774.         ((mac_socket *)data)[s].hasData = 1;
  775.         break;
  776.     default:
  777.         ;
  778.     }
  779. }*/