home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES2.ZIP / UUCICO / ulibip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-07  |  28.5 KB  |  861 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       u l i b i p . c                                              */
  3. /*                                                                    */
  4. /*       TCP/IP port communications driver for Windows sockets        */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*    Copyright (c) David M. Watt 1993, All Rights Reserved           */
  9. /*--------------------------------------------------------------------*/
  10.  
  11. /*--------------------------------------------------------------------*/
  12. /*    Changes Copyright (c) 1989-1993 by Kendra Electronic            */
  13. /*    Wonderworks.                                                    */
  14. /*                                                                    */
  15. /*    All rights reserved except those explicitly granted by the      */
  16. /*    UUPC/extended license agreement.                                */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*--------------------------------------------------------------------*/
  20. /*                          RCS Information                           */
  21. /*--------------------------------------------------------------------*/
  22.  
  23. /*
  24.  *    $Id: ulibip.c 1.11 1993/11/06 17:56:09 rhg Exp $
  25.  *
  26.  *    $Log: ulibip.c $
  27.  * Revision 1.11  1993/11/06  17:56:09  rhg
  28.  * Drive Drew nuts by submitting cosmetic changes mixed in with bug fixes
  29.  *
  30.  * Revision 1.10  1993/10/30  22:07:49  dmwatt
  31.  * Host byte ordering corrections
  32.  *
  33.  * Revision 1.9  1993/10/16  15:13:17  ahd
  34.  * Allow parsing target port address when connecting to remote
  35.  *
  36.  * Revision 1.8  1993/10/12  01:33:23  ahd
  37.  * Normalize comments to PL/I style
  38.  *
  39.  * Revision 1.7  1993/10/07  22:56:45  ahd
  40.  * Use dynamically allocated buffer
  41.  *
  42.  * Revision 1.6  1993/10/02  23:12:35  dmwatt
  43.  * Winsock error message support
  44.  *
  45.  * Revision 1.5  1993/09/26  03:32:27  dmwatt
  46.  * Use Standard Windows NT error message module
  47.  *
  48.  * Revision 1.4  1993/09/25  03:07:56  ahd
  49.  * Addition error traps by Dave Watt
  50.  *
  51.  * Revision 1.3  1993/09/23  03:26:51  ahd
  52.  * Correct setting of carrier detect
  53.  *
  54.  * Revision 1.2  1993/09/21  01:42:13  ahd
  55.  * Use standard MAXPACK limit for save buffer size
  56.  *
  57.  * Revision 1.1  1993/09/20  04:48:25  ahd
  58.  * Initial revision
  59.  *
  60.  */
  61.  
  62. /*--------------------------------------------------------------------*/
  63. /*                        System include files                        */
  64. /*--------------------------------------------------------------------*/
  65.  
  66. #include <windows.h>
  67. #include "winsock.h"
  68.  
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include <time.h>
  73.  
  74. /*--------------------------------------------------------------------*/
  75. /*                    UUPC/extended include files                     */
  76. /*--------------------------------------------------------------------*/
  77.  
  78. #include "lib.h"
  79. #include "hlib.h"
  80. #include "ulib.h"
  81. #include "comm.h"          /* Modem status bits                       */
  82. #include "ssleep.h"
  83. #include "catcher.h"
  84.  
  85. #include "commlib.h"       /* Trace functions, etc.                    */
  86. #include "pwserr.h"        /* Windows sockets error messages           */
  87.  
  88. #ifdef _Windows
  89. #include "pwinsock.h"      /* definitions for 16 bit Winsock functions  */
  90. #endif
  91.  
  92. /*--------------------------------------------------------------------*/
  93. /*                        Internal prototypes                         */
  94. /*--------------------------------------------------------------------*/
  95.  
  96. void AtWinsockExit(void);
  97. boolean IsFatalSocketError(int err);
  98. void tcloseline(void);
  99.  
  100. /*--------------------------------------------------------------------*/
  101. /*                          Global variables                          */
  102. /*--------------------------------------------------------------------*/
  103.  
  104. static boolean carrierDetect = FALSE;
  105.  
  106. currentfile();
  107. static boolean hangupNeeded = TRUE;
  108. extern boolean winsockActive;                   /* Initialized in catcher.c  */
  109. static SOCKET pollingSock = INVALID_SOCKET;     /* The current polling socket  */
  110. static SOCKET connectedSock = INVALID_SOCKET;   /* The currently connected socket  */
  111. static boolean connectionDied = FALSE;          /* The current connection failed  */
  112.  
  113. /*--------------------------------------------------------------------*/
  114. /*                           Local defines                            */
  115. /*--------------------------------------------------------------------*/
  116.  
  117. #ifndef MAKEWORD
  118. #define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8))
  119. #endif
  120.  
  121. /*--------------------------------------------------------------------*/
  122. /*    I n i t W i n s o c k                                           */
  123. /*                                                                    */
  124. /*    Start the Windows sockets DLL                                   */
  125. /*--------------------------------------------------------------------*/
  126.  
  127. boolean InitWinsock(void)
  128. {
  129.    WSADATA WSAData;
  130.    int status;
  131.    static boolean firstPass = TRUE;
  132.  
  133.    if ( winsockActive )
  134.       return TRUE;
  135.  
  136. /*--------------------------------------------------------------------*/
  137. /*       The atexit() must precede the WSAStartup() so the            */
  138. /*       FreeLibrary() call gets done                                 */
  139. /*--------------------------------------------------------------------*/
  140.  
  141.    if ( firstPass )
  142.    {
  143.       firstPass = FALSE;
  144.       atexit(AtWinsockExit);
  145.    }
  146.  
  147. #ifdef _Windows
  148.    if (!pWinSockInit())
  149.       return FALSE;
  150. #endif
  151.  
  152. /* status = WSAStartup(MAKEWORD(1,1), &WSAData); */
  153.    status = WSAStartup(0x0101, &WSAData);
  154.  
  155.    if (status != 0)
  156.    {
  157.       printf("WSAStartup Error: %d", status);
  158.       return FALSE;
  159.    }
  160.  
  161.    winsockActive = TRUE;
  162.    return TRUE;
  163.  
  164. } /* InitWinsock */
  165.  
  166. /*--------------------------------------------------------------------*/
  167. /*       A t W i n s o c k E x i t                                    */
  168. /*                                                                    */
  169. /*       Clean up Windows DLL at shutdown                             */
  170. /*--------------------------------------------------------------------*/
  171.  
  172.  
  173. void AtWinsockExit(void)
  174. {
  175.    WSACleanup();
  176.  
  177. #ifdef _Windows
  178.    pWinSockExit();
  179. #endif
  180.  
  181.    winsockActive = FALSE;
  182.  
  183. }  /* AtWinsockExit */
  184.  
  185. /*--------------------------------------------------------------------*/
  186. /*    t o p e n a c t i v e                                           */
  187. /*                                                                    */
  188. /*    Open an active socket connection for I/O                        */
  189. /*--------------------------------------------------------------------*/
  190.  
  191. #ifdef __TURBOC__
  192. #pragma argsused
  193. #endif
  194.  
  195. int tactiveopenline(char *name, BPS bps, const boolean direct)
  196. {
  197.    SOCKADDR_IN sin;
  198.    LPHOSTENT phe;
  199.    LPSERVENT pse;
  200.    u_short remotePort;
  201.    char *portStr;
  202.  
  203.    if (!InitWinsock())           /* Initialize library?               */
  204.       return TRUE;               /* No --> Report error               */
  205.  
  206.    if (portActive)              /* Was the port already active?      */
  207.       closeline();               /* Yes --> Shutdown it before open  */
  208.  
  209.    printmsg(15, "tactiveopenline: %s", name);
  210.  
  211.    norecovery = FALSE;     /* Flag we need a graceful shutdown after  */
  212.                            /* Ctrl-BREAK                              */
  213.  
  214.    carrierDetect = FALSE;  /* No modem connected yet                */
  215.  
  216.    connectionDied = FALSE; /* The connection hasn't failed yet */
  217.  
  218. /*--------------------------------------------------------------------*/
  219. /*                        Parse out port address                      */
  220. /*--------------------------------------------------------------------*/
  221.    remotePort = 0;
  222.    portStr = strchr(name, ':');
  223.    if (portStr)
  224.    {
  225.          *portStr = '\0';
  226.          portStr++;
  227.          remotePort = (u_short)atoi(portStr);
  228.          printmsg(4, "tactiveopenline: connecting to remote port %d",
  229.             (int)remotePort);
  230.    }
  231.  
  232. /*--------------------------------------------------------------------*/
  233. /*                        Get remote host name                        */
  234. /*--------------------------------------------------------------------*/
  235.  
  236.    sin.sin_family = AF_INET;
  237.    phe = gethostbyname(name);
  238.  
  239.    if (phe)
  240. #ifdef _Windows
  241.       _fmemcpy((char FAR *) &(sin.sin_addr),
  242.                (char FAR *) phe->h_addr,
  243.                phe->h_length);
  244. #else
  245.       memcpy((char FAR *) &(sin.sin_addr),
  246.              (char FAR *) phe->h_addr,
  247.              phe->h_length);
  248. #endif
  249.    else {
  250.       sin.sin_addr.s_addr = inet_addr(name);
  251.  
  252.       if ( sin.sin_addr.s_addr == INADDR_NONE )
  253.       {
  254.          int wsErr = WSAGetLastError();
  255.  
  256.          printmsg(0, "tactiveopenline: "
  257.             "Is '%s' listed in the hosts file or a valid IP address?",
  258.             name);
  259.          printWSerror("gethostbyname", wsErr);
  260.          return TRUE;
  261.       }
  262.  
  263.    } /* else */
  264.  
  265. /*--------------------------------------------------------------------*/
  266. /*                     Get the TCP/IP port number                     */
  267. /*--------------------------------------------------------------------*/
  268.  
  269.    if (remotePort == 0)
  270.    {
  271.       pse = getservbyname("uucp", "tcp");
  272.       if (pse == NULL)
  273.       {
  274.          int wsErr = WSAGetLastError();
  275.  
  276.          sin.sin_port = htons(540);
  277.          printWSerror("getservbyname", wsErr);
  278.          printmsg(0, "tactiveopenline: using port %d", (int)htons(sin.sin_port));
  279.       }
  280.       else
  281.          sin.sin_port = pse->s_port;
  282.    }
  283.    else
  284.       sin.sin_port = remotePort;
  285.  
  286.    connectedSock = socket( AF_INET, SOCK_STREAM, 0);
  287.    if (connectedSock == INVALID_SOCKET)
  288.    {
  289.       printmsg(0, "tactiveopenline: socket() failed");
  290.       return TRUE;
  291.    }
  292.  
  293.    if (connect( connectedSock, (PSOCKADDR) &sin, sizeof(sin)) < 0)
  294.    {
  295.       int wsErr = WSAGetLastError();
  296.  
  297.       printmsg(0, "tactiveopenline: connect() failed");
  298.       printWSerror("connect", wsErr);
  299.       closesocket( connectedSock );
  300.       connectedSock = INVALID_SOCKET;
  301.  
  302.       return TRUE;
  303.    }
  304.  
  305.    traceStart( name );
  306.  
  307.    portActive = TRUE;     /* record status for error handler */
  308.    carrierDetect = TRUE;   /* Carrier detect = connection              */
  309.  
  310.    return FALSE;                       /* Return success to caller     */
  311.  
  312. } /* tactiveopenline */
  313.  
  314. /*--------------------------------------------------------------------*/
  315. /*    t o p e n p a s s i v e                                         */
  316. /*                                                                    */
  317. /*    Listen on a socket for an incoming uucp connection              */
  318. /*--------------------------------------------------------------------*/
  319.  
  320. #ifdef __TURBOC__
  321. #pragma argsused
  322. #endif
  323.  
  324. int tpassiveopenline(char *name, BPS bps, const boolean direct)
  325. {
  326.    SOCKADDR_IN sin;
  327.    LPSERVENT pse;
  328.  
  329.    if (!InitWinsock())           /* Initialize library?               */
  330.       return TRUE;               /* No --> Report error               */
  331.  
  332.    if (portActive)              /* Was the port already active?      */
  333.       closeline();               /* Yes --> Shutdown it before open  */
  334.  
  335.    printmsg(15, "tpassiveopenline: opening passive connection");
  336.  
  337.    norecovery = FALSE;     /* Flag we need a graceful shutdown after  */
  338.                            /* Ctrl-BREAK                              */
  339.  
  340.    carrierDetect = FALSE;  /* No network connection yet             */
  341.  
  342.    connectionDied = FALSE; /* The connection hasn't failed yet */
  343.  
  344. /*--------------------------------------------------------------------*/
  345. /*                    Fill in host and family info                    */
  346. /*--------------------------------------------------------------------*/
  347.  
  348.    sin.sin_family = AF_INET;
  349.  
  350. /*--------------------------------------------------------------------*/
  351. /*                Fill in service information for tcp                 */
  352. /*--------------------------------------------------------------------*/
  353.  
  354.    printmsg(15, "tpassiveopenline: doing getservbyname");
  355.    pse = getservbyname("uucp", "tcp");
  356.  
  357.    if (pse == NULL)
  358.    {
  359.       int wsErr = WSAGetLastError();
  360.  
  361.       sin.sin_port = htons(540);
  362.       printWSerror("getservbyname", wsErr);
  363.       printmsg(0, "tpassiveopenline: using port %d",
  364.                   (int)ntohs(sin.sin_port));
  365.    }
  366.    else
  367.       sin.sin_port = pse->s_port;
  368.  
  369.    sin.sin_addr.s_addr = 0;
  370.  
  371.    printmsg(5, "tpassiveopenline: waiting on port %d",
  372.                (int)ntohs(sin.sin_port));
  373.  
  374. /*--------------------------------------------------------------------*/
  375. /*                     Create and bind TCP socket                     */
  376. /*--------------------------------------------------------------------*/
  377.  
  378.    printmsg(15, "tpassiveopen: doing socket()");
  379.    pollingSock = socket( AF_INET, SOCK_STREAM, 0);
  380.  
  381.    if (pollingSock == INVALID_SOCKET)
  382.    {
  383.       int wsErr = WSAGetLastError();
  384.  
  385.       printmsg(0, "tpassiveopen: socket() failed");
  386.       printWSerror("socket", wsErr);
  387.       return TRUE;
  388.    }
  389.  
  390.    printmsg(15, "tpassiveopen: doing bind()");
  391.  
  392.    if (bind(pollingSock,
  393.            (struct sockaddr FAR *) &sin,
  394.            sizeof(sin)) == SOCKET_ERROR)
  395.    {
  396.       int wsErr = WSAGetLastError();
  397.  
  398.       printmsg(0, "tpassiveopen: bind(pollingSock) failed");
  399.       printWSerror("bind", wsErr);
  400.       return TRUE;                      /* report failure              */
  401.    }
  402.  
  403.    printmsg(15, "tpassiveopen: doing listen()");
  404.    if (listen(pollingSock, 2) == SOCKET_ERROR)
  405.    {
  406.       int wsErr = WSAGetLastError();
  407.  
  408.       printmsg(0, "tpassiveopen: listen(pollingSock) failed");
  409.       printWSerror("listen", wsErr);
  410.       return TRUE;
  411.    }
  412.  
  413.    traceStart( name );
  414.  
  415.    portActive = TRUE;     /* record status for error handler */
  416.  
  417.    return FALSE;          /* Return success to caller                 */
  418.  
  419. } /* tpassiveopen */
  420.  
  421. /*--------------------------------------------------------------------*/
  422. /*    t s r e a d                                                     */
  423. /*                                                                    */
  424. /*    Read from the network socket                                    */
  425. /*                                                                    */
  426. /*    Non-blocking read essential to "g" protocol.  See               */
  427. /*    "dcpgpkt.c" for description.  This all changes in a             */
  428. /*    multi-tasking system.  Requests for I/O should get queued       */
  429. /*    and an event flag given.  Then the requesting process (e.g.     */
  430. /*    gmachine()) waits for the event flag to fire processing         */
  431. /*    either a read or a write.  Could be implemented on VAX/VMS      */
  432. /*    or DG but not MS-DOS.                                           */
  433. /*--------------------------------------------------------------------*/
  434.  
  435. unsigned int tsread(char *output, unsigned int wanted, unsigned int timeout)
  436. {
  437.    fd_set readfds;
  438.    struct timeval tm;
  439.    int nReady;
  440.    time_t stop_time ;
  441.    time_t now ;
  442.  
  443. /*--------------------------------------------------------------------*/
  444. /*           Determine if our internal buffer has the data            */
  445. /*--------------------------------------------------------------------*/
  446.  
  447.    if (commBufferUsed >= wanted)
  448.    {
  449.       memcpy( output, commBuffer, wanted );
  450.       commBufferUsed -= wanted;
  451.       if ( commBufferUsed )   /* Any data left over?                 */
  452.          memmove( commBuffer, commBuffer + wanted, commBufferUsed );
  453.                               /* Yes --> Save it                     */
  454.       return wanted + commBufferUsed;
  455.    } /* if */
  456.  
  457.    if (connectionDied || connectedSock == INVALID_SOCKET)
  458.    {                             /* Haven't accepted a connection yet?  */
  459.       return 0;
  460.    }
  461.  
  462. /*--------------------------------------------------------------------*/
  463. /*                 Determine when to stop processing                  */
  464. /*--------------------------------------------------------------------*/
  465.  
  466.    if ( timeout == 0 )
  467.    {
  468.       stop_time = 0;
  469.       now = 1;                /* Any number greater than stop time   */
  470.    }
  471.    else {
  472.       time( & now );
  473.       stop_time = now + timeout;
  474.    }
  475.  
  476.    do {
  477.       int received;
  478.       int needed = wanted - commBufferUsed;
  479.  
  480. /*--------------------------------------------------------------------*/
  481. /*          Initialize fd_set structure for select() call             */
  482. /*--------------------------------------------------------------------*/
  483.  
  484.       FD_ZERO(&readfds);
  485.       FD_SET(connectedSock, &readfds);
  486.  
  487. /*--------------------------------------------------------------------*/
  488. /*                     Handle an aborted program                      */
  489. /*--------------------------------------------------------------------*/
  490.  
  491.       if ( terminate_processing )
  492.       {
  493.          static boolean recurse = FALSE;
  494.          if ( ! recurse )
  495.          {
  496.             printmsg(2,"sread: User aborted processing");
  497.             recurse = TRUE;
  498.          }
  499.          return 0;
  500.       }
  501.  
  502. /*--------------------------------------------------------------------*/
  503. /*       Special case for network sockets: block for at least 5      */
  504. /*       msec if we have to read at least one character (this         */
  505. /*       needs to be tuned)                                           */
  506. /*--------------------------------------------------------------------*/
  507.  
  508.       if (stop_time > now )
  509.       {
  510.          tm.tv_sec = stop_time - now;
  511.          tm.tv_usec = 0;
  512.       }
  513.       else {
  514.  
  515.          tm.tv_usec = 5000;
  516.          tm.tv_sec = 0;
  517.       }
  518.  
  519. /*--------------------------------------------------------------------*/
  520. /*                 Read the data from the socket                      */
  521. /*--------------------------------------------------------------------*/
  522.  
  523.       nReady = select(1, &readfds, NULL, NULL, &tm);
  524.       if (nReady == SOCKET_ERROR)
  525.       {
  526.          int err = WSAGetLastError();
  527.          printmsg(0, "tsread: error in select()");
  528.          printWSerror("select", err);
  529.  
  530.          if (IsFatalSocketError(err))
  531.          {
  532.             shutdown(connectedSock, 2);  /* Fail both reads and writes  */
  533.             connectionDied = TRUE;
  534.          }
  535.          commBufferUsed = 0;
  536.          return 0;
  537.       }
  538.       else if (nReady == 0)
  539.       {
  540.          printmsg(5, "tsread: timeout after %d seconds",timeout);
  541.          commBufferUsed = 0;
  542.          return 0;
  543.       }
  544.       else {
  545.          received = recv(connectedSock,
  546.                          commBuffer + commBufferUsed,
  547.                          needed,
  548.                          0);
  549.  
  550.          if (received == SOCKET_ERROR)
  551.          {
  552.             int wsErr = WSAGetLastError();
  553.  
  554.             printmsg(0, "tsread: recv() failed");
  555.             printWSerror("recv", wsErr);
  556.             commBufferUsed = 0;
  557.             return 0;
  558.          }
  559.       }  /* else */
  560.  
  561. #ifdef UDEBUG
  562.       printmsg(15,"sread: Want %d characters, received %d, total %d in buffer",
  563.                   (int) wanted,
  564.                   (int) received,
  565.                   (int) commBufferUsed + received);
  566. #endif
  567.  
  568. /*--------------------------------------------------------------------*/
  569. /*                    Log the newly received data                     */
  570. /*--------------------------------------------------------------------*/
  571.  
  572.       traceData( commBuffer + commBufferUsed,
  573.                  (unsigned) received,
  574.                  FALSE );
  575.  
  576. /*--------------------------------------------------------------------*/
  577. /*            If we got the data, return it to the caller             */
  578. /*--------------------------------------------------------------------*/
  579.  
  580.       commBufferUsed += received;
  581.       if ( commBufferUsed == wanted )
  582.       {
  583.          memcpy( output, commBuffer, commBufferUsed);
  584.          commBufferUsed = 0;
  585.  
  586.          return wanted;
  587.       } /* if */
  588.  
  589. /*--------------------------------------------------------------------*/
  590. /*                 Update the clock for the next pass                 */
  591. /*--------------------------------------------------------------------*/
  592.  
  593.       if (stop_time > 0)
  594.          time( &now );
  595.  
  596.    } while (stop_time > now);
  597.  
  598. /*--------------------------------------------------------------------*/
  599. /*         We don't have enough data; report what we do have          */
  600. /*--------------------------------------------------------------------*/
  601.  
  602.    return commBufferUsed;
  603.  
  604. } /* tsread */
  605.  
  606. /*--------------------------------------------------------------------*/
  607. /*    t s w r i t e                                                   */
  608. /*                                                                    */
  609. /*    Write to the open socket                                        */
  610. /*   Note:  this is non-blocking, so we've got to use select() to     */
  611. /*    gradually write out the entire buffer                           */
  612. /*--------------------------------------------------------------------*/
  613.  
  614. int tswrite(char *data, unsigned int len)
  615. {
  616.    int status;
  617.  
  618. /* Has connection died? */
  619.    if (connectionDied || connectedSock == INVALID_SOCKET)
  620.       return 0;
  621.  
  622.    status = send(connectedSock, data, len, 0);
  623.  
  624.    if (status == SOCKET_ERROR)
  625.    {
  626.       int err;
  627.  
  628.       err = WSAGetLastError();
  629.       printmsg(0, "tswrite: Error sending data to socket");
  630.       printWSerror("send", err);
  631.  
  632.       if (IsFatalSocketError(err))
  633.       {
  634.          shutdown(connectedSock, 2);  /* Fail both reads and writes   */
  635.          connectionDied = TRUE;
  636.       }
  637.       return 0;
  638.    }
  639.  
  640.    if (status < (int)len)     /* Breaks if len > 32K, which is unlikely */
  641.    {
  642.       printmsg(0,"tswrite: Write to network failed.");
  643.       return status;
  644.    }
  645.  
  646. /*--------------------------------------------------------------------*/
  647. /*                        Log the data written                        */
  648. /*--------------------------------------------------------------------*/
  649.  
  650.    traceData( data, len, TRUE );
  651.  
  652. /*--------------------------------------------------------------------*/
  653. /*              Return byte count transmitted to caller               */
  654. /*--------------------------------------------------------------------*/
  655.  
  656.    return len;
  657.  
  658. } /* tswrite */
  659.  
  660. /*--------------------------------------------------------------------*/
  661. /*    t s s e n d b r k                                               */
  662. /*                                                                    */
  663. /*    Send a break signal over the network                            */
  664. /*--------------------------------------------------------------------*/
  665.  
  666. #ifdef __TURBOC__
  667. #pragma argsused
  668. #endif
  669.  
  670. void tssendbrk(unsigned int duration)
  671. {
  672.    printmsg(12, "tsendbrk: ignored break of duration %d", duration);
  673.    return;
  674.  
  675. } /* tssendbrk */
  676.  
  677. /*--------------------------------------------------------------------*/
  678. /*    t c l o s e l i n e                                             */
  679. /*                                                                    */
  680. /*    Close the serial port down                                      */
  681. /*--------------------------------------------------------------------*/
  682.  
  683. void tcloseline(void)
  684. {
  685.    if (!portActive)
  686.       panic();
  687.  
  688.    portActive = FALSE;     /* flag port closed for error handler  */
  689.  
  690.    if (connectedSock != INVALID_SOCKET)
  691.    {
  692.       closesocket(connectedSock);
  693.       connectedSock = INVALID_SOCKET;
  694.    }
  695.  
  696.    if (pollingSock != INVALID_SOCKET)
  697.    {
  698.       closesocket(pollingSock);
  699.       pollingSock = INVALID_SOCKET;
  700.    }
  701.  
  702.    carrierDetect = FALSE;  /* No network connection yet               */
  703.    traceStop();
  704.  
  705. } /* tcloseline */
  706.  
  707. /*--------------------------------------------------------------------*/
  708. /*    t h a n g u p                                                   */
  709. /*                                                                    */
  710. /*    Break the connection with the remote system.                    */
  711. /*--------------------------------------------------------------------*/
  712.  
  713. void thangup( void )
  714. {
  715.    if (!hangupNeeded)
  716.       return;
  717.    hangupNeeded = FALSE;
  718.  
  719.    if (connectedSock != INVALID_SOCKET)
  720.    {
  721.       closesocket(connectedSock);
  722.       connectedSock = INVALID_SOCKET;
  723.    }
  724.  
  725.    if (pollingSock != INVALID_SOCKET)
  726.    {
  727.       closesocket(pollingSock);
  728.       pollingSock = INVALID_SOCKET;
  729.    }
  730.  
  731.    carrierDetect = FALSE;  /* No network connection yet               */
  732.  
  733. } /* thangup */
  734.  
  735. /*--------------------------------------------------------------------*/
  736. /*    t S I O S p e e d                                               */
  737. /*                                                                    */
  738. /*    Re-specify the speed of an opened serial port                   */
  739. /*--------------------------------------------------------------------*/
  740.  
  741. #ifdef __TURBOC__
  742. #pragma argsused
  743. #endif
  744.  
  745. void tSIOSpeed(BPS bps)
  746. {
  747.    return;  /* Irrelevant on network */
  748. } /* iSIOSpeed */
  749.  
  750. /*--------------------------------------------------------------------*/
  751. /*    t f l o w c o n t r o l                                         */
  752. /*                                                                    */
  753. /*    Enable/Disable in band (XON/XOFF) flow control                  */
  754. /*--------------------------------------------------------------------*/
  755.  
  756. #ifdef __TURBOC__
  757. #pragma argsused
  758. #endif
  759.  
  760. void tflowcontrol( boolean flow )
  761. {
  762.    return;                  /* Irrelevant on network (we hope)       */
  763. } /* tflowcontrol */
  764.  
  765. /*--------------------------------------------------------------------*/
  766. /*    t G e t S p e e d                                               */
  767. /*                                                                    */
  768. /*    Report current speed of communications connection               */
  769. /*--------------------------------------------------------------------*/
  770.  
  771. BPS tGetSpeed( void )
  772. {
  773.    return 57600;           /* Arbitary large number to avoid possible  */
  774.                            /* divide by zero error in caller           */
  775. } /* GetSpeed */
  776.  
  777. /*--------------------------------------------------------------------*/
  778. /*    t C D                                                           */
  779. /*                                                                    */
  780. /*    Report if we have carrier detect and lost it                    */
  781. /*--------------------------------------------------------------------*/
  782.  
  783. boolean tCD( void )
  784. {
  785.    boolean online = carrierDetect;
  786.  
  787.    return online;
  788. } /* tCD */
  789.  
  790. /*--------------------------------------------------------------------*/
  791. /*       t W a i t F o r N e t C o n n e c t                          */
  792. /*                                                                    */
  793. /*       Wait for remote system to connect to our waiting server      */
  794. /*--------------------------------------------------------------------*/
  795.  
  796. boolean tWaitForNetConnect(int timeout)
  797. {
  798.    fd_set readfds;
  799.    int nReady;
  800.    struct timeval tm;
  801.  
  802.    tm.tv_sec = timeout;
  803.    tm.tv_usec = 0;
  804.  
  805.    FD_ZERO(&readfds);
  806.    FD_SET(pollingSock, &readfds);
  807.  
  808.    nReady = select(1, &readfds, NULL, NULL, &tm);
  809.  
  810.    if (nReady == SOCKET_ERROR)
  811.    {
  812.       int wsErr = WSAGetLastError();
  813.  
  814.       printmsg(0, "WaitForNetConnect: select() failed");
  815.       printWSerror("select", wsErr);
  816.       return FALSE;
  817.    }
  818.    else if (nReady == 0)
  819.    {
  820.       printmsg(5, "WaitForNetConnect: select() timed out");
  821.       return FALSE;
  822.    }
  823.  
  824.    connectedSock = accept(pollingSock, NULL, NULL);
  825.    if (connectedSock == INVALID_SOCKET)
  826.    {
  827.       int wsErr = WSAGetLastError();
  828.  
  829.       printmsg(0, "WaitForNetConnect: could not accept a connection");
  830.       printWSerror("accept", wsErr);
  831.    }
  832.  
  833.    carrierDetect = TRUE;
  834.  
  835.    return TRUE;
  836.  
  837. } /* tWaitForNetConnect */
  838.  
  839. /*--------------------------------------------------------------------*/
  840. /*      I s F a t a l S o c k e t E r r o r                           */
  841. /*                                                                    */
  842. /*      Determine if an error is a show stopped                       */
  843. /*--------------------------------------------------------------------*/
  844.  
  845. boolean IsFatalSocketError(int err)
  846. {
  847.    if (err == WSAENOTSOCK     ||
  848.        err == WSAENETDOWN     ||
  849.        err == WSAENETRESET    ||
  850.        err == WSAECONNABORTED ||
  851.        err == WSAECONNRESET   ||
  852.        err == WSAENOTCONN     ||
  853.        err == WSAECONNREFUSED ||
  854.        err == WSAEHOSTDOWN    ||
  855.        err == WSAEHOSTUNREACH)
  856.        return TRUE;
  857.     else
  858.        return FALSE;
  859.  
  860. } /* IsFatalSocketError */
  861.