home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / TCPIP.C < prev    next >
Text File  |  1996-05-13  |  33KB  |  683 lines

  1. /*****************************************************************************/
  2. /* File:                                                                     */
  3. /*   tcpip.c                                                                 */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  tcpip management functions.                                              */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   05/01/96 Created.                                                       */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14.  
  15. #include "all.h"
  16.  
  17. #define  OS2
  18.  #undef   T_NULL                        /* resolve conflict                  */
  19.  #undef   T_PTR                         /* resolve conflict                  */
  20.  #include <types.h>
  21.  #include <netinet\in.h>
  22.  #include <arpa\nameser.h>
  23.  #include <resolv.h>
  24.  #include <sys\socket.h>
  25.  #include <netdb.h>
  26. #undef   OS2
  27.  
  28. /*****************************************************************************/
  29. /* - tcpip dlls are loaded only if the user tries to make a tcpip            */
  30. /*   connection.                                                             */
  31. /* - functions are called by pointer.                                        */
  32. /* - following are the prototypes currently used.                            */
  33. /*****************************************************************************/
  34. #define htons_(x)   ((* bswap_)(x))
  35. #define ntohs_(x)   ((* bswap_)(x))
  36. #define htonl_(x)   ((* lswap_)(x))
  37. #define ntohl_(x)   ((* lswap_)(x))
  38.  
  39. static int ( * _System sock_init_)( void );
  40. static void( * _System psock_errno_)( char * );
  41. static int ( * _System socket_)( int, int, int );
  42. static int ( * _System connect_)( int, struct sockaddr *, int );
  43. static int ( * _System bind_)( int, struct sockaddr *, int );
  44. static int ( * _System gethostid_)(void);
  45. static int ( * _System listen_)( int, int);
  46. static int ( * _System accept_)( int, struct sockaddr *, int * );
  47. static int ( * _System sock_errno_)( void );
  48. static int ( * _System send_)( int, char *, int, int );
  49. static int ( * _System recv_)( int, char *, int, int );
  50. static int ( * _System soclose_)( int );
  51. static int ( * _System setsockopt_)( int, int, int, char *, int );
  52.  
  53. static struct hostent * ( * _System gethostbyname_)( char * );
  54. static struct servent * ( * _System getservbyname_)( char *, char * );
  55. static struct hostent * ( * _System gethostbyaddr_)( char *, int, int );
  56. static unsigned short   ( * _System bswap_)(unsigned short);
  57. static unsigned long    ( * _System lswap_)(unsigned long);
  58. static char *           ( * _System inet_ntoa_)(struct in_addr);
  59.  
  60. /*****************************************************************************/
  61. /* - this is the socket decriptor bound to the machine address on the        */
  62. /*   server side of the connection.                                          */
  63. /*****************************************************************************/
  64. static int BaseSocketDescriptor;
  65.  
  66. int  SockGetDescriptor(void){return(BaseSocketDescriptor);}
  67. void SockSetDescriptor(int s){BaseSocketDescriptor=s;}
  68.  
  69. /*****************************************************************************/
  70. /* SockInit()                                                                */
  71. /*                                                                           */
  72. /* Description:                                                              */
  73. /*                                                                           */
  74. /*   Manage the sd386/esp connections.                                       */
  75. /*                                                                           */
  76. /* Parameters:                                                               */
  77. /*                                                                           */
  78. /*   pConnection    -> to the structure defining the remote connection.      */
  79. /*   pLsnHandle     where to stuff the session handle for the caller.        */
  80. /*   p_MoreRcInfo   ->holder of additional tcpip error return codes(rc).     */
  81. /*                                                                           */
  82. /* Return:                                                                   */
  83. /*                                                                           */
  84. /*   rc            system/tcpip return code.                                 */
  85. /*                                                                           */
  86. /* Assumptions:                                                              */
  87. /*                                                                           */
  88. /*   SD386 is the client and esp is the server.                              */
  89. /*                                                                           */
  90. /*****************************************************************************/
  91. APIRET SockInit( CONNECTION *pConnection,
  92.                  LHANDLE    *pLsnHandle,
  93.                  int        *p_MoreRcInfo )
  94. {
  95.  APIRET  rc;
  96.  char    buf[CCHMAXPATH];
  97.  ULONG   somte = 0;
  98.  ULONG   tcpmte = 0;
  99.  int     SocketDescriptor;
  100.  int     NewSocketDescriptor;
  101.  int     DbgOrEsp;
  102.  
  103.  /****************************************************************************/
  104.  /* - load the dlls and the function entry points.                           */
  105.  /****************************************************************************/
  106.  rc = DosLoadModule( buf, sizeof(buf), "SO32DLL", &somte );
  107.  if(rc)
  108.  {
  109.   *p_MoreRcInfo = CANT_LOAD_TCPIP_DLL;
  110.   return(rc);
  111.  }
  112.  
  113.  rc = DosLoadModule( buf, sizeof(buf), "TCP32DLL", &tcpmte );
  114.  if(rc)
  115.  {
  116.   *p_MoreRcInfo = CANT_LOAD_TCPIP_DLL;
  117.   return(rc);
  118.  }
  119.  
  120.  if( (rc = DosQueryProcAddr(somte,  0, "SOCK_INIT"    , (PFN*)&sock_init_  ))||
  121.      (rc = DosQueryProcAddr(somte,  0, "PSOCK_ERRNO"  , (PFN*)&psock_errno_))||
  122.      (rc = DosQueryProcAddr(somte,  0, "SOCK_ERRNO"   , (PFN*)&sock_errno_ ))||
  123.      (rc = DosQueryProcAddr(somte,  0, "SOCKET"       , (PFN*)&socket_     ))||
  124.      (rc = DosQueryProcAddr(somte,  0, "CONNECT"      , (PFN*)&connect_    ))||
  125.      (rc = DosQueryProcAddr(somte,  0, "GETHOSTID"    , (PFN*)&gethostid_  ))||
  126.      (rc = DosQueryProcAddr(somte,  0, "BIND"         , (PFN*)&bind_       ))||
  127.      (rc = DosQueryProcAddr(somte,  0, "LISTEN"       , (PFN*)&listen_     ))||
  128.      (rc = DosQueryProcAddr(somte,  0, "ACCEPT"       , (PFN*)&accept_     ))||
  129.      (rc = DosQueryProcAddr(somte,  0, "SEND"         , (PFN*)&send_       ))||
  130.      (rc = DosQueryProcAddr(somte,  0, "RECV"         , (PFN*)&recv_       ))||
  131.      (rc = DosQueryProcAddr(somte,  0, "SOCLOSE"      , (PFN*)&soclose_    ))||
  132.      (rc = DosQueryProcAddr(somte,  0, "SETSOCKOPT"   , (PFN*)&setsockopt_ ))||
  133.      (rc = DosQueryProcAddr(tcpmte, 0, "BSWAP"        , (PFN*)&bswap_      ))||
  134.      (rc = DosQueryProcAddr(tcpmte, 0, "LSWAP"        , (PFN*)&lswap_      ))||
  135.      (rc = DosQueryProcAddr(tcpmte, 0, "INET_NTOA"    , (PFN*)&inet_ntoa_  ))||
  136.      (rc = DosQueryProcAddr(tcpmte, 0, "GETHOSTBYNAME", (PFN*)&gethostbyname_))||
  137.      (rc = DosQueryProcAddr(tcpmte, 0, "GETHOSTBYADDR", (PFN*)&gethostbyaddr_))||
  138.      (rc = DosQueryProcAddr(tcpmte, 0, "GETSERVBYNAME", (PFN*)&getservbyname_))
  139.    )
  140.   return(rc);
  141.  
  142.  /****************************************************************************/
  143.  /* - check for a running tcpip.                                             */
  144.  /****************************************************************************/
  145.  rc = (* sock_init_)();
  146.  if( rc != 0 )
  147.  {
  148.   (* psock_errno_)("\nsock_init()");
  149.   *p_MoreRcInfo = TCPIP_NOT_RUNNING;
  150.    return(1);
  151.  }
  152.  
  153.  /****************************************************************************/
  154.  /* - Esp is the server.                                                     */
  155.  /* - Dbg(SD386) is the client.                                              */
  156.  /****************************************************************************/
  157.  DbgOrEsp = pConnection->DbgOrEsp;
  158.  
  159.  rc = 0;
  160.  if( DbgOrEsp == _DBG )
  161.  {
  162.   /***************************************************************************/
  163.   /* - on the client side grab a socket descriptor and connect to the        */
  164.   /*   foreign machine name.                                                 */
  165.   /***************************************************************************/
  166.   SocketDescriptor = SockSocket();
  167.   if( SocketDescriptor < 0 )
  168.   {
  169.    *p_MoreRcInfo = TCPIP_ERROR;
  170.    return(1);
  171.   }
  172.   rc = SockConnect(SocketDescriptor, pConnection->pLsnName );
  173.   NewSocketDescriptor  = SocketDescriptor;
  174.   BaseSocketDescriptor = 0;
  175.  }
  176.  else /* esp/server */
  177.  {
  178.   /***************************************************************************/
  179.   /* - on the server side grab a socket descriptor, bind the port to         */
  180.   /*   to the machine address, and signal readiness for connections.         */
  181.   /***************************************************************************/
  182.   if( IsParent() )
  183.   {
  184.    BaseSocketDescriptor = SocketDescriptor = SockSocket();
  185.    if( SocketDescriptor < 0 )
  186.    {
  187.     *p_MoreRcInfo = TCPIP_ERROR;
  188.     return(1);
  189.    }
  190.   }
  191.   else
  192.    SocketDescriptor = BaseSocketDescriptor;
  193.  
  194.   if( IsParent() )
  195.   {
  196.    rc = SockBind(SocketDescriptor);
  197.    if(rc == 0 )
  198.    {
  199.     rc = SockListen(SocketDescriptor);
  200.    }
  201.   }
  202.  
  203.   /***************************************************************************/
  204.   /* - now accept a connection from a client.                                */
  205.   /***************************************************************************/
  206.   if( rc == 0 )
  207.   {
  208.    NewSocketDescriptor = SockAccept(SocketDescriptor);
  209.    if(NewSocketDescriptor < 0 )
  210.     rc = TCPIP_ERROR;
  211.   }
  212.  }
  213.  
  214.  if( rc )
  215.  {
  216.   *p_MoreRcInfo = rc;
  217.    rc = 1;
  218.  }
  219.  else
  220.   *pLsnHandle = NewSocketDescriptor;
  221.  
  222.  return(rc);
  223. }
  224.  
  225. /*****************************************************************************/
  226. /* SockGetAnotherSocket()                                                    */
  227. /*                                                                           */
  228. /* Description:                                                              */
  229. /*                                                                           */
  230. /*   This function is only used for parallel connections to set up           */
  231. /*   connection between the esp and dbg queues.                              */
  232. /*                                                                           */
  233. /* Parameters:                                                               */
  234. /*                                                                           */
  235. /*   pConnection    -> to the structure defining the remote connection.      */
  236. /*                                                                           */
  237. /* Return:                                                                   */
  238. /*                                                                           */
  239. /*   SocketDescriptor                                                        */
  240. /*                                                                           */
  241. /* Assumptions:                                                              */
  242. /*                                                                           */
  243. /*****************************************************************************/
  244. int SockGetAnotherSocket( CONNECTION *pConnection )
  245. {
  246.  int     SocketDescriptor;
  247.  int     DbgOrEsp;
  248.  
  249.  /****************************************************************************/
  250.  /* - Esp is the server.                                                     */
  251.  /* - Dbg(SD386) is the client.                                              */
  252.  /****************************************************************************/
  253.  DbgOrEsp = pConnection->DbgOrEsp;
  254.  
  255.  if( DbgOrEsp == _DBG )
  256.  {
  257.   SocketDescriptor = SockSocket();
  258.   SockConnect(SocketDescriptor, pConnection->pLsnName );
  259.  }
  260.  else /* esp/server */
  261.  {
  262.   SocketDescriptor = SockAccept(BaseSocketDescriptor);
  263.  }
  264.  return(SocketDescriptor);
  265. }
  266.  
  267. /*****************************************************************************/
  268. /* SockSocket()                                                              */
  269. /*                                                                           */
  270. /* Description:                                                              */
  271. /*                                                                           */
  272. /*   Get a stream socket.                                                    */
  273. /*                                                                           */
  274. /* Parameters:                                                               */
  275. /*                                                                           */
  276. /* Return:                                                                   */
  277. /*                                                                           */
  278. /*   SocketDescriptor                                                        */
  279. /*                                                                           */
  280. /* Assumptions:                                                              */
  281. /*                                                                           */
  282. /*****************************************************************************/
  283. int SockSocket( void )
  284. {
  285.  int SocketDescriptor;
  286.  /****************************************************************************/
  287.  /*  Get a stream socket for accepting connections.                          */
  288.  /*                                                                          */
  289.  /*   SocketDescriptor = socket( int domain, int type, int protocol )        */
  290.  /*                                                                          */
  291.  /*   domain   = AF_INET is the domain supported by OS/2.                    */
  292.  /*   type     = SOCK_STREAM for reliable xmission at TCP layer.             */
  293.  /*   protocol = 0 for default protocol associated with AF_INET/SOCK_STREAM  */
  294.  /*                                                                          */
  295.  /****************************************************************************/
  296.  SocketDescriptor = (* socket_)(AF_INET, SOCK_STREAM, 0);
  297.  if( SocketDescriptor < 0)
  298.  {
  299.   (* psock_errno_)("\nSocket()");
  300.  }
  301.  return(SocketDescriptor);
  302. }
  303.  
  304. /*****************************************************************************/
  305. /* SockConnect()                                                             */
  306. /*                                                                           */
  307. /* Description:                                                              */
  308. /*                                                                           */
  309. /*   Connect to a server.                                                    */
  310. /*                                                                           */
  311. /* Parameters:                                                               */
  312. /*                                                                           */
  313. /*   SocketDescriptor                                                        */
  314. /*   ip_name           this is a foreign name such as "elvis".               */
  315. /*                                                                           */
  316. /* Return:                                                                   */
  317. /*                                                                           */
  318. /*   rc                                                                      */
  319. /*                                                                           */
  320. /* Assumptions:                                                              */
  321. /*                                                                           */
  322. /*****************************************************************************/
  323. int SockConnect( int SocketDescriptor, char *ip_name )
  324. {
  325.  int port;
  326.  int rc;
  327.  
  328.  struct in_addr      IP_address;
  329.  struct sockaddr_in  ForeignAddress;
  330.  struct servent      ServEnt;
  331.  struct hostent      ForeignHost;
  332.  struct sockaddr    *pForeignAddress;
  333.  struct servent     *pServEnt;
  334.  struct hostent     *pForeignHost;
  335.  
  336.  pForeignHost    = &ForeignHost;
  337.  pForeignAddress = (struct sockaddr *)&ForeignAddress;
  338.  pServEnt        = &ServEnt;
  339.  
  340.  /****************************************************************************/
  341.  /* - get the name and address of this machine.                              */
  342.  /****************************************************************************/
  343.  memset(&ForeignHost, 0, sizeof(ForeignHost));
  344.  
  345.  pForeignHost = gethostbyname_(ip_name);
  346.  if( pForeignHost == NULL )
  347.   return(TCPIP_NO_HOST_NAME);
  348.  
  349.  /****************************************************************************/
  350.  /* - get the sockets port assigned to sd386.                                */
  351.  /****************************************************************************/
  352.  pServEnt = getservbyname_( "sd386", NULL );
  353.  if( pServEnt == NULL )
  354.   return(TCPIP_NO_SERVICES_PORT);
  355.  
  356.  /****************************************************************************/
  357.  /* - define/print the foreign address we're connecting to.                  */
  358.  /****************************************************************************/
  359.  IP_address.s_addr = *((unsigned long *)pForeignHost->h_addr);
  360.  port              = ntohs_(pServEnt->s_port);
  361.  
  362.  if( IsVerbose() ) {printf("\nforeign addr = %s", inet_ntoa_(IP_address));}
  363.  if( IsVerbose() ) {printf("\nforeign name = %s", pForeignHost->h_name ); }
  364.  if( IsVerbose() ) {printf("\nforeign port = %d", port );fflush(0);       }
  365.  
  366.  /****************************************************************************/
  367.  /* - make a connection.                                                     */
  368.  /* - this is done by the client only.                                       */
  369.  /* - if the server is not ready to accept connections, then sleep for       */
  370.  /*   a second and try again.                                                */
  371.  /****************************************************************************/
  372.  rc = -1;
  373.  while( rc != 0 )
  374.  {
  375.   memset(&ForeignAddress, 0, sizeof(ForeignAddress));
  376.   ForeignAddress.sin_family      = AF_INET;
  377.   ForeignAddress.sin_port        = htons_(port);
  378.   ForeignAddress.sin_addr.s_addr = IP_address.s_addr;
  379.   rc = (* connect_)(SocketDescriptor, pForeignAddress, sizeof(ForeignAddress));
  380.   if( rc )
  381.   {
  382.    (* psock_errno_)("\nconnect()");
  383.    rc = (* sock_errno_)();
  384.    if( rc == SOCECONNREFUSED )
  385.     return(TCPIP_ESP_NOT_STARTED);
  386.    else
  387.     return(TCPIP_ERROR);
  388.   }
  389.  }
  390.  return(0);
  391. }
  392.  
  393. /*****************************************************************************/
  394. /* SockBind()                                                                */
  395. /*                                                                           */
  396. /* Description:                                                              */
  397. /*                                                                           */
  398. /*   Bind a socket to a machine address. (Server only )                      */
  399. /*                                                                           */
  400. /* Parameters:                                                               */
  401. /*                                                                           */
  402. /*   SocketDescriptor                                                        */
  403. /*                                                                           */
  404. /* Return:                                                                   */
  405. /*                                                                           */
  406. /*   rc                                                                      */
  407. /*                                                                           */
  408. /* Assumptions:                                                              */
  409. /*                                                                           */
  410. /*****************************************************************************/
  411. int SockBind( int SocketDescriptor )
  412. {
  413.  int rc;
  414.  int port;
  415.  
  416.  struct in_addr      IP_address;
  417.  struct servent      ServEnt;
  418.  struct sockaddr_in  ServerAddress;
  419.  struct sockaddr    *pServerAddress;
  420.  struct servent     *pServEnt;
  421.  struct hostent      HostEnt;
  422.  struct hostent     *pHostEnt = &HostEnt;
  423.  
  424.  pServerAddress = (struct sockaddr *)&ServerAddress;
  425.  pServEnt       = &ServEnt;
  426.  
  427.  /****************************************************************************/
  428.  /* - get the name and address of this machine.                              */
  429.  /****************************************************************************/
  430.  IP_address.s_addr = htonl_(gethostid_());
  431.  
  432.  pHostEnt = (* gethostbyaddr_)((char*)&IP_address, sizeof(IP_address), AF_INET);
  433.  
  434.  printf("\nmachine addr = %s", inet_ntoa_(IP_address));
  435.  printf("\nmachine name = %s", pHostEnt->h_name);
  436.  
  437.  /****************************************************************************/
  438.  /* - get the sockets port assigned to sd386.                                */
  439.  /****************************************************************************/
  440.  pServEnt = getservbyname_( "sd386", NULL );
  441.  if( pServEnt == NULL )
  442.   return(TCPIP_NO_SERVICES_PORT);
  443.  
  444.  port = ntohs_(pServEnt->s_port);
  445.  
  446.  printf("\nsockets port = %d", port );fflush(0);
  447.  fflush(0);
  448.  
  449.  memset(pServerAddress, 0, sizeof(ServerAddress) );
  450.  
  451.  ServerAddress.sin_family      = AF_INET;
  452.  ServerAddress.sin_port        = htons_(port);
  453.  ServerAddress.sin_addr.s_addr = INADDR_ANY;
  454.  
  455.  rc = (* bind_)( SocketDescriptor, pServerAddress, sizeof(ServerAddress) );
  456.  if( rc < 0)
  457.  {
  458.   (* psock_errno_)("\nbind()");
  459.   return(TCPIP_ERROR);
  460.  }
  461.  return(rc);
  462. }
  463.  
  464. /*****************************************************************************/
  465. /* SockListen()                                                              */
  466. /*                                                                           */
  467. /* Description:                                                              */
  468. /*                                                                           */
  469. /*   Signal readiness for accepting connections on the server side of        */
  470. /*   the connection.                                                         */
  471. /*                                                                           */
  472. /* Parameters:                                                               */
  473. /*                                                                           */
  474. /*   SocketDescriptor                                                        */
  475. /*                                                                           */
  476. /* Return:                                                                   */
  477. /*                                                                           */
  478. /*   rc                                                                      */
  479. /*                                                                           */
  480. /* Assumptions:                                                              */
  481. /*                                                                           */
  482. /*****************************************************************************/
  483. int SockListen( int SocketDescriptor )
  484. {
  485.  int rc;
  486.  /****************************************************************************/
  487.  /* - signal readiness for accepting connections.                            */
  488.  /****************************************************************************/
  489.  rc = (* listen_)(SocketDescriptor, 1);
  490.  if(rc)
  491.  {
  492.   (* psock_errno_)("\nlisten()");
  493.  }
  494.  return(rc);
  495. }
  496.  
  497. /*****************************************************************************/
  498. /* SockAccept()                                                              */
  499. /*                                                                           */
  500. /* Description:                                                              */
  501. /*                                                                           */
  502. /*   Accept connections on the server side.                                  */
  503. /*                                                                           */
  504. /* Parameters:                                                               */
  505. /*                                                                           */
  506. /*   SocketDescriptor                                                        */
  507. /*                                                                           */
  508. /* Return:                                                                   */
  509. /*                                                                           */
  510. /*   rc                                                                      */
  511. /*                                                                           */
  512. /* Assumptions:                                                              */
  513. /*                                                                           */
  514. /*****************************************************************************/
  515. int SockAccept( int SocketDescriptor )
  516. {
  517.  int SocketNameLen;
  518.  int NewSocketDescriptor;
  519.  
  520.  struct sockaddr_in  ForeignAddress;
  521.  struct in_addr      IP_address;
  522.  struct hostent      HostEnt;
  523.  struct hostent     *pHostEnt        = &HostEnt;
  524.  struct sockaddr    *pForeignAddress = (struct sockaddr *)&ForeignAddress;
  525.  
  526.  /****************************************************************************/
  527.  /* - accept a connection from a foreign host.                               */
  528.  /****************************************************************************/
  529.  memset(&ForeignAddress, 0, sizeof(ForeignAddress) );
  530.  SocketNameLen = sizeof(ForeignAddress);
  531.  NewSocketDescriptor = (* accept_)(SocketDescriptor,
  532.                                    pForeignAddress,
  533.                                    &SocketNameLen);
  534.  if( NewSocketDescriptor == -1 )
  535.  {
  536.   (* psock_errno_)("\naccept()");
  537.   return(-1);
  538.  }
  539.  
  540.  /****************************************************************************/
  541.  /* - get the name and address of this machine.                              */
  542.  /****************************************************************************/
  543.  IP_address = ForeignAddress.sin_addr;
  544.  pHostEnt   = (* gethostbyaddr_)((char*)&IP_address, sizeof(IP_address), AF_INET);
  545.  
  546.  printf("\nconnection accepted from %s", pHostEnt->h_name );
  547.  
  548.  return(NewSocketDescriptor);
  549. }
  550.  
  551. /*****************************************************************************/
  552. /* SockSend()                                                                */
  553. /*                                                                           */
  554. /* Description:                                                              */
  555. /*                                                                           */
  556. /*   Send bytes.                                                             */
  557. /*                                                                           */
  558. /* Parameters:                                                               */
  559. /*                                                                           */
  560. /*   SocketDescriptor                                                        */
  561. /*   pBuf             -> our transmit buffer.                                */
  562. /*   Len              number of bytes to transmit.                           */
  563. /*                                                                           */
  564. /* Return:                                                                   */
  565. /*                                                                           */
  566. /* Assumptions:                                                              */
  567. /*                                                                           */
  568. /*****************************************************************************/
  569. void SockSend( int SocketDescriptor, PVOID pBuf, ULONG Len )
  570. {
  571.  int rc;
  572.  
  573.  if( Len == 0 )
  574.   return;
  575.  
  576. again:
  577.  rc = (* send_)(SocketDescriptor, pBuf, Len, 0);
  578.  if( rc < 0 )
  579.  {
  580.   rc = (* sock_errno_)();
  581.   if( rc == SOCEINTR )
  582.    goto again;
  583.  
  584.   /***************************************************************************/
  585.   /* - We will get this return code when the socket has been closed.         */
  586.   /* - Just wait for the operating system to kill this thread.               */
  587.   /***************************************************************************/
  588.   if( (rc == SOCENOTSOCK) /* || rc == any other error */ )
  589.   {
  590.    for(;;){ DosSleep(60000); }
  591.   }
  592.  }
  593. }
  594.  
  595. /*****************************************************************************/
  596. /* SockRecv()                                                                */
  597. /*                                                                           */
  598. /* Description:                                                              */
  599. /*                                                                           */
  600. /*   Recv bytes.                                                             */
  601. /*                                                                           */
  602. /* Parameters:                                                               */
  603. /*                                                                           */
  604. /*   SocketDescriptor                                                        */
  605. /*   pBuf             -> our transmit buffer.                                */
  606. /*   Len              number of bytes to transmit.                           */
  607. /*                                                                           */
  608. /* Return:                                                                   */
  609. /*                                                                           */
  610. /* Assumptions:                                                              */
  611. /*                                                                           */
  612. /*****************************************************************************/
  613. void SockRecv( int SocketDescriptor, PVOID pBuf, ULONG Len )
  614. {
  615.  int   Bytes;
  616.  int   rc;
  617.  char *cp;
  618.  
  619.  if( Len == 0 )
  620.   return;
  621.  
  622.  cp    = (char *)pBuf;
  623.  
  624.  while( Len > 0 )
  625.  {
  626.   Bytes  = (* recv_)( SocketDescriptor, cp, Len, 0 );
  627.   if( Bytes < 0 )
  628.   {
  629.    rc = (* sock_errno_)();
  630.    if( rc == SOCEINTR )
  631.     continue;
  632.  
  633.    /**************************************************************************/
  634.    /* - We will get this return code when the socket has been closed.        */
  635.    /**************************************************************************/
  636.    if( (rc == SOCENOTSOCK) /* || rc == any other error */ )
  637.    {
  638.     for(;;){ DosSleep(60000); }
  639.    }
  640.   }
  641.   cp    += Bytes;
  642.   Len   -= Bytes;
  643.  }
  644.  return;
  645. }
  646.  
  647. /*****************************************************************************/
  648. /* SockClose()                                                               */
  649. /*                                                                           */
  650. /* Description:                                                              */
  651. /*                                                                           */
  652. /*   Close a socket.                                                         */
  653. /*                                                                           */
  654. /* Parameters:                                                               */
  655. /*                                                                           */
  656. /*   SocketDescriptor                                                        */
  657. /*                                                                           */
  658. /* Return:                                                                   */
  659. /*                                                                           */
  660. /* Assumptions:                                                              */
  661. /*                                                                           */
  662. /*****************************************************************************/
  663. void SockClose( int SocketDescriptor )
  664. {
  665.  int rc;
  666.  
  667.  if( SocketDescriptor == 0 )
  668.  {
  669.   if( BaseSocketDescriptor == 0 )
  670.    return;
  671.   SocketDescriptor = BaseSocketDescriptor;
  672.   (* setsockopt_)( SocketDescriptor, SOL_SOCKET, SO_REUSEADDR, NULL, 0 );
  673.  }
  674.  
  675.  rc = (* soclose_)(SocketDescriptor);
  676.  if(rc < 0 )
  677.  {
  678.   (* psock_errno_)("\nclose()");
  679.  }
  680.  if( IsVerbose() ) {printf("\nSocket close rc=%d", rc);}
  681.  if( IsVerbose() ) {printf("  Socket Descriptor=%d", SocketDescriptor);fflush(0);}
  682. }
  683.