home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / k95source / ckonet.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  180KB  |  5,916 lines

  1. #ifdef NT
  2. char *ckonetv = "Win32 Network support, 8.0.071, 21 Apr 2004";
  3. #else /* NT */
  4. char *ckonetv = "OS/2 Network support, 8.0.071, 21 Apr 2004";
  5. #endif /* NT */
  6.  
  7. /*  C K O N E T  --  OS/2 and Win32 specific network support  */
  8.  
  9. /*
  10.   COPYRIGHT NOTICE:
  11.  
  12.   Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New
  13.   York.  All rights reserved.
  14. */
  15.  
  16. /*
  17.    Currently supported network services:
  18.  
  19.    - DECnet (PATHWORKS) LAT (support resides in this module)
  20.    - Meridian Technologies SuperLAT [Jeffrey Altman]
  21.    - TCP/IP Telnet (for which this module acts as a front end to ckcnet.c)
  22.    - Named pipes  [Jeffrey Altman]
  23.    - NETBIOS      [Jeffrey Altman]
  24.    - COMMAND      [Jeffrey Altman]
  25.    - DLL          [Jeffrey Altman]
  26.    - SSH          [Jeffrey Altman]
  27. */
  28. #include "ckcdeb.h"
  29. #include "ckcker.h"
  30. #include "ckuusr.h"
  31. #include "ckcasc.h"
  32.  
  33. #define EXTERN
  34. #include "ckcnet.h"  /* include ckonet.h and this includes ckotcp.h */
  35.  
  36. #ifndef NETCONN
  37. /*
  38.   Network support not defined.
  39.   Dummy functions here in case #ifdef's forgotten elsewhere.
  40. */
  41. int                                     /* Open network connection */
  42. os2_netopen(char * name, int * lcl, int nett) {
  43.     return(-1);
  44. }
  45. int                                     /* Close network connection */
  46. os2_netclos(void) {
  47.     return(-1);
  48. }
  49. int                                     /* Check network input buffer */
  50. os2_nettchk(void) {
  51.     return(-1);
  52. }
  53. int                                     /* Flush network input buffer */
  54. os2_netflui(void) {
  55.     return(-1);
  56. }
  57. int                                     /* Send network BREAK */
  58. os2_netbreak(void) {
  59.     return(-1);
  60. }
  61. int                                     /* Input character from network */
  62. os2_netinc(int timo) {
  63.     return(-1);
  64. }
  65. int
  66. os2_netxin(int n,char* buf) {
  67.     return(-1);
  68. }
  69. int                                     /* Output character to network */
  70. os2_nettoc(int c) {
  71.     return(-1);
  72. }
  73. int
  74. os2_nettol(char *s, int n) {
  75.     return(-1);
  76. }
  77. int
  78. os2_netxout(char *s, int n) {
  79.     return(1);
  80. }
  81.  
  82. #else /* NETCONN is defined (rest of this module...) */
  83.  
  84. #ifndef __32BIT__
  85. #define far _far
  86. #define near _near
  87. #define pascal _pascal
  88. #endif
  89.  
  90. #ifdef NPIPE
  91. #include <time.h>
  92. extern char pipename[PIPENAML+1];
  93. #endif /* NPIPE */
  94.  
  95. #ifdef NT
  96. #include <windows.h>
  97. #define itoa _itoa
  98. #else /* NT */
  99. #define INCL_NOPM
  100. #define INCL_DOSPROCESS
  101. #define INCL_DOSQUEUES
  102. #define INCL_DOSMODULEMGR
  103. #define INCL_DOSSEMAPHORES
  104. #define INCL_ERRORS
  105. #define INCL_DOSDATETIME
  106. #define  INCL_DOSNMPIPES
  107. #include <os2.h>
  108. #undef COMMENT
  109. #endif /* NT */
  110.  
  111. #ifndef SEM_INDEFINITE_WAIT
  112. #define SEM_INDEFINITE_WAIT INFINITE
  113. #endif /* SEM_INDEFINITE_WAIT */
  114.  
  115. #include "ckocon.h"
  116. #ifdef NT
  117. #include "cknwin.h"
  118. #endif /* NT */
  119. #include "ckowin.h"
  120. #include <stdio.h>
  121. #include <io.h>
  122. #include <fcntl.h>
  123. #include <string.h>
  124.  
  125. #include <setjmp.h>
  126. #include "ckcsig.h"
  127.  
  128. #ifdef CK_AUTHENTICATION
  129. #include "ckuath.h"
  130. #endif /* CK_AUTHENTICATION */
  131.  
  132. extern int ttnproto, tn_deb;
  133. #ifndef NOTERM
  134. extern int tt_type;
  135. extern char *tn_term;
  136. #endif /* NOTERM */
  137. extern int ck_sleepint ;
  138. char tcpname[512];                      /* For SHOW NET */
  139. int tcp_avail = 0;
  140. #ifdef NT
  141. int winsock_version = 0;
  142. #endif /* NT */
  143. #ifdef DECNET
  144. int dnet_avail = 0;
  145. #endif /* DECNET */
  146. #ifdef SUPERLAT
  147. int slat_avail = 0 ;
  148. char slat_pwd[18] ;
  149. #endif /* SUPERLAT */
  150. USHORT netbiosAvail = 0;
  151.  
  152. #ifdef DECNET
  153. #ifdef OS2ONLY
  154. #ifdef __32BIT__
  155. #pragma seg16(lcb)
  156. #pragma seg16(latinfo)
  157. #pragma seg16(inbuf)
  158. #else /* __32BIT__ */
  159. #define _Seg16
  160. #define APIENTRY16 APIENTRY
  161. #define APIRET16 USHORT
  162. #endif /* __32BIT__ */
  163. #include "ckolat.h"
  164. static APIRET16 (* APIENTRY16 LATENTRY)(struct lat_cb * _Seg16) = NULL;
  165. static struct lat_cb lcb;
  166. static struct lat_info latinfo;
  167. #endif /* OS2ONLY */
  168. #ifdef NT
  169. #include "cknlat.h"
  170. /******************************************************************************
  171. ;                                                                             *
  172. ; Function Declarations provided in DECTAL.DLL                                *
  173. ;                                                                             *
  174. ******************************************************************************/
  175.  
  176. static int (* InstalledAccess)( BYTE bType ) = NULL;
  177. static int (* InquireServices)( BYTE bType ) = NULL;
  178. static int (* GetNextService)( LPSTR lpServiceName,
  179.                                BYTE bType )=NULL;
  180. static int (* OpenSession)( LPDWORD SessionID,
  181.                             LPSTR lpServiceName,
  182.                             LPVOID ConnectData,
  183.                             BYTE bType)=NULL;
  184. static int (* CloseSession)( DWORD SessionID )=NULL;
  185. static int (* ReadData)( DWORD SessionID, LPSTR lpString,
  186.                          DWORD dwLength )=NULL;
  187. static int (* WriteData)( DWORD SessionID, LPSTR lpString,
  188.                           DWORD dwLength )=NULL;
  189. static int (* SendBreak)( DWORD SessionID )=NULL;
  190. static int (* GetDetailError)( DWORD, DWORD)=NULL;
  191. static int (* DataNotify)( DWORD SessionID, HWND hWnd,
  192.                                           UINT wMsg, DWORD dwEventMask)=NULL;
  193. #endif /* NT */
  194. #endif /* DECNET */
  195.  
  196. #ifdef SUPERLAT
  197. #include <winioctl.h>
  198. #include <ntddtdi.h>
  199. #include <tihdr.h>
  200.  
  201. typedef unsigned char uint8;
  202. typedef unsigned short uint16;
  203. typedef unsigned int uint32;
  204. typedef unsigned long queue_t;
  205.  
  206. #include <tdi.h>
  207. #include <packoff.h>
  208. #include <latioc.h>
  209. #include <packon.h>
  210. #endif /* SUPERLAT */
  211.  
  212. /* N E T I N C - Input Buffer */
  213. static unsigned long size = 0, pos = 0;
  214. static unsigned char inbuf[MAXRP+1] ;
  215.  
  216. /* T C P S R V _ O P E N */
  217. /* T C P S O C K E T _ O P E N */
  218. int tcpsrv_open( char * name, int * lcl, int nett, int timo ) ;
  219. void tcpsrv_close(void);
  220. int tcpsocket_open( char * name, int * lcl, int nett, int timo ) ;
  221. #ifndef INADDR_ANY
  222. #define INADDR_ANY 0
  223. #endif /* INADDR_ANY */
  224. int tcpsrv_fd = -1 ;
  225. static unsigned short tcpsrv_port = 0 ;
  226. extern int tcp_incoming;
  227. extern int sstelnet;
  228. extern int tcp_rdns;
  229. extern char *tcp_address;               /* Preferred Local Address */
  230. #ifdef IKSD
  231. extern int inserver;
  232. #endif/* IKSD */
  233.  
  234. #define NAMECPYL 100                    /* Local copy of hostname */
  235. extern char namecopy[] ;
  236. extern char ipaddr[20] ;                /* Global copy of IP address */
  237. extern int ttnet  ;             /* Network type */
  238.  
  239. extern int duplex, debses, seslog, ttyfd, quiet, doconx; /* Extern vars */
  240. extern int nettype;
  241. extern int exithangup;
  242. extern char ttname[] ;
  243. extern char myhost[] ;
  244.  
  245. #ifdef SOL_SOCKET
  246. #ifdef TCP_NODELAY
  247. extern int tcp_nodelay ; /* Nagle algorithm TCP_NODELAY */
  248. #endif /* TCP_NODELAY */
  249. #ifdef SO_DONTROUTE
  250. extern int tcp_dontroute;
  251. #endif /* SO_DONTROUTE */
  252. #ifdef SO_LINGER
  253. extern int tcp_linger ;    /* SO_LINGER */
  254. extern int tcp_linger_tmo ; /* SO_LINGER timeout */
  255. #endif /* SO_LINGER */
  256. #ifdef SO_SNDBUF
  257. extern int tcp_sendbuf ;
  258. #endif /* SO_SNDBUF */
  259. #ifdef SO_RCVBUF
  260. extern int tcp_recvbuf ;
  261. #endif /* SO_RCVBUF */
  262. #ifdef SO_KEEPALIVE
  263. extern int tcp_keepalive ;
  264. #endif /* SO_KEEPALIVE */
  265. #endif /* SOL_SOCKET */
  266.  
  267. #ifdef CK_SSL
  268. #include "ck_ssl.h"
  269. #endif /* CK_SSL */
  270.  
  271.  
  272. #ifdef NPIPE
  273. #ifdef NT
  274.  HANDLE hPipe = INVALID_HANDLE_VALUE;
  275. #else
  276.  HPIPE  hPipe = 0 ;
  277. #endif /* NT */
  278.  UCHAR  PipeName[PIPENAML+1]; /* Pipe name */
  279. #endif /* NPIPE */
  280.  
  281. #ifdef CK_NETBIOS
  282. #ifndef NT
  283. #include "ckonbi.h"
  284. #endif /* NT */
  285. extern PNCB pWorkNCB ;
  286. extern PNCB pListenNCB ;
  287. extern PNCB pRecvNCB ;
  288. extern PNCB pSendNCB[MAXWS] ;
  289. extern BYTE NetBiosLSN  ;
  290. extern HEV  hevNetBiosLSN ;
  291. extern UCHAR  NetBiosRemote[NETBIOS_NAME_LEN+1] ;
  292. extern UCHAR  NetBiosName[NETBIOS_NAME_LEN+1] ;
  293. extern UCHAR NetBiosAdapter ;
  294. extern TID ListenThreadID ;
  295. extern BYTE NetBiosRecvBuf[MAXRP] ;
  296. extern BYTE * NetBiosSendBuf[MAXWS] ;
  297. extern USHORT MaxCmds,MaxSess,MaxNames,MaxWs ;
  298. void NetbiosListenThread(void * pArgList);
  299. #endif /* CK_NETBIOS */
  300.  
  301. #ifdef NETCMD
  302. #ifdef NT
  303. static HANDLE hSaveStdIn=NULL, hSaveStdOut=NULL, hSaveStdErr=NULL;
  304. static HANDLE hChildStdinRd=NULL, hChildStdinWr=NULL, hChildStdinWrDup=NULL,
  305.               hChildStdoutRd=NULL, hChildStdoutRdDup=NULL, hChildStdoutWr=NULL,
  306.               hInputFile=NULL, hSaveStdin=NULL, hSaveStdout=NULL;
  307. static SECURITY_ATTRIBUTES saAttr;
  308. static BOOL fSuccess;
  309. static PROCESS_INFORMATION procinfo ;
  310. static STARTUPINFO         startinfo ;
  311. #else /* NT */
  312. static HFILE hSaveStdIn=-1, hSaveStdOut=-1, hSaveStdErr=-1;
  313. static HFILE hChildStdinRd=-1, hChildStdinWr=-1, hChildStdinWrDup=-1,
  314.              hChildStdoutRd=-1, hChildStdoutRdDup=-1, hChildStdoutWr=-1,
  315.              hInputFile=-1, hSaveStdin=-1, hSaveStdout=-1;
  316. static BOOL fSuccess;
  317. static PID  pid=0;
  318. #define STILL_ACTIVE -1L
  319. #endif /* NT */
  320.  
  321.  
  322. /* The following functions will provide the interface for the local echo */
  323. /* buffer to be used when 'duplex' is TRUE                               */
  324.  
  325. #define NET_CMD_BUFSIZE 512
  326. static USHORT NetCmdBuf[NET_CMD_BUFSIZE] ;
  327. static int NetCmdStart=0, NetCmdEnd=0, NetCmdData=0 ;
  328.  
  329. void
  330. NetCmdInit( void ) {
  331.    int i;
  332.  
  333.     CreateNetCmdAvailSem( FALSE );
  334.     CreateNetCmdMutex( TRUE ) ;
  335.     for ( i = 0 ; i < NET_CMD_BUFSIZE ; i++ )
  336.         memset(NetCmdBuf,0,NET_CMD_BUFSIZE*sizeof(USHORT)) ;
  337.     NetCmdStart = 0 ;
  338.     NetCmdEnd = 0 ;
  339.     NetCmdData = 0;
  340.     ReleaseNetCmdMutex() ;
  341. }
  342.  
  343. void
  344. NetCmdCleanup( void ) {
  345.     CloseNetCmdMutex() ;
  346.     CloseNetCmdAvailSem() ;
  347. }
  348.  
  349. int
  350. NetCmdInBuf( void ) {
  351.     int rc = 0 ;
  352.  
  353.     RequestNetCmdMutex( SEM_INDEFINITE_WAIT ) ;
  354.     if ( NetCmdStart != NetCmdEnd )
  355.     {
  356.         rc = (NetCmdEnd - NetCmdStart + NET_CMD_BUFSIZE)%NET_CMD_BUFSIZE;
  357.     }
  358.     ReleaseNetCmdMutex() ;
  359.     return rc ;
  360. }
  361.  
  362. int
  363. NetCmdPutStr( char * s )
  364. {
  365.     char * p ;
  366.     int rc = 0 ;
  367.     RequestNetCmdMutex( SEM_INDEFINITE_WAIT ) ;
  368.     for ( p=s; *p && !rc ; p++ )
  369.       rc = NetCmdPutChar( *p ) ;
  370.     ReleaseNetCmdMutex() ;
  371.     return rc ;
  372. }
  373.  
  374. int
  375. NetCmdPutChars( char * s, int n )
  376. {
  377.     int rc = 0 ;
  378.     int i = 0;
  379.  
  380.     hexdump("NetCmdPutChars",s,n);
  381.     RequestNetCmdMutex( SEM_INDEFINITE_WAIT ) ;
  382.     for ( i=0 ; i<n ; i++ )
  383.       rc = NetCmdPutChar( s[i] ) ;
  384.     ReleaseNetCmdMutex() ;
  385.     debug(F101,"NetCmdPutChars","",rc);
  386.     return rc ;
  387. }
  388.  
  389. int
  390. NetCmdPutChar( char ch ) {
  391.     int rc = 0 ;
  392.  
  393.     RequestNetCmdMutex( SEM_INDEFINITE_WAIT ) ;
  394.     while ( (NetCmdStart - NetCmdEnd == 1) ||
  395.             ( NetCmdStart == 0 && NetCmdEnd == NET_CMD_BUFSIZE - 1 ) )
  396.         /* Buffer is full */
  397.     {
  398.         debug(F111,"NetCmdPutChar","Buffer is Full",ch);
  399.         ReleaseNetCmdMutex() ;
  400.         msleep(250);
  401.         RequestNetCmdMutex( SEM_INDEFINITE_WAIT ) ;
  402.     }
  403.  
  404.     NetCmdBuf[NetCmdEnd++] = ch ;
  405.     if ( NetCmdEnd == NET_CMD_BUFSIZE )
  406.         NetCmdEnd = 0 ;
  407.     NetCmdData = TRUE;
  408.     PostNetCmdAvailSem()  ;
  409.     ReleaseNetCmdMutex() ;
  410.     return rc ;
  411. }
  412.  
  413. int
  414. NetCmdGetChar( char * pch )
  415. {
  416.     int rc = 0 ;
  417.  
  418.     RequestNetCmdMutex( SEM_INDEFINITE_WAIT ) ;
  419.     if ( NetCmdStart != NetCmdEnd ) {
  420.         *pch = NetCmdBuf[NetCmdStart] ;
  421.         NetCmdBuf[NetCmdStart]=0;
  422.         NetCmdStart++ ;
  423.  
  424.         if ( NetCmdStart == NET_CMD_BUFSIZE )
  425.           NetCmdStart = 0 ;
  426.  
  427.         if ( NetCmdStart == NetCmdEnd ) {
  428.             NetCmdData = FALSE;
  429.             ResetNetCmdAvailSem() ;
  430.         }
  431.         rc++ ;
  432.     }
  433.     else
  434.     {
  435.         *pch = 0 ;
  436.     }
  437.     ReleaseNetCmdMutex() ;
  438.     return rc ;
  439. }
  440.  
  441. #ifdef NT
  442. void
  443. NetCmdReadThread( HANDLE pipe )
  444. {
  445.     int success = 1;
  446.     CHAR c;
  447.     DWORD io;
  448.  
  449.     while ( success && ttyfd != -1 ) {
  450.         if ( success = ReadFile(pipe, &c, 1, &io, NULL ) )
  451.         {
  452.             NetCmdPutChar(c);
  453.         }
  454.     }
  455. }
  456. #else /* NT */
  457. void
  458. NetCmdReadThread( HFILE pipe )
  459. {
  460.     int success = 1;
  461.     CHAR c;
  462.     ULONG io;
  463.  
  464.     while ( success && ttyfd != -1 ) {
  465.         if ( success = !DosRead(pipe, &c, 1, &io) )
  466.         {
  467.             NetCmdPutChar(c);
  468.         }
  469.     }
  470. }
  471. #endif  /* NT */
  472. #endif /* NETCMD */
  473.  
  474. #ifdef NETDLL
  475. HINSTANCE hNetDll=NULL;
  476.  
  477. int    (*net_dll_netopen)(char *,char *,int,int,
  478.                          int(*)(char*,char*,int))=NULL;
  479. int    (*net_dll_netclos)(void)=NULL;
  480. int    (*net_dll_nettchk)(void)=NULL;
  481. int    (*net_dll_netflui)(void)=NULL;
  482. int    (*net_dll_netbreak)(void)=NULL;
  483. int    (*net_dll_netinc)(int)=NULL;
  484. int    (*net_dll_netxin)(int,char*)=NULL;
  485. int    (*net_dll_nettoc)(int)=NULL;
  486. int    (*net_dll_nettol)(char *,int)=NULL;
  487. int    (*net_dll_ttpkt)(void)=NULL;
  488. int    (*net_dll_ttvt)(void)=NULL;
  489. int    (*net_dll_ttres)(void)=NULL;
  490. void   (*net_dll_terminfo)(char *,int,int)=NULL;
  491. char * (*net_dll_version)(void)=NULL;
  492. char * (*net_dll_errorstr)(int)=NULL;
  493.  
  494. int
  495. netdll_unload(void)
  496. {
  497.     CloseHandle(hNetDll);
  498.     hNetDll = NULL;
  499.  
  500.     net_dll_netopen=NULL;
  501.     net_dll_netclos=NULL;
  502.     net_dll_nettchk=NULL;
  503.     net_dll_netflui=NULL;
  504.     net_dll_netbreak=NULL;
  505.     net_dll_netinc=NULL;
  506.     net_dll_netxin=NULL;
  507.     net_dll_nettoc=NULL;
  508.     net_dll_nettol=NULL;
  509.     net_dll_terminfo=NULL;
  510.     net_dll_version=NULL;
  511.     net_dll_errorstr=NULL;
  512.     net_dll_ttpkt=NULL;
  513.     net_dll_ttvt=NULL;
  514.     net_dll_ttres=NULL;
  515.     return(0);
  516. }
  517.  
  518. int
  519. netdll_load( char * dllname )
  520. {
  521.     int rc=0;
  522.  
  523.     hNetDll = LoadLibrary(dllname) ;
  524.     if ( !hNetDll )
  525.     {
  526.         rc = GetLastError() ;
  527.         debug(F111, "netdll_load LoadLibrary failed",dllname,rc) ;
  528.         if ( rc == 126 )
  529.             printf("?Unable to find %s or a required module\n",dllname);
  530.         else
  531.             printf("?Unable to load %s\n",dllname);
  532.         bleep(BP_FAIL);
  533.         return (-1);
  534.     }
  535.  
  536.     if (((FARPROC) net_dll_netopen =
  537.           GetProcAddress( hNetDll, "netopen" )) == NULL )
  538.     {
  539.         rc = GetLastError() ;
  540.         debug(F111, "netdll_load GetProcAddress failed","netopen",rc) ;
  541.         netdll_unload();
  542.         return(-1);
  543.     }
  544.     if (((FARPROC) net_dll_netclos =
  545.           GetProcAddress( hNetDll, "netclos" )) == NULL )
  546.     {
  547.         rc = GetLastError() ;
  548.         debug(F111, "netdll_load GetProcAddress failed","netclos",rc) ;
  549.         netdll_unload();
  550.         return(-1);
  551.     }
  552.     if (((FARPROC) net_dll_nettchk =
  553.           GetProcAddress( hNetDll, "nettchk" )) == NULL )
  554.     {
  555.         rc = GetLastError() ;
  556.         debug(F111, "netdll_load GetProcAddress failed","nettchk",rc) ;
  557.         netdll_unload();
  558.         return(-1);
  559.     }
  560.     if (((FARPROC) net_dll_netflui =
  561.           GetProcAddress( hNetDll, "netflui" )) == NULL )
  562.     {
  563.         rc = GetLastError() ;
  564.         debug(F111, "netdll_load GetProcAddress failed","netflui",rc) ;
  565.         netdll_unload();
  566.         return(-1);
  567.     }
  568.     if (((FARPROC) net_dll_netbreak =
  569.           GetProcAddress( hNetDll, "netbreak" )) == NULL )
  570.     {
  571.         rc = GetLastError() ;
  572.         debug(F111, "netdll_load GetProcAddress failed","netbreak",rc) ;
  573.         netdll_unload();
  574.         return(-1);
  575.     }
  576.     if (((FARPROC) net_dll_netinc =
  577.           GetProcAddress( hNetDll, "netinc" )) == NULL )
  578.     {
  579.         rc = GetLastError() ;
  580.         debug(F111, "netdll_load GetProcAddress failed","netinc",rc) ;
  581.         netdll_unload();
  582.         return(-1);
  583.     }
  584.     if (((FARPROC) net_dll_netxin =
  585.           GetProcAddress( hNetDll, "netxin" )) == NULL )
  586.     {
  587.         rc = GetLastError() ;
  588.         debug(F111, "netdll_load GetProcAddress failed","netxin",rc) ;
  589.         netdll_unload();
  590.         return(-1);
  591.     }
  592.     if (((FARPROC) net_dll_nettoc =
  593.           GetProcAddress( hNetDll, "nettoc" )) == NULL )
  594.     {
  595.         rc = GetLastError() ;
  596.         debug(F111, "netdll_load GetProcAddress failed","nettoc",rc) ;
  597.         netdll_unload();
  598.         return(-1);
  599.     }
  600.     if (((FARPROC) net_dll_nettol =
  601.           GetProcAddress( hNetDll, "nettol" )) == NULL )
  602.     {
  603.         rc = GetLastError() ;
  604.         debug(F111, "netdll_load GetProcAddress failed","nettol",rc) ;
  605.         netdll_unload();
  606.         return(-1);
  607.     }
  608.     if (((FARPROC) net_dll_terminfo =
  609.           GetProcAddress( hNetDll, "terminfo" )) == NULL )
  610.     {
  611.         rc = GetLastError() ;
  612.         debug(F111, "netdll_load GetProcAddress failed","terminfo",rc) ;
  613.         netdll_unload();
  614.         return(-1);
  615.     }
  616.     if (((FARPROC) net_dll_version =
  617.           GetProcAddress( hNetDll, "version" )) == NULL )
  618.     {
  619.         rc = GetLastError() ;
  620.         debug(F111, "netdll_load GetProcAddress failed","version",rc) ;
  621.         netdll_unload();
  622.         return(-1);
  623.     }
  624.     if (((FARPROC) net_dll_errorstr =
  625.           GetProcAddress( hNetDll, "errorstr" )) == NULL )
  626.     {
  627.         rc = GetLastError() ;
  628.         debug(F111, "netdll_load GetProcAddress failed","errorstr",rc) ;
  629.         netdll_unload();
  630.         return(-1);
  631.     }
  632.     if (((FARPROC) net_dll_ttpkt =
  633.           GetProcAddress( hNetDll, "ttpkt" )) == NULL )
  634.     {
  635.         rc = GetLastError() ;
  636.         debug(F111, "netdll_load GetProcAddress failed","ttpkt",rc) ;
  637.         netdll_unload();
  638.         return(-1);
  639.     }
  640.     if (((FARPROC) net_dll_ttres =
  641.           GetProcAddress( hNetDll, "ttres" )) == NULL )
  642.     {
  643.         rc = GetLastError() ;
  644.         debug(F111, "netdll_load GetProcAddress failed","ttres",rc) ;
  645.         netdll_unload();
  646.         return(-1);
  647.     }
  648.     if (((FARPROC) net_dll_ttvt =
  649.           GetProcAddress( hNetDll, "ttvt" )) == NULL )
  650.     {
  651.         rc = GetLastError() ;
  652.         debug(F111, "netdll_load GetProcAddress failed","ttvt",rc) ;
  653.         netdll_unload();
  654.         return(-1);
  655.     }
  656.  
  657.     printf("%s loaded.\n",net_dll_version());
  658.     return(0);
  659. }
  660. #endif /* NETDLL */
  661.  
  662. #ifdef NT
  663. /*
  664. WinSOCK --
  665. */
  666.  
  667. int WSASafeToCancel = 0 ;
  668. #endif /* NT */
  669.  
  670. extern int ishandle;
  671. static int NulCheck = 0;
  672.  
  673. /*  N E T O P E N  --  Open a network connection.  */
  674. /*  Returns 0 on success, -1 on failure.  */
  675.  
  676. /*
  677.   Calling conventions same as ttopen(), except third argument is network
  678.   type rather than modem type.  Designed to be called from within ttopen.
  679. */
  680. int
  681. os2_netopen(name, lcl, nett) char *name; int *lcl, nett; {
  682.  
  683. #ifdef NPIPE
  684. #ifdef NT
  685.     DWORD   OpenMode;
  686.     DWORD   PipeMode;
  687.     DWORD   OutBufSize;
  688.     DWORD   InBufSize;
  689.     DWORD   TimeOut;
  690.     DWORD   AvailData ;
  691. #else
  692.    ULONG   OpenMode;
  693.    ULONG   PipeMode;
  694.    ULONG   OutBufSize;
  695.    ULONG   InBufSize;
  696.    ULONG   TimeOut;
  697.  
  698.    ULONG   ActionTaken ;
  699.    ULONG   OpenFlag ;
  700.  
  701.    ULONG   BytesRead ;
  702.    AVAILDATA AvailData ;
  703.    ULONG   PipeState ;
  704. #endif /* NT */
  705. #endif /* NPIPE */
  706.  
  707.    int rc = -1;
  708.  
  709.     errno = 0;
  710.         nettype = nett;
  711.  
  712. #ifdef SSHBUILTIN
  713.     if ( nettype == NET_SSH ) {
  714.         debug(F100,"os2_netopen calling ssh_open()","",0);
  715.         rc = ssh_open();
  716.         if (rc == 0) {
  717.             ttnet = nett;
  718.             ttyfd = -3;
  719.         }
  720.         return(rc);
  721.     }
  722. #endif /* SSHBUILTIN */
  723.  
  724. #ifdef CK_NETBIOS
  725.     if ( nettype == NET_BIOS ) {
  726.         ULONG PostCount ;
  727.         UCHAR RemoteName[NETBIOS_NAME_LEN+1] = "                \0" ;
  728.  
  729.         if ( !netbiosAvail )
  730.           return -1 ;
  731.  
  732.         ckstrncpy( RemoteName, name, NETBIOS_NAME_LEN+1 ) ;
  733.  
  734.         if ( NetBiosLSN > 0             /* Make sure a handle doesn't exist */
  735.              || ttyfd > -1 )
  736.           return 0 ;
  737.  
  738.         DosResetEventSem( hevNetBiosLSN, &PostCount ) ;
  739.  
  740.         if ( !strcmp( "*               ", RemoteName ) ) { /* Server Mode */
  741.             if ( pListenNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS)
  742.               return 0 ;
  743.  
  744.             printf("Listening for a NetBios connection\n") ;
  745.             rc = NCBListen( NetbeuiAPI,
  746.                             pListenNCB, NetBiosAdapter, NetBiosName, RemoteName,
  747.                             NB_RECV_TIMEOUT, NB_SEND_TIMEOUT, FALSE ) ;
  748.             if ( rc )
  749.               return -1 ;
  750.  
  751.             ttyfd = NetBiosLSN = 0 ;
  752.  
  753.             ListenThreadID = _beginthread( &NetbiosListenThread, 0, 16384, 0 );
  754.             if ( ListenThreadID == -1 ) {
  755.                 Dos16SemWait( pListenNCB->basic_ncb.ncb_semaphore,
  756.                               SEM_INDEFINITE_WAIT ) ;
  757.                 switch (pListenNCB->basic_ncb.bncb.ncb_retcode) {
  758.                 case NB_COMMAND_SUCCESSFUL:
  759.                     ttyfd = NetBiosLSN = pListenNCB->basic_ncb.bncb.ncb_lsn ;
  760.                     return 0 ;
  761.                     break;
  762.                 default:
  763.                     return -1 ;
  764.                 }
  765.             }
  766.             return 0 ;
  767.         }
  768.         else
  769.         {                               /* Remote Mode */
  770.             int oldalarm = alarm(0) ;
  771.             printf("Calling \"%s\" via NetBios\n", RemoteName ) ;
  772.             rc = NCBCall( NetbeuiAPI, pWorkNCB, NetBiosAdapter, NetBiosName,
  773.                           RemoteName, NB_RECV_TIMEOUT, NB_SEND_TIMEOUT, FALSE ) ;
  774.             rc = Dos16SemWait( pWorkNCB->basic_ncb.ncb_semaphore,
  775.                                SEM_INDEFINITE_WAIT ) ;
  776.             if (rc)
  777.               return -1 ;
  778.  
  779.             switch ( pWorkNCB->basic_ncb.bncb.ncb_retcode ) {
  780.             case NB_COMMAND_SUCCESSFUL:
  781.                 ckstrncpy( NetBiosRemote, pWorkNCB->basic_ncb.bncb.ncb_callname,
  782.                          NETBIOS_NAME_LEN ) ;
  783.                 ttyfd = NetBiosLSN = pWorkNCB->basic_ncb.bncb.ncb_lsn ;
  784.                 NCBReceive( NetbeuiAPI, pRecvNCB, NetBiosAdapter, NetBiosLSN,
  785.                             NetBiosRecvBuf, sizeof(NetBiosRecvBuf), FALSE ) ;
  786.                 Dos16SemClear(pListenNCB->basic_ncb.ncb_semaphore ) ;
  787.                 DosPostEventSem( hevNetBiosLSN ) ;
  788.                 rc = 0 ;
  789.                 break;
  790.             case ERROR_FILE_NOT_FOUND:
  791.             case ERROR_ACCESS_DENIED:
  792.             case ERROR_INVALID_PARAMETER:
  793.             default:
  794.                 rc = -1 ;
  795.             }
  796.             alarm(oldalarm) ;
  797.             return rc ;
  798.         }
  799.     }
  800. #endif /* CK_NETBIOS */
  801.  
  802. #ifdef NPIPE
  803.    if ( nettype == NET_PIPE ) {
  804.        if ( hPipe ) {                   /* Make sure a pipe isn't open */
  805.            char buffer[64];
  806. #ifdef NT
  807.            if (PeekNamedPipe(hPipe, NULL, 0, NULL, &AvailData, NULL))
  808.                return 0;
  809.            
  810.            rc = GetLastError();
  811.            if ( rc == ERROR_BAD_PIPE || rc == ERROR_PIPE_NOT_CONNECTED )
  812.                ttclos(0);
  813. #else
  814.            rc = DosPeekNPipe(hPipe, buffer, sizeof(buffer),
  815.                              &BytesRead, &AvailData, &PipeState);
  816.            switch ( rc ) {
  817.              case NO_ERROR:
  818.                return 0 ;
  819.              case ERROR_BAD_PIPE:
  820.              case ERROR_PIPE_NOT_CONNECTED:
  821.                ttclos(0);
  822.                break;
  823.              default:
  824.                break;
  825.            }
  826. #endif
  827.        }
  828. #ifdef NT
  829.        if ( *name == '\0' ) {
  830.            ckstrncpy( PipeName, "\\PIPE\\Kermit", PIPENAML+1 ) ;
  831.        } else {
  832.            ckstrncpy( PipeName, name, PIPENAML+1 ) ;
  833.        }
  834.  
  835.        rc = 0;
  836.        if ( PipeName[0] == '\\' && PipeName[1] == '\\' ) {
  837.            /* Client Mode */
  838.            hPipe = CreateFile( PipeName, 
  839.                                PIPE_ACCESS_DUPLEX,
  840.                                FILE_SHARE_READ|FILE_SHARE_WRITE,
  841.                                NULL, /* security */
  842.                                OPEN_EXISTING,
  843.                                0,   /* ignored */
  844.                                NULL );
  845.            if ( hPipe == INVALID_HANDLE_VALUE ) {
  846.                rc = GetLastError();
  847.                debug( F101, "CreateFile error: return code","",rc) ;
  848.                printf( "\nCreateFile error: return code = %ld\n",rc ) ;
  849.            } else {
  850.                DWORD Mode = PIPE_NOWAIT | PIPE_READMODE_BYTE;
  851.                ttyfd = (int) hPipe ;
  852.                SetNamedPipeHandleState( hPipe, &Mode, NULL, NULL) ;
  853.                printf("\nNamed Pipe %s open.\nConnection to server complete.\n",
  854.                       PipeName);
  855.            }
  856.        } else {                         /* Server Mode */
  857.            int i;
  858.            if (strlen(PipeName) + 3 > PIPENAML) {
  859.                printf("?Pipename too long\n");
  860.                return -1;
  861.            }
  862.  
  863.            for ( i=strlen(PipeName)+1; i>=0; i--) {
  864.                PipeName[i+3] = PipeName[i];
  865.            }
  866.            PipeName[0] = '\\';
  867.            PipeName[1] = '\\';
  868.            PipeName[2] = '.';
  869.  
  870.            OpenMode = PIPE_ACCESS_DUPLEX | 
  871.                       FILE_FLAG_FIRST_PIPE_INSTANCE |
  872.                       FILE_FLAG_WRITE_THROUGH;
  873.            PipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
  874.            OutBufSize = MAXSP + 4 ;
  875.            InBufSize = MAXRP + 4 ;
  876.            TimeOut = 10000;
  877.            hPipe = CreateNamedPipe( PipeName, OpenMode, PipeMode, 0x01, 
  878.                                     OutBufSize, InBufSize, TimeOut, NULL);
  879.            if (hPipe == INVALID_HANDLE_VALUE) {
  880.                rc = GetLastError();
  881.                debug( F101,"CreateNamedPipe error: return code","",rc) ;
  882.                printf("\nCreateNamedPipe error: return code = %ld\n", rc);
  883.            } else {
  884.                ttyfd = (int) hPipe;
  885.                printf("\nNamed Pipe %s created.\nWaiting for client connection ...\n\n",
  886.                        PipeName ) ;
  887.                if (!ConnectNamedPipe( hPipe, NULL )) {
  888.                    rc = GetLastError();
  889.                    if (rc != ERROR_PIPE_NOT_CONNECTED) {
  890.                        debug( F101,"DosConnectNPipe error: return code","",rc) ;
  891.                        printf("\nDosConnectNPipe error: return code = %ld\n", rc);
  892.                    }
  893.                } else {
  894.                    DWORD Mode = PIPE_NOWAIT | PIPE_READMODE_BYTE;
  895.                    ttyfd = (int) hPipe ;
  896.                    SetNamedPipeHandleState( hPipe, &Mode, NULL, NULL) ;
  897.                }
  898.            }
  899.        }
  900. #else /* NT */
  901.        if ( *name == '\0' ) {
  902.            ckstrncpy( PipeName, "\\PIPE\\Kermit", PIPENAML+1 ) ;
  903.        } else {
  904.            ckstrncpy( PipeName, name, PIPENAML+1 ) ;
  905.        }
  906.  
  907.        if ( PipeName[0] == '\\' && PipeName[1] == '\\' ) {
  908.            /* Client Mode */
  909.            OpenFlag = OPEN_ACTION_OPEN_IF_EXISTS ;
  910.            OpenMode = OPEN_FLAGS_WRITE_THROUGH |
  911.                       OPEN_FLAGS_FAIL_ON_ERROR |
  912.                         OPEN_FLAGS_RANDOM |
  913.                            OPEN_SHARE_DENYNONE |
  914.                            OPEN_ACCESS_READWRITE ;
  915.  
  916.            if (PipeName[2] == '.' && PipeName[3] == '\\') { /* Internal use. */
  917.                int i, n = strlen(PipeName);
  918.                for (i = 3; i <= n; i++)
  919.                  PipeName[i-3] = PipeName[i];
  920.            }
  921.  
  922.            rc = DosOpen( PipeName, &hPipe, &ActionTaken, 0, 0,
  923.                         OpenFlag, OpenMode, 0 ) ;
  924.            switch (rc) {
  925.              case NO_ERROR:
  926.                ttyfd = hPipe ;
  927.                DosSetNPHState( hPipe, NP_NOWAIT | NP_READMODE_BYTE ) ;
  928.                printf(
  929.                      "\nNamed Pipe %s open.\nConnection to server complete.\n",
  930.                       PipeName
  931.                       );
  932.                break;
  933.              case ERROR_BAD_NETPATH:
  934.                printf("\nInvalid Server specified in Pipe Name: %s\n",
  935.                       PipeName ) ;
  936.                break;
  937.              case ERROR_PATH_NOT_FOUND:
  938.              case ERROR_FILE_NOT_FOUND:
  939.                printf("\nNonexistent Named Pipe: %s\n", PipeName ) ;
  940.                break;
  941.              case ERROR_PIPE_BUSY:
  942.                printf("\nNamed Pipe Already in Use: %s\n", PipeName ) ;
  943.                break;
  944.              default:
  945.                debug( F101, "DosOpen error: return code","",rc) ;
  946.                printf( "\nDosOpen error: return code = %ld\n",rc ) ;
  947.            }
  948.        } else {                         /* Server Mode */
  949.            OpenMode = NP_ACCESS_DUPLEX | NP_INHERIT | NP_NOWRITEBEHIND |
  950.              NP_TYPE_BYTE | NP_READMODE_BYTE ;
  951.            PipeMode = NP_NOWAIT | 0x01;
  952.            OutBufSize = MAXSP + 4 ;
  953.            InBufSize = MAXRP + 4 ;
  954.            TimeOut = 10000;
  955.            rc = DosCreateNPipe( PipeName, &hPipe, OpenMode,
  956.                                PipeMode, OutBufSize, InBufSize, TimeOut);
  957.            switch (rc) {
  958.              case NO_ERROR:
  959.                ttyfd = hPipe ;
  960.                rc = DosConnectNPipe( hPipe ) ;
  961.                if (rc == NO_ERROR || rc == ERROR_PIPE_NOT_CONNECTED) {
  962.      printf("\nNamed Pipe %s created.\nWaiting for client connection ...\n\n",
  963.                   PipeName ) ;
  964.                   rc = 0 ;
  965.                } else {
  966.                    debug( F101,"DosConnectNPipe error: return code","",rc) ;
  967.                    printf("\nDosConnectNPipe error: return code = %ld\n", rc);
  968.                }
  969.                break;
  970.              case ERROR_PATH_NOT_FOUND:
  971.                printf("\nInvalid Pipe Name: %s\n", PipeName ) ;
  972.                break;
  973.              case ERROR_PIPE_BUSY:
  974.                printf("\nNamed Pipe Already in Use: %s\n", PipeName ) ;
  975.                break;
  976.              default:
  977.                debug( F101,"DosCreateNPipe error: return code","",rc) ;
  978.                printf("\nDosCreateNPipe error: return code = %ld\n", rc);
  979.            }
  980.        }
  981. #endif /* NT */
  982.        return ( rc ? -1 : 0 ) ;
  983.    }
  984. #endif /* NPIPE */
  985.  
  986. #ifdef TCPSOCKET
  987.     if ( nettype == NET_TCPB )
  988.     {
  989.         if (!tcp_avail)
  990.             return -1 ;
  991.  
  992. #ifdef CK_SOCKS
  993.         SOCKS_init();
  994. #endif /* CK_SOCKS */
  995.  
  996.         switch ( name[0] )
  997.         {
  998.         case '*':
  999.             /* server mode -- not supported in ckcnet.c */
  1000.             rc = tcpsrv_open(name, lcl, nett, 0) ;
  1001.             break;
  1002.         case '_':
  1003.             /* raw socket number -- not supported in ckcnet.c */
  1004.             rc = tcpsocket_open(name, lcl, nett, 0);
  1005.             ishandle = 1;    /* Remember so we don't close it */
  1006.             exithangup = 0;  /* Do not close on exit */
  1007.             break;
  1008.         case '$':
  1009.             /* server side raw socket number -- not supported in ckcnet.c */
  1010.             tcp_incoming = 1;
  1011.             sstelnet = 1;
  1012.             rc = tcpsocket_open(name, lcl, nett, 0);
  1013.             break;
  1014. #ifdef OS2ONLY
  1015.         case '!':
  1016.             /* raw socket number -- not supported in ckcnet.c */
  1017.             rc = tcpsocket_open(name, lcl, nett, 0);
  1018.             break;
  1019. #endif /* OS2ONLY */
  1020.         default:
  1021.             rc = netopen(name, lcl, nett) ;
  1022.         }
  1023.         if (!rc) {
  1024.             DialerSend( OPT_KERMIT_CONNECT, 0 ) ;
  1025.         }
  1026.         return(rc);
  1027.     }
  1028. #endif /* TCPSOCKET */
  1029.  
  1030. #ifdef DECNET
  1031.    if ( nettype == NET_DEC ) {
  1032. #ifdef OS2ONLY
  1033.        if ( LATENTRY == NULL )
  1034.           return -1;
  1035. #endif /* OS2ONLY */
  1036.  
  1037.        if (ttnproto == NP_LAT) {
  1038. #ifdef OS2ONLY
  1039.            memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  1040.            lcb.LatFunction = START_SESSION;
  1041.            lcb.BufferSize = strlen(name);
  1042.            lcb.BufferPtr = (void * _Seg16) name;
  1043.  
  1044.            LATENTRY(&lcb);
  1045.  
  1046.            ttyfd = lcb.SessionHandle;
  1047.            printf(lcb.LatStatus ? "failed.\n" : "OK.\n");
  1048.  
  1049.            rc = (lcb.LatStatus == 0) ? 0 : -1;
  1050. #endif /* OS2ONLY */
  1051. #ifdef NT
  1052.            DWORD SessionID=0;
  1053.            rc = OpenSession( &SessionID, name, NULL, LAT_ACCESS );
  1054.            if ( rc ) {
  1055.                printf("failed.\n");
  1056.                debug(F111,"DECNet LAT OpenSession failed",name,rc);
  1057.                rc = -1;
  1058.            }
  1059.            else {
  1060.                printf("OK.\n");
  1061.                ttyfd = SessionID;
  1062.            }
  1063. #endif /* NT */
  1064.        }
  1065.        else if ( ttnproto == NP_CTERM ) {
  1066. #ifdef OS2ONLY
  1067.            rc = -1;             /* Not supported */
  1068. #endif /* OS2ONLY */
  1069. #ifdef NT
  1070.            DWORD SessionID=0;
  1071.            rc = OpenSession( &SessionID, name, NULL, CTERM_ACCESS );
  1072.            if ( rc ) {
  1073.                printf("failed.\n");
  1074.                debug(F111,"DECNet CTERM OpenSession failed",name,rc);
  1075.                rc = -1;
  1076.            }
  1077.            else {
  1078.                printf("OK.\n");
  1079.                ttyfd = SessionID;
  1080.            }
  1081. #endif /* NT */
  1082.        }
  1083.    }
  1084. #endif /* DECNET */
  1085.  
  1086. #ifdef SUPERLAT
  1087.    if ( nettype == NET_SLAT )
  1088.    {
  1089.       L_bind bindstruct ;
  1090.       ULONG BytesReturned = 0;
  1091.       TA_LAT_ADDRESS connectstruct ;
  1092.       OVERLAPPED OverLapped ;
  1093.       HANDLE thehEvent ;
  1094.       int i=0, service = 0 ;
  1095.       char * port = NULL ;
  1096.  
  1097.       ttnproto = NP_LAT ;
  1098.  
  1099.       /* Create a file handle, first try NT way, then try Win95 way */
  1100.       ttyfd = (int) CreateFile ("\\\\.\\Lat",
  1101.                         GENERIC_READ    | GENERIC_WRITE,
  1102.                         FILE_SHARE_READ | FILE_SHARE_WRITE,
  1103.                         NULL,
  1104.                         OPEN_EXISTING,
  1105.                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  1106.                         NULL);
  1107.  
  1108.       if ((HANDLE) ttyfd == INVALID_HANDLE_VALUE)
  1109.       {
  1110.          ttyfd = (int) CreateFile ("\\\\.\\slatwin",
  1111.                            GENERIC_READ    | GENERIC_WRITE,
  1112.                            FILE_SHARE_READ | FILE_SHARE_WRITE,
  1113.                            NULL,
  1114.                            OPEN_EXISTING,
  1115.                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  1116.                            NULL);
  1117.          if ( (HANDLE) ttyfd == INVALID_HANDLE_VALUE )
  1118.          {
  1119.             ttyfd = -1 ;
  1120.             return -1 ;
  1121.          }
  1122.       }
  1123.  
  1124.       memset( &bindstruct, 0, sizeof(bindstruct) ) ;
  1125.       bindstruct.type = L_CLIENT ;
  1126.  
  1127.       if ( !DeviceIoControl( (HANDLE) ttyfd, IOCTL_TDI_ASSOCIATE_ADDRESS,
  1128.                              &bindstruct, sizeof(bindstruct),
  1129.                              NULL, 1, &BytesReturned, NULL ) )
  1130.       {
  1131.          printf( "... Error: bind ack failed\n") ;
  1132.          CloseHandle( (HANDLE) ttyfd ) ;
  1133.          ttyfd = -1 ;
  1134.          return -1;
  1135.       }
  1136.  
  1137.       service = 1 ;  /* assume it is a service name */
  1138.       for ( i=0 ; name[i] ; i++ )
  1139.          if ( name[i] == '/' )
  1140.          {
  1141.             service = 0 ;    /* no its a node/port specification */
  1142.             port = & name[i+1] ;
  1143.             break;
  1144.          }
  1145.       if ( service )
  1146.       {
  1147.          connectstruct.Address[0].Address[0].CONN_type = L_SESSION;
  1148.          ckstrncpy (connectstruct.Address[0].Address[0].CONN_service,
  1149.                      name, NA_MAX);
  1150.          connectstruct.Address[0].Address[0].CONN_node[0] = 0 ;
  1151.          connectstruct.Address[0].Address[0].CONN_port[0] = 0 ;
  1152.       }
  1153.       else
  1154.       {
  1155.          connectstruct.Address[0].Address[0].CONN_type = L_HIC;
  1156.          connectstruct.Address[0].Address[0].CONN_service[0] = 0 ;
  1157.          ckstrncpy(connectstruct.Address[0].Address[0].CONN_node,
  1158.                     name,NA_MAX);
  1159.          ckstrncpy(connectstruct.Address[0].Address[0].CONN_port,
  1160.                     port,NA_MAX);
  1161.       }
  1162.  
  1163.       if ( slat_pwd[0] )
  1164.          ckstrncpy( connectstruct.Address[0].Address[0].CONN_password,
  1165.                     slat_pwd, NA_MAX ) ;
  1166.       else
  1167.          connectstruct.Address[0].Address[0].CONN_password[0] = 0 ;
  1168.  
  1169.       connectstruct.Address[0].AddressLength = sizeof (L_connect);
  1170.       connectstruct.Address[0].AddressType = TDI_ADDRESS_TYPE_LAT;
  1171.       connectstruct.TAAddressCount = 1;
  1172.  
  1173.       OverLapped.Offset = 0;
  1174.       OverLapped.OffsetHigh = 0;
  1175.       thehEvent = CreateEvent (0, TRUE, 0, NULL);
  1176.       OverLapped.hEvent = thehEvent;
  1177.  
  1178.       if ( !DeviceIoControl ((HANDLE) ttyfd, IOCTL_TDI_CONNECT,
  1179.                                   &connectstruct, sizeof (connectstruct),
  1180.                                   NULL, 0, &BytesReturned, &OverLapped))
  1181.       {
  1182.          if (GetLastError() == ERROR_IO_PENDING)
  1183.             GetOverlappedResult ((HANDLE) ttyfd, &OverLapped, &BytesReturned, TRUE);
  1184.          else BytesReturned = 1;
  1185.       }
  1186.  
  1187.       if (BytesReturned)
  1188.       {
  1189.          printf ("Connect failure..\r\n");
  1190.          CloseHandle( (HANDLE) ttyfd ) ;
  1191.          CloseHandle( thehEvent ) ;
  1192.          ttyfd = -1 ;
  1193.          return -1 ;
  1194.       }
  1195.  
  1196.       rc = 0 ;
  1197.    }
  1198. #endif /* SUPERLAT */
  1199.  
  1200. #ifdef NETFILE
  1201.    if ( nettype == NET_FILE )
  1202.    {
  1203. #ifdef NT
  1204.       OVERLAPPED OverLapped ;
  1205.  
  1206.       /* Create a file handle */
  1207.       ttyfd = (int) CreateFile (name,
  1208.                         GENERIC_READ   ,
  1209.                         FILE_SHARE_READ,
  1210.                         NULL,
  1211.                         OPEN_EXISTING,
  1212.                         FILE_ATTRIBUTE_NORMAL,
  1213.                         NULL);
  1214.  
  1215.       if ((HANDLE) ttyfd == INVALID_HANDLE_VALUE)
  1216.       {
  1217.          ttyfd = -1 ;
  1218.          return -1 ;
  1219.       }
  1220.        rc = 0 ;
  1221. #else /* NT */
  1222.        ULONG Action;
  1223.        rc = DosOpen( name, (PHFILE) &ttyfd, &Action, 0, FILE_NORMAL,
  1224.                      OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  1225.                      OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0);
  1226.        if ( rc ) {
  1227.            ttyfd = -1;
  1228.            return -1;
  1229.        }
  1230. #endif /* NT */
  1231.    }
  1232. #endif /* NETFILE */
  1233.  
  1234. #ifdef NETCMD
  1235.     if ( nettype == NET_CMD ) {
  1236.         char cmd_line[256], *cmd_exe, *args, *p;
  1237.         int argslen;
  1238.  
  1239. #ifdef NT
  1240.         hSaveStdOut = GetStdHandle( STD_OUTPUT_HANDLE ) ;
  1241.         hSaveStdIn  = GetStdHandle( STD_INPUT_HANDLE ) ;
  1242.         hSaveStdErr = GetStdHandle( STD_ERROR_HANDLE ) ;
  1243.  
  1244.         /* Set the bInheritHandle flag so pipe handles are inherited. */
  1245.  
  1246.         saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  1247.         saAttr.bInheritHandle = TRUE;
  1248.         saAttr.lpSecurityDescriptor = NULL;
  1249.  
  1250.         /*
  1251.         * The steps for redirecting child's STDOUT:
  1252.         *     1.  Save current STDOUT, to be restored later.
  1253.         *     2.  Create anonymous pipe to be STDOUT for child.
  1254.         *     3.  Set STDOUT of parent to be write handle of pipe, so
  1255.         *         it is inherited by child.
  1256.         */
  1257.  
  1258.         /* Create a pipe for the child's STDOUT. */
  1259.  
  1260.         if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 65535))
  1261.             debug(F100,"Stdout pipe creation failed\n","",0);
  1262.  
  1263.         /* Set a write handle to the pipe to be STDOUT. */
  1264.  
  1265.         if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr) ||
  1266.              ! SetStdHandle(STD_ERROR_HANDLE, hChildStdoutWr) )
  1267.             debug(F100,"Redirecting STDOUT/STDERR failed","",0);
  1268.  
  1269.         /*
  1270.         * The steps for redirecting child's STDIN:
  1271.         *     1.  Save current STDIN, to be restored later.
  1272.         *     2.  Create anonymous pipe to be STDIN for child.
  1273.         *     3.  Set STDIN of parent to be read handle of pipe, so
  1274.         *         it is inherited by child.
  1275.         *     4.  Create a noninheritable duplicate of write handle,
  1276.         *         and close the inheritable write handle.
  1277.         */
  1278.  
  1279.         /* Create a pipe for the child's STDIN. */
  1280.  
  1281.         if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 65535))
  1282.             debug(F100,"Stdin pipe creation failed\n","",0);
  1283.  
  1284.         /* Set a read handle to the pipe to be STDIN. */
  1285.  
  1286.         if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
  1287.             debug(F100,"Redirecting Stdin failed","",0);
  1288.  
  1289.         /* Duplicate the write handle to the pipe so it is not inherited. */
  1290.  
  1291.         fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
  1292.                                   GetCurrentProcess(), &hChildStdinWrDup, 0,
  1293.                                   FALSE,       /* not inherited */
  1294.                                   DUPLICATE_SAME_ACCESS);
  1295.         if (! fSuccess) {
  1296.             debug(F100,"DuplicateHandle failed","",0);
  1297.  
  1298.             SetStdHandle( STD_OUTPUT_HANDLE, hSaveStdOut );
  1299.             SetStdHandle( STD_INPUT_HANDLE, hSaveStdIn );
  1300.             SetStdHandle( STD_ERROR_HANDLE, hSaveStdErr );
  1301.  
  1302.             CloseHandle(hChildStdoutRd);  hChildStdoutRd = NULL;
  1303.             CloseHandle(hChildStdoutWr);  hChildStdoutWr = NULL;
  1304.             CloseHandle(hChildStdinRd);  hChildStdinRd = NULL;
  1305.             CloseHandle(hChildStdinWr);  hChildStdinWr = NULL;
  1306.         }
  1307.  
  1308.         fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
  1309.                                     GetCurrentProcess(), &hChildStdoutRdDup, 0,
  1310.                                     FALSE,       /* not inherited */
  1311.                                     DUPLICATE_SAME_ACCESS);
  1312.         if (! fSuccess) {
  1313.             debug(F100,"DuplicateHandle failed","",0);
  1314.  
  1315.             SetStdHandle( STD_OUTPUT_HANDLE, hSaveStdOut );
  1316.             SetStdHandle( STD_INPUT_HANDLE, hSaveStdIn );
  1317.             SetStdHandle( STD_ERROR_HANDLE, hSaveStdErr );
  1318.  
  1319.             CloseHandle(hChildStdoutRd);  hChildStdoutRd = NULL;
  1320.             CloseHandle(hChildStdoutWr);  hChildStdoutWr = NULL;
  1321.             CloseHandle(hChildStdinRd);  hChildStdinRd = NULL;
  1322.             CloseHandle(hChildStdinWr);  hChildStdinWr = NULL;
  1323.         }
  1324.  
  1325.         CloseHandle(hChildStdinWr);
  1326.         hChildStdinWr = NULL;
  1327.  
  1328.         cmd_line[0] = '\0' ;
  1329.         /* Now create the child process. */
  1330.  
  1331.         cmd_exe = getenv("SHELL");
  1332.         if ( !cmd_exe )
  1333.             cmd_exe = getenv("COMSPEC");
  1334.         if ( !cmd_exe )
  1335.             cmd_exe = "cmd.exe";
  1336.         ckstrncpy(cmd_line, cmd_exe,256);
  1337.         args = cmd_line + strlen(cmd_line); /* don't skip zero */
  1338.         argslen = 256-strlen(cmd_line);
  1339.  
  1340.         /* Look for MKS Shell, if found use -c instead of /c */
  1341.         _strlwr(cmd_exe);
  1342.         debug(F110,"os2_netopen NET_CMD cmd_exe",cmd_exe,0);
  1343.         p = strstr(cmd_exe,"sh.exe");
  1344.         if ( !p )
  1345.             p = strstr(cmd_exe,"bash.exe");
  1346.         if ( !p )
  1347.             p = strstr(cmd_exe,"ash.exe");
  1348.         if ( p && (p == cmd_exe || *(p-1) == '\\' || *(p-1) == '/')) {
  1349.             sprintf(args, " -c \"%s\"",name);
  1350.         }
  1351.         else {
  1352.             ckstrncpy(args, " /c ",argslen);
  1353.             ckstrncat(args, name,argslen);
  1354.         }
  1355.         debug(F110,"os2_netopen NET_CMD args",args,0);
  1356.  
  1357.         memset( &startinfo, 0, sizeof(STARTUPINFO) ) ;
  1358.         startinfo.cb = sizeof(STARTUPINFO) ;
  1359.  
  1360.         fSuccess = CreateProcess( NULL,               /* application name */
  1361.                      cmd_line,              /* command line */
  1362.                      NULL,                  /* process security attributes */
  1363.                      NULL,                  /* primary thread security attrs */
  1364.                      TRUE,                  /* inherit handles */
  1365.                      NORMAL_PRIORITY_CLASS, /* creation flags */
  1366.                      NULL,                  /* use parent's environment */
  1367.                      NULL,                  /* use parent's current directory */
  1368.                      &startinfo,            /* startup info */
  1369.                      &procinfo ) ;          /* proc info returned */
  1370.  
  1371.         if ( !fSuccess )
  1372.             debug(F111,"os2_netopen unable to start process",cmd_line,GetLastError());
  1373.  
  1374.         CloseHandle(procinfo.hProcess);
  1375.         CloseHandle(procinfo.hThread);
  1376.  
  1377.         if ( !SetStdHandle( STD_OUTPUT_HANDLE, hSaveStdOut ) ||
  1378.              !SetStdHandle( STD_INPUT_HANDLE, hSaveStdIn ) ||
  1379.              !SetStdHandle( STD_ERROR_HANDLE, hSaveStdErr ) )
  1380.         {
  1381.             debug( F101,"os2_netopen Unable to restore standard handles","",GetLastError() ) ;
  1382.             CloseHandle(hChildStdoutRd);  hChildStdoutRd = NULL;
  1383.             CloseHandle(hChildStdoutWr);  hChildStdoutWr = NULL;
  1384.             CloseHandle(hChildStdinRd);  hChildStdinRd = NULL;
  1385.             CloseHandle(hChildStdinWrDup);  hChildStdinWrDup = NULL;
  1386.             return -1;
  1387.         }
  1388.  
  1389.         if ( !fSuccess ) {
  1390.             CloseHandle(hChildStdoutRd);  hChildStdoutRd = NULL;
  1391.             CloseHandle(hChildStdoutWr);  hChildStdoutWr = NULL;
  1392.             CloseHandle(hChildStdinRd);  hChildStdinRd = NULL;
  1393.             CloseHandle(hChildStdinWrDup);  hChildStdinWrDup = NULL;
  1394.             return(-1);
  1395.         }
  1396. #else /* NT */
  1397.         HFILE temp;
  1398.         char fail[256]="";
  1399.         RESULTCODES res;
  1400.  
  1401.         /* Save existing handles */
  1402.         rc = DosDupHandle(0,&hSaveStdIn);
  1403.         rc = DosSetFHState(hSaveStdIn, OPEN_FLAGS_NOINHERIT);
  1404.         rc = DosDupHandle(1,&hSaveStdOut);
  1405.         rc = DosSetFHState(hSaveStdOut, OPEN_FLAGS_NOINHERIT);
  1406.         rc = DosDupHandle(2,&hSaveStdErr);
  1407.         rc = DosSetFHState(hSaveStdErr, OPEN_FLAGS_NOINHERIT);
  1408.  
  1409.         /* Create a pipe for the child's STDOUT */
  1410.         if (rc = DosCreatePipe(&hChildStdoutRd, &hChildStdoutWr, 65535))
  1411.             debug(F100,"Stdout pipe creation failed\n","",0);
  1412.  
  1413.         /* Set a write handle to the pipe to be STDOUT */
  1414.         temp = 1;       /* stdout */
  1415.         rc = DosDupHandle(hChildStdoutWr, &temp);
  1416.         temp = 2;       /* stderr */
  1417.         rc = DosDupHandle(hChildStdoutWr, &temp);
  1418.  
  1419.         /* Create a pipe for the child's STDOUT */
  1420.         if (rc = DosCreatePipe(&hChildStdinRd, &hChildStdinWr, 4096))
  1421.             debug(F100,"Stdout pipe creation failed\n","",0);
  1422.  
  1423.         /* Set a write handle to the pipe to be STDOUT */
  1424.         temp = 0;       /* stdin */
  1425.         rc = DosDupHandle(hChildStdinRd, &temp);
  1426.  
  1427.         rc = DosSetFHState(hChildStdoutRd, OPEN_FLAGS_NOINHERIT);
  1428.         rc = DosSetFHState(hChildStdinWr, OPEN_FLAGS_NOINHERIT);
  1429.  
  1430.         rc = DosDupHandle(hChildStdinWr,&hChildStdinWrDup);
  1431.         rc = DosDupHandle(hChildStdoutRd,&hChildStdoutRdDup);
  1432.         rc = DosClose(hChildStdinWr);
  1433.         hChildStdinWr = -1;
  1434.         rc = DosClose(hChildStdoutRd);
  1435.         hChildStdoutRd = -1;
  1436.  
  1437.         cmd_line[0] = '\0' ;
  1438.         /* Now create the child process. */
  1439.  
  1440.         cmd_exe = getenv("SHELL");
  1441.         if ( !cmd_exe )
  1442.             cmd_exe = getenv("COMSPEC");
  1443.         if ( !cmd_exe )
  1444.             cmd_exe = "cmd.exe";
  1445.         ckstrncpy(cmd_line, cmd_exe, 256);
  1446.         args = cmd_line + strlen(cmd_line); /* don't skip zero */
  1447.  
  1448.         /* Look for MKS Shell, if found use -c instead of /c */
  1449.         strlwr(cmd_exe);
  1450.         debug(F110,"os2_netopen NET_CMD cmd_exe",cmd_exe,0);
  1451.         p = strstr(cmd_exe,"sh.exe");
  1452.         if ( !p )
  1453.             p = strstr(cmd_exe,"bash.exe");
  1454.         if ( !p )
  1455.             p = strstr(cmd_exe,"ash.exe");
  1456.         if ( p && (p == cmd_exe || *(p-1) == '\\' || *(p-1) == '/')) {
  1457.             sprintf(args, "-c%c%s%c",0,name,0);
  1458.         }
  1459.         else {
  1460.             sprintf(args, "/c%c%s%c",0,name,0);
  1461.         }
  1462.         debug(F110,"os2_netopen NET_CMD args",args,0);
  1463.  
  1464.         rc = DosExecPgm(fail, sizeof(fail), EXEC_ASYNCRESULT,
  1465.                         args, 0, &res, cmd_exe);
  1466.  
  1467.         /* Restore Standard Handles for this process */
  1468.         temp = 0;
  1469.         rc = DosDupHandle(hSaveStdIn,&temp);
  1470.         temp = 1;
  1471.         rc = DosDupHandle(hSaveStdOut,&temp);
  1472.         temp = 2;
  1473.         rc = DosDupHandle(hSaveStdErr,&temp);
  1474.  
  1475.         if (rc) {
  1476.             debug(F111,"ttruncmd failed",fail,rc);
  1477.             rc = DosClose(hChildStdinRd); hChildStdinRd = -1;
  1478.             rc = DosClose(hChildStdinWr); hChildStdinWr = -1;
  1479.             rc = DosClose(hChildStdoutRd);hChildStdoutRd = -1;
  1480.             rc = DosClose(hChildStdoutWr);hChildStdoutWr = -1;
  1481.             return 1;
  1482.         }
  1483.  
  1484.         pid = res.codeTerminate;            /* save the Process ID */
  1485. #endif /* NT */
  1486.  
  1487.         ttyfd = 999;
  1488.  
  1489.         /* Start reading from pipe */
  1490.         _beginthread( NetCmdReadThread,
  1491. #ifndef NT
  1492.                      0,
  1493. #endif /* NT */
  1494.                      65536, hChildStdoutRdDup );
  1495.         rc = 0;
  1496.     }
  1497. #endif /* NETCMD */
  1498. #ifdef NETDLL
  1499.     if ( nettype == NET_DLL ) {
  1500.         extern int tt_type, max_tt;
  1501.         extern int tt_rows[], tt_cols[];
  1502.         extern struct tt_info_rec tt_info[];
  1503.         extern char *tn_term;
  1504.         int readpass(char *,char *,int);
  1505.         char * cmdline = NULL;
  1506.  
  1507.         if ( net_dll_netopen ) {
  1508.             cmdline = strdup(name);
  1509.             if ((rc = net_dll_netopen(cmdline,
  1510.                                      tn_term ? tn_term :
  1511.                                      (tt_type >= 0 && tt_type <= max_tt) ?
  1512.                                      tt_info[tt_type].x_name :
  1513.                                      "UNKNOWN",
  1514.                                      tt_rows[VTERM],
  1515.                                      tt_cols[VTERM],
  1516.                                      readpass)
  1517.                   ) >= 0) {
  1518.                 ttyfd = 999;
  1519.                 rc = 0;
  1520.             }
  1521.             else if (net_dll_errorstr) {
  1522.                 printf("? %s\n",net_dll_errorstr(rc));
  1523.                 rc = -1;
  1524.             }
  1525.             free(cmdline);
  1526.         }
  1527.         else
  1528.             rc = -1;
  1529.     }
  1530. #endif /* NETDLL */
  1531.  
  1532.    return rc;
  1533. }
  1534.  
  1535. /*  N E T C L O S  --  Close current network connection.  */
  1536.  
  1537. int
  1538. os2_netclos() {
  1539.    int rc = 0;
  1540.  
  1541.    if (ttyfd == -1)                     /* Was open? */
  1542.       return(rc);                       /* Wasn't. */
  1543.  
  1544.  
  1545. #ifdef SSHBUILTIN
  1546.     if ( nettype == NET_SSH ) {
  1547.                 ttyfd = -1;
  1548.         return(ssh_clos());
  1549.     }
  1550. #endif /* SSHBUILTIN */
  1551.  
  1552. #ifdef CK_NETBIOS
  1553.     if ( nettype == NET_BIOS ) {
  1554.         ULONG PostCount ;
  1555.         if ( NetBiosLSN >= 0 ) {
  1556.             NCB CleanupNCB ;
  1557.             int i ;
  1558.  
  1559.             if ( pWorkNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  1560.               NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pWorkNCB ) ;
  1561.             if ( pListenNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  1562.             {
  1563.                 NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pListenNCB ) ;
  1564.                 DosWaitEventSem( hevNetBiosLSN, SEM_INDEFINITE_WAIT ) ;
  1565.             }
  1566.             if ( pRecvNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  1567.               NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pRecvNCB ) ;
  1568.  
  1569.             for ( i=0 ; i<MAXWS ; i++ ) {
  1570.                 if ( pSendNCB[i]->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS )
  1571.                   NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pSendNCB[i] ) ;
  1572.             }
  1573.  
  1574.             NCBHangup( NetbeuiAPI, pWorkNCB, NetBiosAdapter, NetBiosLSN ) ;
  1575.         }
  1576.         NetBiosLSN = 0 ;
  1577.         ckstrncpy( NetBiosRemote, "               ", NETBIOS_NAME_LEN+1 ) ;
  1578.         DosResetEventSem( hevNetBiosLSN, &PostCount ) ;
  1579.         ttyfd = -1 ;
  1580.         Dos16SemSet( pListenNCB->basic_ncb.ncb_semaphore ) ;
  1581.     }
  1582. #endif /* CK_NETBIOS */
  1583.  
  1584. #ifdef NPIPE
  1585.     if ( nettype == NET_PIPE ) {
  1586.         if ( hPipe ) {
  1587. #ifdef NT
  1588.             CloseHandle( hPipe );
  1589.             hPipe = INVALID_HANDLE_VALUE;
  1590. #else /* NT */
  1591.             rc = DosClose( hPipe ) ;
  1592.             hPipe = 0 ;
  1593. #endif /* NT */
  1594.             ttyfd = -1 ;
  1595.         }
  1596.         return rc ;
  1597.     }
  1598. #endif /* NPIPE */
  1599.  
  1600.  
  1601. #ifdef TCPSOCKET
  1602.     if ( nettype == NET_TCPB )
  1603.     {
  1604.         if (!tcp_avail)
  1605.             return -1 ;
  1606.         if (!ishandle)
  1607.             rc = netclos();
  1608.         else {
  1609. #ifdef TCPIPLIB
  1610.             extern int ttibp, ttibn;
  1611. #endif /* TCPIPLIB */
  1612.             extern int tn_init;
  1613.  
  1614.             ttyfd = -1;                         /* Mark it as closed. */
  1615.             ishandle = 0;
  1616.             NulCheck = 0;
  1617.  
  1618.             debug(F100,"os2_netclos setting tn_init = 0","",0);
  1619.             tn_init = 0;                        /* Remember about telnet protocol... */
  1620.             *ipaddr = '\0';                     /* Zero the IP address string */
  1621.             tcp_incoming = 0;                   /* No longer incoming */
  1622.             sstelnet = 0;                       /* Client-side Telnet */
  1623.             /* Don't reset ttnproto so that we can remember which protocol is in use */
  1624. #ifdef TCPIPLIB
  1625.             /*
  1626.             Empty the internal buffers so they won't be used as invalid input on
  1627.             the next connect attempt (rlogin).
  1628.             */
  1629.             ttibp = 0;
  1630.             ttibn = 0;
  1631. #endif /* TCPIPLIB */
  1632.         }
  1633.         return(rc);
  1634.     }
  1635. #endif /* TCPSOCKET */
  1636.  
  1637. #ifdef DECNET
  1638.    if ( nettype == NET_DEC ) {
  1639.        if (ttyfd > -1) {
  1640.            if ( ttnproto == NP_LAT ) {
  1641. #ifdef OS2ONLY
  1642.                memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  1643.                lcb.LatFunction = STOP_SESSION;
  1644.                lcb.SessionHandle = ttyfd;
  1645.                LATENTRY(&lcb);
  1646.                rc = (lcb.LatStatus == 0) ? 0 : -1;
  1647. #endif /* OS2ONLY */
  1648. #ifdef NT
  1649.                rc = CloseSession( (DWORD) ttyfd );
  1650.                if ( rc ) {
  1651.                    debug(F101,"DECNet LAT CloseSession failed","",rc);
  1652.                    rc = -1;
  1653.                }
  1654. #endif /* NT */
  1655.            }
  1656.            else if ( ttnproto == NP_CTERM ) {
  1657. #ifdef OS2ONLY
  1658.                rc = -1;         /* not implemented */
  1659. #endif /* OS2ONLY */
  1660. #ifdef NT
  1661.                rc = CloseSession( (DWORD) ttyfd );
  1662.                if ( rc ) {
  1663.                    debug(F101,"DECNet CTERM CloseSession failed","",rc);
  1664.                    rc = -1;
  1665.                }
  1666. #endif /* NT */
  1667.            }
  1668.        }
  1669.    }
  1670. #endif /* DECNET */
  1671.  
  1672. #ifdef SUPERLAT
  1673.    if ( nettype == NET_SLAT )
  1674.    {
  1675.       CloseHandle( (HANDLE) ttyfd ) ;
  1676.    }
  1677. #endif /* SUPERLAT */
  1678.  
  1679. #ifdef NETFILE
  1680.     if ( nettype == NET_FILE )
  1681.     {
  1682. #ifdef NT
  1683.         if (!CloseHandle( (HANDLE) ttyfd ))
  1684.             rc = -1;
  1685. #else /* NT */
  1686.         if (DosClose( ttyfd ))
  1687.             rc = -1;
  1688. #endif /* NT */
  1689.     }
  1690. #endif /* NETFILE */
  1691.  
  1692. #ifdef NETCMD
  1693.     if ( nettype == NET_CMD ) {
  1694. #ifdef NT
  1695.         DWORD exitcode=1;
  1696.  
  1697.         if (WaitForSingleObject(procinfo.hProcess, 0L) == WAIT_OBJECT_0)
  1698.             GetExitCodeProcess(procinfo.hProcess, &exitcode);
  1699.         else if (!TerminateProcess(procinfo.hProcess,exitcode)) {
  1700.             int gle = GetLastError();
  1701.             debug(F111,"net_clos NET_CMD","unable to TerminateProcess",gle);
  1702.         }
  1703.         else {
  1704.             if (WaitForSingleObject(procinfo.hProcess, 5000) == WAIT_OBJECT_0) {
  1705.                 GetExitCodeProcess(procinfo.hProcess, &exitcode);
  1706.                 debug(F111,"os2_netclos NET_CMD","exitcode",exitcode);
  1707.             } else {
  1708.                 printf("!ERROR: Unable to terminate network command!\n");
  1709.                 debug(F110,"os2_netclose NET_CMD",
  1710.                        "unable to termiate network command",0);
  1711.             }
  1712.         }
  1713.  
  1714.         /* Close the pipe handle so the child stops reading. */
  1715.         CloseHandle(hChildStdoutRd);    hChildStdoutRd = NULL;
  1716.         CloseHandle(hChildStdoutWr);    hChildStdoutWr = NULL;
  1717.         CloseHandle(hChildStdinRd);     hChildStdinRd = NULL;
  1718.         CloseHandle(hChildStdinWrDup);  hChildStdinWrDup = NULL;
  1719.         CloseHandle(hChildStdoutRdDup); hChildStdoutRdDup = NULL;
  1720.  
  1721.         CloseHandle( procinfo.hProcess ) ;
  1722.         CloseHandle( procinfo.hThread ) ;
  1723. #else /* NT */
  1724.         ULONG exitcode=STILL_ACTIVE;
  1725.         RESULTCODES res;
  1726.         PID pid2;
  1727.  
  1728.         res.codeTerminate = 99;
  1729.         rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &res, &pid2, pid);
  1730.         if ( (rc==0) && (res.codeTerminate != 99) ) {
  1731.             exitcode = res.codeResult;
  1732.         }
  1733.  
  1734.         if ( exitcode == STILL_ACTIVE && pid )
  1735.         {
  1736.             DosKillProcess(DKP_PROCESSTREE,pid);
  1737.             exitcode = 128;
  1738.             if (!DosWaitChild(DCWA_PROCESSTREE, DCWW_WAIT, &res, &pid2, pid))
  1739.                 exitcode = res.codeResult;
  1740.             debug(F111,"ttruncmd","res.codeResult",res.codeResult);
  1741.  
  1742.         }
  1743.  
  1744.         DosClose(hChildStdinRd); hChildStdinRd = -1;
  1745.         DosClose(hChildStdinWr); hChildStdinWr = -1;
  1746.         DosClose(hChildStdoutRd); hChildStdoutRd = -1;
  1747.         DosClose(hChildStdoutWr); hChildStdoutWr = -1;
  1748.         DosClose(hChildStdinWrDup);  hChildStdinWrDup = -1;
  1749.         DosClose(hChildStdoutRdDup); hChildStdoutRdDup = -1;
  1750.         pid = 0;
  1751. #endif /* NT */
  1752.     }
  1753. #endif /* NETCMD */
  1754. #ifdef NETDLL
  1755.     if ( nettype == NET_DLL ) {
  1756.         if ( net_dll_netclos ) {
  1757.             rc = net_dll_netclos();
  1758.             debug(F111,"net_dll_netclos()",
  1759.                    net_dll_errorstr?net_dll_errorstr(rc):"",rc);
  1760.             rc = (rc < 0 ? -1 : 0 );
  1761.         }
  1762.         else
  1763.             rc = -1;
  1764.     }
  1765. #endif /* NETDLL */
  1766.  
  1767.    ttyfd = -1;                          /* Mark it as closed. */
  1768.    return(rc);
  1769. }
  1770.  
  1771. /*  N E T T C H K  --  Check if network up, and how many bytes can be read */
  1772. /*
  1773.   Returns number of bytes waiting, or -1 if connection has been dropped.
  1774. */
  1775. int                                     /* Check how many bytes are ready */
  1776. os2_nettchk() {                         /* for reading from network */
  1777.    int rc = 0 ;
  1778. #ifdef NPIPE
  1779. #ifdef NT
  1780.     DWORD availdata ;
  1781. #else /* NT */
  1782.     ULONG bytesread ;
  1783.     AVAILDATA availdata ;
  1784.     ULONG PipeState ;
  1785. #endif /* NT */
  1786. #endif /* NPIPE */
  1787.  
  1788. #ifdef SSHBUILTIN
  1789.     if ( nettype == NET_SSH ) {
  1790.         return(ssh_tchk());
  1791.     }
  1792. #endif /* SSHBUILTIN */
  1793.  
  1794. #ifdef CK_NETBIOS
  1795.     if ( nettype == NET_BIOS ) {
  1796.         if ( NetBiosLSN > 0 )
  1797.         {
  1798.             SESSIONINFO statusinfo ;
  1799.  
  1800.             if ( pos < size )
  1801.               return size - pos ;
  1802.  
  1803. #ifndef NONBTCHK
  1804.       /* This is for testing on a machine with LAN Distance installed
  1805.          when we want to run two CKs on the same machine without connecting
  1806.          to a remote network.  NCBSessionStatus fails to return under
  1807.          these conditions.
  1808.       */
  1809.             NCBSessionStatus( NetbeuiAPI, pWorkNCB, NetBiosAdapter, NetBiosName,
  1810.                               &statusinfo, sizeof(SESSIONINFO), TRUE ) ;
  1811.             if ( pWorkNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_SUCCESSFUL &&
  1812.                  statusinfo.session_state >= NB_SESSION_STATE_SESSION_ACTIVE )
  1813. #endif /* NONBTCHK */
  1814.               return 0 ;
  1815.         }
  1816.         return -1 ;
  1817.     }
  1818. #endif /* CK_NETBIOS */
  1819.  
  1820. #ifdef NPIPE
  1821.     if ( nettype == NET_PIPE ) {
  1822.         char buffer[64];
  1823.  
  1824.         if ( pos < size )
  1825.             return size - pos ;
  1826.  
  1827. #ifdef NT
  1828.         if ( PeekNamedPipe(hPipe, NULL, 0, NULL, &availdata, NULL) ) {
  1829.             return availdata;
  1830.         } else {
  1831.             DWORD error = GetLastError();
  1832.             switch ( error ) {
  1833.             case ERROR_PIPE_LISTENING:
  1834.                 return 0;
  1835.             default:
  1836.                 debug(F111,"os2_nettchk","named pipe",error);
  1837.                 return -1;
  1838.             }
  1839.         }
  1840. #else /* NT */
  1841.         if ( !(rc = DosPeekNPipe(hPipe, buffer, sizeof(buffer),
  1842.                                   &bytesread, &availdata, &PipeState)) ) 
  1843.         {
  1844.             switch ( PipeState ) {
  1845.             case NP_STATE_DISCONNECTED:
  1846.             case NP_STATE_CLOSING:
  1847.                 if ( PipeName[0] != PipeName[1] ) {
  1848.                     /* Server Mode */
  1849.                     DosDisConnectNPipe( hPipe ) ;
  1850.                     DosConnectNPipe( hPipe ) ;
  1851.                 } else {
  1852.                     /* Client Mode */
  1853.                     ttclos(0) ;
  1854.                 }   
  1855.                 return -2 ;
  1856.                 break;
  1857.             case NP_STATE_LISTENING:
  1858.                 return 0 ;
  1859.                 break;      
  1860.             case NP_STATE_CONNECTED:
  1861.                 return availdata.cbpipe ;
  1862.                 break;
  1863.             default:
  1864.                 return -1 ;
  1865.             } /* switch */
  1866.         } 
  1867.         return (rc > 0 ? -rc : rc) ;
  1868. #endif /* NT */
  1869.     }
  1870. #endif /* NPIPE */
  1871.  
  1872. #ifdef TCPSOCKET
  1873.     if ( nettype == NET_TCPB )
  1874.       {
  1875.       if (!tcp_avail)
  1876.          return -1 ;
  1877.       return nettchk();
  1878.       }
  1879. #endif /* TCPSOCKET */
  1880.  
  1881. #ifdef DECNET
  1882.    if ( nettype == NET_DEC ) {
  1883.        if ( pos < size ) {
  1884.            return size - pos ;
  1885.        } else {
  1886.            if ( ttnproto == NP_LAT ) {
  1887. #ifdef OS2ONLY
  1888.                memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  1889.                lcb.LatFunction = GET_STATUS ;
  1890.                lcb.SessionHandle = ttyfd;
  1891.                LATENTRY(&lcb);
  1892.                debug(F101,"os2_nettchk (DECNET) lcb.SessionStatus",
  1893.                       "",lcb.SessionStatus) ;
  1894.                debug(F101,"os2_nettchk (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  1895.                return ( lcb.LatStatus & LS_RxData ) ? 1 : 0 ;
  1896. #endif /* OS2ONLY */
  1897. #ifdef NT
  1898.                rc = 0;          /* No way to check the network status */
  1899. #endif /* NT */
  1900.            }
  1901.            else if ( ttnproto == NP_CTERM ) {
  1902. #ifdef OS2ONLY
  1903.                rc = -1;         /* Not implemented */
  1904. #endif /* OS2ONLY */
  1905. #ifdef NT
  1906.                rc = 0;          /* No way to check the network status */
  1907. #endif /* NT */
  1908.            }
  1909.        }
  1910.    }
  1911. #endif /* DECNET */
  1912.  
  1913. #ifdef SUPERLAT
  1914.    if ( nettype == NET_SLAT )
  1915.    {
  1916.       ULONG BytesReturned = 0;
  1917.       static OVERLAPPED OverLapped;
  1918.       static HANDLE  thehEvent = NULL;
  1919.       static char eventString[80];
  1920.       static ReadActive = 0 ;
  1921.       int i;
  1922.  
  1923.       if ( !slat_avail )
  1924.          return -1 ;
  1925.       else if ( pos < size )
  1926.          return size - pos ;
  1927.       else
  1928.       {
  1929. #ifdef COMMENT
  1930.          /*
  1931.             we can't check to see how much data is waiting,
  1932.             so just check to see if the network is still up
  1933.          */
  1934.  
  1935.          if ( !thehEvent )
  1936.             for (i=0; i<200; i++)
  1937.             {
  1938.                thehEvent = CreateEvent (NULL, TRUE, FALSE, eventString);
  1939.                if (!GetLastError())
  1940.                   break;
  1941.             }
  1942.  
  1943.          OverLapped.Offset = 0;
  1944.          OverLapped.OffsetHigh = 0;
  1945.          OverLapped.hEvent = thehEvent;
  1946.                  ResetSem( thehEvent ) ;
  1947.          if (!DeviceIoControl ((HANDLE)ttyfd, IOCTL_TDI_RECEIVE,
  1948.                                 NULL, 0,
  1949.                                 NULL, 0,
  1950.                                 &BytesReturned, NULL))
  1951.          {
  1952.             /* call failed */
  1953.             return -1;
  1954.          }
  1955.          return 0 ;
  1956. #else /* COMMENT */
  1957.           int cmd=0;
  1958.           int ReadCount=-1;
  1959.           int rc=0;
  1960.           cmd = LIOC_PEND_READS;
  1961.  
  1962.           /* Returns non-zero on success */
  1963.           rc = DeviceIoControl ((HANDLE)ttyfd,
  1964.                                  IOCTL_TDI_ACTION,
  1965.                                  &cmd, sizeof (cmd),
  1966.                                  &ReadCount, sizeof (ReadCount),
  1967.                                  &BytesReturned,
  1968.                                  NULL);
  1969.  
  1970.  
  1971.           debug(F111,"os2_nettchk SUPERLAT","ReadCount",ReadCount);
  1972.           debug(F111,"os2_nettchk SUPERLAT","rc",rc);
  1973.           if ( rc )
  1974.           {
  1975.               if ( ReadCount >= 0 )
  1976.                   return (ReadCount);
  1977.               else {
  1978.                   return -1 ;
  1979.               }
  1980.          }
  1981.           else {
  1982.               int gle = GetLastError();
  1983.               debug(F111,"os2_nettchk SUPERLAT","GetLastError",
  1984.                      gle);
  1985.               if ( gle == ERROR_NOT_SUPPORTED )
  1986.                   return(0);
  1987.               else
  1988.                   return(-1);
  1989.          }
  1990. #endif /* COMMENT */
  1991.       }
  1992.    }
  1993. #endif /* SUPERLAT */
  1994.  
  1995. #ifdef NETFILE
  1996.     if ( nettype == NET_FILE ) {
  1997.         rc = 0 ;
  1998.     }
  1999. #endif /* NETFILE */
  2000.  
  2001. #ifdef NETCMD
  2002.     if ( nettype == NET_CMD ) {
  2003. #ifdef NT
  2004.         if (WaitForSingleObject(procinfo.hProcess, 0L) == WAIT_OBJECT_0) {
  2005.             ttclos(0);
  2006.             return(-1);
  2007.         }
  2008. #else   /* NT */
  2009.         RESULTCODES res;
  2010.         PID pid2;
  2011.         ULONG rc;
  2012.  
  2013.         res.codeTerminate = 99;
  2014.  
  2015.         rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &res, &pid2, pid);
  2016.         if ( (rc==0) && (res.codeTerminate != 99) ) {
  2017.             ttclos(0);
  2018.             return(-1);
  2019.         }
  2020.  
  2021. #endif  /* NT */
  2022.         else
  2023.             return(NetCmdInBuf());
  2024.     }
  2025. #endif /* NETCMD */
  2026. #ifdef NETDLL
  2027.     if ( nettype == NET_DLL ) {
  2028.         if ( net_dll_nettchk ) {
  2029.             rc = net_dll_nettchk();
  2030.             debug(F111,"net_dll_nettchk()",
  2031.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  2032.             return(rc < 0 ? -1 : rc );
  2033.         }
  2034.         else
  2035.             return(-1);
  2036.     }
  2037. #endif /* NETDLL */
  2038.  
  2039.     return(0);
  2040. }
  2041.  
  2042. /* N E T X I N -- Input a block of characters from network     */
  2043. /*                handling TELNET negotiations and conversions */
  2044.  
  2045. static char * tngcp = NULL ;
  2046. static int    tngcl = 0 ;
  2047. static int
  2048. ckotngc(int timo) {
  2049.     if ( tngcl == 0 )
  2050.         return os2_netinc(timo) ;
  2051.     else if ( tngcl == 1 ) {
  2052.         char c = *tngcp ;
  2053. #ifdef CK_ENCRYPTION
  2054.         if ( TELOPT_U(TELOPT_ENCRYPTION) )
  2055.             ck_tn_decrypt(&c,1);
  2056. #endif /* CK_ENCRYPTION */
  2057.         *tngcp = 0;
  2058.         tngcl = 0;
  2059.         return c;
  2060.     }
  2061.     else {
  2062.         char c = *tngcp ;
  2063. #ifdef CK_ENCRYPTION
  2064.         if ( TELOPT_U(TELOPT_ENCRYPTION) )
  2065.             ck_tn_decrypt(&c,1);
  2066. #endif /* CK_ENCRYPTION */
  2067.         memmove(tngcp,tngcp+1,--tngcl);
  2068.         tngcp[tngcl] = 0;
  2069.         return c;
  2070.     }
  2071. }
  2072.  
  2073. int
  2074. os2_netxin(int n, CHAR * buf) {
  2075.     int len;
  2076.     int rc ;
  2077.  
  2078. #ifdef SSHBUILTIN
  2079.     if ( nettype == NET_SSH ) {
  2080.         return(ssh_xin(n,buf));
  2081.     }
  2082. #endif /* SSHBUILTIN */
  2083. #ifdef TCPSOCKET
  2084.     if ( nettype == NET_TCPB ) {
  2085.         if (!tcp_avail)
  2086.             return -1 ;
  2087.         len = netxin(n,buf);
  2088.         debug(F101,"os2_netxin returns","",len);
  2089.         if ( len <= 0 )
  2090.             return(len);
  2091. #ifdef TNCODE
  2092.         if (ttnproto == NP_TELNET) {
  2093.             /* Check for Telnet negotiations */
  2094.             extern int u_binary, me_binary, tn_b_meu, tn_b_ume ;
  2095.             int i,tx;
  2096.  
  2097.             hexdump("os2_netxin buf[]",buf,len);
  2098.  
  2099.             for ( i=0;i<len;i++ ) {
  2100. #ifdef CK_ENCRYPTION
  2101.                 if ( TELOPT_U(TELOPT_ENCRYPTION) )
  2102.                     ck_tn_decrypt(&buf[i],1);
  2103. #endif /* CK_ENCRYPTION */
  2104.  
  2105.                 if (i == 0 && NulCheck) {
  2106.                     debug(F110,"os2_netxin","Checking for NUL or LF",0);
  2107.                     NulCheck = 0;
  2108.                     if ( buf[0] == NUL ) {
  2109.                         debug(F111,"os2_netxin","TELNET NUL FOUND",buf[0]);
  2110.                         memmove(buf, &buf[1], len-1 );
  2111.                         len-- ;
  2112.                         i--;
  2113.                         continue;
  2114. #ifdef COMMENT
  2115.                         hexdump("os2_netxin buf[]",buf,len);
  2116. #endif /* COMMENT */
  2117.                     }
  2118.                     else if ( buf[0] == LF ) {
  2119.                         debug(F111,"os2_netxin","TELNET LF FOUND",buf[0]);
  2120.                         debug(F111,"os2_netxin","len",len);
  2121.                     }
  2122.                     else {
  2123.                         debug(F111,"os2_netxin","TELNET ERROR - NUL NOT FOUND",buf[0]);
  2124. #ifdef COMMENT
  2125.                         hexdump("os2_netxin buf[]",buf,len);
  2126. #endif /* COMMENT */
  2127.                     }
  2128.  
  2129.                 }
  2130.  
  2131.                 if ( buf[i] == IAC ) {
  2132.                     debug(F111,"os2_netxin","TELNET IAC FOUND",i);
  2133. #ifdef COMMENT
  2134.                     hexdump("os2_netxin buf[]",buf,len);
  2135. #endif /* COMMENT */
  2136.                     len-- ;             /* take one character out */
  2137.                     tngcp = &buf[i];
  2138.                     tngcl = len-i;
  2139.                     if ( tngcl > 0 )
  2140.                         memmove(tngcp,tngcp+1,tngcl);
  2141.                     tngcp[tngcl] = 0;
  2142.                     if ((tx = tn_doop((CHAR)(IAC),duplex,ckotngc)) == 0) {
  2143.                         len = i + tngcl;
  2144.                         debug(F111,"os2_netxin","len",len);
  2145.                         tngcl = 0 ;
  2146.                         tngcp = NULL ;
  2147.                         i--;
  2148.                         continue;
  2149.                     } else if (tx < 0) {        /* I/O error */
  2150.                         debug(F111,"os2_netxin","TELNET ERROR I/O",i);
  2151.                         len = i + tngcl;
  2152.                         debug(F111,"os2_netxin","len",len);
  2153.                         tngcl = 0 ;
  2154.                         tngcp = NULL ;
  2155.                         return tx;
  2156.                     } else if (tx == 0) {       /* Not TELNET */
  2157.                         debug(F111,"os2_netxin","TELNET ERROR - NOT VALID IAC SEQUENCE",i);
  2158.                         len = i + tngcl;
  2159.                         debug(F111,"os2_netxin","len",len);
  2160.                         tngcl = 0 ;
  2161.                         tngcp = NULL ;
  2162.                         return tx;
  2163.                     } else if (tx == 1) {       /* ECHO change */
  2164.                         duplex = 1;             /* Get next char */
  2165.                         debug(F111,"os2_netxin","TELNET DUPLEX",i);
  2166.                         len = i + tngcl;
  2167.                         debug(F111,"os2_netxin","len",len);
  2168.                         tngcl = 0 ;
  2169.                         tngcp = NULL ;
  2170.                         i--;
  2171.                         continue;
  2172.                     } else if (tx == 2) {       /* ECHO change */
  2173.                         duplex = 0;             /* Get next char */
  2174.                         debug(F111,"os2_netxin","TELNET DUPLEX",i);
  2175.                         len = i + tngcl;
  2176.                         debug(F111,"os2_netxin","len",len);
  2177.                         tngcl = 0 ;
  2178.                         tngcp = NULL ;
  2179.                         i--;
  2180.                         continue;
  2181.                     } else if (tx == 3) {       /* Quoted IAC */
  2182.                         memmove(tngcp+1,tngcp,tngcl);
  2183.                         *tngcp = IAC ;
  2184.                         debug(F111,"os2_netxin","TELNET IAC QUOTED",i);
  2185.                         len = i + tngcl + 1;
  2186.                         debug(F111,"os2_netxin","len",len);
  2187.                         tngcl = 0 ;
  2188.                         tngcp = NULL ;
  2189.                     } else {
  2190.                         debug(F111,"os2_netxin","TELNET OTHER",i);
  2191.                         len = i + tngcl;
  2192.                         debug(F111,"os2_netxin","len",len);
  2193.                         tngcl = 0 ;
  2194.                         tngcp = NULL ;
  2195.                         i--;
  2196.                         continue;
  2197.                     }
  2198.                 }
  2199.                 else if ( (!TELOPT_U(TELOPT_BINARY) &&
  2200.                             !(TELOPT_ME(TELOPT_BINARY) && tn_b_meu)) &&
  2201.                           buf[i] == CR )
  2202.                 {
  2203.                     debug(F111,"os2_netxin","TELNET CR FOUND",i);
  2204.                     debug(F111,"os2_netxin","len",len);
  2205.                     i++ ;
  2206.  
  2207.                     if ( i == len ) {
  2208.                         NulCheck = 1;
  2209.                         debug(F110,"os2_netxin","Check NUL or LF on next call",0);
  2210.                     }
  2211.                     else {
  2212. #ifdef CK_ENCRYPTION
  2213.                         if ( TELOPT_U(TELOPT_ENCRYPTION) )
  2214.                             ck_tn_decrypt(&buf[i],1);
  2215. #endif /* CK_ENCRYPTION */
  2216.                         if ( buf[i] == NUL ) {
  2217.                             debug(F111,"os2_netxin","TELNET NUL FOUND",i);
  2218.                             memmove(&buf[i], &buf[i+1], len-(i+1) );
  2219.                             len-- ;
  2220.                             i--;        /* so that we don't miss an IAC or CR */
  2221. #ifdef COMMENT
  2222.                             hexdump("os2_netxin buf[]",buf,len);
  2223. #endif /* COMMENT */
  2224.                         }
  2225.                         else if ( buf[i] == LF ) {
  2226.                             debug(F111,"os2_netxin","TELNET LF FOUND",i);
  2227.                             debug(F111,"os2_netxin","len",len);
  2228.                         }
  2229.                         else {
  2230.                             debug(F111,"os2_netxin","TELNET ERROR - NUL NOT FOUND",i);
  2231. #ifdef COMMENT
  2232.                             hexdump("os2_netxin buf[]",buf,len);
  2233. #endif /* COMMENT */
  2234.                         }
  2235.                     }
  2236.                 }
  2237.             }
  2238.         }
  2239.         else
  2240. #endif /* TNCODE */
  2241. #ifdef CK_ENCRYPTION
  2242.             if ( TELOPT_U(TELOPT_ENCRYPTION) )
  2243.                 ck_tn_decrypt(buf,len);
  2244. #endif /* CK_ENCRYPTION */
  2245.         return len;
  2246.     }
  2247. #endif /* TCPSOCKET */
  2248. #ifdef NETDLL
  2249.     if ( nettype == NET_DLL ) {
  2250.         int rc = 0;
  2251.         if ( net_dll_netxin ) {
  2252.             rc = net_dll_netxin(n,buf);
  2253.             debug(F111,"net_dll_netxin()",
  2254.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  2255.             return(rc<0?-1:rc);
  2256.         }
  2257.         else
  2258.             return(-1);
  2259.     }
  2260. #endif /* NETDLL */
  2261.  
  2262.     if ( pos == size ) {
  2263.         if ( (rc = os2_netinc(0)) < 0 )
  2264.             return(rc);
  2265.         pos-- ;         /* move it back one position */
  2266.     }
  2267.     len = size - pos ;
  2268.     if (len <= n) {
  2269.         memcpy(buf, &inbuf[pos], len );
  2270.         pos = size ;
  2271.         return(len);
  2272.     }
  2273.     else {
  2274.         memcpy(buf, &inbuf[pos], n ) ;
  2275.         pos += n ;
  2276.         return(n);
  2277.     }
  2278.     return(-1);
  2279. }
  2280.  
  2281. /*  N E T T I N C --  Input character from network */
  2282.  
  2283. int
  2284. os2_netinc(timo) int timo; {
  2285.  
  2286.     int chr = -1;
  2287.     int rc = 0 ;
  2288. #ifdef NT
  2289.     extern int ck_sleepint;
  2290. #endif /* NT */
  2291.  
  2292.     time_t timer, timenow ;
  2293.  
  2294. #ifdef SSHBUILTIN
  2295.     if ( nettype == NET_SSH ) {
  2296.         return(ssh_inc(timo));
  2297.     }
  2298. #endif /* SSHBUILTIN */
  2299. #ifdef CK_NETBIOS
  2300.     if ( nettype == NET_BIOS ) {
  2301.         if ( NetBiosLSN == -1 )
  2302.           return -1 ;
  2303.         else if ( NetBiosLSN == 0 ) {
  2304.             if (pListenNCB->basic_ncb.bncb.ncb_retcode != NB_COMMAND_IN_PROCESS)
  2305.             {
  2306.                 return -1 ;
  2307.             } else {
  2308.                 rc = DosWaitEventSem( hevNetBiosLSN,
  2309.                                        timo > 0 ? timo * 1000 :
  2310.                                        timo < -1 ?
  2311.                                        1000 :
  2312.                                        SEM_INDEFINITE_WAIT ) ;
  2313.                 if (rc)
  2314.                     return -1 ;
  2315.             }
  2316.         }
  2317.         if ( pos < size ) {
  2318.             chr = inbuf[pos++];
  2319.         } else {
  2320.             rc = 0 ;
  2321.             if ((pRecvNCB->basic_ncb.bncb.ncb_retcode) == NB_COMMAND_IN_PROCESS)
  2322.             {
  2323.                 rc = Dos16SemWait( pRecvNCB->basic_ncb.ncb_semaphore,
  2324.                                     timo > 0 ? timo * 1000 :
  2325.                                     timo < -1 ? 1000 : SEM_INDEFINITE_WAIT ) ;
  2326.             }
  2327.             if ( rc ) {
  2328.                 return -1 ;
  2329.             }
  2330.             switch ( pRecvNCB->basic_ncb.bncb.ncb_retcode ) {
  2331.             case NB_COMMAND_SUCCESSFUL:
  2332.                 if ( (size = pRecvNCB->basic_ncb.bncb.ncb_length) == 0 )
  2333.                   return -1 ;
  2334.                 memcpy( inbuf, NetBiosRecvBuf, size ) ;
  2335.                 rc = NCBReceive( NetbeuiAPI, pRecvNCB, NetBiosAdapter,
  2336.                                  NetBiosLSN, NetBiosRecvBuf,
  2337.                                  sizeof(NetBiosRecvBuf), FALSE );
  2338.                 break;
  2339.             case NB_SESSION_CLOSED:
  2340.             case NB_SESSION_ENDED_ABNORMALLY:
  2341.                 ttclos(0) ;
  2342. #ifdef COMMENT
  2343.                 if ( ttname[0] == '*' ) {
  2344.                     os2_netopen( "*",0,0 ) ;
  2345.                     return -1 ;
  2346.                 } else
  2347. #endif /* COMMENT */
  2348.                   return -3 ;
  2349.                 break;
  2350.             case NB_OS_ERROR_DETECTED:
  2351.                 ttclos(0) ;
  2352.                 return -3 ;
  2353.                 break;
  2354.             case NB_COMMAND_IN_PROCESS:
  2355.             case NB_COMMAND_TIME_OUT:
  2356.             case NB_COMMAND_CANCELLED:
  2357.             default:
  2358.                 return -1 ;
  2359.             }
  2360.             pos = 0 ;
  2361.             chr = inbuf[pos++] ;
  2362.         }
  2363.         return chr ;
  2364.     }
  2365. #endif /* CK_NETBIOS */
  2366.  
  2367. #ifdef NPIPE
  2368.     if ( nettype == NET_PIPE ) {
  2369.         if ( timo < -1 )
  2370.           timo = 1 ;                    /* Can't set timeout less than 1 sec */
  2371.         if ( pos < size ) {
  2372.             chr = inbuf[pos++];
  2373.         } else {
  2374.             if ( !timo ) {
  2375.                 while ( !os2_nettchk() )
  2376.                   msleep(100) ;
  2377.             } else {
  2378.                 timer = 0 ;
  2379.                 while (1) {
  2380.                     if ( os2_nettchk() )
  2381.                       break;
  2382.                     if ( timo > 0 ) {
  2383.                         if ( !timer )
  2384.                           timer = time(0) ;
  2385.                         timenow = time(0) ;
  2386.                         if ( timenow - timer > timo )
  2387.                           return -1 ;
  2388.                     }
  2389.                     msleep(100) ;
  2390.                 }
  2391.             }
  2392. #ifdef NT
  2393.             if (ReadFile( hPipe, &inbuf, sizeof(inbuf), &size, NULL)) {
  2394.                 if ( !size )
  2395.                     return -1 ;
  2396.             } else {
  2397.                 DWORD error = GetLastError();
  2398.                 switch ( error ) {
  2399.                 case ERROR_BROKEN_PIPE:
  2400.                     if ( PipeName[0] != PipeName[1] ) {
  2401.                         /* Server Mode */
  2402.                         DisconnectNamedPipe( hPipe ) ;
  2403.                         ConnectNamedPipe( hPipe, NULL ) ;
  2404.                     } else {
  2405.                         /* Client Mode */
  2406.                         ttclos(0) ;
  2407.                     }
  2408.                     return -2 ;
  2409.                     break;
  2410.                 default:
  2411.                     return -1 ;
  2412.                 }
  2413.             }
  2414. #else /* NT */
  2415.             rc = DosRead( hPipe, &inbuf, sizeof(inbuf), &size ) ;
  2416.             switch ( rc ) {
  2417.               case NO_ERROR:
  2418.                 if ( !size )
  2419.                   return -1 ;
  2420.                 break;
  2421.               case ERROR_BROKEN_PIPE:
  2422.                 if ( PipeName[0] != PipeName[1] ) {
  2423.                     /* Server Mode */
  2424.                     DosDisConnectNPipe( hPipe ) ;
  2425.                     DosConnectNPipe( hPipe ) ;
  2426.                 } else {
  2427.                     /* Client Mode */
  2428.                     ttclos(0) ;
  2429.                 }
  2430.                 return -2 ;
  2431.                 break;
  2432.               default:
  2433.                 return -1 ;
  2434.             }
  2435. #endif /* NT */
  2436.             pos = 0 ;
  2437.             chr = inbuf[pos++] ;
  2438.         }
  2439.         return chr ;
  2440.     }
  2441. #endif /* NPIPE */
  2442.  
  2443. #ifdef TCPSOCKET
  2444.     if ( nettype == NET_TCPB ) {
  2445. #ifdef NT
  2446.         int interval, tr, tt, i, t;
  2447.         if (!tcp_avail)
  2448.           return -1 ;
  2449.  
  2450.         if (timo == 0) {                        /* Untimed read. */
  2451.             do {
  2452.                 chr = netinc(-ck_sleepint);
  2453.                 if ( NulCheck && chr > -1 ) {
  2454.                     if ( chr == NUL ) {
  2455.                         debug(F110,"os2_netinc","TELNET NUL FOUND",0);
  2456.                         chr = -1;
  2457.                     } else
  2458.                         debug(F111,"os2_netinc","TELNET NUL NOT FOUND",chr);
  2459.  
  2460.                     NulCheck = 0;
  2461.                 }
  2462. #ifdef NTSIG
  2463.                 ck_ih();
  2464. #endif /* NTSIG */
  2465.             } while (chr == -1);                /* Wait for a character. */
  2466.             return(chr);
  2467.         }
  2468.  
  2469.         if (timo < 0)
  2470.         {
  2471.             timo = -timo;
  2472.             t = 0 ;
  2473.         }
  2474.         else
  2475.         {
  2476.             t = timo ;
  2477.             timo *= 1000;
  2478.         }
  2479.  
  2480.         tr = timo % ck_sleepint;
  2481.         tt = timo / ck_sleepint;
  2482.         if ( tt )
  2483.             interval = ck_sleepint + tr / tt ;
  2484.         else
  2485.         {
  2486.             tt = 1 ;
  2487.             interval = tr ;
  2488.         }
  2489.         for (i = 0; i < tt; i++) {
  2490.             chr = netinc(-interval);
  2491.             if ( NulCheck && chr > -1 ) {
  2492.                 if ( chr == NUL ) {
  2493.                     debug(F110,"os2_netinc","TELNET NUL FOUND",0);
  2494.                     chr = -1;
  2495.                 } else
  2496.                     debug(F111,"os2_netinc","TELNET NUL NOT FOUND",chr);
  2497.  
  2498.                 NulCheck = 0;
  2499.             }
  2500. #ifdef NTSIG
  2501.             ck_ih();
  2502. #endif /* NTSIG */
  2503.             if (chr != -1 )
  2504.                 return(chr);
  2505.         }
  2506.         return (nettchk() == -1) ? -2 : -1;
  2507. #else /* NT */
  2508.         if (!tcp_avail)
  2509.             return -1 ;
  2510.  
  2511.         if ( (chr = netinc(timo)) != -1 ) {
  2512.             if ( NulCheck && chr > -1 ) {
  2513.                 if ( chr == NUL ) {
  2514.                     debug(F110,"os2_netinc","TELNET NUL FOUND",0);
  2515.                     chr = -1;
  2516.                     NulCheck = 0;
  2517.                     chr = os2_netinc(timo);
  2518.                 } else
  2519.                     debug(F110,"os2_netinc","TELNET NUL NOT FOUND",chr);
  2520.  
  2521.                 NulCheck = 0;
  2522.             }
  2523.             return chr;
  2524.         } else
  2525.             return (nettchk() == -1) ? -2 : -1;
  2526. #endif /* NT */
  2527.     }
  2528. #endif /* TCPSOCKET */
  2529.  
  2530. #ifdef DECNET
  2531.     if ( nettype == NET_DEC ) {
  2532.         if ( pos < size )
  2533.           return inbuf[pos++];
  2534.  
  2535.         if ( ttnproto == NP_LAT ) {
  2536. #ifdef OS2ONLY
  2537.             memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  2538.             memset( inbuf, 0, sizeof(inbuf) ) ;
  2539.             lcb.LatFunction = GET_CHAR;
  2540.             lcb.SessionHandle = ttyfd;
  2541.             lcb.BufferSize = 1;
  2542.             lcb.BufferPtr = (void * _Seg16) inbuf;
  2543.  
  2544.             if ( timo < -1 )
  2545.                 lcb.WaitTime = 10L * -timo ;
  2546.             else if ( timo > 0 )
  2547.                 lcb.WaitTime = 1000L * timo ;
  2548.             else
  2549.                 lcb.WaitTime = LAT_INDEFINITE_WAIT ;
  2550.  
  2551.             LATENTRY(&lcb);
  2552.             debug(F101,"os2_netinc (DECNET) lcb.SessionStatus","",
  2553.                    lcb.SessionStatus) ;
  2554.             debug(F101,"os2_netinc (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  2555.             if ( (lcb.SessionStatus & 0xFF) == SS_Stopped )
  2556.                 return -2;
  2557.  
  2558.             if ( lcb.LatStatus ) {
  2559.                 if ( lcb.LatStatus & LS_InvalidSize )
  2560.                     debug(F101,"os2_netinc (DECNET) LS_InvalidSize","",
  2561.                            lcb.BufferSize) ;
  2562.                 return -1 ;
  2563.             }
  2564.             pos = 0;
  2565.             size = lcb.BufferSize;
  2566.             debug(F111,"os2_netinc (DECNET) lcb.BufferSize",inbuf,lcb.BufferSize) ;
  2567.             chr = inbuf[pos++];
  2568. #endif /* OS2ONLY */
  2569. #ifdef NT
  2570.             rc = ReadData((DWORD) ttyfd, inbuf, sizeof(inbuf));
  2571.             if ( rc < 0 ) {
  2572.                 debug(F101,"DECNet LAT ReadData failed","",rc);
  2573.                 return -2;
  2574.             }
  2575.             else if ( rc == 0 ) {
  2576.                 msleep(50);
  2577.                 return -1;
  2578.             }
  2579.             else {
  2580.                 pos = 0;
  2581.                 size = rc;
  2582.                 chr = inbuf[pos++];
  2583.                 inbuf[size]='\0';
  2584.                 debug(F111,"DECNet LAT ReadData",inbuf,rc);
  2585.             }
  2586. #endif /* NT */
  2587.         }
  2588.         else if ( ttnproto == NP_CTERM ) {
  2589. #ifdef OS2ONLY
  2590.             return -2;
  2591. #endif /* OS2ONLY */
  2592. #ifdef NT
  2593.             rc = ReadData((DWORD) ttyfd, inbuf, sizeof(inbuf));
  2594.             if ( rc < 0 ) {
  2595.                 debug(F101,"DECNet CTERM ReadData failed","",rc);
  2596.                 return -2;
  2597.             }
  2598.             else if ( rc == 0 ) {
  2599.                 msleep(50);
  2600.                 return -1;
  2601.             }
  2602.             else {
  2603.                 pos = 0;
  2604.                 size = rc;
  2605.                 chr = inbuf[pos++];
  2606.                 inbuf[size]='\0';
  2607.                 debug(F111,"DECNet CTERM ReadData",inbuf,rc);
  2608.             }
  2609. #endif /* NT */
  2610.         }
  2611.     }
  2612. #endif /* DECNET */
  2613.  
  2614. #ifdef SUPERLAT
  2615.    if ( nettype == NET_SLAT )
  2616.    {
  2617.       static ULONG BytesReturned = 0;
  2618.       static OVERLAPPED OverLapped;
  2619.       static HANDLE  thehEvent = NULL;
  2620.       static char eventString[80] ;
  2621.       static ReadActive = 0 ;
  2622.       int i;
  2623.           static HANDLE fd = 0 ;
  2624.  
  2625.       if ( pos < size )
  2626.          return inbuf[pos++];
  2627.  
  2628.  
  2629.        if ( !thehEvent ) {
  2630.            for (i=0; i<200; i++)
  2631.            {
  2632.                sprintf(eventString,"netinc_event_%d",i);
  2633.                thehEvent = CreateEvent (NULL, TRUE, FALSE, eventString);
  2634.                if (!GetLastError())
  2635.                    break;
  2636.            }
  2637.            debug(F110,"os2_netinc SUPERLAT CreateEvent",eventString,0);
  2638.        }
  2639.  
  2640.       if ( ReadActive )
  2641.       {
  2642.          if ( !timo )
  2643.          {
  2644.             if ( !GetOverlappedResult ((HANDLE) fd, &OverLapped, &BytesReturned, TRUE) )
  2645.             {
  2646.                debug(F111,"os2_netinc SUPERLAT error","GetOverlappedResult(TRUE)",
  2647.                       0xFFFF & GetLastError() ) ;
  2648.                ReadActive = 0 ;
  2649.                return -2 ;
  2650.             }
  2651.             ReadActive = 0 ;
  2652.          }
  2653.          else
  2654.          {
  2655.             if ( !GetOverlappedResult ((HANDLE) fd, &OverLapped, &BytesReturned, FALSE) )
  2656.             {
  2657.                DWORD LastError = GetLastError() ;
  2658.                if ( LastError == ERROR_IO_INCOMPLETE )
  2659.                {
  2660.                   DWORD WaitRet = WaitForSingleObject( OverLapped.hEvent, timo > 0 ? timo * 1000 : -timo ) ;
  2661.                   if ( WaitRet == WAIT_OBJECT_0 )
  2662.                   {
  2663.                      if ( !GetOverlappedResult ((HANDLE) fd, &OverLapped, &BytesReturned, FALSE))
  2664.                      {
  2665.                         debug(F111,"os2_netinc SUPERLAT error",
  2666.                                "WaitRet == WAIT_OBJECT_0 &&GetOverlappedResult(TRUE)",
  2667.                                0xFFFF & GetLastError() ) ;
  2668.                         ReadActive = 0 ;
  2669.                         return -2 ;
  2670.                      }
  2671.                      ReadActive = 0 ;
  2672.                   }
  2673.                   else if ( WaitRet == WAIT_TIMEOUT )
  2674.                   {
  2675. #ifdef COMMENT
  2676.                       debug(F111,"os2_netinc SUPERLAT error",
  2677.                              "WaitRet == WAIT_TIMEOUT &&GetOverlappedResult(TRUE)",
  2678.                              0xFFFF & GetLastError() ) ;
  2679. #endif /* COMMENT */
  2680.                       return -1 ;
  2681.                   }
  2682.                   else
  2683.                   {
  2684.                      debug(F111,"os2_netinc SUPERLAT error","WaitForSingleObject()",
  2685.                             0xFFFF & GetLastError() ) ;
  2686.                      ReadActive = 0 ;
  2687.                      return -1;
  2688.                   }
  2689.                }
  2690.                else if (LastError == ERROR_OPERATION_ABORTED)
  2691.                {
  2692.                    debug(F111,"os2_netinc SUPERLAT error Operation Aborted",
  2693.                           "GetOverlappedResult(FALSE)",LastError);
  2694.                    ReadActive = 0 ;
  2695.                    return -1 ;
  2696.                }
  2697.                else
  2698.                {
  2699.                   debug(F101,"os2_netinc SUPERLAT error","GetOverlappedResult(FALSE)",
  2700.                          0xFFFF & LastError ) ;
  2701.                   ReadActive = 0 ;  /* This outstanding request failed */
  2702.                   return -2 ;
  2703.                }
  2704.             }
  2705.             ReadActive = 0 ;
  2706.          }
  2707.       }
  2708.       else
  2709.       {
  2710.          OverLapped.Offset = 0;
  2711.          OverLapped.OffsetHigh = 0;
  2712.          OverLapped.hEvent = thehEvent;
  2713.                  ResetSem( thehEvent ) ;
  2714.                  fd = (HANDLE) ttyfd ;
  2715.          if (!DeviceIoControl ((HANDLE)fd, IOCTL_TDI_RECEIVE,
  2716.                                 NULL, 0,
  2717.                                 inbuf, sizeof (inbuf),
  2718.                                 &BytesReturned, &OverLapped))
  2719.          {
  2720.             DWORD LastError = GetLastError() ;
  2721.             if (LastError == ERROR_IO_PENDING) {
  2722.                if ( !timo )
  2723.                {
  2724.                   if ( !GetOverlappedResult ((HANDLE) fd, &OverLapped, &BytesReturned, TRUE))
  2725.                   {
  2726.                      return -1 ;
  2727.                   }
  2728.                }
  2729.                else
  2730.                {
  2731.                   DWORD WaitRet = WaitForSingleObject( OverLapped.hEvent, timo > 0 ? timo * 1000 : -timo ) ;
  2732.                   ReadActive = 1 ;
  2733.                   if ( WaitRet == WAIT_OBJECT_0 )
  2734.                   {
  2735.                      if ( !GetOverlappedResult ((HANDLE) fd, &OverLapped, &BytesReturned, FALSE))
  2736.                      {
  2737.                         debug(F111,"os2_netinc SUPERLAT error",
  2738.                                "WaitRet == WAIT_OBJECT_0 && GetOverlappedResult(FALSE)",
  2739.                                0xFFFF & GetLastError() ) ;
  2740.                         ReadActive = 0 ;
  2741.                         return -2;
  2742.                      }
  2743.                      ReadActive = 0 ;
  2744.                   }
  2745.                   else if ( WaitRet == WAIT_TIMEOUT )
  2746.                   {
  2747. #ifdef COMMENT
  2748.                       debug(F111,"os2_netinc SUPERLAT error",
  2749.                              "WaitRet == WAIT_TIMEOUT && GetOverlappedResult(FALSE)",
  2750.                              0xFFFF & GetLastError() ) ;
  2751. #endif /* COMMENT */
  2752.                       return -1 ;
  2753.                   }
  2754.                   else
  2755.                   {
  2756.                      debug(F111,"os2_netinc SUPERLAT error",
  2757.                             "WaitForSingleObject()",
  2758.                             0xFFFF & GetLastError() ) ;
  2759.                      ReadActive = 0 ;
  2760.                      return -2;
  2761.                   }
  2762.                }
  2763.             } else {
  2764.                debug(F111,"os2_netinc SUPERLAT error","GetOverlappedResult()",
  2765.                       0xFFFF & LastError ) ;
  2766.                ReadActive = 0 ; /* This Read Request failed */
  2767.                return -2;
  2768.             }
  2769.          }
  2770.       }
  2771.  
  2772.        if ( (LONG) BytesReturned <= 0 ) {
  2773.            debug(F101,"os2_netinc (SUPERLAT) BytesReturned","",BytesReturned) ;
  2774.            return(BytesReturned?-2:-1);
  2775.        }
  2776.        else {
  2777.            pos = 0;
  2778.            size = BytesReturned ;
  2779. #ifdef COMMENT
  2780.            if ( size < (sizeof(inbuf)-1) )
  2781.                inbuf[size] = '\0' ;
  2782. #endif /* COMMENT */
  2783.            debug(F111,"os2_netinc (SUPERLAT) BytesReturned",inbuf,BytesReturned) ;
  2784.            chr = inbuf[pos++];
  2785.        }
  2786.    }
  2787. #endif /* SUPERLAT */
  2788.  
  2789. #ifdef NETFILE
  2790.    if ( nettype == NET_FILE )
  2791.    {
  2792. #ifdef NT
  2793.        DWORD bytesread = 0;
  2794.        CHAR  c ;
  2795.        if ( ReadFile( (HANDLE) ttyfd, &c, 1, &bytesread, NULL ) && bytesread )
  2796.             chr = c ;
  2797.        else
  2798.        {
  2799.            return -2;
  2800.        }
  2801. #else /* NT */
  2802.        ULONG bytesread = 0 ;
  2803.        UCHAR c ;
  2804.        if ( DosRead( ttyfd, &c, 1, &bytesread ) || !bytesread )
  2805.            return -2 ;
  2806.        else
  2807.            chr = c ;
  2808. #endif /* NT */
  2809.           debug(F111,"netinc NET_FILE","chr",chr);
  2810.    }
  2811. #endif /* NETFILE */
  2812.  
  2813. #ifdef NETCMD
  2814.     if ( nettype == NET_CMD ) {
  2815.         CHAR  c ;
  2816.  
  2817.         if ( !WaitNetCmdAvailSem(timo<0?-timo:timo*1000) ) {
  2818.             if (NetCmdGetChar(&c))
  2819.                 return(c);
  2820.             else
  2821.                 return(-1);
  2822.         }
  2823.         else
  2824.             return(-1);
  2825.     }
  2826. #endif /* NETCMD */
  2827. #ifdef NETDLL
  2828.     if ( nettype == NET_DLL ) {
  2829.         int rc=0;
  2830.         if ( net_dll_netinc ) {
  2831.             rc = net_dll_netinc(timo);
  2832.             debug(F111,"net_dll_netinc()",
  2833.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  2834.             return(rc<0?-1:rc);
  2835.         }
  2836.         else
  2837.             return(-1);
  2838.     }
  2839. #endif /* NETDLL */
  2840.     return chr;
  2841. }
  2842.  
  2843. #ifdef CK_NETBIOS
  2844. static int NextSendNCB = 0 ;
  2845. #endif /* CK_NETBIOS */
  2846.  
  2847. /*  N E T T O C  --   Output character to network */
  2848. /*
  2849.   Call with character to be transmitted.
  2850.   Returns 0 if transmission was successful, or
  2851.   -1 upon i/o error, or -2 if called improperly.
  2852. */
  2853. int
  2854. os2_nettoc(c) int c; {
  2855.  
  2856. #ifdef DECNET
  2857. #ifdef NT
  2858.     char ch = c;
  2859. #else /* NT */
  2860.     int i;
  2861. #endif /* NT */
  2862. #endif /* DECNET */
  2863.     int rc = -1;
  2864.     ULONG bytesWritten ;
  2865.  
  2866. #ifdef SSHBUILTIN
  2867.     if ( nettype == NET_SSH ) {
  2868.         return(ssh_toc(c));
  2869.     }
  2870. #endif /* SSHBUILTIN */
  2871. #ifdef CK_NETBIOS
  2872.     if ( nettype == NET_BIOS ) {
  2873.         int i = 0 ;
  2874.         int SendNCB ;
  2875.         UCHAR chr = c ;
  2876.         if ( NetBiosLSN == -1 )
  2877.           return -1 ;
  2878.         else if ( NetBiosLSN == 0 ) {
  2879. #ifdef COMMENT
  2880. /*
  2881.   This code enables us to issue a blocking send prior to the
  2882.   establishment of a connection.  The problem with this is that
  2883.   when a connection terminates and we are in Kermit Server mode,
  2884.   the Kermit Server will send a NAK in response to the timeout it
  2885.   received when the connection was lost.  This NAK will be the
  2886.   first packet received by the next Client to complete a connection,
  2887.   and all packets in the exchange will be out of sequence.
  2888.  
  2889.   Therefore, we don't allow packets to be issued prior to the
  2890.   establishment of a real connection.
  2891. */
  2892.             if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  2893.                  NB_COMMAND_IN_PROCESS )
  2894.             {
  2895.                 return -1 ;
  2896.             } else {
  2897.                 rc = DosWaitEventSem( hevNetBiosLSN,
  2898.                                       SEM_INDEFINITE_WAIT ) ;
  2899.                 if (rc)
  2900.                     return -1 ;
  2901.             }
  2902. #else
  2903.             if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  2904.                  NB_COMMAND_SUCCESSFUL )
  2905.               return -1 ;
  2906. #endif /* COMMENT */
  2907.         }
  2908.  
  2909.         /* If there are no Window Slot NCBs, then just return an error */
  2910.         if ( MaxWs <= 0 )
  2911.             return -1 ;
  2912.  
  2913.         /* Find an unused NCB, or block until one becomes free */
  2914.         SendNCB = 0 ;
  2915.         while (1) {
  2916.             if ( SendNCB == MaxWs ) {
  2917.                 SendNCB = 0 ;
  2918.                 msleep(250);
  2919.             }
  2920.             if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  2921.                  != NB_COMMAND_IN_PROCESS )
  2922.               break;
  2923.             SendNCB++ ;
  2924.         }
  2925.  
  2926.         if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  2927.              == NB_COMMAND_IN_PROCESS) {
  2928.             NCB CancelNCB ;
  2929.             rc = NCBCancel( NetbeuiAPI, &CancelNCB, NetBiosAdapter,
  2930.                             pSendNCB[SendNCB] ) ;
  2931.             Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  2932.                           SEM_INDEFINITE_WAIT ) ;
  2933.         }
  2934.         memcpy( NetBiosSendBuf[SendNCB], &chr, sizeof(chr) ) ;
  2935.         rc = NCBSend( NetbeuiAPI, pSendNCB[SendNCB], NetBiosAdapter,
  2936.                       NetBiosLSN, NetBiosSendBuf[SendNCB], sizeof(chr), FALSE );
  2937. #ifdef COMMENT
  2938.         /* Let's try a nonblocking Send */
  2939.         Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  2940.                       SEM_INDEFINITE_WAIT ) ;
  2941. #endif /* COMMENT */
  2942.  
  2943.         switch ( pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode ) {
  2944.         case NB_COMMAND_SUCCESSFUL:
  2945.         case NB_COMMAND_IN_PROCESS:
  2946.             return 0 ;
  2947.             break;
  2948.         case NB_SESSION_CLOSED:
  2949.         case NB_SESSION_ENDED_ABNORMALLY:
  2950.             ttclos(0) ;
  2951. #ifdef COMMENT
  2952.             if ( ttname[0] == '*' ) {
  2953.                 os2_netopen( "*",0,0 ) ;
  2954.                 return -1 ;
  2955.             } else
  2956. #endif /* COMMENT */
  2957.               return -2 ;
  2958.             break;
  2959.         case NB_OS_ERROR_DETECTED:
  2960.             ttclos(0) ;
  2961.             return -3 ;
  2962.             break;
  2963.         case NB_COMMAND_TIME_OUT:
  2964.         case NB_COMMAND_CANCELLED:
  2965.         default:
  2966.             return -1 ;
  2967.         }
  2968.     }
  2969. #endif /* CK_NETBIOS */
  2970.  
  2971. #ifdef NPIPE
  2972.     if ( nettype == NET_PIPE ) {
  2973.         UCHAR  chr = c ;
  2974. #ifdef NT
  2975.         if (WriteFile( hPipe, &chr, sizeof(chr), &bytesWritten, NULL ))
  2976.             return 0;
  2977.         else 
  2978.             return -1;
  2979. #else /* NT */
  2980.         rc = DosWrite( hPipe, &chr, sizeof(chr), &bytesWritten ) ;
  2981.         if ( rc )
  2982.           return -1 ;
  2983.         else
  2984.           return 0 ;
  2985. #endif /* NT */
  2986.     }
  2987. #endif /* NPIPE */
  2988.  
  2989. #ifdef TCPSOCKET
  2990.     if ( nettype == NET_TCPB ) {
  2991.         if (!tcp_avail)
  2992.           return -1 ;
  2993.         return nettoc((char) c);
  2994.     }
  2995. #endif /* TCPSOCKET */
  2996.  
  2997. #ifdef DECNET
  2998.     if ( nettype == NET_DEC ) {
  2999.  
  3000.         if ( ttnproto == NP_LAT ) {
  3001. #ifdef OS2ONLY
  3002.             debug(F100,"os2_nettoc (DECNET) begin send char","",0);
  3003.  
  3004.             /* send the character */
  3005.             memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  3006.             lcb.LatFunction = SEND_CHAR;
  3007.             lcb.SessionHandle = ttyfd;
  3008.             lcb.CharByte = c;
  3009.  
  3010.             LATENTRY(&lcb);
  3011.             debug(F101,"os2_nettoc (DECNET) lcb.SessionStatus","",
  3012.                    lcb.SessionStatus) ;
  3013.             debug(F101,"os2_nettoc (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  3014.  
  3015.             for (i = 0; i < 10000 && ( lcb.LatStatus & LS_CharNotSent ); i++) {
  3016.                 msleep(1);              /* give up rest of current time slice */
  3017.                 LATENTRY(&lcb) ;
  3018.                 debug(F100,"os2_nettoc (DECNET) repeat char send","",0);
  3019.                 debug(F101,"os2_nettoc (DECNET) lcb.SessionStatus",
  3020.                        "",lcb.SessionStatus) ;
  3021.                 debug(F101,"os2_nettoc (DECNET) lcb.LatStatus","",lcb.LatStatus) ;
  3022.             }
  3023.  
  3024.             debug(F100,"os2_nettoc (DECNET) end send char","",0);
  3025.  
  3026.             rc = (lcb.LatStatus == LS_NoError) ? 0 : -1;
  3027. #endif /* OS2ONLY */
  3028. #ifdef NT
  3029.             debug(F111,"DECNet LAT WriteData","ch",ch);
  3030.             rc = WriteData((DWORD) ttyfd, &ch, 1);
  3031.             while ( rc == TAL_TXQUEFULL ) {
  3032.                 debug(F111,"DECNet LAT WriteData","TXQUEFULL",rc);
  3033.                 msleep(250);
  3034.                 rc = WriteData((DWORD) ttyfd, &ch, 1);
  3035.             }
  3036.             if ( rc ) {
  3037.                 debug(F101,"DECNet LAT WriteData failed","",rc);
  3038.                 rc = -1;
  3039.             }
  3040. #endif /* NT */
  3041.         }
  3042.         else if ( ttnproto == NP_CTERM ) {
  3043. #ifdef OS2ONLY
  3044.             rc = -1;
  3045. #endif /* OS2ONLY */
  3046. #ifdef NT
  3047.             debug(F111,"DECNet CTERM WriteData","ch",ch);
  3048.             rc = WriteData((DWORD) ttyfd, &ch, 1);
  3049.             while ( rc == TAL_TXQUEFULL ) {
  3050.                 debug(F111,"DECNet CTERM WriteData","TXQUEFULL",rc);
  3051.                 msleep(250);
  3052.                 rc = WriteData((DWORD) ttyfd, &ch, 1);
  3053.             }
  3054.             if ( rc ) {
  3055.                 debug(F101,"DECNet CTERM WriteData failed","",rc);
  3056.                 rc = -1;
  3057.             }
  3058. #endif /* NT */
  3059.         }
  3060.     }
  3061. #endif /* DECNET */
  3062.  
  3063. #ifdef SUPERLAT
  3064.    if ( nettype == NET_SLAT )
  3065.    {
  3066.       static HANDLE  thehEvent=NULL;
  3067.       int     i;
  3068.       char    ch;
  3069.       static DWORD BytesWritten=0;
  3070.       DWORD LastError = 0 ;
  3071.       static OVERLAPPED OverLapped;
  3072.       static char eventString[80];
  3073.           HANDLE fd = (HANDLE) ttyfd ;
  3074.  
  3075.        if ( !thehEvent ) {
  3076.            for (i=0; i<200; i++)
  3077.            {
  3078.                sprintf (eventString, "nettoc_event_%d", i);
  3079.                thehEvent = CreateEvent (NULL, FALSE, FALSE, eventString);
  3080.  
  3081.                if (!GetLastError())
  3082.                    break;
  3083.            }
  3084.            debug(F110,"os2_nettoc SUPERLAT CreateEvent",eventString,0);
  3085.        }
  3086.  
  3087.       OverLapped.Offset = 0;
  3088.       OverLapped.OffsetHigh = 0;
  3089.       OverLapped.hEvent = thehEvent;
  3090.       ResetSem( thehEvent ) ;
  3091.  
  3092.       ch = (char) c ;
  3093.       SetLastError (0);
  3094.       if (!DeviceIoControl ((HANDLE)fd, IOCTL_TDI_SEND,
  3095.                              &ch, sizeof (ch),
  3096.                              NULL, 0, &BytesWritten,
  3097.                              isWin95() ? NULL : &OverLapped ))
  3098.       {
  3099.          LastError = GetLastError() ;
  3100.          if (LastError == ERROR_IO_PENDING) {
  3101. #ifdef COMMENT
  3102.             DWORD WaitRet = WAIT_TIMEOUT ;
  3103.             while ( WaitRet == WAIT_TIMEOUT )
  3104.             {
  3105.                WaitRet = WaitForSingleObject( OverLapped.hEvent, ck_sleepint );
  3106. #ifdef NTSIG
  3107.                ck_ih() ;
  3108. #endif /* NTSIG */
  3109.             }
  3110.  
  3111.             if ( ttyfd >= 0 && WaitRet == WAIT_OBJECT_0)
  3112.             {
  3113.             }
  3114.             else
  3115.             {
  3116.                debug(F101, "nettoc SUPERLAT WaitForSingleObject error","",GetLastError());
  3117.                BytesWritten = -1 ;
  3118.             }
  3119. #else /* COMMENT */
  3120.             if ( !GetOverlappedResult ((HANDLE)fd, &OverLapped, &BytesWritten, TRUE))
  3121.             {
  3122.                debug(F101, "nettoc SUPERLAT GetOverlappedResult error","",GetLastError());
  3123.                BytesWritten = -1;
  3124.             }
  3125. #endif /* COMMENT */
  3126.          } else {
  3127.             BytesWritten = -2; /* Anything else is a hard error */
  3128.          }
  3129.       }
  3130.       rc = BytesWritten == 1 ? 0 : -1 ;
  3131.    }
  3132. #endif /* SUPERLAT */
  3133.  
  3134. #ifdef NETFILE
  3135.     if ( nettype == NET_FILE ) {
  3136.         rc = 0;
  3137.         debug(F111,"nettoc NET_FILE","c",c);
  3138.     }
  3139. #endif /* NETFILE */
  3140.  
  3141. #ifdef NETCMD
  3142.     if ( nettype == NET_CMD ) {
  3143. #ifdef NT
  3144.         ULONG byteswritten=0;
  3145.         if ( !WriteFile( hChildStdinWrDup, &c, 1, &byteswritten, NULL ) )
  3146.         {
  3147.             debug(F101,"nettoc unable to write to child process","",GetLastError());
  3148.             return(-1);
  3149.         }
  3150.         else if (byteswritten == 1)
  3151.             return(0);
  3152.         else
  3153.             return(-1);
  3154. #else   /* NT */
  3155.         UINT written;
  3156.         if(DosWrite(hChildStdinWrDup,&c,1,(PVOID)&written))
  3157.             return -1 ;
  3158.         else if (written == 1)
  3159.             return(0);
  3160.         else
  3161.             return -1;
  3162. #endif /* NT */
  3163.     }
  3164. #endif /* NETCMD */
  3165. #ifdef NETDLL
  3166.     if ( nettype == NET_DLL ) {
  3167.         if ( net_dll_nettoc ) {
  3168.             int rc=0;
  3169.             rc = net_dll_nettoc(c);
  3170.             debug(F111,"net_dll_nettoc()",
  3171.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  3172.             return(rc<0?-1:rc);
  3173.         }
  3174.         else
  3175.             return(-1);
  3176.     }
  3177. #endif /* NETDLL */
  3178.  
  3179.     return rc;
  3180. }
  3181.  
  3182. /*  N E T X O U T --  Output block of characters to network       */
  3183. /*                    performing TELNET translations as necessary */
  3184. /*
  3185.   Call with s = pointer to string, n = length.
  3186.   Returns number of bytes actually written on success, or
  3187.   -1 on i/o error, -2 if called improperly.
  3188.   Relies on nettol() to do the actual transmission.
  3189. */
  3190. int
  3191. os2_netxout(char *s, int n)
  3192. {
  3193.     int rc = 0 ;
  3194.  
  3195. #ifdef SSHBUILTIN
  3196.     if ( nettype == NET_SSH ) {
  3197.         return(ssh_tol(s,n));
  3198.     }
  3199. #endif /* SSHBUILTIN */
  3200.     if ( nettype == NET_TCPB ) {
  3201.         if (!tcp_avail)
  3202.             return -1 ;
  3203. #ifdef TNCODE
  3204.         if ( ttnproto == NP_TELNET ) {
  3205.             /* Handle TELNET conversions */
  3206.             extern int u_binary, me_binary, tn_b_meu, tn_b_ume ;
  3207.             static char buf[12288] ;
  3208.             int len = 0, i=0 ;
  3209.  
  3210.             while ( i < n ) {
  3211.             for ( ; i<n && len<12277 ; i++,len++ ) {
  3212.                 buf[len] = s[i] ;
  3213.                 if ( s[i] == IAC ) {
  3214.                     len++ ;
  3215.                     buf[len] = IAC ;
  3216.                 }
  3217.                 else if ( s[i] == CR && !TELOPT_ME(TELOPT_BINARY) &&
  3218.                           !(TELOPT_U(TELOPT_BINARY) && tn_b_ume) ) {
  3219.                     len++ ;
  3220.                     buf[len] = NUL ;
  3221.                 }
  3222.             }
  3223.             rc = nettol(buf,len);
  3224.             if ( rc < 0 )
  3225.                 return(rc);
  3226.             else if ( rc != len )
  3227.                 return(i);
  3228.             else
  3229.                 len = 0 ;
  3230.             }
  3231.             rc = n ;
  3232.         }
  3233.         else
  3234. #endif /* TNCODE */
  3235.             rc = nettol(s,n);
  3236.     }
  3237.     else
  3238.         rc = os2_nettol(s,n);
  3239.     return rc;
  3240. }
  3241.  
  3242.  
  3243. /*  N E T T O L  --  Output a string of bytes to the network  */
  3244. /*
  3245.   Call with s = pointer to string, n = length.
  3246.   Returns number of bytes actually written on success, or
  3247.   -1 on i/o error, -2 if called improperly.
  3248. */
  3249. int
  3250. os2_nettol(s,n) char *s; int n; {
  3251.     int rc=0;
  3252. #ifdef CK_NETBIOS
  3253.     int SendNCB ;
  3254. #endif /* CK_NETBIOS */
  3255. #ifdef NPIPE
  3256.     ULONG bytesWritten ;
  3257. #endif /* NPIPE */
  3258.  
  3259. #ifdef SSHBUILTIN
  3260.     if ( nettype == NET_SSH ) {
  3261.         return(ssh_tol(s,n));
  3262.     }
  3263. #endif /* SSHBUILTIN */
  3264. #ifdef TCPSOCKET
  3265.     if ( nettype == NET_TCPB ) {
  3266.         if (!tcp_avail)
  3267.           return -1 ;
  3268.         return nettol(s, n);
  3269.     }
  3270. #endif /* TCPSOCKET */
  3271.  
  3272. #ifdef CK_NETBIOS
  3273.     if ( nettype == NET_BIOS ) {
  3274.         if ( NetBiosLSN == -1 )
  3275.           return -3 ;
  3276.         else if ( NetBiosLSN == 0 ) {
  3277. #ifdef COMMENT
  3278. /*
  3279.   This code enables us to issue a blocking send prior to the
  3280.   establishment of a connection.  The problem with this is that
  3281.   when a connection terminates and we are in Kermit Server mode,
  3282.   the Kermit Server will send a NAK in response to the timeout it
  3283.   received when the connection was lost.  This NAK will be the
  3284.   first packet received by the next Client to complete a connection,
  3285.   and all packets in the exchange will be out of sequence.
  3286.  
  3287.   Therefore, we don't allow packets to be issued prior to the
  3288.   establishment of a real connection.
  3289. */
  3290.             if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  3291.                  NB_COMMAND_IN_PROCESS )
  3292.             {
  3293.                 return -1 ;
  3294.             } else {
  3295.                 rc = DosWaitEventSem( hevNetBiosLSN,
  3296.                                       SEM_INDEFINITE_WAIT ) ;
  3297.                 if (rc)
  3298.                     return -1 ;
  3299.             }
  3300. #else
  3301.             if ( pListenNCB->basic_ncb.bncb.ncb_retcode !=
  3302.                  NB_COMMAND_SUCCESSFUL )
  3303.               return -1 ;
  3304. #endif /* COMMENT */
  3305.         }
  3306.  
  3307.         /* If there are no Window Slot NCBs, then just return an error */
  3308.         if ( MaxWs <= 0 )
  3309.             return -1 ;
  3310.  
  3311.         /* Find an unused NCB, or block until one becomes free */
  3312.         SendNCB = 0 ;
  3313.         while (1) {
  3314.             if ( SendNCB == MaxWs ) {
  3315.                 SendNCB = 0 ;
  3316.                 msleep(250);
  3317.             }
  3318.             if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  3319.                  != NB_COMMAND_IN_PROCESS )
  3320.               break;
  3321.             SendNCB++ ;
  3322.         }
  3323.  
  3324.         if (pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode
  3325.              == NB_COMMAND_IN_PROCESS) {
  3326.             NCB CancelNCB ;
  3327.             rc = NCBCancel( NetbeuiAPI, &CancelNCB, NetBiosAdapter,
  3328.                             pSendNCB[SendNCB] );
  3329.             Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  3330.                           SEM_INDEFINITE_WAIT ) ;
  3331.         }
  3332.         memcpy( NetBiosSendBuf[SendNCB], s, n ) ;
  3333.         rc = NCBSend( NetbeuiAPI, pSendNCB[SendNCB], NetBiosAdapter,
  3334.                       NetBiosLSN, NetBiosSendBuf[SendNCB], n, FALSE ) ;
  3335. #ifdef COMMENT
  3336.         /* Lets try a non blocking Send */
  3337.         Dos16SemWait( pSendNCB[SendNCB]->basic_ncb.ncb_semaphore,
  3338.                       SEM_INDEFINITE_WAIT ) ;
  3339. #endif /* COMMENT */
  3340.  
  3341.         debug(F101,"NETTOL: SendNCB","",SendNCB ) ;
  3342.         debug(F101,"NETTOL: NCB_retcode","",
  3343.                pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode ) ;
  3344.  
  3345.         switch ( pSendNCB[SendNCB]->basic_ncb.bncb.ncb_retcode ) {
  3346.         case NB_COMMAND_SUCCESSFUL:
  3347.         case NB_COMMAND_IN_PROCESS:
  3348.             return pSendNCB[SendNCB]->basic_ncb.bncb.ncb_length ;
  3349.             break;
  3350.         case NB_SESSION_CLOSED:
  3351.         case NB_SESSION_ENDED_ABNORMALLY:
  3352.             ttclos(0) ;
  3353. #ifdef COMMENT
  3354.             if ( ttname[0] == '*' ) {
  3355.                 os2_netopen( "*",0,0 ) ;
  3356.                 return -1 ;
  3357.             } else
  3358. #endif /* COMMENT */
  3359.               return -2 ;
  3360.             break;
  3361.         case NB_OS_ERROR_DETECTED:
  3362.             ttclos(0) ;
  3363.             return -3 ;
  3364.             break;
  3365.         case NB_MAX_CMNDS_EXCEEDED:
  3366.         case NB_COMMAND_TIME_OUT:
  3367.         case NB_COMMAND_CANCELLED:
  3368.         default:
  3369.             return -1 ;
  3370.         }
  3371.     }
  3372. #endif /* CK_NETBIOS */
  3373.  
  3374. #ifdef NPIPE
  3375.     if ( nettype == NET_PIPE ) {
  3376. #ifdef NT
  3377.         if (WriteFile( hPipe, s, n, &bytesWritten, NULL ))
  3378.             return bytesWritten;
  3379.         else
  3380.             return -1;
  3381. #else /* NT */
  3382.         rc = DosWrite( hPipe, s, n, &bytesWritten ) ;
  3383.         return ( rc ? -1 : bytesWritten ) ;
  3384. #endif /* NT */
  3385.     }
  3386. #endif /* NPIPE */
  3387.  
  3388. #ifdef DECNET
  3389.     if ( nettype == NET_DEC ) {
  3390.         int i ;
  3391.         if ( ttnproto == NP_LAT ) {
  3392. #ifdef OS2ONLY
  3393.             for ( rc = 0; rc < n; rc++, s++ )
  3394.                 if ( i = os2_nettoc(*s) ) {
  3395.                     return i ;
  3396.                 }
  3397. #endif /* OS2ONLY */
  3398. #ifdef NT
  3399.             debug(F111,"DECNet LAT WriteData",s,n);
  3400.             rc = WriteData((DWORD) ttyfd, s, n);
  3401.             while ( rc == TAL_TXQUEFULL ) {
  3402.                 debug(F111,"DECNet LAT WriteData","TXQUEFULL",rc);
  3403.                 msleep(250);
  3404.                 rc = WriteData((DWORD) ttyfd, s, n);
  3405.             }
  3406.             if ( rc ) {
  3407.                 debug(F101,"DECNet LAT WriteData failed","",rc);
  3408.                 rc = -1;
  3409.             }
  3410.             else {
  3411.                 rc = n;
  3412.             }
  3413. #endif /* NT */
  3414.         }
  3415.         else if ( ttnproto == NP_CTERM ) {
  3416. #ifdef OS2ONLY
  3417.             rc = -1;
  3418. #endif /* OS2ONLY */
  3419. #ifdef NT
  3420.             debug(F111,"DECNet CTERM WriteData",s,n);
  3421.             rc = WriteData((DWORD) ttyfd, s, n);
  3422.             while ( rc == TAL_TXQUEFULL ) {
  3423.                 debug(F111,"DECNet CTERM WriteData","TXQUEFULL",rc);
  3424.                 msleep(250);
  3425.                 rc = WriteData((DWORD) ttyfd, s, n);
  3426.             }
  3427.             if ( rc ) {
  3428.                 debug(F101,"DECNet CTERM WriteData failed","",rc);
  3429.                 rc = -1;
  3430.             }
  3431.             else {
  3432.                 rc = n;
  3433.             }
  3434. #endif /* NT */
  3435.         }
  3436.     }
  3437. #endif /* DECNET */
  3438.  
  3439. #ifdef SUPERLAT
  3440.    if ( nettype == NET_SLAT )
  3441.    {
  3442.       static HANDLE  thehEvent=NULL;
  3443.       int     i;
  3444.       static DWORD BytesWritten=0;
  3445.       DWORD LastError=0;
  3446.       static OVERLAPPED OverLapped;
  3447.       static char eventString[80];
  3448.      HANDLE fd = (HANDLE) ttyfd ;
  3449.  
  3450.       if ( !thehEvent )
  3451.          for (i=0; i<200; i++)
  3452.          {
  3453.             sprintf (eventString, "nettol_event_%d", i);
  3454.             thehEvent = CreateEvent (NULL, FALSE, FALSE, eventString);
  3455.  
  3456.             if (!GetLastError())
  3457.                break;
  3458.          }
  3459.  
  3460.       OverLapped.Offset = 0;
  3461.       OverLapped.OffsetHigh = 0;
  3462.       OverLapped.hEvent = thehEvent;
  3463.       ResetSem( thehEvent ) ;
  3464.  
  3465.       SetLastError (0);
  3466.       if (!DeviceIoControl ((HANDLE)fd, IOCTL_TDI_SEND,
  3467.                              s, n, NULL, 0, &BytesWritten,
  3468.                              isWin95() ? NULL : &OverLapped ))
  3469.       {
  3470.          LastError = GetLastError() ;
  3471.          if (LastError == ERROR_IO_PENDING) {
  3472. #ifdef COMMENT
  3473.             DWORD WaitRet = WAIT_TIMEOUT ;
  3474.             while ( WaitRet == WAIT_TIMEOUT )
  3475.             {
  3476. #ifdef NTSIG
  3477.                ck_ih() ;
  3478. #endif /* NTSIG */
  3479.                WaitRet = WaitForSingleObject( OverLapped.hEvent, ck_sleepint );
  3480.             }
  3481.  
  3482.             if ( WaitRet == WAIT_OBJECT_0 && ttyfd >= 0 )
  3483.             {
  3484.                if ( !GetOverlappedResult ((HANDLE)fd, &OverLapped, &BytesWritten, TRUE))
  3485.                {
  3486.                   debug(F101, "nettol SUPERLAT GetOverlappedResult error","",GetLastError());
  3487.                   BytesWritten = -1;
  3488.                }
  3489.             }
  3490.             else
  3491.             {
  3492.                debug(F101, "nettol SUPERLAT WaitForSingleObject error","",GetLastError());
  3493.                BytesWritten = -1 ;
  3494.             }
  3495. #else /* COMMENT */
  3496.             if ( !GetOverlappedResult ((HANDLE)fd, &OverLapped, &BytesWritten, TRUE))
  3497.             {
  3498.                debug(F101, "nettol SUPERLAT GetOverlappedResult error","",GetLastError());
  3499.                BytesWritten = -1;
  3500.             }
  3501. #endif /* COMMENT */
  3502.          } else {
  3503.             BytesWritten = -2;  /* Hard Error */
  3504.          }
  3505.       }
  3506.       rc = BytesWritten ;
  3507.    }
  3508. #endif /* SUPERLAT */
  3509.  
  3510. #ifdef NETFILE
  3511.    if ( nettype == NET_FILE ) {
  3512.        int i;
  3513.        for ( i=0;i<n;i++ )
  3514.            nettoc(s[i]);
  3515.        rc = n;
  3516.  
  3517.    }
  3518. #endif /* NETFILE */
  3519.  
  3520. #ifdef NETCMD
  3521.     if ( nettype == NET_CMD ) {
  3522. #ifdef NT
  3523.         ULONG byteswritten=0;
  3524.         if ( !WriteFile( hChildStdinWrDup, s, n, &byteswritten, NULL ) )
  3525.         {
  3526.             debug(F101,"nettol unable to write to child process","",GetLastError());
  3527.             return(-1);
  3528.         }
  3529.         else
  3530.             return(byteswritten);
  3531. #else   /* NT */
  3532.         UINT written;
  3533.         if(DosWrite(hChildStdinWrDup, s,n,(PVOID)&written))
  3534.             return -1 ;
  3535.         else
  3536.             return written;
  3537. #endif  /* NT */
  3538.     }
  3539. #endif /* NETCMD */
  3540. #ifdef NETDLL
  3541.     if ( nettype == NET_DLL ) {
  3542.         if ( net_dll_nettol ) {
  3543.             int rc = 0;
  3544.             rc = net_dll_nettol(s,n);
  3545.             debug(F111,"net_dll_nettol()",
  3546.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  3547.             return(rc<0?-1:rc);
  3548.         }
  3549.         else
  3550.             return(-1);
  3551.     }
  3552. #endif /* NETDLL */
  3553.  
  3554.     return(rc);
  3555. }
  3556.  
  3557. /*  N E T F L U I  --  Flush network input buffer  */
  3558.  
  3559. int
  3560. os2_netflui() {
  3561.  
  3562. #ifdef SSHBUILTIN
  3563.     if ( nettype == NET_SSH ) {
  3564.         return(ssh_flui());
  3565.     }
  3566. #endif /* SSHBUILTIN */
  3567. #ifdef CK_NETBIOS
  3568.     if ( nettype == NET_BIOS ) {
  3569.       pos = size ;
  3570.       return 0 ;
  3571.     }
  3572. #endif /* CK_NETBIOS */
  3573.  
  3574. #ifdef NPIPE
  3575.     if ( nettype == NET_PIPE ) {
  3576.       pos = size ;
  3577.       return 0 ;
  3578.     }
  3579. #endif /* NPIPE */
  3580.  
  3581. #ifdef TCPSOCKET
  3582.     if ( nettype == NET_TCPB )
  3583.     {
  3584.         if (!tcp_avail)
  3585.           return 0 ;
  3586.         return netflui();
  3587.     }
  3588. #endif /* TCPSOCKET */
  3589.  
  3590. #ifdef DECNET
  3591.     if ( nettype == NET_DEC ) {
  3592.       pos = size ;
  3593.       return (0) ;
  3594.     }
  3595. #endif /* DECNET */
  3596.  
  3597. #ifdef SUPERLAT
  3598.    if ( nettype == NET_SLAT )
  3599.    {
  3600.       pos = size ;
  3601.       return(0);
  3602.    }
  3603. #endif /* SUPERLAT */
  3604.  
  3605. #ifdef NETFILE
  3606.     if ( nettype == NET_FILE ) {
  3607.        return 0;
  3608.     }
  3609. #endif /* NETFILE */
  3610.  
  3611. #ifdef NETCMD
  3612.     if ( nettype == NET_CMD ) {
  3613.         return(0);
  3614.     }
  3615. #endif /* NETCMD */
  3616. #ifdef NETDLL
  3617.     if ( nettype == NET_DLL ) {
  3618.         if ( net_dll_netflui ) {
  3619.             int rc=0;
  3620.             rc = net_dll_netflui();
  3621.             debug(F111,"net_dll_netflui()",
  3622.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  3623.             return(rc<0?-1:rc);
  3624.         }
  3625.         else
  3626.             return(-1);
  3627.     }
  3628. #endif /* NETDLL */
  3629.     return(0);
  3630. }
  3631.  
  3632. /* Send network BREAK */
  3633. /*
  3634.   Returns -1 on error, 0 if nothing happens, 1 if BREAK sent successfully.
  3635. */
  3636. int
  3637. os2_netbreak() {
  3638.  
  3639.     int rc = -1;
  3640.  
  3641. #ifdef SSHBUILTIN
  3642.     if ( nettype == NET_SSH ) {
  3643.         return(ssh_break());
  3644.     }
  3645. #endif /* SSHBUILTIN */
  3646. #ifdef CK_NETBIOS
  3647.     if ( nettype == NET_BIOS ) {
  3648.         return 0 ;
  3649.     }
  3650. #endif /* CK_NETBIOS */
  3651.  
  3652. #ifdef NPIPE
  3653.     if ( nettype == NET_PIPE )
  3654.       return 0 ;
  3655. #endif /* NPIPE */
  3656.  
  3657. #ifdef TCPSOCKET
  3658.     if ( nettype == NET_TCPB ) {
  3659.         if (!tcp_avail)
  3660.           return -1 ;
  3661.         return netbreak();
  3662.     }
  3663. #endif /* TCPSOCKET */
  3664.  
  3665. #ifdef DECNET
  3666.     if ( nettype == NET_DEC ) {
  3667.         if ( ttnproto == NP_LAT ) {
  3668. #ifdef OS2ONLY
  3669.             memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  3670.             lcb.LatFunction = SEND_BREAK;
  3671.             lcb.SessionHandle = ttyfd;
  3672.  
  3673.             LATENTRY(&lcb);
  3674.  
  3675.             rc = (lcb.LatStatus == 0) ? 0 : -1;
  3676. #endif /* OS2ONLY */
  3677. #ifdef NT
  3678.             rc = SendBreak((DWORD) ttyfd);
  3679.             if ( rc ) {
  3680.                 debug(F101,"DECNet LAT SendBreak failed","",rc);
  3681.                 rc = -1;
  3682.             }
  3683. #endif /* NT */
  3684.         }
  3685.         else if ( ttnproto == NP_CTERM ) {
  3686.             /* CTERM does not support BREAK */
  3687.             return 0;
  3688.         }
  3689.     }
  3690. #endif /* DECNET */
  3691.  
  3692. #ifdef SUPERLAT
  3693.     if ( nettype == NET_SLAT )
  3694.     {
  3695.         return(-1);
  3696.     }
  3697. #endif /* SUPERLAT */
  3698.  
  3699. #ifdef NETFILE
  3700.     if ( nettype == NET_FILE )
  3701.         return(-1);
  3702. #endif /* NETFILE */
  3703.  
  3704. #ifdef NETCMD
  3705.     if ( nettype == NET_CMD ) {
  3706.         return(-1);
  3707.     }
  3708. #endif /* NETCMD */
  3709. #ifdef NETDLL
  3710.     if ( nettype == NET_DLL ) {
  3711.         if ( net_dll_netbreak ) {
  3712.             int rc=0;
  3713.             rc = net_dll_netbreak();
  3714.             debug(F111,"net_dll_netbreak()",
  3715.                    (net_dll_errorstr && rc<0)?net_dll_errorstr(rc):"",rc);
  3716.             return(rc<0?-1:rc);
  3717.         }
  3718.         else
  3719.             return(-1);
  3720.     }
  3721. #endif /* NETDLL */
  3722.     return rc;
  3723. }
  3724.  
  3725. /*
  3726.  * what follows is all dynamic link stuff to let the same executable
  3727.  * run on machines with and without networking software
  3728.  */
  3729.  
  3730. #ifdef __32BIT__
  3731. #define GetProc(h, n, e) DosQueryProcAddr(h, 0, n, (PFN *) e)
  3732. #define PREFIX
  3733. #else
  3734. #define GetProc(h, n, e) DosGetProcAddr(h, n, (PFN *) e)
  3735. #define PREFIX "_"
  3736. #endif
  3737.  
  3738.  
  3739.  
  3740. #ifdef TCPSOCKET
  3741. #ifdef CK_ENVIRONMENT
  3742.     extern char tn_env_acct[64];
  3743.     extern char tn_env_disp[64];
  3744.     extern char tn_env_job[64];
  3745.     extern char tn_env_prnt[64];
  3746.     extern char tn_env_sys[64];
  3747.     extern char uidbuf[], pwbuf[];
  3748.     char * env=NULL;
  3749. #endif /* CK_ENVIRONMENT */
  3750.  
  3751. int
  3752. os2_tcpipinit() {
  3753.     int rc=1 ;
  3754. #ifdef NT
  3755.     WSADATA data ;
  3756. #else /* NT */
  3757.     char dll[_MAX_PATH], fail[_MAX_PATH];
  3758.     HMODULE library;
  3759.     extern char exedir[];
  3760.     char * CKTCPIPDLL ;
  3761.     char *p, *q;
  3762. #endif /* NT */
  3763.  
  3764. #ifndef NT
  3765.     p = q = strdup(exedir);
  3766.     if (p) {
  3767.         while (*p) {
  3768.             if (*p == '/') *p = '\\';
  3769.             if (islower(*p)) *p = toupper(*p);
  3770.             p++;
  3771.         }
  3772.         p = q;
  3773.     } else p = exedir;
  3774.  
  3775.     tcp_avail = 0 ;
  3776.  
  3777.     if (deblog) {
  3778.         printf( "  TCP/IP support..." ) ;
  3779.         debug(F100,"TCP/IP support...","",0);
  3780.     }
  3781.     tcpname[0] = NUL;
  3782.  
  3783.     /* User can override DLL search order with an environment variable */
  3784.  
  3785.     CKTCPIPDLL = getenv( "CKTCPIPDLL" ) ;
  3786.     if ( CKTCPIPDLL ) {
  3787.         ckstrncpy(dll, p, _MAX_PATH);
  3788.         ckstrncat(dll, CKTCPIPDLL, _MAX_PATH );
  3789.         rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3790.         if (!rc) {
  3791.             if (deblog)
  3792.                 printf( "CKTCPIPDLL=%s loaded...",CKTCPIPDLL) ;
  3793.             sprintf(tcpname,"CKTCPIPDLL=%s",CKTCPIPDLL) ;
  3794.             debug(F111,"CKTCPIPDLL var loaded",CKTCPIPDLL,rc);
  3795.         } else {
  3796.             debug(F110,"CKTCPIPDLL",CKTCPIPDLL,0);
  3797.             debug(F111,"CKTCPIPDLL DosLoadModule failed",fail,rc);
  3798.         }
  3799.     } else
  3800.         debug(F100,"CKTCPIPDLL not defined","",0);
  3801.  
  3802. #ifdef __32BIT__
  3803. /*
  3804.   Attempt to load in the following order:
  3805.   1. CKTCPIPDLL environment variable
  3806.   2. IBM 2.0
  3807.   3. FTP 1.3
  3808.   4. IBM 1.2
  3809. */
  3810.     if (rc != 0) {
  3811.         ckstrncpy(dll, p, _MAX_PATH);
  3812.         ckstrncat(dll, "CKO32I20.DLL", _MAX_PATH);
  3813.         rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3814.         if ( rc ) {
  3815.             ckstrncpy(dll,"CKO32I20", _MAX_PATH);
  3816.             rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3817.         }
  3818.         if (!rc) {
  3819.             if (deblog) printf( "32bit IBM TCP/IP 2.0 or higher loaded...") ;
  3820.             sprintf(tcpname,"%s = 32-bit IBM TCP/IP 2.0 or higher", dll);
  3821.             debug(F111,"32bit IBM TCP/IP 2.0 or higher loaded",dll,rc);
  3822.         } else
  3823.           debug(F111,"32bit IBM TCP/IP 2.0 or higher load failed",dll,rc);
  3824.     }
  3825.     if (rc != 0) {
  3826.         ckstrncpy(dll, p, _MAX_PATH);
  3827.         ckstrncat(dll, "CKO32F13.DLL", _MAX_PATH);
  3828.         rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3829.         if ( rc ) {
  3830.             ckstrncpy(dll, "CKO32F13", _MAX_PATH);
  3831.             rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3832.         }
  3833.         if (!rc) {
  3834.             if (deblog) printf( "32bit FTP PC/TCP 1.3 loaded...") ;
  3835.             sprintf(tcpname,"%s = 32-bit FTP PC/TCP 1.3", dll);
  3836.             debug(F111,"32bit FTP PC/TCP 1.3 loaded",dll,rc);
  3837.         } else
  3838.           debug(F111,"32bit FTP PC/TCP 1.3 load failed",dll,rc);
  3839.     }
  3840.     if (rc != 0) {
  3841.         ckstrncpy(dll, p, _MAX_PATH);
  3842.         ckstrncat(dll, "CKO32I12.DLL", _MAX_PATH);
  3843.         rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3844.         if ( rc ) {
  3845.             ckstrncpy(dll, "CKO32I12", _MAX_PATH);
  3846.             rc = DosLoadModule(fail, sizeof(fail), "CKO32I12", &library) ;
  3847.         }
  3848.         if (!rc)
  3849.         {
  3850.             HMODULE tcpiplib ;
  3851.             PFN pfn ;
  3852.             rc = DosLoadModule(fail, sizeof(fail), "TCPIPDLL", &tcpiplib) ;
  3853.             rc = GetProc(tcpiplib,"_bsdselect", &pfn);
  3854.         }
  3855.         if (!rc) {
  3856.             if (deblog)
  3857.                 printf( "32bit IBM TCP/IP 1.2 (or compatible) loaded...") ;
  3858.             sprintf(tcpname,"%s = 32-bit IBM TCP/IP 1.2 (or compatible)", dll);
  3859.             debug(F111,"32bit IBM TCP/IP 1.2 (or compatible) loaded",dll,rc);
  3860.         } else
  3861.             debug(F111,
  3862.                    "32bit IBM TCP/IP 1.2 (or compatible) load failed",dll,rc);
  3863.     }
  3864. #else
  3865. /*
  3866.   Attempt to load in the following order:
  3867.   1. CKTCPIPDLL environment variable
  3868.   2. FTP 1.3
  3869.   3. IBM 1.2
  3870. */
  3871.     if (rc != 0) {
  3872.         ckstrncpy(dll, p, _MAX_PATH);
  3873.         ckstrncat(dll, "CKO16F13.DLL", _MAX_PATH);
  3874.         rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3875.         if (!rc) {
  3876.             if (deblog) printf( "16bit FTP PC/TCP 1.3 loaded...") ;
  3877.             sprintf(tcpname,"%s = 16-bit FTP PC/TCP 1.3", dll);
  3878.             debug(F111,"16bit FTP PC/TCP 1.3 loaded",dll,rc);
  3879.         } else
  3880.           debug(F111,"16bit FTP PC/TCP 1.3 load failed",dll,rc);
  3881.     }
  3882.     if (rc != 0) {
  3883.         ckstrncpy(dll, p, _MAX_PATH);
  3884.         ckstrncat(dll, "CKO16I12.DLL", _MAX_PATH);
  3885.         rc = DosLoadModule(fail, sizeof(fail), dll, &library) ;
  3886.       if (!rc)
  3887.          {
  3888.          HMODULE tcpiplib ;
  3889.          PFN pfn ;
  3890.          rc = DosLoadModule(fail, sizeof(fail), "TCPIPDLL", &tcpiplib) ;
  3891.          rc = GetProc(tcpiplib,"_bsdselect", &pfn);
  3892.          }
  3893.         if (!rc) {
  3894.             if (deblog)
  3895.               printf( "16bit IBM TCP/IP 1.2 (or compatible) loaded...") ;
  3896.             sprintf(tcpname,"%s = 16-bit IBM TCP/IP 1.2", dll);
  3897.             debug(F111,"16bit IBM TCP/IP 1.2 (or compatible) loaded",dll,rc);
  3898.         } else
  3899.           debug(F111,
  3900.                 "16bit IBM TCP/IP 1.2 (or compatible) load failed",dll,rc);
  3901.     }
  3902. #endif /* __32BIT__ */
  3903.  
  3904.     if (rc != 0) {
  3905.         if (deblog) {
  3906.             printf( "Not installed\n") ;
  3907.             debug(F101,"TCP/IP not installed - rc","",rc);
  3908.         }
  3909.         sprintf(tcpname," - ERROR: Unable to load a DLL");
  3910.         return -1;
  3911.     }
  3912.     if (GetProc(library, PREFIX "ck_sockinit", &sockinit) ||
  3913.          GetProc(library, PREFIX "ck_connect", &connect) ||
  3914.          GetProc(library, PREFIX "ck_bind", &bind) ||
  3915.          GetProc(library, PREFIX "ck_listen", &listen) ||
  3916.          GetProc(library, PREFIX "ck_accept", &accept) ||
  3917.          GetProc(library, PREFIX "ck_ioctl", &ioctl) ||
  3918.          GetProc(library, PREFIX "ck_recv", &recv) ||
  3919.          GetProc(library, PREFIX "ck_select", &select) ||
  3920.          GetProc(library, PREFIX "ck_send", &send) ||
  3921.          GetProc(library, PREFIX "ck_setsockopt", &setsockopt) ||
  3922.          GetProc(library, PREFIX "ck_getsockopt", &getsockopt) ||
  3923.          GetProc(library, PREFIX "ck_socket", &socket) ||
  3924.          GetProc(library, PREFIX "ck_soclose", &soclose) ||
  3925.          GetProc(library, PREFIX "ck_gethostbyname", &gethostbyname) ||
  3926.          GetProc(library, PREFIX "ck_getservbyname", &getservbyname) ||
  3927.          GetProc(library, PREFIX "ck_gethostbyaddr", &gethostbyaddr) ||
  3928.          GetProc(library, PREFIX "ck_getservbyport", &getservbyport) ||
  3929.          GetProc(library, PREFIX "ck_getpeername", &getpeername) ||
  3930.          GetProc(library, PREFIX "ck_getsockname", &getsockname) ||
  3931.          GetProc(library, PREFIX "ck_gethostname", &gethostname) ||
  3932.          GetProc(library, PREFIX "ck_inet_addr", &inet_addr) ||
  3933.          GetProc(library, PREFIX "ck_inet_ntoa", &inet_ntoa))  {
  3934.         if (deblog) {
  3935.             printf( "Not installed\n") ;
  3936.             debug(F100,"TCP/IP not installed","",0);
  3937.         }
  3938.         ckstrncat(tcpname," - ERROR: Missing Entry DLL Points",sizeof(tcpname));
  3939.         return -1;
  3940.     }
  3941.  
  3942.     if ( GetProc(library, PREFIX "ck_addsockettolist", &addsockettolist) )
  3943.     {
  3944.         debug(F100,"INETD support not available","",0);
  3945.         addsockettolist = NULL;
  3946.     }
  3947.     else
  3948.         debug(F100,"INETD support available","",0);
  3949.  
  3950.     rc = sockinit() ;
  3951. #else /* NT */
  3952.     winsock_version = 0;
  3953.     rc = WSAStartup( MAKEWORD( 2, 0 ), &data ) ;
  3954.     if ( rc == WSAVERNOTSUPPORTED )
  3955.     {
  3956.        debug(F110,"tcpipinit",
  3957.               "WSAStartup(2.0,&data) returns WSAVERNOTSUPPORTED",0);
  3958.        WSACleanup() ;
  3959.        rc = WSAStartup( MAKEWORD( 1, 1 ), &data ) ;
  3960.        if ( rc == WSAVERNOTSUPPORTED ) {
  3961.            debug(F110,"tcpipinit",
  3962.                   "WSAStartup(1.1,&data) returns WSAVERNOTSUPPORTED",0);
  3963.        } else
  3964.            winsock_version = 11;
  3965.     } else
  3966.         winsock_version = 20;
  3967.     if ( rc == 0 ) {
  3968.         debug(F110,"WSADATA.szDescription",data.szDescription,0);
  3969.         debug(F110,"WSADATA.szSystemStatus",data.szSystemStatus,0);
  3970. #ifdef BETADEBUG
  3971.         printf("WSADATA.szDescription: %s\n",data.szDescription);
  3972.         printf("WSADATA.szSystemStatus: %s\n",data.szSystemStatus);
  3973. #else
  3974.         if ( deblog ) {
  3975.             printf("WSADATA.szDescription: %s\n",data.szDescription);
  3976.             printf("WSADATA.szSystemStatus: %s\n",data.szSystemStatus);
  3977.         }
  3978. #endif /* BETADEBUG */
  3979.     }
  3980. #endif /* NT */
  3981.  
  3982.    if (rc)
  3983.    {
  3984.       tcp_avail = 0 ;
  3985.       if (deblog) {
  3986.             printf( "init failed\n" ) ;
  3987.             ckstrncat(tcpname," - ERROR: Initialization Failed",sizeof(tcpname));
  3988.             debug(F101,"TCP/IP sockinit() failed","",rc);
  3989.         }
  3990.     } else {
  3991.         tcp_avail = 1;
  3992.         if (deblog) {
  3993.             printf( "initialized\n" ) ;
  3994.             debug(F101,"TCP/IP sockinit() successful","",rc);
  3995.         }
  3996.     }
  3997. #ifdef CK_ENVIRONMENT
  3998.     if ( env = getenv("ACCT") ) {
  3999.         ckstrncpy(tn_env_acct,env,64);
  4000.     }
  4001.     else
  4002.         tn_env_acct[0] = NUL;
  4003.     if ( env = getenv("DISPLAY") ) {
  4004.         ckstrncpy(tn_env_disp,env,64);
  4005.     }
  4006.     else
  4007.         tn_env_disp[0] = NUL;
  4008.     if ( env = getenv("JOB") ) {
  4009.         ckstrncpy(tn_env_job,env,64);
  4010.     }
  4011.     else
  4012.         tn_env_job[0] = NUL;
  4013.     if ( env = getenv("PRINTER") ) {
  4014.         ckstrncpy(tn_env_prnt,env,64);
  4015.     }
  4016.     else
  4017.         tn_env_prnt[0] = NUL;
  4018. #ifdef NT
  4019.     ckstrncpy(tn_env_sys,"WIN32",64);
  4020. #else
  4021.     ckstrncpy(tn_env_sys,"OS/2",64);
  4022. #endif /* NT */
  4023. #endif /* CK_ENVIRONMENT */
  4024.     return rc;
  4025. }
  4026. #endif /* TCPSOCKET */
  4027.  
  4028. #ifdef DECNET
  4029. #ifdef NT
  4030. HINSTANCE hDECTAL=NULL;
  4031. int
  4032. LoadDECTAL( void )
  4033. {
  4034.     int       rc=0;
  4035.  
  4036.     hDECTAL = LoadLibrary("dectal") ;
  4037.     if ( !hDECTAL )
  4038.     {
  4039.         rc = GetLastError() ;
  4040.         debug(F111, "LoadDECTAL LoadLibrary failed","dectal",rc) ;
  4041.         return FALSE;
  4042.     }
  4043.     if (((FARPROC) InstalledAccess = GetProcAddress( hDECTAL, "InstalledAccess" )) == NULL )
  4044.     {
  4045.         rc = GetLastError() ;
  4046.         debug(F111, "LoadDECTAL GetProcAddress failed","InstalledAccess",rc) ;
  4047.         return FALSE;
  4048.     }
  4049.     if (((FARPROC) InquireServices = GetProcAddress( hDECTAL, "InquireServices" )) == NULL )
  4050.     {
  4051.         rc = GetLastError() ;
  4052.         debug(F111, "LoadDECTAL GetProcAddress failed","InquireServices",rc) ;
  4053.         return FALSE;
  4054.     }
  4055.     if (((FARPROC) GetNextService = GetProcAddress( hDECTAL, "GetNextService" )) == NULL )
  4056.     {
  4057.         rc = GetLastError() ;
  4058.         debug(F111, "LoadDECTAL GetProcAddress failed","GetNextService",rc) ;
  4059.         return FALSE;
  4060.     }
  4061.     if (((FARPROC) OpenSession = GetProcAddress( hDECTAL, "OpenSession" )) == NULL )
  4062.     {
  4063.         rc = GetLastError() ;
  4064.         debug(F111, "LoadDECTAL GetProcAddress failed","OpenSession",rc) ;
  4065.         return FALSE;
  4066.     }
  4067.     if (((FARPROC) CloseSession = GetProcAddress( hDECTAL, "CloseSession" )) == NULL )
  4068.     {
  4069.         rc = GetLastError() ;
  4070.         debug(F111, "LoadDECTAL GetProcAddress failed","CloseSession",rc) ;
  4071.         return FALSE;
  4072.     }
  4073.     if (((FARPROC) ReadData = GetProcAddress( hDECTAL, "ReadData" )) == NULL )
  4074.     {
  4075.         rc = GetLastError() ;
  4076.         debug(F111, "LoadDECTAL GetProcAddress failed","ReadData",rc) ;
  4077.         return FALSE;
  4078.     }
  4079.     if (((FARPROC) WriteData = GetProcAddress( hDECTAL, "WriteData" )) == NULL )
  4080.     {
  4081.         rc = GetLastError() ;
  4082.         debug(F111, "LoadDECTAL GetProcAddress failed","WriteData",rc) ;
  4083.         return FALSE;
  4084.     }
  4085.     if (((FARPROC) SendBreak = GetProcAddress( hDECTAL, "SendBreak" )) == NULL )
  4086.     {
  4087.         rc = GetLastError() ;
  4088.         debug(F111, "LoadDECTAL GetProcAddress failed","SendBreak",rc) ;
  4089.         return FALSE;
  4090.     }
  4091.     if (((FARPROC) GetDetailError = GetProcAddress( hDECTAL, "GetDetailError" )) == NULL )
  4092.     {
  4093.         rc = GetLastError() ;
  4094.         debug(F111, "LoadDECTAL GetProcAddress failed","GetDetailError",rc) ;
  4095.         return FALSE;
  4096.     }
  4097.     if (((FARPROC) DataNotify = GetProcAddress( hDECTAL, "DataNotify" )) == NULL )
  4098.     {
  4099.         rc = GetLastError() ;
  4100.         debug(F111, "LoadDECTAL GetProcAddress failed","DataNotify",rc) ;
  4101.         return FALSE;
  4102.     }
  4103.     return TRUE;
  4104. }
  4105. #endif /* NT */
  4106. #endif /* DECNET */
  4107.  
  4108. void
  4109. netinit() {
  4110.     extern int nettype;
  4111.     char fail[256];
  4112.     HMODULE library;
  4113.     extern unsigned long startflags;
  4114.  
  4115.    if (deblog) {
  4116.       printf( "Initializing Network Support:\n" ) ;
  4117.       debug(F100,"Initializing Network Support:","",0) ;
  4118.    }
  4119.  
  4120.     if ( !(startflags & 2) ) {
  4121. #ifdef CK_NETBIOS
  4122.         os2_netbiosinit() ;
  4123. #endif /* CK_NETBIOS */
  4124.  
  4125. #ifdef DECNET
  4126.         if (deblog) {
  4127.             printf("  DECNet support..." ) ;
  4128.             debug(F100,"DECNet support...","",0);
  4129.         }
  4130. #ifdef OS2ONLY
  4131.         if ( !DosLoadModule(fail, sizeof(fail), "LATCALLS", &library) ) {
  4132.             if ( !GetProc(library, "LATENTRY", &LATENTRY) ) {
  4133.                 dnet_avail = 1;
  4134.                 if (deblog) {
  4135.                     printf("OK\n") ;
  4136.                     debug(F100,"DECNet OK","",0);
  4137.  
  4138.                     memset( &lcb, 0, sizeof(struct lat_cb) ) ;
  4139.                     lcb.LatFunction = READ_LATINFO;
  4140.                     lcb.BufferSize = sizeof(latinfo);
  4141.                     lcb.BufferPtr = (void * _Seg16) &latinfo;
  4142.  
  4143.                     LATENTRY(&lcb);
  4144.  
  4145.                     debug(F101,"DECNet LatStatus","",lcb.LatStatus) ;
  4146.                     if (!lcb.LatStatus) {
  4147.                         debug(F101,"DECNet Major Version","",latinfo.vermjr) ;
  4148.                         debug(F101,"DECNet Minor Version","",latinfo.vermir) ;
  4149.                         debug(F101,"DECNet Max Sessions","",latinfo.NSessions) ;
  4150.                         debug(F101,"DECNet Max Buffers per Session","",
  4151.                                latinfo.NBuffers) ;
  4152.                         debug(F101,"DECNet Max Services","",latinfo.NServices) ;
  4153.                     }
  4154.                 }
  4155.             } else {
  4156.                 dnet_avail = 0 ;
  4157.                 if (deblog) {
  4158.                     printf("Not installed\n" ) ;
  4159.                     debug(F100,"DECNet not installed","",0) ;
  4160.                 }
  4161.             }
  4162.         } else {
  4163.             dnet_avail = 0 ;
  4164.             if (deblog) {
  4165.                 printf("Not installed\n" ) ;
  4166.                 debug(F100,"DECNet not installed","",0) ;
  4167.             }
  4168.         }
  4169. #endif /* OS2ONLY */
  4170. #ifdef NT
  4171.         if (dnet_avail = LoadDECTAL()) {
  4172.             if (deblog) {
  4173.                 int version=0;
  4174.  
  4175.                 printf("OK\n") ;
  4176.                 debug(F100,"DECNet OK","",0);
  4177.  
  4178.                 version = InstalledAccess(LAT_ACCESS);
  4179.                 if ( version >= 0 ) {
  4180.                     printf("DECNet LAT available: version %d\n",version);
  4181.                     debug(F111,"DECNet LAT available","version",version);
  4182.                 }
  4183.                 else {
  4184.                     printf("DECNet LAT not available: error %d\n",version);
  4185.                     debug(F111,"DECNet LAT not available","error",version);
  4186.                 }
  4187.                 version = InstalledAccess(CTERM_ACCESS);
  4188.                 if ( version >= 0 ) {
  4189.                     printf("DECNet CTERM available: version %d\n",version);
  4190.                     debug(F111,"DECNet CTERM available","version",version);
  4191.                 }
  4192.                 else {
  4193.                     printf("DECNet CTERM not available: error %d\n",version);
  4194.                     debug(F111,"DECNet CTERM not available","error",version);
  4195.                 }
  4196.                 version = InstalledAccess(TELNET_ACCESS);
  4197.                 if ( version >= 0 ) {
  4198.                     printf("DECNet TELNET available: version %d\n",version);
  4199.                     debug(F111,"DECNet TELNET available","version",version);
  4200.                 }
  4201.                 else {
  4202.                     printf("DECNet TELNET not available: error %d\n",version);
  4203.                     debug(F111,"DECNet TELNET not available","error",version);
  4204.                 }
  4205.             }
  4206.         }
  4207.         else {
  4208.             if (deblog) {
  4209.                 printf("Not installed\n" ) ;
  4210.                 debug(F100,"DECNet not installed","",0) ;
  4211.             }
  4212.         }
  4213. #endif /* NT */
  4214. #endif /* DECNET */
  4215.  
  4216. #ifdef SUPERLAT
  4217.         /* Create a file handle, first try NT way, then try Win95 way */
  4218.         ttyfd = (int) CreateFile ("\\\\.\\Lat",
  4219.                                    GENERIC_READ    | GENERIC_WRITE,
  4220.                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
  4221.                                    NULL,
  4222.                                    OPEN_EXISTING,
  4223.                                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  4224.                                    NULL);
  4225.  
  4226.         if ((HANDLE) ttyfd == INVALID_HANDLE_VALUE)
  4227.         {
  4228.             ttyfd = (int) CreateFile ("\\\\.\\slatwin",
  4229.                                        GENERIC_READ    | GENERIC_WRITE,
  4230.                                        FILE_SHARE_READ | FILE_SHARE_WRITE,
  4231.                                        NULL,
  4232.                                        OPEN_EXISTING,
  4233.                                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  4234.                                        NULL);
  4235.             if ( (HANDLE) ttyfd == INVALID_HANDLE_VALUE )
  4236.             {
  4237.                 ttyfd = -1 ;
  4238.             }
  4239.         }
  4240.  
  4241.         if ( (HANDLE) ttyfd != INVALID_HANDLE_VALUE )
  4242.         {
  4243.             slat_avail = 1 ;
  4244.             CloseHandle( (HANDLE) ttyfd ) ;
  4245.             ttyfd = -1 ;
  4246.         }
  4247. #endif /* SUPERLAT */
  4248.     }
  4249.  
  4250. #ifdef TCPSOCKET
  4251. #ifdef OS2ONLY
  4252.     if ( !(startflags & 2) )            /* OS/2 is not linked to the DLLs */
  4253. #endif /* OS2ONLY */
  4254.         os2_tcpipinit() ;
  4255. #endif /* TCPSOCKET */
  4256.  
  4257.     if (tcp_avail)                      /* Set the default network type */
  4258.         nettype = NET_TCPB;               /* TCP/IP first */
  4259. #ifdef DECNET
  4260.     else if (dnet_avail)                /* Then DECnet */
  4261.         nettype = NET_DEC;
  4262. #endif /* DECNET */
  4263. #ifdef SUPERLAT
  4264.     else if (slat_avail)                /* Then SuperLAT */
  4265.         nettype = NET_SLAT;
  4266. #endif /* SUPERLAT */
  4267.  
  4268. #ifdef COMMENT
  4269. /*
  4270.   NetBios cannot be set as a default network type even though
  4271.   we would like to because it requires that a NetBiosName be
  4272.   specified.  If the default is already in use, then we will
  4273.   not know what name to use.  Not providing a name will leave
  4274.   Kermit in an unknown state (network type NetBios without any
  4275.   means for addressing this session.)  Better never to allow
  4276.   it to be set as a default.
  4277.  
  4278.   All the code to implement it is shown below though just in case.
  4279. */
  4280.     else if (netbiosAvail) {            /* Then NETBIOS */
  4281.         NCB ncb ;
  4282.         APIRET rc ;
  4283.         int x,y ;
  4284.  
  4285.         nettype = NET_BIOS;
  4286.  
  4287.         ckstrncpy(NetBiosName, (*myhost?myhost:"kermit"),NETBIOS_NAME_LEN+1);
  4288.         for (x = y; x < NETBIOS_NAME_LEN; x++)
  4289.           NetBiosName[x] = SP;
  4290.         NetBiosName[NETBIOS_NAME_LEN] = NUL;
  4291.  
  4292.         printf("Verifying \"%s\" is a unique NetBIOS node name ...\n",
  4293.                 NetBiosName) ;
  4294.         rc = NCBAddName( NetbeuiAPI, &ncb, 0, NetBiosName ) ;
  4295.         if ( rc ) {
  4296.           printf("?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
  4297.                   NetBiosName);
  4298.             for ( x=0; x < NETBIOS_NAME_LEN; x++)
  4299.                NetBiosName[x] = SP ;
  4300.         }
  4301.     }
  4302. #endif /* COMMENT */
  4303. #ifdef NPIPE
  4304.     else {                              /* Otherwise Named Pipes, */
  4305.         nettype = NET_PIPE;             /* which is always there. */
  4306.         ckstrncpy(pipename,"kermit",PIPENAML);  /* better set the pipename */
  4307.     }
  4308. #else
  4309.     else nettype = NET_NONE;
  4310. #endif /* NPIPE */
  4311.  
  4312. #ifdef NETCMD
  4313.     NetCmdInit();
  4314. #endif /* NETCMD */
  4315.  
  4316. }
  4317.  
  4318. int
  4319. netcleanup() {
  4320. #ifdef CK_NETBIOS
  4321.     os2_netbioscleanup() ;
  4322. #endif /* CK_NETBIOS */
  4323.  
  4324. #ifdef TCPSOCKET
  4325.     if ( tcpsrv_fd >= 0 )
  4326.     {
  4327.        debug(F100,"netcleanup closing tcpsrv_fd","",0);
  4328.         tcpsrv_close();
  4329.     }
  4330. #ifdef NT
  4331.    WSACleanup() ;
  4332. #endif /* NT */
  4333. #endif /* TCPSOCKET */
  4334.     return 0 ;
  4335.  
  4336.  
  4337. #ifdef NETCMD
  4338.     NetCmdCleanup();
  4339. #endif /* NETCMD */
  4340. }
  4341.  
  4342. #ifdef CK_NETBIOS
  4343. void
  4344. NetbiosListenThread(void * pArgList) {
  4345.     APIRET rc = 0 ;
  4346.     rc = Dos16SemWait( pListenNCB->basic_ncb.ncb_semaphore,
  4347.                        SEM_INDEFINITE_WAIT ) ;
  4348.  
  4349.     if ( rc ||
  4350.          pListenNCB->basic_ncb.bncb.ncb_retcode != NB_COMMAND_SUCCESSFUL )
  4351.     {
  4352.         os2_netclos() ;
  4353.     } else {
  4354.         ttyfd = NetBiosLSN = pListenNCB->basic_ncb.bncb.ncb_lsn ;
  4355.         ckstrncpy( NetBiosRemote,
  4356.                  pListenNCB->basic_ncb.bncb.ncb_callname,
  4357.                  NETBIOS_NAME_LEN+1 ) ;
  4358.  
  4359. #ifdef COMMENT
  4360.         if ( pRecvNCB->basic_ncb.bncb.ncb_retcode == NB_COMMAND_IN_PROCESS ) {
  4361.             NCB CleanupNCB ;
  4362.             NCBCancel( NetbeuiAPI, &CleanupNCB, NetBiosAdapter, pRecvNCB ) ;
  4363.             Dos16SemWait( pRecvNCB->basic_ncb.ncb_semaphore,
  4364.                           SEM_INDEFINITE_WAIT ) ;
  4365.         }
  4366. #endif /* COMMENT */
  4367.  
  4368.         NCBReceive( NetbeuiAPI, pRecvNCB, NetBiosAdapter, NetBiosLSN,
  4369.                     NetBiosRecvBuf, sizeof(NetBiosRecvBuf), FALSE ) ;
  4370.     }
  4371.     DosPostEventSem( hevNetBiosLSN ) ;
  4372.     ListenThreadID = -1 ;
  4373. }
  4374. #endif /* CK_NETBIOS */
  4375.  
  4376. #ifdef TCPSOCKET
  4377.  
  4378.  
  4379. #ifdef OS2
  4380. #ifdef NT
  4381. #define BSDSELECT
  4382. #else  /* NT */
  4383. #define IBMSELECT
  4384. #endif /* NT */
  4385. #endif /* OS2 */
  4386.  
  4387. /* T C P S O C K E T _ O P E N -- Open a preexisting socket number */
  4388. int
  4389. tcpsocket_open( char * name, int * lcl, int nett, int timo )
  4390. {
  4391.     int on = 1;
  4392.     static struct servent *service, servrec;
  4393.     static struct hostent *host;
  4394.     static struct sockaddr_in saddr;
  4395.     static int saddrlen ;
  4396.     extern char myipaddr[];
  4397.     struct sockaddr_in l_addr;
  4398.     int l_slen;
  4399. #ifdef BSDSELECT
  4400.     fd_set rfds;
  4401.     struct timeval tv;
  4402. #endif
  4403.     extern int tcp_rdns;
  4404. #ifdef CK_SSL
  4405.     int ssl_failed = 0;
  4406. #endif /* CK_SSL */
  4407.  
  4408.     debug(F101,"tcpsocket_open nett","",nett);
  4409.     *ipaddr = '\0' ;
  4410.  
  4411.     /*
  4412.     Add support for other networks here.
  4413.     */
  4414.     if (nett != NET_TCPB)
  4415.         return(-1);     /* BSD socket support */
  4416.  
  4417.     if ( ttyfd == atoi(&name[1]) )
  4418.         return(0);
  4419.  
  4420.     netclos();                          /* Close any previous connection. */
  4421.     ckstrncpy(namecopy, name, NAMECPYL);  /* Copy the hostname. */
  4422.     ttnproto = NP_NONE;
  4423.     debug(F110,"tcpsocket_open namecopy",namecopy,0);
  4424.  
  4425.     /* assign the socket number to ttyfd and then fill in tcp structures */
  4426.     ttyfd = atoi( &name[1] ) ;
  4427.     debug(F111,"tcpsocket_open","ttyfd",ttyfd);
  4428.  
  4429. #ifdef OS2ONLY
  4430.     /* In OS/2 we must register as owning the socket */
  4431.     /* the program that gave it to us must call      */
  4432.     /* removesocketfromlist( int ) before making the */
  4433.     /* call to us                                    */
  4434.     if ( (name[0] == '!' || name[0] == '$') && addsockettolist )
  4435.         addsockettolist( ttyfd ) ;
  4436.     /* need to add this to the dll and then import it */
  4437. #endif /* OS2ONLY */
  4438.  
  4439. #ifdef SOL_SOCKET
  4440.     setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
  4441.  
  4442. #ifdef TCP_NODELAY
  4443.     no_delay(ttyfd,tcp_nodelay) ;
  4444. #endif /* TCP_NODELAY */
  4445. #ifdef SO_KEEPALIVE
  4446.     keepalive(ttyfd,tcp_keepalive) ;
  4447. #endif /* SO_KEEPALIVE */
  4448. #ifdef SO_DONTROUTE
  4449.     dontroute(ttyfd,tcp_dontroute);
  4450. #endif /* SO_DONTROUTE */
  4451. #ifdef SO_LINGER
  4452.     ck_linger(ttyfd,tcp_linger, tcp_linger_tmo) ;
  4453. #endif /* SO_LINGER */
  4454. #ifdef SO_SNDBUF
  4455.     sendbuf(ttyfd,tcp_sendbuf);
  4456. #ifdef COMMENT
  4457.     if (tcp_sendbuf < (2*MAXSP))
  4458.         sendbuf(((2*MAXSP+1460)/1460)*1460);
  4459. #endif /* COMMENT */
  4460. #endif /* SO_SNDBUF */
  4461. #ifdef SO_RCVBUF
  4462.     recvbuf(ttyfd,tcp_recvbuf);
  4463. #ifdef COMMENT
  4464.     if (tcp_recvbuf < (10*MAXRP))
  4465.         recvbuf(((10*MAXRP+1460)/1460)*1460);
  4466. #endif /* COMMENT */
  4467. #endif /* SO_RCVBUF */
  4468. #endif /* SOL_SOCKET */
  4469.  
  4470.     ttnet = nett;                       /* TCP/IP (sockets) network */
  4471.  
  4472. #ifdef CK_SSL
  4473.     if (ck_ssleay_is_installed()) {
  4474.         debug(F110,"tcpsocket_open","ssl installed",0);
  4475.         if (!ssl_tn_init(tcp_incoming?SSL_SERVER:SSL_CLIENT)) {
  4476.             ssl_failed = 1;
  4477. #ifdef COMMENT
  4478.             if (bio_err!=NULL) {
  4479.                 BIO_printf(bio_err,"do_ssleay_init() failed\n");
  4480.                 ERR_print_errors(bio_err);
  4481.             } else {
  4482.                 fflush(stderr);
  4483.                 fprintf(stderr,"do_ssleay_init() failed\n");
  4484.                 ERR_print_errors_fp(stderr);
  4485.             }
  4486. #endif /* COMMENT */
  4487.             
  4488.             switch (ttnproto) {
  4489.             case NP_SSL:
  4490.             case NP_TLS:
  4491.         case NP_SSL_RAW:
  4492.         case NP_TLS_RAW:
  4493.             case NP_SSL_TELNET:
  4494.             case NP_TLS_TELNET:
  4495.                 socket_close(ttyfd);
  4496.                 ttyfd = -1;
  4497.                 return(-1);
  4498.             }
  4499.             /* we will continue to accept the connection */
  4500.             /* without SSL or TLS support.               */
  4501.             TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4502.             TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4503.             TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4504.             TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4505.         }
  4506.     }
  4507. #endif /* CK_SSL */
  4508.  
  4509. #ifdef IKSD
  4510.     if ( inserver ) {
  4511.         *lcl = 0;
  4512.     } else 
  4513. #endif /* IKSD */
  4514.     {
  4515.         if (*lcl < 0)
  4516.             *lcl = 1;           /* Local mode. */
  4517.     }
  4518.  
  4519.     l_slen = sizeof(l_addr);
  4520.     bzero((char *)&l_addr, l_slen);
  4521.     if (getsockname(ttyfd, (struct sockaddr *)&l_addr, &l_slen) >= 0) {
  4522.         char * s = (char *)inet_ntoa(l_addr.sin_addr);
  4523.         sprintf(myipaddr, "%s", s);
  4524.         debug(F110,"getsockname",myipaddr,0);
  4525.     }
  4526.  
  4527.     /* Get the name of the host we are connected to */
  4528.     saddrlen = sizeof(saddr) ;
  4529.     getpeername( ttyfd,(struct sockaddr *)&saddr,&saddrlen) ;
  4530.  
  4531.     if ( tcp_rdns ) {
  4532.         if ((host = gethostbyaddr((char *)&saddr.sin_addr,4,PF_INET)) != NULL) {
  4533.             debug(F100,"tcpsocket_open gethostbyname != NULL","",0);
  4534.             host = ck_copyhostent(host);
  4535.             if ( strlen(host->h_name)+strlen(name)+6 < 80 ) {
  4536.                 ckstrncpy(name,host->h_name,80);
  4537.                 strncat(name,":",80-strlen(name));
  4538.                 itoa( ntohs(saddr.sin_port), name+strlen(name), 10 ) ;
  4539.             } else {
  4540.                 ckstrncpy(name,"host-name-too-long", sizeof(name));
  4541.             }
  4542.             ckstrncpy(ipaddr,(char *)inet_ntoa(saddr.sin_addr),20);
  4543.         }
  4544.     }
  4545.     if ( !tcp_rdns || !host ) {
  4546.         int len;
  4547.         ckstrncpy(ipaddr,(char *)inet_ntoa(saddr.sin_addr),20);
  4548.         ckstrncpy(name,ipaddr,80);
  4549.         len = strlen(name);
  4550.         strncat(name,":",80-len);
  4551.         itoa( ntohs(saddr.sin_port), name+strlen(name), 10 ) ;
  4552.     }
  4553.  
  4554. #ifdef CK_SECURITY
  4555.     /* Before Initialization Telnet/Rlogin Negotiations Init Kerberos */
  4556.     ck_auth_init((tcp_rdns && host && host->h_name && host->h_name[0]) ?
  4557.                 host->h_name : ipaddr,
  4558.                 ipaddr,
  4559. #ifdef IKSD
  4560.                 inserver ? "" :
  4561. #endif /* IKSD */
  4562.                   uidbuf,
  4563.                 ttyfd
  4564.                 );
  4565. #endif /* CK_SECURITY */
  4566.  
  4567. #ifdef CK_SSL
  4568.         if (ck_ssleay_is_installed() && !ssl_failed) {
  4569.             if ( ck_ssl_incoming(ttyfd) < 0 ) {
  4570.                 socket_close(ttyfd);
  4571.                 ttyfd = -1;
  4572.                 return(-1);
  4573.             }
  4574.         }
  4575. #endif /* CK_SSL */
  4576.  
  4577.     if (!quiet && !doconx)
  4578.         printf("%s connected on port %d\n",name,ntohs(saddr.sin_port));
  4579.  
  4580.     /* If we are IKSD assume then the service is TELNET; otherwise assume 
  4581.      * the service is TELNET but do not perform Negotiation. */
  4582. #ifdef IKSD
  4583.     ttnproto = inserver ? NP_TELNET : NP_NONE;
  4584. #else
  4585.     ttnproto = NP_NONE;
  4586. #endif
  4587.     if (tn_ini()<0)                     /* Initialize Telnet. */
  4588.         if (ttchk()<0)
  4589.             return(-1);
  4590.  
  4591.     return(0);                          /* Done. */
  4592. }
  4593.  
  4594.  
  4595. /*  T C P S R V _ O P E N  --  Open a TCP/IP Server connection  */
  4596. /*
  4597.   Calling conventions same as Uttopen(), except third argument is network
  4598.   type rather than modem type.  Designed to be called from within os2_netopen.
  4599. */
  4600. void
  4601. tcpsrv_close(void)
  4602. {
  4603.     socket_close(tcpsrv_fd) ;
  4604.     tcpsrv_fd = -1 ;
  4605.     tcpsrv_port = 0 ;
  4606.     tcp_incoming = 0;               /* Not an incoming connection */
  4607.     sstelnet = 0;
  4608. }
  4609.  
  4610. int
  4611. tcpsrv_open(char * name, int * lcl, int nett, int timo) {
  4612.    char *p;
  4613.    int i, x;
  4614.    int on = 1;
  4615.    int ready_to_accept = 0 ;
  4616.    static struct servent *service, servrec;
  4617.    static struct hostent *host;
  4618.    static struct sockaddr_in saddr;
  4619.    static int saddrlen ;
  4620. #ifdef BSDSELECT
  4621.     fd_set rfds;
  4622.     struct timeval tv;
  4623. #endif
  4624. #ifdef CK_SSL
  4625.     int ssl_failed = 0;
  4626. #endif /* CK_SSL */
  4627.  
  4628.     debug(F110,"tcpsrv_open name",name,0);
  4629.     debug(F101,"tcpsrv_open nett","",nett);
  4630.     *ipaddr = '\0' ;
  4631.  
  4632. /*
  4633.   Add support for other networks here.
  4634. */
  4635.     if (nett != NET_TCPB)
  4636.         return(-1);     /* BSD socket support */
  4637.  
  4638.     netclos();                          /* Close any previous connection. */
  4639.     strncpy(namecopy, name, NAMECPYL);  /* Copy the hostname. */
  4640.  
  4641.     /* ttnproto = NP_NONE;                      /* No protocol selected yet. - don't do this */
  4642.     debug(F110,"tcpsrv_open namecopy",namecopy,0);
  4643.  
  4644.    p = namecopy;                        /* Was a service requested? */
  4645.    while (*p != '\0' && *p != ':')
  4646.       p++; /* Look for colon */
  4647.    if (*p == ':') {                     /* Have a colon */
  4648.       *p++ = '\0';                      /* Get service name or number */
  4649.    } else {                             /* Otherwise use kermit */
  4650.       p = "kermit";
  4651.    }
  4652.    debug(F110,"tcpsrv_open service requested",p,0);
  4653.    if (isdigit(*p)) {                   /* Use socket number without lookup */
  4654.       service = &servrec;
  4655.       service->s_port = htons((unsigned short)atoi(p));
  4656.    } else {                             /* Otherwise lookup the service name */
  4657.       service = getservbyname(p, "tcp");
  4658.    }
  4659.    if ( !service && !strcmp( "kermit", p ) )
  4660.    {  /* use now assigned Kermit Service Port */
  4661.       service = &servrec ;
  4662.       service->s_port = htons( 1649 ) ;
  4663.    }
  4664.  
  4665.    if (!service) {
  4666.       fprintf(stderr, "Cannot find port for service %s\n", p);
  4667.  
  4668.       debug(F101,"tcpsrv_open can't get service","",errno);
  4669.  
  4670.       errno = 0;                        /* rather than mislead */
  4671.       return(-1);
  4672.    }
  4673.  
  4674.     if ( service && !strcmp("login",p) && service->s_port != htons(513) ) {
  4675.         fprintf(stderr, "  Warning: login service on port %d instead of port 513\n",
  4676.                  ntohs(service->s_port));
  4677.         fprintf(stderr, "  Edit SERVICES file if RLOGIN fails to connect.\n");
  4678.         debug(F101,"tcpsrv_open login on port","",ntohs(service->s_port));
  4679.     }
  4680.  
  4681.     /* if we currently have a listen active but port has changed then close */
  4682.    if ( tcpsrv_fd != -1 && tcpsrv_port != ntohs((unsigned short)service->s_port))
  4683.    {
  4684.       socket_close( tcpsrv_fd ) ;
  4685.       tcpsrv_fd = -1 ;
  4686.    }
  4687.  
  4688.    if ( tcpsrv_fd == -1 )
  4689.    {
  4690.       /* Set up socket structure and get host address */
  4691.  
  4692.       bzero((char *)&saddr, sizeof(saddr));
  4693.       debug(F100,"tcpsrv_open bzero ok","",0);
  4694.       saddr.sin_family = AF_INET ;
  4695.        if ( tcp_address )
  4696.            saddr.sin_addr.s_addr = inet_addr(tcp_address);
  4697.        else
  4698.            saddr.sin_addr.s_addr = INADDR_ANY ;
  4699.  
  4700.       /* Get a file descriptor for the connection. */
  4701.  
  4702.       saddr.sin_port = service->s_port;
  4703.       ipaddr[0] = '\0' ;
  4704.  
  4705.       if ((tcpsrv_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  4706.       {
  4707.          perror("TCP socket error");
  4708.          debug(F101,"tcpsrv_open socket error","",errno);
  4709.          return (-1);
  4710.       }
  4711.       errno = 0;
  4712.  
  4713.       /* Specify the Port may be reused */
  4714.       setsockopt(tcpsrv_fd, SOL_SOCKET, SO_REUSEADDR,(char *) &on, sizeof on);
  4715.  
  4716. #ifdef SOL_SOCKET
  4717. #ifdef TCP_NODELAY
  4718.       no_delay(tcpsrv_fd,tcp_nodelay);
  4719. #endif /* TCP_NODELAY */
  4720. #ifdef SO_KEEPALIVE
  4721.       keepalive(tcpsrv_fd,tcp_keepalive);
  4722. #endif /* SO_KEEPALIVE */
  4723. #ifdef SO_DONTROUTE
  4724.        dontroute(tcpsrv_fd,tcp_dontroute);
  4725. #endif /* SO_DONTROUTE */
  4726. #ifdef SO_LINGER
  4727.       ck_linger(tcpsrv_fd,tcp_linger, tcp_linger_tmo);
  4728. #endif /* SO_LINGER */
  4729. #ifdef SO_SNDBUF
  4730.     sendbuf(tcpsrv_fd,tcp_sendbuf);
  4731. #ifdef COMMENT
  4732.     if (tcp_sendbuf < (2*MAXSP))
  4733.       sendbuf(tcpsrv_fd,((2*MAXSP+1460)/1460)*1460);
  4734. #endif /* COMMENT */
  4735. #endif /* SO_SNDBUF */
  4736. #ifdef SO_RCVBUF
  4737.     recvbuf(tcpsrv_fd,tcp_recvbuf);
  4738. #ifdef COMMENT
  4739.     if (tcp_recvbuf < (10*MAXRP))
  4740.       recvbuf(tcpsrv_fd,((10*MAXRP+1460)/1460)*1460);
  4741. #endif /* COMMENT */
  4742. #endif /* SO_RCVBUF */
  4743. #endif /* SOL_SOCKET */
  4744.  
  4745.       /* Now bind to the socket */
  4746.       printf("\nBinding socket to port %d ...\n",
  4747.               ntohs((unsigned short)service->s_port)) ;
  4748.       if (bind(tcpsrv_fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
  4749.       {
  4750.          i = errno;                     /* save error code */
  4751.          socket_close(tcpsrv_fd) ;
  4752.          tcpsrv_fd = -1 ;
  4753.          tcpsrv_port = 0 ;
  4754.          ttyfd = -1;
  4755.          errno = i;                     /* and report this error */
  4756.          debug(F101,"tcpsrv_open bind errno","",errno);
  4757.          return(-1);
  4758.       }
  4759.  
  4760.       printf("Listening ...\n");
  4761.       if (listen(tcpsrv_fd, 15) < 0)
  4762.       {
  4763.          i = errno;                     /* save error code */
  4764.          socket_close(tcpsrv_fd) ;
  4765.          tcpsrv_fd = -1 ;
  4766.          tcpsrv_port = 0 ;
  4767.          ttyfd = -1;
  4768.          errno = i;                     /* and report this error */
  4769.          debug(F101,"tcpsrv_open listen errno","",errno);
  4770.          return(-1);
  4771.       }
  4772.       tcpsrv_port = ntohs((unsigned short)service->s_port) ;
  4773.    }
  4774.  
  4775. #ifdef CK_SSL
  4776.     if (ck_ssleay_is_installed()) {
  4777.         if (!ssl_tn_init(SSL_SERVER)) {
  4778.             ssl_failed = 1;
  4779.             if (bio_err!=NULL) {
  4780.                 BIO_printf(bio_err,"do_ssleay_init() failed\n");
  4781.                 ERR_print_errors(bio_err);
  4782.             } else {
  4783.                 fflush(stderr);
  4784.                 fprintf(stderr,"do_ssleay_init() failed\n");
  4785.                 ERR_print_errors_fp(stderr);
  4786.             }
  4787.  
  4788.             switch (ttnproto) {
  4789.             case NP_SSL:
  4790.             case NP_TLS:
  4791.         case NP_SSL_RAW:
  4792.         case NP_TLS_RAW:
  4793.             case NP_SSL_TELNET:
  4794.             case NP_TLS_TELNET:
  4795.                 i = errno;                     /* save error code */
  4796.                 socket_close(tcpsrv_fd) ;
  4797.                 tcpsrv_fd = -1 ;
  4798.                 tcpsrv_port = 0 ;
  4799.                 ttyfd = -1;
  4800.                 errno = i;                     /* and report this error */
  4801.                 return(-1);
  4802.             }
  4803.  
  4804.             /* otherwise, we will continue to accept the connection */
  4805.             /* without SSL or TLS support.               */
  4806.             TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4807.             TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4808.             TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4809.             TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
  4810.         }
  4811.     }
  4812. #endif /* CK_SSL */
  4813.  
  4814.    printf("\nWaiting to Accept a TCP/IP connection on port %d ...\n",
  4815.            ntohs((unsigned short)service->s_port) ) ;
  4816.    saddrlen = sizeof(saddr) ;
  4817.  
  4818. #ifdef BSDSELECT
  4819.     tv.tv_sec  = tv.tv_usec = 0L;
  4820.     if (timo < 0) {
  4821. #ifdef NT
  4822.         tv.tv_usec = (long) -timo * 1000L;
  4823. #else  /* NT */
  4824.         tv.tv_usec = (long) -timo * 10000L;
  4825. #endif /* NT */
  4826.     } else if ( timo > 0 )
  4827.         tv.tv_sec = timo;
  4828.     else
  4829.     {
  4830.         tv.tv_usec = ck_sleepint ;
  4831.     }
  4832.     debug(F101,"tcpsrv_open BSDSELECT","",timo);
  4833. #endif /* BSDSELECT */
  4834.  
  4835. #ifdef NT
  4836.     WSASafeToCancel = 1 ;
  4837. #endif /* NT */
  4838.  
  4839.     do {
  4840. #ifdef BSDSELECT
  4841.             FD_ZERO(&rfds);
  4842.             FD_SET(tcpsrv_fd, &rfds);
  4843.             ready_to_accept = ((select(FD_SETSIZE, &rfds,
  4844.                                         NULL, NULL, &tv ) > 0) &&
  4845.                                 FD_ISSET(tcpsrv_fd, &rfds)) ;
  4846. #else /* BSDSELECT */
  4847. #ifdef IBMSELECT
  4848.             ready_to_accept = ( select(&tcpsrv_fd, 1, 0, 0,
  4849.                                         timo < 0 ? -timo :
  4850.                                         (timo > 0 ? timo * 1000L :
  4851.                                           ck_sleepint )) == 1) ;
  4852. #endif /* IBMSELECT */
  4853. #endif /* BSDSELECT */
  4854. #ifdef NTSIG
  4855.          ck_ih() ;
  4856. #endif /* NTSIG */
  4857.  
  4858.         if ( ready_to_accept )
  4859.             break;
  4860.  
  4861.         msleep(100);      /* Do not hog the machine */
  4862.     } while ( timo == 0 );
  4863.  
  4864.     if ( ready_to_accept )
  4865.     {
  4866.        printf("Ready to Accept ...\n");
  4867.         if ((ttyfd = accept(tcpsrv_fd, (struct sockaddr *)&saddr,&saddrlen)) < 0)
  4868.         {
  4869. #ifdef NT
  4870.             WSASafeToCancel = 0 ;
  4871. #endif /* NT */
  4872.             i = errno;                  /* save error code */
  4873.             socket_close(tcpsrv_fd) ;
  4874.             ttyfd = -1;
  4875.             tcpsrv_close();
  4876.             errno = i;                  /* and report this error */
  4877.             debug(F101,"tcpsrv_open accept errno","",errno);
  4878.             return(-1);
  4879.         }
  4880. #ifdef NT
  4881.         WSASafeToCancel = 0 ;
  4882. #endif /* NT */
  4883.  
  4884.         setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof(int));
  4885. #ifdef SO_RCVTIMEO
  4886. #ifdef SO_SNDTIMEO
  4887.         i = 30000;
  4888.         setsockopt(ttyfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &i, sizeof(int));
  4889.         setsockopt(ttyfd, SOL_SOCKET, SO_SNDTIMEO, (char *) &i, sizeof(int));
  4890. #endif /* SO_SNDTIMEO */
  4891. #endif /* SO_RCVTIMEO */
  4892.  
  4893. #ifdef SOL_SOCKET
  4894. #ifdef TCP_NODELAY
  4895.         no_delay(ttyfd,tcp_nodelay);
  4896.         debug(F101,"tcpsrv_open no_delay","",tcp_nodelay);
  4897. #endif /* TCP_NODELAY */
  4898. #ifdef SO_KEEPALIVE
  4899.         keepalive(ttyfd,tcp_keepalive);
  4900.         debug(F101,"tcpsrv_open keepalive","",tcp_keepalive);
  4901. #endif /* SO_KEEPALIVE */
  4902. #ifdef SO_DONTROUTE
  4903.         dontroute(ttyfd,tcp_dontroute);
  4904.         debug(F101,"tcpsrv_open dontroute","",tcp_dontroute);
  4905. #endif /* SO_DONTROUTE */
  4906. #ifdef SO_LINGER
  4907.         ck_linger(ttyfd,tcp_linger, tcp_linger_tmo);
  4908.         debug(F101,"tcpsrv_open linger","",tcp_linger_tmo);
  4909. #endif /* SO_LINGER */
  4910. #ifdef SO_SNDBUF
  4911.         sendbuf(ttyfd,tcp_sendbuf);
  4912. #endif /* SO_SNDBUF */
  4913. #ifdef SO_RCVBUF
  4914.         recvbuf(ttyfd,tcp_recvbuf);
  4915. #endif /* SO_RCVBUF */
  4916. #endif /* SOL_SOCKET */
  4917.  
  4918.         ttnet = nett;                   /* TCP/IP (sockets) network */
  4919.         tcp_incoming = 1;               /* This is an incoming connection */
  4920.         sstelnet = 1;                   /* Server side telnet */
  4921.  
  4922.         /* See if the service is TELNET. */
  4923.         if ((x = ntohs((unsigned short)service->s_port)) ==
  4924.              getservbyname("telnet", "tcp")->s_port ) {
  4925.             if (ttnproto != NP_TCPRAW)  /* Yes and if raw port not requested */
  4926.                 ttnproto = NP_TELNET;   /* Yes, set global flag. */
  4927.         }
  4928.  
  4929.         /* Store the ipaddress */
  4930.         ckstrncpy(ipaddr,(char *)inet_ntoa(saddr.sin_addr),20);
  4931.  
  4932.         if (tcp_rdns) {                 /* Get real host name */
  4933. #ifdef NT
  4934.             if ( isWin95() )
  4935.                 sleep(1);
  4936. #endif /* NT */
  4937.  
  4938.             printf("  Reverse DNS Lookup...");
  4939.             if ((host = gethostbyaddr((char *)&saddr.sin_addr,4,PF_INET)) != NULL) {
  4940.                 host = ck_copyhostent(host);
  4941.                 debug(F100,"tcpsrv_open gethostbyname != NULL","",0);
  4942.                 name[0]='*' ;
  4943.                 ckstrncpy(&name[1],host->h_name,79);
  4944.                 strncat(name,":",80-strlen(name));
  4945.                 strncat(name,p,80-strlen(name));
  4946.                 ckstrncpy(ipaddr,(char *)inet_ntoa(saddr.sin_addr),20);
  4947.                 if (!quiet && !doconx)
  4948.                     printf("%s connected on port %s\n",host->h_name,p) ;
  4949.             }
  4950.         }
  4951.         if ( !tcp_rdns || !host ) {
  4952.             name[0] = '*';
  4953.             ckstrncpy(&name[1],ipaddr,79);
  4954.             strncat(name,":",80-strlen(name));
  4955.             itoa( ntohs(saddr.sin_port), name+strlen(name), 10 ) ;
  4956.             if (!quiet && !doconx)
  4957.                 printf("%s connected on port %d\n",
  4958.                         ipaddr,ntohs(saddr.sin_port)) ;
  4959.         }
  4960.  
  4961. #ifdef CK_SECURITY
  4962.         /* Before Initialization Telnet/Rlogin Negotiations Init Kerberos */
  4963.         ck_auth_init((tcp_rdns && host && host->h_name && host->h_name[0]) ?
  4964.                      host->h_name : ipaddr,
  4965.                      ipaddr,
  4966.                      uidbuf,
  4967.                      ttyfd
  4968.                      );
  4969. #endif /* CK_SECURITY */
  4970.  
  4971.  
  4972. #ifdef CK_SSL
  4973.         if (ck_ssleay_is_installed() && !ssl_failed) {
  4974.             if ( ck_ssl_incoming(ttyfd) < 0 ) {
  4975.                 socket_close(ttyfd);
  4976.                 ttyfd = -1;
  4977.                 return(-1);
  4978.             }
  4979.         }
  4980. #endif /* CK_SSL */
  4981.  
  4982.         if (tn_ini()<0)                 /* Start TELNET negotiations. */
  4983.             if (ttchk()<0) {
  4984. #ifdef NT
  4985.                 WSASafeToCancel = 0 ;
  4986. #endif /* NT */
  4987.                 i = errno;                      /* save error code */
  4988.                 ttyfd = -1;
  4989.                 errno = i;                      /* and report this error */
  4990.                 debug(F101,"tcpsrv_open accept errno","",errno);
  4991.                 return(-1);
  4992.             }
  4993.         debug(F101,"tcpsrv_open service","",x);
  4994.         if (*lcl < 0)
  4995.             *lcl = 1;           /* Local mode. */
  4996.  
  4997. #ifdef CK_KERBEROS
  4998. #ifdef KRB5
  4999.         if (ttnproto == NP_K5U2U ) {
  5000.             if (k5_user_to_user_server_auth() != 0) {
  5001.                 socket_close(ttyfd);
  5002.                 ttyfd = -1;
  5003.                 return(-1);
  5004.             }
  5005.         }
  5006. #endif /* KRB5 */
  5007. #endif /* CK_KERBEROS */
  5008.  
  5009. #ifdef NT_TCP_OVERLAPPED
  5010.         /* Reset the Overlapped I/O structures */
  5011.         OverlappedWriteInit();
  5012.         OverlappedReadInit();
  5013. #endif /* NT_TCP_OVERLAPPED */
  5014.         return(ttyfd == -1 ? -1 : 0);           /* Done. */
  5015.     }
  5016.     else
  5017.     {
  5018. #ifdef NT
  5019.         WSASafeToCancel = 0 ;
  5020. #endif /* NT */
  5021.         i = errno;                      /* save error code */
  5022.         ttyfd = -1;
  5023.         tcpsrv_close();
  5024.         errno = i;                      /* and report this error */
  5025.         debug(F101,"tcpsrv_open accept errno","",errno);
  5026.         return(-1);
  5027.     }
  5028. }
  5029. #endif /* TCPSOCKET */
  5030.  
  5031. char *
  5032. os2_gethostname( void )
  5033. {
  5034.     static char * host=NULL;
  5035. #ifdef NT
  5036.     HKEY  hkSubKey=0;
  5037.     CHAR  lpszKeyValue[256];
  5038.     DWORD dwType=0;
  5039.     DWORD dwSize=0;
  5040.     CHAR *lpszValueName=NULL;
  5041. #endif /* NT */
  5042.  
  5043.     if ( host )
  5044.         return host;
  5045.  
  5046. #ifdef NT
  5047.     if ( !RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  5048.                 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0,
  5049.                 KEY_READ, &hkSubKey) )
  5050.     {
  5051.         dwSize = sizeof(lpszKeyValue);
  5052.         lpszValueName = "HostName";
  5053.         if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType,
  5054.                                lpszKeyValue, &dwSize ))
  5055.         {
  5056.             host = lpszKeyValue;
  5057.         }
  5058.         RegCloseKey( hkSubKey );
  5059.     }
  5060.  
  5061.     if ( host )
  5062.         return host;
  5063.  
  5064.     if ( !RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  5065.                 "System\\CurrentControlSet\\Services\\VxD\\MSTCP", 0,
  5066.                 KEY_READ, &hkSubKey) )
  5067.     {
  5068.         dwSize = sizeof(lpszKeyValue);
  5069.         lpszValueName = "HostName";
  5070.         if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType,
  5071.                                lpszKeyValue, &dwSize ))
  5072.         {
  5073.             host = lpszKeyValue;
  5074.         }
  5075.         RegCloseKey( hkSubKey );
  5076.     }
  5077.  
  5078.     if ( host )
  5079.         return host;
  5080.  
  5081.     if ( !RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  5082.                 "System\\CurrentControlSet\\Control\\ComputerName\\ComputerName", 0,
  5083.                 KEY_READ, &hkSubKey) )
  5084.     {
  5085.         dwSize = sizeof(lpszKeyValue);
  5086.         lpszValueName = "ComputerName";
  5087.         if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType,
  5088.                                lpszKeyValue, &dwSize ))
  5089.         {
  5090.             host = lpszKeyValue;
  5091.         }
  5092.         RegCloseKey( hkSubKey );
  5093.     }
  5094. #else /* NT */
  5095.     host = getenv("HOSTNAME");          /* (Created by TCP/IP install) */
  5096.     if (!host) host = getenv("SYSTEMNAME");     /* (Created by PATHWORKS install?) */
  5097. #endif /* NT */
  5098.     return host;
  5099. }
  5100.  
  5101. #ifdef CK_SOCKS
  5102. #ifdef CK_SOCKS5
  5103. !Not implemented yet
  5104. #else /* CK_SOCKS5 */
  5105. #endif /* CK_SOCKS5 */
  5106. /* SOCKS 4.2 code derived from CSTC_RELEASE 4.2 on ftp.nec.com /pub/security */
  5107.  
  5108. static int usesocks = FALSE ;
  5109. static int usesocksns = FALSE ;
  5110. static int socks_usens = FALSE ;
  5111. static struct in_addr socks_server, socks_ns, default_server ;
  5112. static unsigned short socks_port;
  5113. static int server_count ;
  5114. static char * username ;
  5115. enum socks_action { deny, direct, sockd } ;
  5116.  
  5117. char *tcp_socks_svr = NULL;             /* SOCKS Server location */
  5118. char *tcp_socks_user = NULL;            /* SOCKS Username */
  5119.  
  5120.  
  5121. /* Current SOCKS protocol version */
  5122. #define SOCKS_VERSION_4  4
  5123.  
  5124. /*
  5125.  **  Response commands/codes
  5126.  */
  5127. #define SOCKS_CONNECT   1
  5128. #define SOCKS_BIND      2
  5129. #define SOCKS_SUCCESS   90
  5130. #define SOCKS_FAIL      91
  5131. #define SOCKS_NO_IDENTD 92 /* Failed to connect to Identd on client machine */
  5132. #define SOCKS_BAD_ID    93 /* Client's Identd reported a different user-id */
  5133.  
  5134. typedef unsigned long u_int32;
  5135.  
  5136. typedef struct {
  5137.     u_int32  host; /* in network byte order */
  5138.     unsigned short          port; /* in network byte oreder */
  5139.     unsigned char           version;
  5140.     unsigned char           cmd;
  5141.     } Socks_t;
  5142.  
  5143. enum portcmp { e_lt, e_gt, e_eq, e_neq, e_le, e_ge, e_nil };
  5144. typedef enum portcmp Portcmp;
  5145.  
  5146. /* structure for caching configurations.  this is improves performance in
  5147.  * clients when VERSATILE_CLIENTS is defined or in servers
  5148.  * when NOT_THROUGH_INETD is defined.
  5149.  * Also used in the SOCKS library.
  5150.  */
  5151.  
  5152. #ifdef interface
  5153. #undef interface
  5154. #endif
  5155.  
  5156. struct config {
  5157.     enum socks_action action;
  5158.     int use_identd;
  5159.     Portcmp tst;
  5160.     char *userlist, *serverlist;
  5161.     struct in_addr saddr;       /* source addr */
  5162.     struct in_addr smask;       /* source mask */
  5163.     struct in_addr daddr;       /* destination addr */
  5164.     struct in_addr dmask;       /* destination mask */
  5165.     struct in_addr interface;   /* interface (for route file) */
  5166.     char *cmdp;
  5167.     unsigned short dport;
  5168. };
  5169.  
  5170. #define CONF_INCR       100     /* step increment for realloc */
  5171. void    SOCKS_mkargs();
  5172. int     SOCKS_getaddr();
  5173. int     SOCKS_getquad();
  5174. long    SOCKS_getport();
  5175. int     SOCKS_checkuser();
  5176. char    socks_src_user[];
  5177. struct sockaddr_in       socks_nsin;
  5178. ULONG SocksHost;
  5179. char *socks_def_server = NULL ;
  5180. char *socks_serverlist = NULL ;
  5181.  
  5182. static struct config *confPtr=NULL, **confNtries = NULL;
  5183. static int Ntries = 0;
  5184.  
  5185. /*
  5186. **  Simple 'SOCKS_mkargs' doesn't handle \, ", or '.
  5187. */
  5188. void SOCKS_mkargs(cp, argc, argv, max)
  5189. char    *cp;
  5190. int     *argc;
  5191. char    *argv[];
  5192. int     max;
  5193. {
  5194.         *argc = 0;
  5195.         while (isspace(*cp))
  5196.                 cp++;
  5197.  
  5198.         while (*cp != '\0') {
  5199.                 argv[(*argc)++] = cp;
  5200.                 if (*argc >= max)
  5201.                         return;
  5202.  
  5203.                 while (!isspace(*cp) && (*cp != '\0'))
  5204.                         cp++;
  5205.                 while (isspace(*cp))
  5206.                         *cp++ = '\0';
  5207.         }
  5208. }
  5209.  
  5210.  
  5211. int SOCKS_getquad(dotquad, addr)
  5212. char            *dotquad;
  5213. struct in_addr  *addr;
  5214. /* dotquad must be in dotted quad form. Returns -1 if not. */
  5215. {
  5216.         if ((addr->s_addr = inet_addr(dotquad)) != (ULONG) -1)
  5217.                 return 0;
  5218.         if (strcmp(dotquad, "255.255.255.255") == 0)
  5219.                 return 0;
  5220.         return -1;
  5221. }
  5222.  
  5223. /*
  5224. **  Get address, must be dotted quad, or full domain name, or network name.
  5225. **  Returns -1 if none of the above.
  5226. */
  5227. int SOCKS_getaddr(name, addr)
  5228.     char            *name;
  5229.     struct in_addr  *addr;
  5230. {
  5231.     struct hostent  *hp;
  5232.     struct netent   *np;
  5233.  
  5234.     if (SOCKS_getquad(name, addr) != -1)
  5235.         return 0;
  5236.     if ((hp = gethostbyname(name)) != NULL) {
  5237.         hp = ck_copyhostent(hp);
  5238.         bcopy(hp->h_addr_list[0], &(addr->s_addr), hp->h_length);
  5239.         return 0;
  5240.     }
  5241. #ifdef COMMENT
  5242.     /* Not implemented on Windows and we only use AF_INET anyway */
  5243.     if ((np = getnetbyname(name)) != NULL) {
  5244.         addr->s_addr = np->n_net;
  5245.         return 0;
  5246.     }
  5247. #else /* COMMENT */
  5248.     addr->s_addr = AF_INET;
  5249. #endif /* COMMENT */
  5250.     return -1;
  5251. }
  5252.  
  5253. long SOCKS_getport(name)
  5254. char            *name;
  5255. {
  5256.         struct servent  *sp;
  5257.  
  5258.         if ((sp = getservbyname(name, "tcp")) != NULL) {
  5259.                 return sp->s_port;
  5260.         }
  5261.         if (!isdigit(*name))
  5262.                 return -1;
  5263.         return htons(atol(name));
  5264. }
  5265.  
  5266. /*
  5267.  *   -1 no socks.conf file or no valid entries
  5268.  *    0 everything okay
  5269.  */
  5270. static int
  5271. SOCKS_read_config( void )
  5272. {
  5273.     FILE            *fd;
  5274.     static char     filename[256];
  5275.     static char     buf[1024];
  5276.     char            *bp;
  5277.     int             linenum = 0;
  5278.     char    *argv[10];
  5279.     int     argc;
  5280.     struct in_addr  daddr, dmask;
  5281.     int     next_arg;
  5282.     enum socks_action  action;
  5283.     char    *userlist = NULL, *server_list = NULL;
  5284.     long    p;
  5285.     unsigned short dport;
  5286.     char    *cmdp = NULL;
  5287.     struct  in_addr self;
  5288.     Portcmp tst;
  5289.  
  5290.     if ( confNtries ) {
  5291.         int i;
  5292.         for ( i = 0 ; i < Ntries; i++)
  5293.             if (confNtries[i])
  5294.                 free(confNtries[i]);
  5295.         free(confNtries);
  5296.         confNtries = NULL;
  5297.         confPtr = NULL;
  5298.         Ntries = 0;
  5299.     }
  5300.  
  5301.     /* find the etc directory */
  5302.     bp = getenv("ETC");
  5303. #ifdef NT
  5304.     if ( !bp ) {
  5305.         unsigned int len;
  5306.         len = sizeof(buf);
  5307.  
  5308.         len = GetWindowsDirectory(buf,len);
  5309.         if ( len > 0 && len < sizeof(buf)) {
  5310.             if ( !isWin95() ) {
  5311.                 if ( len == 1 )
  5312.                     ckstrncat(buf,"SYSTEM32/DRIVERS/ETC",sizeof(buf));
  5313.                 else
  5314.                     ckstrncat(buf,"/SYSTEM32/DRIVERS/ETC",sizeof(buf));
  5315.             }
  5316.         }
  5317.         bp = buf;
  5318.     }
  5319. #endif /* NT */
  5320.     if ( bp == NULL )
  5321.         return -1 ;
  5322.  
  5323.     /* check for the socks.conf or socks.cnf */
  5324.     ckstrncpy( filename, bp, sizeof(filename) ) ;
  5325.     if ( bp[strlen(bp)] != '\\' )
  5326.         ckstrncat( filename, "\\", sizeof(filename) ) ;
  5327.     ckstrncat( filename, "socks.conf", sizeof(filename) ) ;
  5328.     fd = fopen( filename, "r" ) ;
  5329.  
  5330.     if ( !fd ) {
  5331.         ckstrncpy( filename, bp, sizeof(filename) ) ;
  5332.         if ( bp[strlen(bp)] != '\\' )
  5333.             ckstrncat( filename, "\\", sizeof(filename) ) ;
  5334.         ckstrncat( filename, "socks.cnf", sizeof(filename) ) ;
  5335.         fd = fopen( filename, "r" ) ;
  5336.     }
  5337.  
  5338.     if ( !fd )
  5339.         return -1 ;
  5340.  
  5341.     while (fgets(buf, sizeof(buf) - 1, fd) != NULL) {
  5342.         int idx;
  5343.         linenum++;
  5344.         /*
  5345.         **  Comments start with a '#' anywhere on the line
  5346.         */
  5347.         cmdp = (char *)0;
  5348.         idx = ckindex("\n", buf, 0, 0, 1);
  5349.         if ( idx == 0 )
  5350.             bp = NULL;
  5351.         else {
  5352.             bp = &buf[idx];
  5353.             *bp = '\0';
  5354.         }
  5355.         for (bp = buf; *bp != '\0'; bp++) {
  5356.             if (*bp == ':') {
  5357.                 *bp++ = '\0';
  5358.                 cmdp = bp;
  5359.                 break;
  5360.             } else if (*bp == '#') {
  5361.                 *bp = '\0';
  5362.                 break;
  5363.             } else if (*bp == '\t')
  5364.                 *bp = ' ';
  5365.         }
  5366.         if (strlen(buf) == 0) continue;
  5367.         SOCKS_mkargs(buf, &argc, argv, 7);
  5368.         if (argc == 0) {
  5369.             continue;
  5370.         }
  5371.  
  5372.         if ((argc < 3) || (argc > 7)) {
  5373.             printf("Invalid entry at line %d in file %s\n",linenum, filename);
  5374.             continue;
  5375.         }
  5376.  
  5377.         /* parse the whole entry now, once. */
  5378.         next_arg = 1;
  5379.         server_list = (char *)0;
  5380.  
  5381.         if (!strcmp(*argv, "sockd")) {
  5382.             server_list = socks_def_server;
  5383.             action = sockd;
  5384.             if (strncmp(*(argv +next_arg), "@=", 2) == 0) {
  5385.                 server_list = *(argv +next_arg) + 2;
  5386.                 if(*server_list == '\0')
  5387.                     server_list = socks_def_server;
  5388.                 next_arg++;
  5389.             }
  5390.         } else if (strncmp(*argv, "sockd@", 6) == 0) {
  5391.             action = sockd;
  5392.             server_list = *(argv) + 6;
  5393.             if (*server_list == '\0')
  5394.                 server_list = socks_def_server;
  5395.         } else if (!strcmp(*argv, "direct")) {
  5396.             action = direct;
  5397.         } else if (!strcmp(*argv, "deny")) {
  5398.             action = deny;
  5399.         } else {
  5400.             printf("Invalid sockd/direct/deny field at line %d in file %s\n", linenum, filename);
  5401.             continue;
  5402.         }
  5403.  
  5404.         userlist = (char *)0;
  5405.         if (strncmp(*(argv +next_arg), "*=", 2) == 0) {
  5406.             if (*(argv +next_arg) +2) userlist = *(argv +next_arg) + 2;
  5407.             next_arg++;
  5408.         }
  5409.         if(argc <= next_arg+1) {
  5410.             printf("Invalid entry at line %d in file %s\n", linenum, filename);
  5411.             continue;
  5412.         }
  5413.         if (SOCKS_getaddr(*(argv +next_arg++), &daddr) == -1){
  5414.             printf("illegal destination field at line %d in file %s\n", linenum, filename);
  5415.             continue;
  5416.         }
  5417.         if (SOCKS_getquad(*(argv +next_arg++), &dmask) == -1) {
  5418.             printf("illegal destination mask at line %d in file %s\n", linenum, filename);
  5419.             continue;
  5420.         }
  5421.         if (argc > next_arg + 1) {
  5422.             if (!strcmp(*(argv +next_arg), "eq"))
  5423.                 tst = e_eq;
  5424.             else if (!strcmp(*(argv +next_arg), "neq"))
  5425.                 tst = e_neq;
  5426.             else if (!strcmp(*(argv +next_arg), "lt"))
  5427.                 tst = e_lt;
  5428.             else if (!strcmp(*(argv +next_arg), "gt"))
  5429.                 tst = e_gt;
  5430.             else if (!strcmp(*(argv +next_arg), "le"))
  5431.                 tst = e_le;
  5432.             else if (!strcmp(*(argv +next_arg), "ge"))
  5433.                 tst = e_ge;
  5434.             else {
  5435.                 printf("Invalid comparison at line %d in file %s\n", linenum, filename);
  5436.                 continue;
  5437.             }
  5438.  
  5439.             if (((p = SOCKS_getport(*(argv +next_arg+1))) < 0) ||
  5440.                  (p >= (1L << 16))) {
  5441.                 printf("Invalid port number at line %d in file %s\n", linenum, filename);
  5442.                 continue;
  5443.                  } else {
  5444.                      dport = p;
  5445.                  }
  5446.         }
  5447.         else {
  5448.             tst = e_nil;
  5449.             dport = 0;
  5450.         }
  5451.  
  5452. #ifdef DEBUG
  5453.         {
  5454.             char msg[1024];
  5455.             if (userlist)
  5456.                 sprintf(msg,"%s %s 0x%08x 0x%08x %s %u",
  5457.                          *argv, userlist, daddr.s_addr, dmask,
  5458.                          tst == e_eq ? "==" :
  5459.                          tst == e_neq ? "!=" :
  5460.                          tst == e_lt ? "<" :
  5461.                          tst == e_gt ? ">" :
  5462.                          tst == e_le ? "<=" :
  5463.                          tst == e_ge ? ">=" : "NIL",
  5464.                          dport);
  5465.             else
  5466.                 sprintf(msg,"%s 0x%08x 0x%08x %s %u",
  5467.                          *argv, daddr.s_addr, dmask,
  5468.                          tst == e_eq ? "==" :
  5469.                          tst == e_neq ? "!=" :
  5470.                          tst == e_lt ? "<" :
  5471.                          tst == e_gt ? ">" :
  5472.                          tst == e_le ? "<=" :
  5473.                          tst == e_ge ? ">=" : "NIL",
  5474.                          dport);
  5475.             printf("%s\n", msg);
  5476.         }
  5477. #endif
  5478.         /* we have a parsed line.  cache it. */
  5479.         if (!confNtries || confPtr - *confNtries >= Ntries) {
  5480.             /* some systems can't be counted on to handle
  5481.             * realloc(NULL, ...) correctly.
  5482.             */
  5483.             if (confNtries == NULL)
  5484.                 confNtries =
  5485.                 (struct config **) malloc(CONF_INCR *sizeof(struct config **));
  5486.             else confNtries = (struct config **)
  5487.                realloc(confNtries, (Ntries +CONF_INCR) *sizeof(struct config));
  5488.         }
  5489.        *(confNtries +Ntries) = (struct config *) malloc(sizeof(struct config));
  5490.         confPtr = *(confNtries +Ntries);
  5491.         Ntries++;
  5492.         confPtr->action = action;
  5493.         confPtr->tst = tst;
  5494.         if (server_list) {
  5495.             confPtr->serverlist = (char *)malloc(strlen(server_list) +1);
  5496.             strcpy(confPtr->serverlist, server_list);
  5497.         }
  5498.         else
  5499.             confPtr->serverlist = NULL;
  5500.         if (userlist) {
  5501.             confPtr->userlist = (char *)malloc(strlen(userlist) +1);
  5502.             strcpy(confPtr->userlist, userlist);
  5503.         }
  5504.         else confPtr->userlist = NULL;
  5505.         confPtr->daddr.s_addr = daddr.s_addr;
  5506.         confPtr->dmask.s_addr = dmask.s_addr;
  5507.         if (cmdp) {
  5508.             confPtr->cmdp = (char *) malloc(strlen(cmdp) +1);
  5509.             strcpy(confPtr->cmdp, cmdp);
  5510.         }
  5511.         else confPtr->cmdp = NULL;
  5512.         confPtr->dport = dport;
  5513.  
  5514.     }
  5515.     fclose(fd);
  5516.     if (confNtries == NULL) {
  5517.         printf("No valid SOCKS entries in file: %s\n", filename);
  5518.         return(-1);
  5519.     }
  5520.     return 0;
  5521. }
  5522.  
  5523. int
  5524. SOCKS_init( void )
  5525. {
  5526.     PSZ var = NULL;
  5527.     struct hostent *host ;
  5528.  
  5529.     /* Reset */
  5530.     socks_server.s_addr = 0 ;
  5531.     socks_ns.s_addr = 0 ;
  5532.     if ( socks_def_server ) {
  5533.         free(socks_def_server);
  5534.         socks_def_server = NULL;
  5535.     }
  5536.  
  5537. #ifdef CK_SOCKS_NS
  5538.     /* get the resolv info */
  5539.     res_init() ;
  5540.     server_count = _res.nscount ;
  5541.     default_server.s_addr = _res.nsaddr_list[0].sin_addr.s_addr ;
  5542. #endif /* CK_SOCKS_NS */
  5543.  
  5544.     /* get the SOCKS server if any */
  5545.     if ( tcp_socks_svr )
  5546.         var = tcp_socks_svr;
  5547.     else
  5548.         var = getenv("SOCKS_SERVER");
  5549.     if ( var ) {
  5550.         char * p;
  5551.         socks_def_server = strdup( var ) ;
  5552.         for (p=socks_def_server; *p && *p != ':'; p++);
  5553.         if ( *p == ':' ) {
  5554.             *p++ = '\0';
  5555.             socks_port = (unsigned short)atoi(p);
  5556.         } else {
  5557.             struct servent *service = getservbyname("socks", "tcp");
  5558.             if ( service )
  5559.                 socks_port = ntohs(service->s_port);
  5560.             else
  5561.                 socks_port = 1080;
  5562.         }
  5563.         host = gethostbyname( socks_def_server ) ;
  5564.         if ( host ) {
  5565.             host = ck_copyhostent(host);
  5566.             memcpy( &socks_server, host->h_addr_list[0],
  5567.                     sizeof(socks_server));
  5568.         }
  5569.         else {
  5570.             socks_server.s_addr = inet_addr(var);
  5571.         }
  5572.     }
  5573.  
  5574.     usesocks = socks_server.s_addr && (socks_server.s_addr != -1);
  5575.  
  5576.     if ( usesocks ) {
  5577. #ifdef CK_SOCKS_NS
  5578.         /* get the SOCKS Name Server if any */
  5579.         if ( var = getenv("SOCKS_NS") ) {
  5580.             host = gethostbyname( var ) ;
  5581.             if ( host ) {
  5582.                 host = ck_copyhostent(host);
  5583.                 memcpy( &socks_ns.s_addr, host->h_addr_list[0],
  5584.                     sizeof(socks_ns.s_addr)) ;
  5585.                 }
  5586.             else {
  5587.                 socks_ns.s_addr = inet_addr( var ) ;
  5588.             }
  5589.  
  5590.             /* now install this name server as the default */
  5591.             if ( socks_ns.s_addr && ( socks_ns.s_addr != -1 ) ) {
  5592.                 _res.nsaddr_list[0].sin_addr.s_addr = socks_ns.s_addr ;
  5593.                 _res.nscount = 1 ;
  5594.                 usesocksns = TRUE ;
  5595.             }
  5596.         }
  5597. #endif /* CK_SOCKS_NS */
  5598.         SOCKS_read_config() ;
  5599.  
  5600.         if ( !quiet )
  5601.             printf( "SOCKS 4.2 is enabled\r\n" ) ;
  5602.     }
  5603.  
  5604.     /* read socks.conf file */
  5605.     return( usesocks ) ;
  5606. }
  5607.  
  5608. enum socks_action
  5609. SOCKS_validate( struct sockaddr_in * dest )
  5610. {
  5611.     int i = 0 ;
  5612.     enum socks_action action = sockd ;
  5613.  
  5614.     for ( i = 0 ; i < Ntries ; i++ ) {
  5615.         if ( ( confNtries[i]->daddr.s_addr & confNtries[i]->dmask.s_addr ) ==
  5616.              ( dest->sin_addr.s_addr & confNtries[i]->dmask.s_addr ) ) {
  5617.             if ( confNtries[i]->tst == e_nil ) {
  5618.                 action = confNtries[i]->action ;
  5619.                 break;
  5620.             }
  5621.             if ((confNtries[i]->tst == e_eq) && (dest->sin_port == confNtries[i]->dport)){
  5622.                 action = confNtries[i]->action ;
  5623.                 break;
  5624.             }
  5625.             if ((confNtries[i]->tst == e_neq) && (dest->sin_port != confNtries[i]->dport)){
  5626.                 action = confNtries[i]->action ;
  5627.                 break;
  5628.             }
  5629.             if ((confNtries[i]->tst == e_lt) && (dest->sin_port < confNtries[i]->dport)){
  5630.                 action = confNtries[i]->action ;
  5631.                 break;
  5632.             }
  5633.             if ((confNtries[i]->tst == e_gt) && (dest->sin_port > confNtries[i]->dport)){
  5634.                 action = confNtries[i]->action ;
  5635.                 break;
  5636.             }
  5637.             if ((confNtries[i]->tst == e_le) && (dest->sin_port <= confNtries[i]->dport)){
  5638.                 action = confNtries[i]->action ;
  5639.                 break;
  5640.             }
  5641.             if ((confNtries[i]->tst == e_ge) && (dest->sin_port >= confNtries[i]->dport)){
  5642.                 action = confNtries[i]->action ;
  5643.                 break;
  5644.             }
  5645.         }
  5646.     }
  5647.     return action ;
  5648. }
  5649.  
  5650. int
  5651. Rconnect(int socket, struct sockaddr * name, int namelen)
  5652. {
  5653.     struct sockaddr_in addr;
  5654.     int rc ;
  5655.     CHAR localuser[UIDBUFLEN+1];
  5656.     char request[100];
  5657.     char *next ;
  5658.     int packetsize ;
  5659.     int sockret ;
  5660.     extern int ck_lcname;
  5661.  
  5662.     if (usesocks) {
  5663.         memset(&addr, 0, sizeof(addr));
  5664.         addr.sin_port        = ((struct sockaddr_in *) name)->sin_port;
  5665.         addr.sin_family      = ((struct sockaddr_in *) name)->sin_family;
  5666.         addr.sin_addr.s_addr = ((struct sockaddr_in *) name)->sin_addr.s_addr;
  5667.  
  5668.         /* Check local cached values from SOCKS.CONF */
  5669.         switch ( SOCKS_validate( &addr ) ) {
  5670.         case deny:
  5671.             return -1 ;
  5672.  
  5673.         case direct:
  5674.             break;
  5675.  
  5676.         case sockd:
  5677.         default:
  5678.             addr.sin_family = AF_INET ;
  5679.             addr.sin_addr = socks_server ;
  5680.             addr.sin_port = htons(socks_port) ;      /* The SOCKS Service */
  5681.  
  5682.             /* Connect to the SOCKS Server */
  5683.             if ( connect(socket, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) {
  5684.                 return -1 ;
  5685.             }
  5686.  
  5687.             /* Build the request packet */
  5688.             next = request;
  5689.             *next++ = SOCKS_VERSION_4 ;
  5690.             *next++ = SOCKS_CONNECT ;
  5691.             memcpy(next, &((struct sockaddr_in *) name)->sin_port,
  5692.                         sizeof(((struct sockaddr_in *) name)->sin_port) ) ;
  5693.             next += sizeof(((struct sockaddr_in *) name)->sin_port) ;
  5694.             memcpy(next, &((struct sockaddr_in *) name)->sin_addr,
  5695.                     sizeof(((struct sockaddr_in *) name)->sin_addr) ) ;
  5696.             next += sizeof(((struct sockaddr_in *) name)->sin_addr) ;
  5697.  
  5698.             localuser[0] = '\0';
  5699.             if ( tcp_socks_user )
  5700.                 ckstrncpy((char*)localuser,tcp_socks_user,UIDBUFLEN);
  5701. #ifdef NT
  5702.             if ( !localuser[0] )
  5703.             {
  5704.                 char localuid[UIDBUFLEN+1];
  5705.                 unsigned long len = UIDBUFLEN;
  5706.                 localuid[0] = '\0';
  5707.                 GetUserName(localuid,&len);
  5708.                 ckstrncpy((char *)localuser,localuid,UIDBUFLEN);
  5709.             }
  5710.  
  5711. #endif /* NT */
  5712.             if ( !localuser[0] )
  5713.             {
  5714.                 char * user = getenv("USER");
  5715.                 if (!user)
  5716.                     user = "";
  5717.                 debug(F110,"Rconnect getenv(USER)",user,0);
  5718.                 ckstrncpy((char *)localuser,user,UIDBUFLEN);
  5719.                 debug(F110,"Rconnect localuser 1",localuser,0);
  5720.             }
  5721.             if ( !localuser[0] )
  5722.                 strcpy((char *)localuser,"unknown");
  5723.             else if (ck_lcname) {
  5724.                 cklower((char *)localuser);
  5725.                 debug(F110,"Rconnect localuser 2",localuser,0);
  5726.             }
  5727.  
  5728.             strcpy(next,localuser) ;
  5729.             next += strlen(localuser) + 1;
  5730.  
  5731.             /* Send the request */
  5732.             rc = send(socket, request, next - request, 0) ;
  5733.  
  5734.             /* Now retrieve the response */
  5735.             packetsize = 8 ; /* VN 1, CD 1, PORT 2, IP 4 */
  5736.             next = request ;
  5737.             while ( packetsize > (next - request) ) {
  5738.                 rc = recv( socket, next, packetsize - (next - request), 0 );
  5739.                 if ( rc <= 0 )
  5740.                     return(-1);
  5741.                 next += rc ;
  5742.             }
  5743.             hexdump("Rconnect response from SOCKS server",request,packetsize);
  5744.             return ( request[1] == SOCKS_SUCCESS ? 0 : -1 );
  5745.         }
  5746.     }
  5747.  
  5748.     /* Direct connection */
  5749.     memset(&addr, 0, sizeof(addr));
  5750.     addr.sin_port        = ((struct sockaddr_in *) name)
  5751.         ->sin_port;
  5752.     addr.sin_family      = ((struct sockaddr_in *) name)
  5753.         ->sin_family;
  5754.     addr.sin_addr.s_addr = ((struct sockaddr_in *) name)
  5755.         ->sin_addr.s_addr;
  5756.     rc = connect(socket, (struct sockaddr *) &addr, sizeof(addr));
  5757.  
  5758.     return rc  ;
  5759. }
  5760.  
  5761. int
  5762. Rbind(int socket, struct sockaddr *name, int namelen)
  5763. {
  5764.     struct sockaddr_in addr;
  5765.  
  5766.     memset(&addr, 0, sizeof(addr));
  5767.     addr.sin_port        = ((struct sockaddr_in *) name) -> sin_port;
  5768.     addr.sin_family      = ((struct sockaddr_in *) name) -> sin_family;
  5769.     addr.sin_addr.s_addr = ((struct sockaddr_in *) name) -> sin_addr.s_addr;
  5770.  
  5771.     return bind(socket, (struct sockaddr *) &addr, sizeof(addr));
  5772. }
  5773.  
  5774. int
  5775. Rlisten(int socket, int backlog)
  5776. {
  5777.     return listen( socket, backlog );
  5778. }
  5779.  
  5780. int
  5781. Raccept(int socket, struct sockaddr *name, int * namelen)
  5782. {
  5783.     struct sockaddr_in addr;
  5784.     int len ;
  5785.     int rc = 0 ;
  5786.  
  5787.     memset(&addr, 0, sizeof(addr));
  5788.     addr.sin_port        = ((struct sockaddr_in *) name) -> sin_port;
  5789.     addr.sin_family      = ((struct sockaddr_in *) name) -> sin_family;
  5790.     addr.sin_addr.s_addr = ((struct sockaddr_in *) name) -> sin_addr.s_addr;
  5791.     len = sizeof(addr) ;
  5792.  
  5793.     rc = accept(socket, (struct sockaddr *) &addr, &len);
  5794.     ((struct sockaddr_in *) name) -> sin_port = addr.sin_port ;
  5795.     ((struct sockaddr_in *) name) -> sin_family = addr.sin_family ;
  5796.     ((struct sockaddr_in *) name) -> sin_addr.s_addr = addr.sin_addr.s_addr;
  5797.     *namelen = len ;
  5798.  
  5799.     return rc ;
  5800. }
  5801.  
  5802. int
  5803. Rgetsockname( int socket, struct sockaddr * name, int * namelen )
  5804. {
  5805.     int len = *namelen;
  5806.     int rc = 0 ;
  5807.  
  5808.     rc = getsockname( socket, name, &len ) ;
  5809.     *namelen = len ;
  5810.     return rc;
  5811. }
  5812. #endif /* CK_SOCKS */
  5813.  
  5814. #ifdef NT_TCP_OVERLAPPED
  5815. /* These are Win32 specific functions which are used in place of #defines */
  5816. /* The hope is to add Overlapped I/O support to these calls               */
  5817.  
  5818. _PROTOTYP( int OverlappedWrite, (int, char *, int));
  5819. _PROTOTYP( int OverlappedRead,  (int, char *, int, int));
  5820. int ionoblock = 0;
  5821. extern int owwait;
  5822.  
  5823. int
  5824. socket_read(int f, char * s, int n)
  5825. {
  5826.     extern char ttibuf[];
  5827.     extern int  ttibp, ttibn;
  5828.     int rc = 0;
  5829.  
  5830.     if ( owwait )
  5831.         return(recv(f,s,n,0));
  5832.  
  5833.     RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
  5834.     if ( ttibn )
  5835.     {
  5836.         if ( n < ttibn ) {
  5837.             memcpy(s,&ttibuf[ttibp],n);
  5838.             ttibp += n;
  5839.             ttibn -= n;
  5840.             rc = n;
  5841.         }
  5842.         else {
  5843.             rc = ttibn;
  5844.             memcpy(s,&ttibuf[ttibp],ttibn);
  5845.             ttibp = ttibn = 0;
  5846.         }
  5847.         ReleaseTCPIPMutex();
  5848.         return(rc);
  5849.     }
  5850.  
  5851.     /* The real test here should be if n is small AND there are no overlapped */
  5852.     /* Reads in progress OR if we are using a non-Microsoft Winsock stack     */
  5853.     if ( n < 32768 ) {
  5854.         rc = OverlappedRead( 0, ttibuf, 32768, ionoblock ? 10 : -1 );
  5855.         if ( rc > 0 ) {
  5856.             ttibp = 0;
  5857.             ttibn = rc;
  5858.             rc = socket_read(f,s,n);
  5859.             ReleaseTCPIPMutex();
  5860.             return rc;
  5861.         }
  5862.         else if ( rc == 0 || rc == -1 ) {
  5863.             ReleaseTCPIPMutex();
  5864.             return(-1);
  5865.         } else if ( rc <= -2 ) {        /* Connection failed */
  5866.             ReleaseTCPIPMutex();
  5867.             return(0);
  5868.         }
  5869.     }
  5870.     else {
  5871.         rc = OverlappedRead( 0, s, n, ionoblock ? 10 : -1 );
  5872.         if ( rc <= -2 ) {        /* Connection failed */
  5873.             ReleaseTCPIPMutex();
  5874.             return(0);
  5875.         } else if ( rc == 0 || rc == -1 ) {
  5876.             ReleaseTCPIPMutex();
  5877.             return(-1);
  5878.         } else {
  5879.             ReleaseTCPIPMutex();
  5880.             return(rc);
  5881.         }
  5882.     }
  5883.     ReleaseTCPIPMutex();
  5884.     return(0);
  5885. }
  5886.  
  5887. int
  5888. socket_write(int f, char * s, int n)
  5889. {
  5890.     int rc;
  5891.  
  5892.     if ( owwait )
  5893.         return(send(f,s,n,0));
  5894.  
  5895.     rc = OverlappedWrite( 0, s, n );
  5896.     if ( rc < 0 )
  5897.         return(-1);
  5898.     else
  5899.         return(rc);
  5900. }
  5901.  
  5902. int
  5903. socket_recv(int f, char * s, int n, int o)
  5904. {
  5905.     return(recv(f,s,n,o));
  5906. }
  5907.  
  5908. int
  5909. socket_send(int f, char * s, int n, int o)
  5910. {
  5911.     return(send(f,s,n,o));
  5912. }
  5913.  
  5914. #endif /* NT_TCP_OVERLAPPED */
  5915. #endif /* NETCONN */
  5916.