home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckc190.zip / ckonet.c < prev    next >
C/C++ Source or Header  |  1994-12-09  |  41KB  |  1,501 lines

  1. char *ckonetv = "OS/2 Network support, 5A(040) 4 Oct 94";
  2.  
  3. /*  C K O N E T  --  OS/2-specific network support  */
  4.  
  5. /*
  6.   COPYRIGHT NOTICE:
  7.  
  8.   Copyright (C) 1985, 1994, Trustees of Columbia University in the City of New
  9.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  10.   sold for profit as a software product itself, nor may it be included in or
  11.   distributed with commercial products or otherwise distributed by commercial
  12.   concerns to their clients or customers without written permission of the
  13.   Office of Kermit Development and Distribution, Columbia University.  This
  14.   copyright notice must not be removed, altered, or obscured.
  15. */
  16.  
  17. /*
  18.    Currently supported network services:
  19.  
  20.    - DECnet (PATHWORKS) LAT (support resides in this module)
  21.    - TCP/IP Telnet (for which this module acts as a front end to ckcnet.c)
  22.    - Named pipes  [Jeffrey Altman <p00118@psilink.com>]
  23.    - NETBIOS      [Jeffrey Altman <p00118@psilink.com>]
  24. */
  25. #include "ckcdeb.h"
  26. #include "ckcker.h"
  27. #include "ckuusr.h"
  28. #include "ckcasc.h"
  29.  
  30. #define EXTERN
  31. #include "ckcnet.h"  /* include ckonet.h and this includes ckotcp.h */
  32.  
  33. #include <io.h>
  34. #include <fcntl.h>
  35. #include <string.h>
  36.  
  37. extern int ttnproto, tt_type;
  38. extern char *tn_term;
  39. char tcpname[512];            /* For SHOW NET */
  40.  
  41. #ifndef NETCONN
  42. /*
  43.   Network support not defined.
  44.   Dummy functions here in case #ifdef's forgotten elsewhere.
  45. */
  46. int                    /* Open network connection */
  47. os2_netopen(name, lcl, nett) char *name; int *lcl, nett; {
  48.     return(-1);
  49. }
  50. int                    /* Close network connection */
  51. os2_netclos() {
  52.     return(-1);
  53. }
  54. int                    /* Check network input buffer */
  55. os2_nettchk() {
  56.     return(-1);
  57. }
  58. int                    /* Flush network input buffer */
  59. os2_netflui() {
  60.     return(-1);
  61. }
  62. int                    /* Send network BREAK */
  63. os2_netbreak() {
  64.     return(-1);
  65. }
  66. int                    /* Input character from network */
  67. os2_netinc(timo) int timo; {
  68. }
  69. int                    /* Output character to network */
  70. os2_nettoc(c) int c; {
  71.     return(-1);
  72. }
  73. int
  74. os2_nettol(s,n) char *s; int n; {
  75.     return(-1);
  76. }
  77.  
  78. #else /* NETCONN is defined (rest of this module...) */
  79.  
  80. #ifndef __32BIT__
  81. #define far _far
  82. #define near _near
  83. #define pascal _pascal
  84. #endif
  85.  
  86. #ifdef NPIPE
  87. #include <time.h>
  88. #define  INCL_DOSNMPIPES
  89. extern char pipename[PIPENAML+1];
  90. #endif /* NPIPE */
  91.  
  92. #define    INCL_NOPM
  93. #define    INCL_DOSPROCESS
  94. #define    INCL_DOSMODULEMGR
  95. #define  INCL_DOSSEMAPHORES
  96. #define  INCL_ERRORS
  97. #include <os2.h>
  98. #undef COMMENT
  99.  
  100. int tcp_avail = 0;
  101. int dnet_avail = 0;
  102. USHORT netbiosAvail = 0;
  103.  
  104. #ifdef DECNET
  105. #ifdef __32BIT__
  106. #pragma seg16(lcb)
  107. #pragma seg16(latinfo)
  108. #pragma seg16(inbuf)
  109. #else /* __32BIT__ */
  110. #define _Seg16
  111. #define APIENTRY16 APIENTRY
  112. #define APIRET16 USHORT
  113. #endif /* __32BIT__ */
  114. #include "ckolat.h"
  115. static APIRET16 (* APIENTRY16 LATENTRY)(struct lat_cb * _Seg16) = NULL;
  116. static struct lat_cb lcb;
  117. static struct lat_info latinfo;
  118. #endif /* DECNET */
  119.  
  120. /* N E T I N C - Input Buffer */ 
  121. static unsigned long size = 0, pos = 0;
  122. static unsigned char inbuf[MAXRP+1] ;
  123.  
  124. extern int duplex, debses, seslog, ttyfd, quiet; /* External variables */
  125. extern int nettype;
  126. extern char ttname[] ;
  127. extern char myhost[] ;
  128.  
  129. #ifdef NPIPE
  130.  HPIPE  hPipe = 0 ;
  131.  UCHAR  PipeName[PIPENAML+1]; /* Pipe name */
  132. #endif /* NPIPE */
  133.  
  134. #ifdef CK_NETBIOS 
  135. #include "ckonbi.h"
  136. extern PNCB pWorkNCB ;
  137. extern PNCB pListenNCB ;
  138. extern PNCB pRecvNCB ;
  139. extern PNCB pSendNCB[MAXWS] ;
  140. extern BYTE NetBiosLSN  ;
  141. extern HEV  hevNetBiosLSN ;
  142. extern UCHAR  NetBiosRemote[NETBIOS_NAME_LEN+1] ;
  143. extern UCHAR  NetBiosName[NETBIOS_NAME_LEN+1] ;
  144. extern UCHAR NetBiosAdapter ;
  145. extern TID ListenThreadID ;
  146. extern BYTE NetBiosRecvBuf[MAXRP] ;
  147. extern BYTE * NetBiosSendBuf[MAXWS] ;
  148. extern USHORT MaxCmds,MaxSess,MaxNames ;
  149. void NetbiosListenThread(void * pArgList);
  150. #endif /* CK_NETBIOS */
  151.  
  152.  
  153. /*  N E T O P E N  --  Open a network connection.  */
  154. /*  Returns 0 on success, -1 on failure.  */
  155.  
  156. /*
  157.   Calling conventions same as ttopen(), except third argument is network
  158.   type rather than modem type.  Designed to be called from within ttopen.
  159. */
  160. int
  161. os2_netopen(name, lcl, nett) char *name; int *lcl, nett; {
  162.  
  163. #ifdef NPIPE
  164.    ULONG   OpenMode;    
  165.    ULONG   PipeMode;
  166.    ULONG   OutBufSize;
  167.    ULONG   InBufSize;
  168.    ULONG   TimeOut;
  169.  
  170.    ULONG   ActionTaken ;
  171.    ULONG   OpenFlag ;
  172.  
  173.    ULONG   BytesRead ;
  174.    AVAILDATA AvailData ;
  175.    ULONG   PipeState ;
  176. #endif /* NPIPE */
  177.  
  178.    int rc = -1;
  179.  
  180. #ifdef CK_NETBIOS
  181.    if ( nettype == NET_BIOS ) {
  182.       ULONG PostCount ;
  183.       UCHAR RemoteName[NETBIOS_NAME_LEN+1] = "                \0" ;
  184.  
  185.       if ( !netbiosAvail )
  186.          return -1 ;
  187.  
  188.       strncpy( RemoteName, name, strlen(name) ) ;
  189.       /* strcpy( name, RemoteName ) ; */ /* name will now be 16 characters */
  190.  
  191.        if ( NetBiosLSN > 0        /* Make sure a handle doesn't exist */
  192.             || ttyfd > -1 ) 
  193.          return 0 ;
  194.  
  195.       DosResetEventSem( hevNetBiosLSN, &PostCount ) ;
  196.  
  197.       if ( !strcmp( "*               ", RemoteName ) ) { /* Server Mode */
  198.       if ( pListenNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS)
  199.             return 0 ;
  200.  
  201.       printf("Listening for a NetBios connection\n") ;
  202.       rc = NCBListen( NetbeuiAPI,
  203.              pListenNCB, NetBiosAdapter, NetBiosName, RemoteName,
  204.              NB_RECV_TIMEOUT, NB_SEND_TIMEOUT, FALSE ) ;
  205.       if ( rc )
  206.             return -1 ;
  207.  
  208.       ttyfd = NetBiosLSN = 0 ;
  209.  
  210.       ListenThreadID = _beginthread( &NetbiosListenThread, 0, 16384, 0 );
  211.       if ( ListenThreadID == -1 ) {
  212.           Dos16SemWait( pListenNCB->basic_ncb.ncb_semaphore,
  213.                SEM_INDEFINITE_WAIT ) ;
  214.           switch (pListenNCB->basic_ncb.bncb.ncb_retcode) {
  215.         case NB_COMMAND_SUCCESSFUL:
  216.           ttyfd = NetBiosLSN = pListenNCB->basic_ncb.bncb.ncb_lsn ;
  217.           return 0 ;
  218.           break;
  219.         default:
  220.           return -1 ;
  221.           }
  222.       }
  223.       return 0 ;
  224.       } else {                /* Remote Mode */
  225.           int oldalarm = alarm(0) ;
  226.           printf("Calling \"%s\" via NetBios\n", RemoteName ) ;
  227.           rc = NCBCall( NetbeuiAPI, pWorkNCB, NetBiosAdapter, NetBiosName,
  228.                RemoteName, NB_RECV_TIMEOUT, NB_SEND_TIMEOUT, FALSE ) ;
  229.       rc = Dos16SemWait( pWorkNCB->basic_ncb.ncb_semaphore,
  230.                 SEM_INDEFINITE_WAIT ) ;
  231.       if (rc)
  232.         return -1 ;
  233.  
  234.           switch ( pWorkNCB->basic_ncb.bncb.ncb_retcode ) {
  235.         case NB_COMMAND_SUCCESSFUL:
  236.           strncpy( NetBiosRemote, pWorkNCB->basic_ncb.bncb.ncb_callname,
  237.               NETBIOS_NAME_LEN ) ;
  238.           ttyfd = NetBiosLSN = pWorkNCB->basic_ncb.bncb.ncb_lsn ;
  239.           NCBReceive( NetbeuiAPI, pRecvNCB, NetBiosAdapter, NetBiosLSN,
  240.              NetBiosRecvBuf, sizeof(NetBiosRecvBuf), FALSE ) ;
  241.           Dos16SemClear(pListenNCB->basic_ncb.ncb_semaphore ) ;
  242.           DosPostEventSem( hevNetBiosLSN ) ;
  243.           rc = 0 ;
  244.           break;
  245.         case ERROR_FILE_NOT_FOUND:
  246.         case ERROR_ACCESS_DENIED:
  247.         case ERROR_INVALID_PARAMETER:
  248.         default:
  249.           rc = -1 ;
  250.       }
  251.           alarm(oldalarm) ;
  252.           return rc ;
  253.       }
  254.   }
  255. #endif /* CK_NETBIOS */
  256.    
  257. #ifdef NPIPE
  258.    if ( nettype == NET_PIPE ) {
  259.        if ( hPipe ) {            /* Make sure a pipe isn't open */
  260.        char buffer[64];
  261.        rc = DosPeekNPipe(hPipe, buffer, sizeof(buffer), 
  262.                  &BytesRead, &AvailData, &PipeState);
  263.        switch ( rc ) {
  264.          case NO_ERROR:
  265.                return 0 ;
  266.          case ERROR_BAD_PIPE:
  267.          case ERROR_PIPE_NOT_CONNECTED:
  268.                ttclos(0);
  269.                break;
  270.          default:
  271.                break;
  272.        }
  273.        }   
  274.        if ( *name == '\0' ) {
  275.        strcpy( PipeName, "\\PIPE\\C-Kermit for OS2" ) ;
  276.        } else {
  277.        strcpy( PipeName, name ) ;
  278.        }
  279.  
  280.        if ( PipeName[0] == '\\' && PipeName[1] == '\\' ) {
  281.        /* Client Mode */
  282.        OpenFlag = OPEN_ACTION_OPEN_IF_EXISTS ;
  283.        OpenMode = OPEN_FLAGS_WRITE_THROUGH |
  284.                   OPEN_FLAGS_FAIL_ON_ERROR |
  285.                     OPEN_FLAGS_RANDOM |
  286.                    OPEN_SHARE_DENYNONE |
  287.                    OPEN_ACCESS_READWRITE ;
  288.  
  289.        if (PipeName[2] == '.' && PipeName[3] == '\\') { /* Internal use. */
  290.            int i, n = strlen(PipeName);
  291.            for (i = 3; i <= n; i++)
  292.          PipeName[i-3] = PipeName[i];
  293.        }
  294.  
  295.        rc = DosOpen( PipeName, &hPipe, &ActionTaken, 0, 0,
  296.             OpenFlag, OpenMode, 0 ) ;
  297.        switch (rc) {
  298.          case NO_ERROR:
  299.                ttyfd = hPipe ;
  300.                DosSetNPHState( hPipe, NP_NOWAIT | NP_READMODE_BYTE ) ;
  301.            printf(
  302.              "\nNamed Pipe %s open.\nConnection to server complete.\n",
  303.               PipeName
  304.               );
  305.                break;
  306.          case ERROR_BAD_NETPATH:
  307.                printf("\nInvalid Server specified in Pipe Name: %s\n",
  308.               PipeName ) ;
  309.                break;
  310.          case ERROR_PATH_NOT_FOUND:
  311.          case ERROR_FILE_NOT_FOUND:
  312.                printf("\nNonexistent Named Pipe: %s\n", PipeName ) ;
  313.                break;
  314.          case ERROR_PIPE_BUSY:
  315.                printf("\nNamed Pipe Already in Use: %s\n", PipeName ) ;
  316.                break;
  317.          default:
  318.                debug( F101, "DosOpen error: return code","",rc) ;
  319.                printf( "\nDosOpen error: return code = %ld\n",rc ) ;
  320.        }
  321.        } else {                /* Server Mode */
  322.        OpenMode = NP_ACCESS_DUPLEX | NP_INHERIT | NP_NOWRITEBEHIND |
  323.          NP_TYPE_BYTE | NP_READMODE_BYTE ;
  324.        PipeMode = NP_NOWAIT | 0x01;
  325.        OutBufSize = MAXSP + 4 ;
  326.        InBufSize = MAXRP + 4 ;
  327.        TimeOut = 10000;
  328.        rc = DosCreateNPipe( PipeName, &hPipe, OpenMode,
  329.                    PipeMode, OutBufSize, InBufSize, TimeOut);
  330.        switch (rc) {
  331.          case NO_ERROR:
  332.                ttyfd = hPipe ;
  333.                rc = DosConnectNPipe( hPipe ) ;
  334.                if (rc == NO_ERROR || rc == ERROR_PIPE_NOT_CONNECTED) {
  335.      printf("\nNamed Pipe %s created.\nWaiting for client connection ...\n\n",
  336.                   PipeName ) ;
  337.                   rc = 0 ;
  338.            } else {
  339.            debug( F101,"DosConnectNPipe error: return code","",rc) ;
  340.            printf("\nDosConnectNPipe error: return code = %ld\n", rc);
  341.            }
  342.                break;
  343.          case ERROR_PATH_NOT_FOUND:
  344.                printf("\nInvalid Pipe Name: %s\n", PipeName ) ;
  345.                break;
  346.          case ERROR_PIPE_BUSY:
  347.                printf("\nNamed Pipe Already in Use: %s\n", PipeName ) ;
  348.                break;
  349.          default:
  350.                debug( F101,"DosCreateNPipe error: return code","",rc) ;
  351.                printf("\nDosCreateNPipe error: return code = %ld\n", rc);
  352.        }
  353.        }
  354.        return ( rc ? -1 : 0 ) ;
  355.    }
  356. #endif /* NPIPE */
  357.    
  358. #ifdef TCPSOCKET
  359.    if ( nettype == NET_TCPB ) {
  360.       if (!tcp_avail)
  361.          return -1 ; 
  362.       rc = netopen(name, lcl, nett);
  363. #ifdef COMMENT
  364.        if ( rc > -1) rc = tn_ini();
  365. #endif /* COMMENT */
  366.        return(rc);
  367.    }
  368. #endif /* TCPSOCKET */
  369.  
  370. #ifdef DECNET
  371.    if ( nettype == NET_DEC ) {
  372.        if ( LATENTRY == NULL )
  373.      return -1;
  374.  
  375.        ttnproto = NP_LAT;
  376.  
  377.        printf("Trying %s ... ", name);
  378.  
  379.        memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  380.        lcb.LatFunction = START_SESSION;
  381.        lcb.BufferSize = strlen(name);
  382.        lcb.BufferPtr = (void * _Seg16) name;
  383.  
  384.        LATENTRY(&lcb);
  385.  
  386.        ttyfd = lcb.SessionHandle;
  387.        printf(lcb.LatStatus ? "failed.\n" : "OK.\n");
  388.  
  389.        rc = (lcb.LatStatus == 0) ? 0 : -1;
  390.    }
  391. #endif /* DECNET */
  392.  
  393.    return rc;
  394. }
  395.  
  396. /*  N E T C L O S  --  Close current network connection.  */
  397.  
  398. int
  399. os2_netclos() {
  400.     int rc = 0;
  401.  
  402.     if (ttyfd < 0)            /* Was open? */
  403.       return(rc);            /* Wasn't. */
  404.  
  405. #ifdef CK_NETBIOS
  406.    if ( nettype == NET_BIOS ) {
  407.       ULONG PostCount ;
  408.     if ( NetBiosLSN >= 0 ) {
  409.       NCB CleanupNCB ;
  410.       int i ;
  411.  
  412.       if ( pWorkNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  413.          NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pWorkNCB ) ;
  414.       if ( pListenNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  415.          {
  416.          NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pListenNCB ) ;
  417.          DosWaitEventSem( hevNetBiosLSN, SEM_INDEFINITE_WAIT ) ;
  418.          }
  419.       if ( pRecvNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  420.          NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pRecvNCB ) ;
  421.      
  422.       for ( i=0 ; i<MAXWS ; i++ ) {
  423.       if ( pSendNCB[i]->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  424.          NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pSendNCB[i] ) ;
  425.          }
  426.  
  427.       NCBHangup( NetbeuiAPI, pWorkNCB, NetBiosAdapter, NetBiosLSN ) ;
  428.       }
  429.    NetBiosLSN = 0 ;
  430.    strncpy( NetBiosRemote, "               ", NETBIOS_NAME_LEN ) ;
  431.    DosResetEventSem( hevNetBiosLSN, &PostCount ) ;
  432.     ttyfd = -1 ;
  433.    Dos16SemSet( pListenNCB->basic_ncb.ncb_semaphore ) ; 
  434.     }
  435. #endif /* CK_NETBIOS */
  436.  
  437. #ifdef NPIPE
  438.     if ( nettype == NET_PIPE ) {
  439.     if ( hPipe ) {
  440.         rc = DosClose( hPipe ) ;
  441.         hPipe = 0 ;
  442.         ttyfd = -1 ;
  443.     }
  444.     return rc ;
  445.     }
  446. #endif /* NPIPE */
  447.  
  448.   
  449. #ifdef TCPSOCKET
  450.     if ( nettype == NET_TCPB )
  451.       {
  452.       if (!tcp_avail)
  453.          return -1 ; 
  454.       return netclos();
  455.       }
  456. #endif /* TCPSOCKET */
  457.  
  458. #ifdef DECNET
  459.    if ( nettype == NET_DEC ) {
  460.        if (ttyfd > -1) {
  461.        memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  462.           lcb.LatFunction = STOP_SESSION;
  463.        lcb.SessionHandle = ttyfd;
  464.        LATENTRY(&lcb);
  465.        rc = (lcb.LatStatus == 0) ? 0 : -1;
  466.        }
  467.    }
  468. #endif /* DECNET */
  469.  
  470.    ttyfd = -1;                /* Mark it as closed. */
  471.  
  472.    return(rc);
  473. }
  474.  
  475. /*  N E T T C H K  --  Check if network up, and how many bytes can be read */
  476. /*
  477.   Returns number of bytes waiting, or -1 if connection has been dropped.
  478. */
  479. int                    /* Check how many bytes are ready */
  480. os2_nettchk() {                /* for reading from network */
  481. #ifdef NPIPE
  482.     int rc = 0 ;
  483.     ULONG bytesread ;
  484.     AVAILDATA availdata ;
  485.     ULONG PipeState ;
  486. #endif /* NPIPE */
  487.  
  488. #ifdef CK_NETBIOS
  489.     if ( nettype == NET_BIOS ) {
  490.       if ( NetBiosLSN > 0 )
  491.       {
  492.       SESSIONINFO statusinfo ;
  493.  
  494.       if ( pos < size )
  495.          return size - pos ;
  496.  
  497. #ifndef NONBTCHK
  498.       /* This is for testing on a machine with LAN Distance installed
  499.          when we want to run two CKs on the same machine without connecting
  500.          to a remote network.  NCBSessionStatus fails to return under
  501.          these conditions.  
  502.       */
  503.       NCBSessionStatus( NetbeuiAPI, pWorkNCB, NetBiosAdapter, NetBiosName,
  504.             &statusinfo, sizeof(SESSIONINFO), TRUE ) ;
  505.          if ( pWorkNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_SUCCESSFUL &&
  506.               statusinfo.session_state > NB_SESSION_STATE_SESSION_ACTIVE )
  507. #endif /* NONBTCHK */
  508.             return 0 ;
  509.       }
  510.       return -1 ;
  511.     }
  512. #endif /* CK_NETBIOS */
  513.  
  514. #ifdef NPIPE
  515.     if ( nettype == NET_PIPE ) {
  516.         char buffer[64];
  517.  
  518.       if ( pos < size )
  519.          return size - pos ;
  520.  
  521.       if ( !(rc = DosPeekNPipe(hPipe, buffer, sizeof(buffer),
  522.                  &bytesread, &availdata, &PipeState)) ) {
  523.         switch ( PipeState ) {
  524.           case NP_STATE_DISCONNECTED:
  525.           case NP_STATE_CLOSING:
  526.         if ( PipeName[0] != PipeName[1] ) {
  527.             /* Server Mode */
  528.             DosDisConnectNPipe( hPipe ) ;
  529.             DosConnectNPipe( hPipe ) ;
  530.         } else {
  531.             /* Client Mode */
  532.             ttclos(0) ;
  533.         }
  534.         return -2 ;
  535.         break;
  536.        case NP_STATE_LISTENING:
  537.         return 0 ;
  538.         break;
  539.       case NP_STATE_CONNECTED:
  540.           return availdata.cbpipe ;
  541.           break;
  542.        default:
  543.           return -1 ;
  544.         } /* switch */
  545.     } else
  546.       return (rc > 0 ? -rc : rc) ;
  547.     }
  548. #endif /* NPIPE */
  549.  
  550. #ifdef TCPSOCKET
  551.     if ( nettype == NET_TCPB )
  552.       {
  553.       if (!tcp_avail)
  554.          return -1 ; 
  555.       return nettchk();
  556.       }
  557. #endif /* TCPSOCKET */
  558.  
  559. #ifdef DECNET
  560.    if ( nettype == NET_DEC ) {
  561.        if ( pos < size ) {
  562.        return size - pos ;
  563.        } else {
  564.        memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  565.        lcb.LatFunction = GET_STATUS ;
  566.        lcb.SessionHandle = ttyfd;
  567.        LATENTRY(&lcb);
  568.        debug(F101,"os2_nettchk (DECNET) lcb.SessionStatus",
  569.          "",lcb.SessionStatus) ;
  570.        debug(F101,"os2_nettchk (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  571.        return ( lcb.LatStatus & LS_RxData ) ? 1 : 0 ;
  572.        }
  573.    }
  574. #endif /* DECNET */
  575.  
  576.     return(0);
  577. }
  578.  
  579. /*  N E T T I N C --  Input character from network */
  580.  
  581. int
  582. os2_netinc(timo) int timo; {
  583.  
  584.     int chr = -1;
  585.     int rc = 0 ;
  586.  
  587.     time_t timer, timenow ;
  588.  
  589. #ifdef CK_NETBIOS
  590.    if ( nettype == NET_BIOS ) {
  591.       if ( NetBiosLSN == -1 )
  592.          return -1 ;
  593.       else if ( NetBiosLSN == 0 )
  594.          {
  595.          if ( pListenNCB->basic_ncb.bncb.ncb_retcode != NB_COMMAND_IN_PROCESS )
  596.          {
  597.            return -1 ;
  598.          }  
  599.          else {
  600.  
  601.             rc = DosWaitEventSem( hevNetBiosLSN,
  602.                timo > 0 ? timo * 1000 :
  603.                timo < -1 ? 1000 : SEM_INDEFINITE_WAIT ) ;
  604.             if (rc) return -1 ;
  605.          } 
  606.        }
  607.  
  608.       if ( pos < size ) {
  609.           chr = inbuf[pos++];
  610.           }
  611.       else {
  612.          rc = 0 ;
  613.          if ( ( pRecvNCB->basic_ncb.bncb.ncb_retcode) == NB_COMMAND_IN_PROCESS)
  614.             {
  615.             rc = Dos16SemWait( pRecvNCB->basic_ncb.ncb_semaphore,
  616.                timo > 0 ? timo * 1000 :
  617.                timo < -1 ? 1000 : SEM_INDEFINITE_WAIT ) ;
  618.             }
  619.  
  620.             if ( rc )
  621.                {
  622.                return -1 ;
  623.                }
  624.  
  625.          switch ( pRecvNCB->basic_ncb.bncb.ncb_retcode ) {
  626.             case NB_COMMAND_SUCCESSFUL:
  627.                if ( (size = pRecvNCB->basic_ncb.bncb.ncb_length) == 0 )
  628.                   return -1 ;
  629.                memcpy( inbuf, NetBiosRecvBuf, size ) ;
  630.                rc = NCBReceive( NetbeuiAPI, pRecvNCB, NetBiosAdapter,
  631.                   NetBiosLSN, NetBiosRecvBuf, sizeof(NetBiosRecvBuf), FALSE );
  632.                break;
  633.             case NB_SESSION_CLOSED:
  634.             case NB_SESSION_ENDED_ABNORMALLY:
  635.                ttclos(0) ;
  636.                if ( ttname[0] == '*' )
  637.                   {
  638.                   os2_netopen( "*",0,0 ) ;
  639.                   return -1 ;
  640.                   }
  641.                else
  642.                   return -3 ;
  643.                break;
  644.             case NB_OS_ERROR_DETECTED:
  645.                ttclos(0) ;
  646.                return -3 ;
  647.                break;
  648.             case NB_COMMAND_IN_PROCESS:
  649.             case NB_COMMAND_TIME_OUT:
  650.             case NB_COMMAND_CANCELLED:
  651.             default:
  652.                return -1 ;
  653.             }
  654.           pos = 0 ;
  655.           chr = inbuf[pos++] ;
  656.            }
  657.       return chr ;
  658.       }
  659. #endif /* CK_NETBIOS */
  660.  
  661. #ifdef NPIPE
  662.    if ( nettype == NET_PIPE ) {
  663.        if ( timo < -1 )
  664.      timo = 1 ;            /* Can't set timeout less than 1 sec */
  665.        if ( pos < size ) {
  666.        chr = inbuf[pos++];
  667.        } else {
  668.        if ( !timo ) {
  669.            while ( !os2_nettchk() )
  670.          DosSleep(100) ;
  671.        } else {
  672.            timer = 0 ;
  673.            while (1) {
  674.            if ( os2_nettchk() ) 
  675.              break;
  676.            if ( timo > 0 ) {
  677.                if ( !timer )
  678.              timer = time(0) ;
  679.                timenow = time(0) ;
  680.                if ( timenow - timer > timo )
  681.              return -1 ;
  682.            }
  683.            DosSleep(100) ;
  684.            }
  685.        }
  686.        rc = DosRead( hPipe, &inbuf, sizeof(inbuf), &size ) ;
  687.        switch ( rc ) {
  688.          case NO_ERROR:
  689.            if ( !size )
  690.          return -1 ;
  691.            break;
  692.          case ERROR_BROKEN_PIPE:
  693.            if ( PipeName[0] != PipeName[1] ) {
  694.            /* Server Mode */
  695.            DosDisConnectNPipe( hPipe ) ;
  696.            DosConnectNPipe( hPipe ) ;
  697.            } else {
  698.            /* Client Mode */
  699.            ttclos(0) ;
  700.            }
  701.            return -2 ;
  702.            break;
  703.          default:
  704.            return -1 ;
  705.        }
  706.        pos = 0 ;
  707.        chr = inbuf[pos++] ;
  708.        }
  709.        return chr ;
  710.    }
  711. #endif /* NPIPE */
  712.  
  713. #ifdef TCPSOCKET
  714.     if ( nettype == NET_TCPB ) {
  715.     if (!tcp_avail)
  716.       return -1 ; 
  717.     if ( (chr = netinc(timo)) != -1 )
  718.       return chr;
  719.     else
  720.       return (nettchk() == -1) ? -2 : -1;
  721.     }
  722. #endif /* TCPSOCKET */
  723.     
  724. #ifdef DECNET
  725.     if ( nettype == NET_DEC ) {
  726.     if ( pos < size )
  727.       return inbuf[pos++];
  728.     memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  729.     memset( inbuf, 0, sizeof(inbuf) ) ;
  730.     lcb.LatFunction = GET_CHAR_BLK;
  731.     lcb.SessionHandle = ttyfd;
  732.     lcb.BufferSize = sizeof(inbuf);
  733.     lcb.BufferPtr = (void * _Seg16) inbuf;
  734.  
  735.     if ( timo < -1 )
  736.       lcb.WaitTime = 10L * -timo ;
  737.     else if ( timo > 0 )
  738.       lcb.WaitTime = 1000L * timo ;
  739.     else
  740.       lcb.WaitTime = LAT_INDEFINITE_WAIT ;
  741.     
  742.     LATENTRY(&lcb);
  743.     debug(F101,"os2_netinc (DECNET) lcb.SessionStatus","",
  744.           lcb.SessionStatus) ;
  745.     debug(F101,"os2_netinc (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  746.     if ( (lcb.SessionStatus & 0xFF) == SS_Stopped )
  747.       return -2;
  748.  
  749.     if ( lcb.LatStatus ) {
  750.         if ( lcb.LatStatus & LS_InvalidSize )
  751.           debug(F101,"os2_netinc (DECNET) LS_InvalidSize","",
  752.             lcb.BufferSize) ;
  753.         return -1 ;
  754.         }
  755.  
  756.     pos = 0;
  757.     size = lcb.BufferSize;
  758.     debug(F111,"os2_netinc (DECNET) lcb.BufferSize",inbuf,lcb.BufferSize) ;
  759.  
  760.     chr = inbuf[pos++];
  761.     }
  762. #endif /* DECNET */
  763.  
  764.     return chr;
  765. }
  766.  
  767. #ifdef CK_NETBIOS
  768. static int NextSendNCB = 0 ;
  769. #endif /* CK_NETBIOS */
  770.  
  771. /*  N E T T O C  --   Output character to network */
  772. /*
  773.   Call with character to be transmitted.
  774.   Returns 0 if transmission was successful, or
  775.   -1 upon i/o error, or -2 if called improperly.
  776. */
  777. int
  778. os2_nettoc(c) int c; {
  779.     
  780. #ifdef DECNET
  781.     int i;
  782. #endif /* DECNET */
  783.     int rc = -1;
  784.     ULONG bytesWritten ;
  785.  
  786. #ifdef CK_NETBIOS
  787.     if ( nettype == NET_BIOS ) {
  788.     int i = 0 ;
  789.     int SendNCB ;
  790.     UCHAR chr = c ;
  791.     if ( NetBiosLSN == -1 )
  792.       return -1 ;
  793.     else if ( NetBiosLSN == 0 ) {
  794. #ifdef COMMENT
  795. /*
  796.   This code enables us to issue a blocking send prior to the
  797.   establishment of a connection.  The problem with this is that
  798.   when a connection terminates and we are in Kermit Server mode,
  799.   the Kermit Server will send a NAK in response to the timeout it
  800.   received when the connection was lost.  This NAK will be the
  801.   first packet received by the next Client to complete a connection,
  802.   and all packets in the exchange will be out of sequence.
  803.  
  804.   Therefore, we don't allow packets to be issued prior to the
  805.   establishment of a real connection.
  806. */
  807.         if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  808.         NB_COMMAND_IN_PROCESS ) {
  809.         return -1 ;
  810.         } else {
  811.         rc = DosWaitEventSem( hevNetBiosLSN,
  812.                      SEM_INDEFINITE_WAIT ) ;
  813.         if (rc) return -1 ;
  814.         }
  815. #else
  816.         if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  817.         NB_COMMAND_SUCCESSFUL )
  818.           return -1 ;
  819. #endif /* COMMENT */
  820.     }
  821.     for ( SendNCB = 0 ; SendNCB < MaxCmds ; SendNCB++ ) {
  822.         if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  823.         != NB_COMMAND_IN_PROCESS )
  824.           break;
  825.     }
  826.     if ( SendNCB == MaxCmds )
  827.       return -1 ;
  828.     if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  829.         == NB_COMMAND_IN_PROCESS) {
  830.         NCB CancelNCB ;
  831.         rc = NCBCancel( NetbeuiAPI, &CancelNCB, NetBiosAdapter,
  832.                pSendNCB[SendNCB] ) ;
  833.         Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  834.              SEM_INDEFINITE_WAIT ) ;
  835.     }
  836.     memcpy( NetBiosSendBuf[SendNCB], &chr, sizeof(chr) ) ;
  837.     rc = NCBSend( NetbeuiAPI, pSendNCB[SendNCB], NetBiosAdapter,
  838.             NetBiosLSN, NetBiosSendBuf[SendNCB], sizeof(chr), FALSE );
  839. #ifdef COMMENT
  840.     /* Let's try a nonblocking Send */
  841.     Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  842.              SEM_INDEFINITE_WAIT ) ;
  843. #endif /* COMMENT */
  844.  
  845.     switch ( pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode ) {
  846.       case NB_COMMAND_SUCCESSFUL:
  847.       case NB_COMMAND_IN_PROCESS:
  848.             return 0 ;
  849.             break;
  850.       case NB_SESSION_CLOSED:
  851.       case NB_SESSION_ENDED_ABNORMALLY:
  852.             ttclos(0) ;
  853.             if ( ttname[0] == '*' ) {
  854.         os2_netopen( "*",0,0 ) ;
  855.         return -1 ;
  856.         } else
  857.           return -2 ;
  858.             break;
  859.       case NB_OS_ERROR_DETECTED:
  860.             ttclos(0) ;
  861.             return -3 ;
  862.             break;
  863.       case NB_COMMAND_TIME_OUT:
  864.       case NB_COMMAND_CANCELLED:
  865.       default:
  866.             return -1 ;
  867.     }
  868.     }
  869. #endif /* CK_NETBIOS */
  870.  
  871. #ifdef NPIPE
  872.     if ( nettype == NET_PIPE ) {
  873.     UCHAR  chr = c ;
  874.     rc = DosWrite( hPipe, &chr, sizeof(chr), &bytesWritten ) ;
  875.     if ( rc )
  876.       return -1 ;
  877.     else
  878.       return 0 ;
  879.     }
  880. #endif /* NPIPE */
  881.  
  882. #ifdef TCPSOCKET
  883.     if ( nettype == NET_TCPB ) {
  884.     if (!tcp_avail)
  885.       return -1 ; 
  886.     return nettoc((char) c);
  887.     }
  888. #endif /* TCPSOCKET */
  889.     
  890. #ifdef DECNET
  891.     if ( nettype == NET_DEC ) {
  892.     debug(F100,"os2_nettoc (DECNET) begin send char","",0);
  893.     pos = size ;
  894.  
  895.     /* Send the character */
  896.     memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  897.     lcb.LatFunction = SEND_CHAR;
  898.     lcb.SessionHandle = ttyfd;
  899.     lcb.CharByte = c;
  900.  
  901.     LATENTRY(&lcb);
  902.     debug(F101,"os2_nettoc (DECNET) lcb.SessionStatus","",
  903.           lcb.SessionStatus) ;
  904.     debug(F101,"os2_nettoc (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  905.  
  906.     for (i = 0; i < 10000 && ( lcb.LatStatus & LS_CharNotSent ); i++) {
  907.         DosSleep(1);            /* give up rest of current timeslice */
  908.         LATENTRY(&lcb) ;
  909.         debug(F100,"os2_nettoc (DECNET) repeat char send","",0);
  910.         debug(F101,"os2_nettoc (DECNET) lcb.SessionStatus",
  911.           "",lcb.SessionStatus) ;
  912.         debug(F101,"os2_nettoc (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  913.     }
  914.  
  915.     debug(F100,"os2_nettoc (DECNET) end send char","",0);
  916.  
  917.     rc = (lcb.LatStatus == LS_NoError) ? 0 : -1;
  918.     }
  919. #endif /* DECNET */
  920.  
  921.     return rc;
  922. }
  923.  
  924. /*  N E T T O L  --  Output a string of bytes to the network  */
  925. /*
  926.   Call with s = pointer to string, n = length.
  927.   Returns number of bytes actuall written on success, or
  928.   -1 on i/o error, -2 if called improperly.
  929. */
  930. int
  931. os2_nettol(s,n) char *s; int n; {
  932.  
  933.     int rc;
  934.  
  935. #ifdef NPIPE
  936.     ULONG bytesWritten ;
  937. #endif /* NPIPE */
  938.  
  939. #ifdef CK_NETBIOS
  940.     int SendNCB ;
  941.  
  942.     if ( nettype == NET_BIOS ) {
  943.     if ( NetBiosLSN == -1 )
  944.       return -3 ;
  945.     else if ( NetBiosLSN == 0 ) {
  946. #ifdef COMMENT
  947. /*
  948.   This code enables us to issue a blocking send prior to the
  949.   establishment of a connection.  The problem with this is that
  950.   when a connection terminates and we are in Kermit Server mode,
  951.   the Kermit Server will send a NAK in response to the timeout it
  952.   received when the connection was lost.  This NAK will be the
  953.   first packet received by the next Client to complete a connection,
  954.   and all packets in the exchange will be out of sequence.
  955.  
  956.   Therefore, we don't allow packets to be issued prior to the
  957.   establishment of a real connection. 
  958. */
  959.         if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  960.         NB_COMMAND_IN_PROCESS ) {
  961.         return -1 ;
  962.         } else {
  963.         rc = DosWaitEventSem( hevNetBiosLSN,
  964.                      SEM_INDEFINITE_WAIT ) ;
  965.         if (rc) return -1 ;
  966.         }
  967. #else
  968.         if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  969.         NB_COMMAND_SUCCESSFUL )
  970.           return -1 ;
  971. #endif /* COMMENT */
  972.     }
  973.     for ( SendNCB = 0 ; SendNCB < MaxCmds ; SendNCB++ ) {
  974.         if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  975.         != NB_COMMAND_IN_PROCESS )
  976.           break;
  977.     }
  978.     if ( SendNCB == MaxCmds )
  979.       return -1 ;
  980.  
  981.     if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  982.         == NB_COMMAND_IN_PROCESS) {
  983.             NCB CancelNCB ;
  984.             rc = NCBCancel( NetbeuiAPI, &CancelNCB, NetBiosAdapter,
  985.                pSendNCB[SendNCB] );
  986.             Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  987.              SEM_INDEFINITE_WAIT ) ;
  988.     }
  989.     memcpy( NetBiosSendBuf[SendNCB], s, n ) ;
  990.     rc = NCBSend( NetbeuiAPI, pSendNCB[SendNCB], NetBiosAdapter,
  991.          NetBiosLSN, NetBiosSendBuf[SendNCB], n, FALSE ) ;
  992. #ifdef COMMENT
  993.     /* Lets try a non blocking Send */
  994.     Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  995.              SEM_INDEFINITE_WAIT ) ;
  996. #endif /* COMMENT */
  997.  
  998.     debug(F101,"NETTOL: SendNCB","",SendNCB ) ;
  999.     debug(F101,"NETTOL: NCB_retcode","",
  1000.           pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode ) ;
  1001.  
  1002.     switch ( pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode ) {
  1003.       case NB_COMMAND_SUCCESSFUL:
  1004.       case NB_COMMAND_IN_PROCESS:
  1005.             return pSendNCB[SendNCB]->basic_ncb.bncb.ncb_length ;
  1006.             break;
  1007.       case NB_SESSION_CLOSED:
  1008.       case NB_SESSION_ENDED_ABNORMALLY:
  1009.             ttclos(0) ;
  1010.             if ( ttname[0] == '*' ) {
  1011.         os2_netopen( "*",0,0 ) ;
  1012.         return -1 ;
  1013.         } else
  1014.           return -2 ;
  1015.             break;
  1016.       case NB_OS_ERROR_DETECTED:
  1017.             ttclos(0) ;
  1018.             return -3 ;
  1019.             break;
  1020.       case NB_MAX_CMNDS_EXCEEDED:
  1021.       case NB_COMMAND_TIME_OUT:
  1022.       case NB_COMMAND_CANCELLED:
  1023.       default:
  1024.             return -1 ;
  1025.     }
  1026.     }
  1027. #endif /* CK_NETBIOS */
  1028.  
  1029. #ifdef NPIPE
  1030.     if ( nettype == NET_PIPE ) {
  1031.     rc = DosWrite( hPipe, s, n, &bytesWritten ) ;
  1032.     return ( rc ? -1 : bytesWritten ) ;
  1033.     }
  1034. #endif /* NPIPE */
  1035.  
  1036. #ifdef TCPSOCKET
  1037.     if ( nettype == NET_TCPB ) {
  1038.     if (!tcp_avail)
  1039.       return -1 ; 
  1040.     return nettol(s, n);
  1041.     }
  1042. #endif /* TCPSOCKET */
  1043.    
  1044. #ifdef DECNET
  1045.     if ( nettype == NET_DEC ) {
  1046.     for ( rc = 0; rc < n; rc++, s++ )
  1047.       if ( os2_nettoc(*s) )
  1048.         break;
  1049.     }
  1050. #endif /* DECNET */
  1051.     return(rc);
  1052. }
  1053.  
  1054. /*  N E T F L U I  --  Flush network input buffer  */
  1055.  
  1056. int
  1057. os2_netflui() {
  1058.  
  1059. #ifdef CK_NETBIOS
  1060.     if ( nettype == NET_BIOS ) {
  1061.       pos = size ;
  1062.       return 0 ;
  1063.     }
  1064. #endif /* CK_NETBIOS */
  1065.  
  1066. #ifdef NPIPE
  1067.     if ( nettype == NET_PIPE )
  1068.       pos = size ;
  1069.       return 0 ;  
  1070. #endif /* NPIPE */
  1071.  
  1072. #ifdef TCPSOCKET
  1073.     if ( nettype == NET_TCPB )
  1074.       {
  1075.       if (!tcp_avail)
  1076.          return 0 ; 
  1077.       return netflui();
  1078.       }
  1079. #endif /* TCPSOCKET */
  1080.  
  1081. #ifdef DECNET
  1082.     if ( nettype == NET_DEC ) {
  1083.     pos = size ;
  1084.     return (0) ;
  1085.     }
  1086. #endif /* DECNET */
  1087.  
  1088.     return(0);
  1089. }
  1090.  
  1091. /* Send network BREAK */
  1092. /*
  1093.   Returns -1 on error, 0 if nothing happens, 1 if BREAK sent successfully.
  1094. */
  1095. int
  1096. os2_netbreak() {
  1097.  
  1098.     int rc = -1;
  1099.  
  1100. #ifdef CK_NETBIOS
  1101.     if ( nettype == NET_BIOS ) {
  1102.       return 0 ;
  1103.     }
  1104. #endif /* CK_NETBIOS */
  1105.  
  1106. #ifdef NPIPE
  1107.     if ( nettype == NET_PIPE )
  1108.       return 0 ;  
  1109. #endif /* NPIPE */
  1110.  
  1111. #ifdef TCPSOCKET
  1112.     if ( nettype == NET_TCPB ) {
  1113.     if (!tcp_avail)
  1114.       return -1 ; 
  1115.     return netbreak();
  1116.     }
  1117. #endif /* TCPSOCKET */
  1118.     
  1119. #ifdef DECNET
  1120.     if ( nettype == NET_DEC ) {
  1121.     memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  1122.     lcb.LatFunction = SEND_BREAK;
  1123.     lcb.SessionHandle = ttyfd;
  1124.  
  1125.     LATENTRY(&lcb);
  1126.  
  1127.     rc = (lcb.LatStatus == 0) ? 0 : -1;
  1128.     }
  1129. #endif /* DECNET */
  1130.  
  1131.     return rc;
  1132. }
  1133.  
  1134. /*
  1135.  * what follows is all dynamic link stuff to let the same executable
  1136.  * run on machines with and without networking software
  1137.  */
  1138.  
  1139. #ifdef __32BIT__
  1140. #define GetProc(h, n, e) DosQueryProcAddr(h, 0, n, (PFN *) e)
  1141. #define PREFIX
  1142. #else
  1143. #define GetProc(h, n, e) DosGetProcAddr(h, n, (PFN *) e)
  1144. #define PREFIX "_"
  1145. #endif
  1146.  
  1147. #ifdef TCPSOCKET
  1148. int
  1149. os2_tcpipinit() {
  1150.     char dll[_MAX_PATH], fail[_MAX_PATH];
  1151.     HMODULE library;
  1152.     extern char startupdir[];
  1153.     int rc=1 ;
  1154.     char * CKTCPIPDLL ;
  1155.     char *p, *q;
  1156.  
  1157.     p = q = strdup(startupdir);
  1158.     if (p) {
  1159.     while (*p) {
  1160.         if (*p == '/') *p = '\\';
  1161.         if (islower(*p)) *p = toupper(*p);
  1162.         p++;
  1163.     }
  1164.     p = q;
  1165.     } else p = startupdir;
  1166.  
  1167.     tcp_avail = 0 ;
  1168.  
  1169.     if (deblog) {
  1170.     printf( "  TCP/IP support..." ) ;
  1171.     debug(F100,"TCP/IP support...","",0);
  1172.     }
  1173.     tcpname[0] = NUL;
  1174.  
  1175.     /* User can override DLL search order with an environment variable */
  1176.  
  1177.     CKTCPIPDLL = getenv( "CKTCPIPDLL" ) ;
  1178.     if ( CKTCPIPDLL ) {
  1179.     strcpy(dll, p);
  1180.     strcat(dll, CKTCPIPDLL ); 
  1181.     rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  1182.     if (!rc) {
  1183.         if (deblog) printf( "CKTCPIPDLL=%s loaded...",CKTCPIPDLL) ;
  1184.         sprintf(tcpname,"CKTCPIPDLL=%s",CKTCPIPDLL) ;
  1185.         debug(F111,"CKTCPIPDLL var loaded",CKTCPIPDLL,rc);
  1186.         } else
  1187.         debug(F111,"CKTCPIPDLL file not found",CKTCPIPDLL,rc);
  1188.     } else
  1189.       debug(F100,"CKTCPIPDLL not defined","",0);
  1190.  
  1191. #ifdef __32BIT__
  1192. /*
  1193.   Attempt to load in the following order:
  1194.   1. CKTCPIPDLL environment variable
  1195.   2. IBM 2.0
  1196.   3. FTP 1.3
  1197.   4. IBM 1.2
  1198. */
  1199.     if (rc != 0) {
  1200.     strcpy(dll, p);
  1201.     strcat(dll, "CKO32I20.DLL");
  1202.     rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  1203.     if (!rc) {
  1204.         if (deblog) printf( "32bit IBM 2.0 TCP/IP loaded...") ;
  1205.         sprintf(tcpname,"%s = 32-bit IBM TCP/IP 2.0", dll);
  1206.         debug(F111,"32bit IBM TCP/IP 2.0 loaded",dll,rc);
  1207.     } else
  1208.       debug(F111,"32bit IBM TCP/IP 2.0 load failed",dll,rc);
  1209.     }
  1210.     if (rc != 0) {
  1211.         strcpy(dll, p);
  1212.     strcat(dll, "CKO32F13.DLL");
  1213.     rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  1214.     if (!rc) {
  1215.         if (deblog) printf( "32bit FTP PC/TCP 1.3 loaded...") ;
  1216.         sprintf(tcpname,"%s = 32-bit FTP PC/TCP 1.3", dll);
  1217.         debug(F111,"32bit FTP PC/TCP 1.3 loaded",dll,rc);
  1218.     } else
  1219.       debug(F111,"32bit FTP PC/TCP 1.3 load failed",dll,rc);
  1220.     }
  1221.     if (rc != 0) {
  1222.         strcpy(dll, p);
  1223.     strcat(dll, "CKO32I12.DLL");
  1224.     rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  1225.       if (!rc)
  1226.          {
  1227.          HMODULE tcpiplib ;
  1228.          PFN pfn ;
  1229.          rc = DosLoadModule(fail, sizeof(fail), "TCPIPDLL", &tcpiplib) ;
  1230.          rc = GetProc(tcpiplib,"_bsdselect", &pfn);
  1231.          }
  1232.     if (!rc) {
  1233.         if (deblog)
  1234.           printf( "32bit IBM TCP/IP 1.2 (or compatible) loaded...") ;
  1235.         sprintf(tcpname,"%s = 32-bit IBM TCP/IP 1.2 (or compatible)", dll);
  1236.         debug(F111,"32bit IBM TCP/IP 1.2 (or compatible) loaded",dll,rc);
  1237.     } else
  1238.       debug(F111,
  1239.         "32bit IBM TCP/IP 1.2 (or compatible) load failed",dll,rc);
  1240.     }
  1241. #else
  1242. /*
  1243.   Attempt to load in the following order:
  1244.   1. CKTCPIPDLL environment variable
  1245.   2. FTP 1.3
  1246.   3. IBM 1.2
  1247. */
  1248.     if (rc != 0) {
  1249.         strcpy(dll, p);
  1250.     strcat(dll, "CKO16F13.DLL");
  1251.     rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  1252.     if (!rc) {
  1253.         if (deblog) printf( "16bit FTP PC/TCP 1.3 loaded...") ;
  1254.         sprintf(tcpname,"%s = 16-bit FTP PC/TCP 1.3", dll);
  1255.         debug(F111,"16bit FTP PC/TCP 1.3 loaded",dll,rc);
  1256.     } else
  1257.       debug(F111,"16bit FTP PC/TCP 1.3 load failed",dll,rc);
  1258.     }
  1259.     if (rc != 0) {
  1260.         strcpy(dll, p);
  1261.     strcat(dll, "CKO16I12.DLL");
  1262.     rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  1263.       if (!rc)
  1264.          {
  1265.          HMODULE tcpiplib ;
  1266.          PFN pfn ;
  1267.          rc = DosLoadModule(fail, sizeof(fail), "TCPIPDLL", &tcpiplib) ;
  1268.          rc = GetProc(tcpiplib,"_bsdselect", &pfn);
  1269.          }
  1270.     if (!rc) {
  1271.         if (deblog)
  1272.           printf( "16bit IBM TCP/IP 1.2 (or compatible) loaded...") ;
  1273.         sprintf(tcpname,"%s = 16-bit IBM TCP/IP 1.2", dll);
  1274.         debug(F111,"16bit IBM TCP/IP 1.2 (or compatible) loaded",dll,rc);
  1275.     } else
  1276.       debug(F111,
  1277.         "16bit IBM TCP/IP 1.2 (or compatible) load failed",dll,rc);
  1278.     }
  1279. #endif /* __32BIT__ */
  1280.  
  1281.     if (rc != 0) {
  1282.     if (deblog) {
  1283.         printf( "Not installed\n") ;
  1284.         debug(F101,"TCP/IP not installed - rc","",rc);
  1285.     }
  1286.     sprintf(tcpname,"(no TCP/IP DLL found)");
  1287.     return -1;
  1288.     }
  1289.     if (GetProc(library, PREFIX "ck_sockinit", &sockinit) ||
  1290.     GetProc(library, PREFIX "ck_connect", &connect) ||
  1291.     GetProc(library, PREFIX "ck_ioctl", &ioctl) ||
  1292.     GetProc(library, PREFIX "ck_recv", &recv) ||
  1293.     GetProc(library, PREFIX "ck_select", &select) ||
  1294.     GetProc(library, PREFIX "ck_send", &send) ||
  1295.     GetProc(library, PREFIX "ck_setsockopt", &setsockopt) ||
  1296.     GetProc(library, PREFIX "ck_socket", &socket) ||
  1297.     GetProc(library, PREFIX "ck_soclose", &soclose) ||
  1298.     GetProc(library, PREFIX "ck_gethostbyname", &gethostbyname) ||
  1299.     GetProc(library, PREFIX "ck_getservbyname", &getservbyname) ||
  1300.     GetProc(library, PREFIX "ck_inet_addr", &inet_addr) ||
  1301.     GetProc(library, PREFIX "ck_inet_ntoa", &inet_ntoa))  {
  1302.     if (deblog) {
  1303.         printf( "Not installed\n") ;
  1304.         debug(F100,"TCP/IP not installed","",0);
  1305.     }
  1306.     strcat(tcpname," - ERROR: Missing Entry Points");
  1307.     return -1;
  1308.     }
  1309.     
  1310.     if (rc = sockinit()) {
  1311.     tcp_avail = 0 ;
  1312.     if (deblog) {
  1313.         printf( "init failed\n" ) ;
  1314.         strcat(tcpname," - ERROR: Initialization Failed");
  1315.         debug(F101,"TCP/IP sockinit() failed","",rc);
  1316.     }
  1317.     } else {
  1318.     tcp_avail = 1;
  1319.     if (deblog) {
  1320.         printf( "initialized\n" ) ;
  1321.         debug(F101,"TCP/IP sockinit() successful","",rc);
  1322.     }
  1323.     }
  1324.     return rc;
  1325. }
  1326. #endif /* TCPSOCKET */
  1327.  
  1328. void
  1329. netinit() {
  1330.  
  1331.     extern int nettype;
  1332.     char fail[256];
  1333.     HMODULE library;
  1334.  
  1335.    if (deblog)
  1336.       {
  1337.       printf( "Initializing Network Support:\n" ) ;
  1338.       debug(F100,"Initializing Network Support:","",0) ;
  1339.       }
  1340.  
  1341. #ifdef CK_NETBIOS
  1342.     os2_netbiosinit() ;
  1343. #endif /* CK_NETBIOS */
  1344.  
  1345. #ifdef DECNET
  1346.     if (deblog) {
  1347.     printf("  DECNet support..." ) ;
  1348.     debug(F100,"DECNet support...","",0);
  1349.     }
  1350.     if ( !DosLoadModule(fail, sizeof(fail), "LATCALLS", &library) ) {
  1351.     if ( !GetProc(library, "LATENTRY", &LATENTRY) ) {
  1352.         dnet_avail = 1;
  1353.         if (deblog) {
  1354.         printf("OK\n") ;
  1355.         debug(F100,"DECNet OK","",0);
  1356.  
  1357.         memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  1358.         lcb.LatFunction = READ_LATINFO;
  1359.         lcb.BufferSize = sizeof(latinfo);
  1360.         lcb.BufferPtr = (void * _Seg16) &latinfo;
  1361.  
  1362.         LATENTRY(&lcb);
  1363.  
  1364.         debug(F101,"DECNet LatStatus","",lcb.LatStatus) ;
  1365.         if (!lcb.LatStatus) {
  1366.             debug(F101,"DECNet Major Version","",latinfo.vermjr) ;
  1367.             debug(F101,"DECNet Minor Version","",latinfo.vermir) ;
  1368.             debug(F101,"DECNet Max Sessions","",latinfo.NSessions) ;
  1369.             debug(F101,"DECNet Max Buffers per Session","",
  1370.               latinfo.NBuffers) ;
  1371.             debug(F101,"DECNet Max Services","",latinfo.NServices) ;
  1372.         }
  1373.         }
  1374.     } else {
  1375.         dnet_avail = 0 ;
  1376.         if (deblog) {
  1377.         printf("Not installed\n" ) ;
  1378.         debug(F100,"DECNet not installed","",0) ;
  1379.         }
  1380.     }
  1381.     } else {
  1382.     dnet_avail = 0 ;
  1383.     if (deblog) {
  1384.         printf("Not installed\n" ) ;
  1385.         debug(F100,"DECNet not installed","",0) ;
  1386.     }
  1387.     }
  1388. #endif /* DECNET */
  1389.  
  1390. #ifdef TCPSOCKET
  1391.     os2_tcpipinit() ;
  1392.  
  1393. #ifdef COMMENT
  1394.  /* this code should never have been added to this module    */
  1395.  /* it results in there being an override variable even when */
  1396.  /* one has never been assigned by the user                  */
  1397.  
  1398.  if (tn_term == NULL) {
  1399.     switch (tt_type) {
  1400.       case TT_VT52:  tn_term = strdup("vt52");  break;
  1401.       case TT_VT100: tn_term = strdup("vt100"); break;
  1402.       case TT_VT102: tn_term = strdup("vt102"); break;
  1403.       case TT_VT220: tn_term = strdup("vt220"); break;
  1404.       case TT_ANSI:  tn_term = strdup("ansi");  break;
  1405.     }
  1406.     }
  1407. #endif /* COMMENT */
  1408. #endif /* TCPSOCKET */
  1409.  
  1410.     if (tcp_avail)            /* Set the default network type */
  1411.       nettype = NET_TCPB;        /* TCP/IP first */
  1412.     else if (dnet_avail)        /* Then DECnet */
  1413.       nettype = NET_DEC;
  1414. #ifdef COMMENT
  1415. /*
  1416.   NetBios cannot be set as a default network type even though
  1417.   we would like to because it requires that a NetBiosName be
  1418.   specified.  If the default is already in use, then we will
  1419.   not know what name to use.  Not providing a name will leave
  1420.   Kermit in an unknown state (network type NetBios without any
  1421.   means for addressing this session.)  Better never to allow
  1422.   it to be set as a default.
  1423.  
  1424.   All the code to implement it is shown below though just in case.
  1425. */      
  1426.     else if (netbiosAvail) {        /* Then NETBIOS */
  1427.     NCB ncb ;
  1428.     APIRET rc ;
  1429.     int x,y ;
  1430.  
  1431.     nettype = NET_BIOS;
  1432.  
  1433.     strncpy(NetBiosName, (*myhost?myhost:"kermit"),NETBIOS_NAME_LEN);
  1434.     for (x = y; x < NETBIOS_NAME_LEN; x++)
  1435.       NetBiosName[x] = SP;
  1436.     NetBiosName[NETBIOS_NAME_LEN] = NUL;
  1437.    
  1438.     printf("Verifying \"%s\" is a unique NetBIOS node name ...\n",
  1439.            NetBiosName) ;
  1440.     rc = NCBAddName( NetbeuiAPI, &ncb, 0, NetBiosName ) ;
  1441.     if ( rc ) {
  1442.         printf(
  1443.         "?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
  1444.            NetBiosName);
  1445.         for ( x=0; x < NETBIOS_NAME_LEN; x++)
  1446.           NetBiosName[x] = SP ;
  1447.     }
  1448.     }
  1449. #endif /* COMMENT */
  1450. #ifdef NPIPE
  1451.     else {                /* Otherwise Named Pipes, */
  1452.     nettype = NET_PIPE;        /* which is always there. */
  1453.     strncpy(pipename,"kermit",PIPENAML);  /* better set the pipename */
  1454.     }
  1455. #else
  1456.     else nettype = NET_NONE;
  1457. #endif /* NPIPE */
  1458.  
  1459. }
  1460.  
  1461. int
  1462. netcleanup() {
  1463. #ifdef CK_NETBIOS
  1464.     os2_netbioscleanup() ;
  1465. #endif /* CK_NETBIOS */
  1466. }
  1467.  
  1468. #ifdef CK_NETBIOS
  1469. void
  1470. NetbiosListenThread(void * pArgList) {
  1471.     APIRET rc = 0 ;
  1472.     rc = Dos16SemWait( pListenNCB->basic_ncb.ncb_semaphore,
  1473.               SEM_INDEFINITE_WAIT ) ;
  1474.  
  1475.     if ( rc ||
  1476.         pListenNCB->basic_ncb.bncb.ncb_retcode != NB_COMMAND_SUCCESSFUL ) {
  1477.     os2_netclos() ;
  1478.     } else {
  1479.     ttyfd = NetBiosLSN = pListenNCB->basic_ncb.bncb.ncb_lsn ;
  1480.     strncpy( NetBiosRemote,
  1481.         pListenNCB->basic_ncb.bncb.ncb_callname,
  1482.         NETBIOS_NAME_LEN ) ;
  1483.  
  1484. #ifdef COMMENT
  1485.     if ( pRecvNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS ) {
  1486.         NCB CleanupNCB ;
  1487.         NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pRecvNCB ) ;
  1488.         Dos16SemWait( pRecvNCB->basic_ncb.ncb_semaphore,
  1489.              SEM_INDEFINITE_WAIT ) ;
  1490.     }
  1491. #endif /* COMMENT */
  1492.  
  1493.     NCBReceive( NetbeuiAPI, pRecvNCB, NetBiosAdapter, NetBiosLSN,
  1494.            NetBiosRecvBuf, sizeof(NetBiosRecvBuf), FALSE ) ;
  1495.     }
  1496.     DosPostEventSem( hevNetBiosLSN ) ;
  1497.     ListenThreadID = -1 ;
  1498. }
  1499. #endif /* CK_NETBIOS */
  1500. #endif /* NETCONN */
  1501.