home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / k95 / k95dll / k95dll.c next >
C/C++ Source or Header  |  2020-01-01  |  7KB  |  381 lines

  1. /* This is an example of how to create your K95 Connection DLL    */
  2. /* The DLL must be safe for multithreading because K95 will call  */
  3. /* it from multiple threads.                                      */
  4.  
  5. /* This example implements a simple ECHO or LOOPBACK service.     */
  6.  
  7. #include <windows.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. /* Local variables for the Local Echo structures that do most of the work. */
  12.  
  13. #define LOCAL_ECHO_BUFSIZE 512
  14. static USHORT LocalEchoBuf[LOCAL_ECHO_BUFSIZE] ;
  15. static int LocalEchoStart=0, LocalEchoEnd=0, LocalEchoData=0 ;
  16. static HANDLE hmtxLocalEcho = (HANDLE) 0 ;
  17. static HANDLE hevLocalEchoAvail = (HANDLE) 0 ;
  18. static open=0;
  19.  
  20. static DWORD
  21. CreateLocalEchoMutex( BOOL owned )
  22. {
  23.     if ( hmtxLocalEcho )
  24.         CloseHandle( hmtxLocalEcho ) ;
  25.     hmtxLocalEcho = CreateMutex( NULL, owned, NULL ) ;
  26.     if (hmtxLocalEcho == NULL)
  27.         return GetLastError();
  28.     return 0;
  29. }
  30.  
  31. static DWORD
  32. RequestLocalEchoMutex( ULONG timo )
  33. {
  34.     DWORD rc = 0 ;
  35.  
  36.     rc = WaitForSingleObjectEx( hmtxLocalEcho, timo, TRUE ) ;
  37.     return rc == WAIT_OBJECT_0 ? 0 : rc ;
  38. }
  39.  
  40. static DWORD
  41. ReleaseLocalEchoMutex( void )
  42. {
  43.     BOOL rc = 0 ;
  44.  
  45.     rc = ReleaseMutex( hmtxLocalEcho ) ;
  46.     return rc == TRUE ? 0 : GetLastError() ;
  47. }
  48.  
  49. static DWORD
  50. CloseLocalEchoMutex( void )
  51. {
  52.     BOOL rc = 0 ;
  53.     rc = CloseHandle( hmtxLocalEcho ) ;
  54.     hmtxLocalEcho = (HANDLE) NULL ;
  55.     return rc == TRUE ? 0 : GetLastError() ;
  56. }
  57.  
  58.  
  59. static DWORD
  60. CreateLocalEchoAvailSem( BOOL posted )
  61. {
  62.     if ( hevLocalEchoAvail )
  63.         CloseHandle( hevLocalEchoAvail ) ;
  64.     hevLocalEchoAvail = CreateEvent( NULL, TRUE, posted, NULL ) ;
  65.     return hevLocalEchoAvail == NULL ? GetLastError() : 0 ;
  66. }
  67.  
  68. static DWORD
  69. PostLocalEchoAvailSem( void )
  70. {
  71.     BOOL rc = 0 ;
  72.  
  73.     rc = SetEvent( hevLocalEchoAvail ) ;
  74.     return rc == TRUE ? 0 : GetLastError() ;
  75. }
  76.  
  77. static DWORD
  78. WaitLocalEchoAvailSem( ULONG timo )
  79. {
  80.     DWORD rc = 0 ;
  81.  
  82.     rc = WaitForSingleObjectEx( hevLocalEchoAvail, timo, TRUE ) ;
  83.     return rc == WAIT_OBJECT_0 ? 0 : rc ;
  84. }
  85.  
  86. static DWORD
  87. WaitAndResetLocalEchoAvailSem( ULONG timo )
  88. {
  89.     DWORD rc = 0 ;
  90.  
  91.     rc = WaitForSingleObjectEx( hevLocalEchoAvail, timo, TRUE ) ;
  92.     if ( rc == WAIT_OBJECT_0 )
  93.         ResetEvent( hevLocalEchoAvail ) ;
  94.     return rc == WAIT_OBJECT_0 ;
  95. }
  96.  
  97. static DWORD
  98. ResetLocalEchoAvailSem( void )
  99. {
  100.     BOOL rc = 0 ;
  101.  
  102.     rc = ResetEvent( hevLocalEchoAvail ) ;
  103.     return rc ;
  104. }
  105.  
  106. static DWORD
  107. CloseLocalEchoAvailSem( void )
  108. {
  109.     BOOL rc = 0 ;
  110.     rc = CloseHandle( hevLocalEchoAvail ) ;
  111.     hevLocalEchoAvail = (HANDLE) NULL ;
  112.     return rc == TRUE ? 0 : GetLastError() ;
  113. }
  114.  
  115.  
  116. static void
  117. LocalEchoInit( void ) {
  118.     CreateLocalEchoAvailSem( FALSE );
  119.     CreateLocalEchoMutex( TRUE ) ;
  120.     memset(LocalEchoBuf,0,LOCAL_ECHO_BUFSIZE*sizeof(USHORT)) ;
  121.     LocalEchoStart = 0 ;
  122.     LocalEchoEnd = 0 ;
  123.     LocalEchoData = 0;
  124.     ReleaseLocalEchoMutex() ;
  125. }
  126.  
  127. static void
  128. LocalEchoCleanup( void ) {
  129.     CloseLocalEchoMutex() ;
  130.     CloseLocalEchoAvailSem() ;
  131. }
  132.  
  133. static int
  134. LocalEchoInBuf() {
  135.     int rc = 0 ;
  136.  
  137.     if (RequestLocalEchoMutex(INFINITE))
  138.         return(-1);
  139.     if ( LocalEchoStart != LocalEchoEnd )
  140.     {
  141.     rc = (LocalEchoEnd - LocalEchoStart + LOCAL_ECHO_BUFSIZE)%LOCAL_ECHO_BUFSIZE;
  142.     }  
  143.     ReleaseLocalEchoMutex() ;
  144.     return rc ;
  145. }
  146.  
  147. static int
  148. LocalEchoPutChar( char ch ) {
  149.     int rc = 0 ;
  150.  
  151.     RequestLocalEchoMutex( INFINITE ) ;
  152.     while ( (LocalEchoStart - LocalEchoEnd == 1) || 
  153.             ( LocalEchoStart == 0 && LocalEchoEnd == LOCAL_ECHO_BUFSIZE - 1 ) )
  154.         /* Buffer is full */
  155.     {
  156.         ReleaseLocalEchoMutex() ;
  157.         Sleep(250);
  158.         RequestLocalEchoMutex( INFINITE ) ;
  159.     }    
  160.  
  161.     LocalEchoBuf[LocalEchoEnd++] = ch ;
  162.     if ( LocalEchoEnd == LOCAL_ECHO_BUFSIZE )
  163.         LocalEchoEnd = 0 ;
  164.     LocalEchoData = TRUE;
  165.     PostLocalEchoAvailSem()  ;
  166.     ReleaseLocalEchoMutex() ;
  167.     return rc ;
  168. }
  169.  
  170. static int
  171. LocalEchoPutChars( char * s, int n )
  172. {
  173.     int rc = 0 ;
  174.     int i = 0;
  175.  
  176.     RequestLocalEchoMutex( INFINITE ) ;
  177.     for ( i=0 ; i<n ; i++ ) 
  178.       rc = LocalEchoPutChar( s[i] ) ;
  179.     ReleaseLocalEchoMutex() ;
  180.     return rc ;
  181. }
  182.  
  183. static int
  184. LocalEchoPutStr( char * s )
  185. {
  186.     char * p ;
  187.     int rc = 0 ;
  188.     RequestLocalEchoMutex( INFINITE ) ;
  189.     for ( p=s; *p && !rc ; p++ )
  190.       rc = LocalEchoPutChar( *p ) ;
  191.     ReleaseLocalEchoMutex() ;
  192.     return rc ;
  193. }
  194.  
  195. static int 
  196. LocalEchoGetChar( char * pch )
  197. {
  198.     int rc = 0 ;
  199.  
  200.     RequestLocalEchoMutex( INFINITE ) ;
  201.     if ( LocalEchoStart != LocalEchoEnd ) {
  202.         *pch = LocalEchoBuf[LocalEchoStart] ;
  203.         LocalEchoBuf[LocalEchoStart]=0;
  204.         LocalEchoStart++ ;
  205.  
  206.         if ( LocalEchoStart == LOCAL_ECHO_BUFSIZE )
  207.           LocalEchoStart = 0 ;
  208.  
  209.         if ( LocalEchoStart == LocalEchoEnd ) {
  210.             LocalEchoData = FALSE;
  211.             ResetLocalEchoAvailSem() ;
  212.         }
  213.         rc++ ;
  214.     }
  215.     else 
  216.     {
  217.         *pch = 0 ;
  218.     }
  219.     ReleaseLocalEchoMutex() ;
  220.     return rc ;
  221. }
  222.  
  223.  
  224.  
  225. int
  226. netopen(char * command_line, char * termtype, int height, int width,
  227.          int (* readpass)(char *,char *,int))
  228. {
  229.     char passwd[64];
  230.  
  231.     LocalEchoInit();
  232.  
  233.     readpass("Password:",passwd,64);
  234.     if ( strcmp(passwd,"echo") )
  235.         return(-3);
  236.  
  237.     LocalEchoPutChars(command_line,strlen(command_line));
  238.     LocalEchoPutChars("\r\n",2);
  239.     LocalEchoPutChars(termtype,strlen(termtype));
  240.     LocalEchoPutChars("\r\n",2);
  241.     open = 1;
  242.     return(0);
  243. }
  244.  
  245. int
  246. netclos() {
  247.     open = 0;
  248.     LocalEchoCleanup();
  249.     return(0);
  250. }
  251. int
  252. nettchk(void) {
  253.     if ( !open ) return(-1);
  254.     return LocalEchoInBuf();
  255. }
  256.  
  257. int
  258. netflui(void) {
  259.     char c;
  260.     if ( !open ) return(-1);
  261.  
  262.     while ( LocalEchoInBuf() > 0 )
  263.         LocalEchoGetChar(&c);
  264.     return(0);
  265. }
  266.     
  267. int
  268. netbreak(void) {
  269.     if ( !open ) return(-1);
  270.     return(0);
  271. }
  272.  
  273. int
  274. netinc(int timeout)  {
  275.     char c;
  276.  
  277.     if ( !open ) return(-1);
  278.  
  279.  
  280.     if ( timeout == 0 ) {
  281.         if (WaitLocalEchoAvailSem( INFINITE ))
  282.             return(-3);
  283.     }
  284.     else {
  285.         if ( timeout > 0 )
  286.             timeout *= 1000;
  287.         else
  288.             timeout *= -1;
  289.  
  290.         if ( WaitLocalEchoAvailSem(timeout) )
  291.             return(-1);
  292.  
  293.         if ( LocalEchoInBuf() > 0 ) {
  294.             LocalEchoGetChar(&c);
  295.             return(c);
  296.         }
  297.         else 
  298.             return(-3);
  299.     }
  300. }
  301.     
  302.  
  303. int
  304. netxin(int count, char * buffer) {
  305.     int i=0;
  306.     
  307.     if ( !open ) return(-1);
  308.     
  309.     while ( i < count ) {
  310.         if ( LocalEchoInBuf() > 0 )
  311.             LocalEchoGetChar(&buffer[i++]);
  312.         else 
  313.             return(-1);
  314.     }
  315.     return(i);
  316. }
  317.     
  318.  
  319. int
  320. nettoc(int c) {
  321.     if ( !open ) return(-1);
  322.  
  323.     LocalEchoPutChar(c);
  324.     return(0);
  325. }
  326.  
  327. int
  328. nettol(char * buffer, int count) {
  329.     if ( !open ) return(-1);
  330.  
  331.     LocalEchoPutChars(buffer,count);
  332.     return(count);
  333. }
  334.  
  335. void
  336. terminfo(char * terminal, int height, int width) {
  337.     LocalEchoPutStr(terminal);
  338. }
  339.  
  340. const char * 
  341. version(void) {
  342.     return("Example K95 Connection DLL");
  343. }
  344.  
  345. const char *
  346. errorstr(int error) {
  347.     switch ( error ) {
  348.     case 0:
  349.         return("success");
  350.     case -1:
  351.         return("timeout");
  352.     case -2:
  353.         return("connection closed");
  354.     case -3:
  355.         return("incorrect password.  Try 'echo'");
  356.     default:
  357.         return("unknown");
  358.     }
  359. }
  360.  
  361. int
  362. ttvt(void)
  363. {
  364.     if ( !open ) return(-1);
  365.     return(0);
  366. }
  367.  
  368. int
  369. ttpkt(void)
  370. {
  371.     if ( !open ) return(-1);
  372.     return(0);
  373. }
  374.  
  375. int
  376. ttres(void)
  377. {
  378.     if ( !open ) return(-1);
  379.     return(0);
  380. }
  381.