home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / perqb / pq2con.pas < prev    next >
Pascal/Delphi Source File  |  2020-01-01  |  12KB  |  417 lines

  1. module KermitConnect;
  2.  
  3. {   Module for simulating a terminal.
  4. {
  5. {       The correct communications parameters must have
  6. {   been set up before this routine is used.
  7. {                                                       }
  8.  
  9. {===========================} exports {====================================}
  10.  
  11. imports FileDefs from FileDefs;
  12.  
  13. procedure   Terminal( EscChar : Char );
  14. procedure   SetSaveFile( NewSaveFile : PathName );
  15.  
  16. {===========================} private {====================================}
  17.  
  18. imports MenuUtils from MenuUtils;
  19. imports system from system;
  20. imports FileSystem from FileSystem;  
  21. imports IO_Unit from IO_Unit;
  22. imports IOErrors from IOErrors;
  23. imports IOUtils from IOUtils;
  24.  
  25. {   own modules:   }
  26. imports KermitScreen from KermitScreen;
  27. imports KermitLineIO from KermitLineIO;
  28. imports KermitParameters from KermitParameters;
  29.  
  30. {----------------------------------------------------------------------------}
  31.  
  32. const   BBuffSize   =   512;    { number of bytes in FS-block }
  33.  
  34. {----------------------------------------------------------------------------}
  35.  
  36. var     
  37.         BuffPtr     :   PDirBlk;
  38.         BufferIndex :   -1..BBuffSize;
  39.         BlockNumber :   FirstBlk..LastBlk;
  40.         Id          :   FileID;
  41.         GetC,SendC  :   char; 
  42.         LineIndex   :   integer;
  43.         TermMenu, SpeedMenu, ParityMenu, StopMenu : pNameDesc;
  44.  
  45. {----------------------------------------------------------------------------}
  46. {
  47. procedure   FlushBuffer;
  48. var     i : integer;
  49. begin
  50.     for i:=MinBuffIndex to BufferIndex do
  51.         write(SaveFile,Buffer[i]);
  52.     BufferIndex:=MinBuffIndex - 1;
  53. end;    
  54. }
  55.  
  56. {----------------------------------------------------------------------------}
  57.  
  58. procedure   SaveInBuffer(ch:char);
  59. begin
  60.     if BufferIndex = BBuffSize - 1 then
  61.     begin
  62.         FSBlkWrite(Id,BlockNumber,BuffPtr);
  63.         BlockNumber := BlockNumber + 1;
  64.         BufferIndex:=-1;
  65.     {   if XonXoff then RSPutChar(XOn);  }
  66.     end;
  67.     BufferIndex:=BufferIndex+1;
  68.     BuffPtr^.ByteBuffer[BufferIndex]:=ord(ch);
  69. end;
  70.  
  71.  
  72. {----------------------------------------------------------------------------}
  73.  
  74. procedure OpenSave;
  75. begin
  76.     Id := FSEnter( SaveFile );
  77.     if Id = 0 then begin
  78.         PutMessage('*** Illegal Log File name ***');
  79.         SaveFile := '';
  80.     end
  81.     else
  82.     begin
  83.         BlockNumber := FirstBlk;
  84.         BufferIndex:= - 1;
  85.     end;
  86.     SwitchWindow( MainWindow );
  87. end; { OpenSave }
  88.  
  89.  
  90. {----------------------------------------------------------------------------}
  91.  
  92. procedure CloseSave;
  93. begin
  94.     if BufferIndex >= 0 then
  95.     begin
  96.          { The last block is partially full }
  97.        FSBlkWrite(Id,BlockNumber,BuffPtr);
  98.        FSClose(Id,BlockNumber,(BufferIndex+1)*8);  
  99.          { last parameter is number of bits in last block }
  100.     end else 
  101.          { The last block is FULL }
  102.         FSClose(Id,BlockNumber-1,BBuffSize*8);
  103. end; { CloseSave }
  104.  
  105.  
  106. {----------------------------------------------------------------------------}
  107.  
  108. procedure SetSaveFile( NewSaveFile : PathName );
  109. begin
  110.     if SaveFile<>'' then 
  111.         CloseSave;
  112.     SaveFile := NewSaveFile;
  113.     if SaveFile<>'' then
  114.         OpenSave;
  115. end;
  116.  
  117.  
  118. {----------------------------------------------------------------------------}
  119.  
  120. procedure ChangeSaveFile;
  121. var NewSaveFile : PathName;
  122.     CurrWin : WinType;
  123. begin
  124.     CurrentWindow( CurrWin );
  125.     SwitchWindow( MessageWindow );
  126.     write( 'Enter name of new log file : ' );
  127.     readln( NewSaveFile );
  128.     SetSaveFile( NewSaveFile );
  129.     SwitchWindow( CurrWin );
  130. end;
  131.  
  132.  
  133. {----------------------------------------------------------------------------}
  134.  
  135. procedure   TreatIncoming(ch:char);
  136. begin
  137.     case ch of
  138.         BS  :   if LineIndex >= 1 then
  139.                     BackSpace(' ') 
  140.                 else
  141.                     write('');
  142.         CR  :   begin
  143.                     LineIndex := 0;
  144.                     if FileSave and not (SaveFile='') then
  145.                         SaveInBuffer(ch);
  146.                     PutChr(chr( LAnd( ord(ch), 127 )));
  147.                 end;
  148.         NULL :  ;
  149.         otherwise :
  150.                 begin
  151.                     LineIndex := LineIndex + 1;
  152.                     if FileSave and not (SaveFile='') then
  153.                         SaveInBuffer(ch);
  154.                     PutChr(chr( LAnd( ord(ch), 127 )));
  155.                 end;
  156.     end;
  157. end;
  158.     
  159.  
  160. {----------------------------------------------------------------------------}
  161.  
  162. function    Xlat(ch:char): char;
  163. var
  164.         Res : char;
  165. begin
  166.     if ( LAnd(ord(ch),#200) <> 0 ) then  { control-character }
  167.         Res := chr(LAnd(ord(ch),#37))
  168.     else
  169.         Res := ch;
  170.     
  171.     Xlat := Res;
  172. end;
  173.  
  174.  
  175. {----------------------------------------------------------------------------}
  176.  
  177. procedure EscHelp;
  178. begin
  179.     SwitchWindow( MainWindow );
  180.     writeln;
  181.     writeln(' ? - This message' );
  182.     writeln(' C - Close connection, return to Perq' );
  183.     writeln(' B - Send break' );
  184.     writeln(' 0 - Send a NUL' );
  185.     writeln(' Q - Quit (turn off) logging to a file' );
  186.     writeln(' R - Resume (turn on) logging to a file' );
  187.     writeln; 
  188.     writeln('Typing the escape character will send it to the remote computer');
  189.     write  ('Command>');
  190. end;
  191.     
  192. {----------------------------------------------------------------------------}
  193.  
  194. function    MakeUpper(ch:char): char;
  195. var
  196.         Res : char;
  197. begin
  198.     Res := Ch;
  199.     if ( LAnd(ord(ch),#200) <> 0 ) then  { control-character }
  200.         Res := chr(LAnd(ord(ch),#177));
  201.     if ch in ['a'..'z'] then
  202.         Res := chr( ord(ch) - (ord('a') - ord('A')) );
  203.     
  204.     MakeUpper := Res;
  205. end;
  206.  
  207.  
  208. {----------------------------------------------------------------------------}
  209.  
  210. procedure   DoSetBaud;
  211.  
  212.     function    GetBaud:SpeedType;
  213.     begin  { GetBaud }
  214.         GetBaud := recast(GetMenuAnswer(SpeedMenu,200),SpeedType);
  215.     end; { GetBaud }
  216.  
  217. begin               
  218.     Baud := GetBaud;
  219.     RefreshBaud;
  220. end;
  221.     
  222.  
  223. {----------------------------------------------------------------------------}
  224.  
  225. procedure   DoSetParity;
  226.     
  227.     function GetKerParity:ParityType;
  228.     begin
  229.         GetKerParity := recast(GetMenuAnswer(ParityMenu,150),ParityType);
  230.     end;
  231.  
  232. begin
  233.     Parity := GetKerParity;
  234.     RefreshParity;
  235. end;
  236.  
  237.  
  238. {----------------------------------------------------------------------------}
  239.  
  240. procedure   DoSetStop;
  241.     
  242.     function GetStop:StopType;
  243.     begin
  244.         GetStop := recast(GetMenuAnswer(StopMenu,150),StopType);
  245.     end;
  246.  
  247. begin
  248.     StopBits := GetStop;
  249.     RefreshStopBits;
  250. end;
  251.  
  252.  
  253. {----------------------------------------------------------------------------}
  254.  
  255. procedure   InitTMenu;
  256. var SetMenu : pMenuEntry;
  257. begin
  258.     AllocNameDesc( NTermComm, 0, TermMenu );
  259.     {$range-}
  260.     with TermMenu^ do begin
  261.         Header := 'Terminal commands';
  262.         Commands[ord(TermHelp)      ] := '?';
  263.         Commands[ord(TermQuit)      ] := 'QUIT terminal mode';
  264.         Commands[ord(TermSetBaud)   ] := 'set BAUD';
  265.         Commands[ord(TermSetStop)   ] := 'set STOP-BITS';
  266.         Commands[ord(TermSetParity) ] := 'set PARITY';
  267.         Commands[ord(TermSaveFile)  ] := 'set LOG-FILE';
  268.         Commands[ord(TermOnSave)    ] := 'set LOG ON';
  269.         Commands[ord(TermOffSave)   ] := 'set LOG OFF';
  270.         Commands[ord(TermOnXonXoff) ] := 'set XON-XOFF ON';
  271.         Commands[ord(TermOffXonXoff)] := 'set XON-XOFF OFF';
  272.     end;
  273.     SetMenu := RootMenu^.NextLevel[ ord( MainSet ) ];
  274.     with SetMenu^ do begin
  275.         SpeedMenu  := NextLevel[ ord( SetBaud ) ]^.MPtr;
  276.         ParityMenu := NextLevel[ ord( SetParity ) ]^.MPtr;
  277.         StopMenu   := NextLevel[ ord( SetStop ) ]^.MPtr;
  278.     end;
  279.     {$range=}
  280. end;
  281.  
  282.  
  283. {----------------------------------------------------------------------------}
  284.  
  285. procedure GiveHelp;
  286. begin
  287.     SwitchWindow( MainWindow );
  288.     writeln;
  289.     writeln(' Terminal commands: ');
  290.     writeln;
  291.     writeln('QUIT           - return to Kermit-Perq main command level');
  292.     writeln('SET BAUD/STOP/PARITY - set line parameters');
  293.     writeln('SET LOG-FILE   - enter name of file to log terminal session to');
  294.     writeln('SET LOG ON/OFF - turn log output on/off');
  295.     writeln('SET XON-XOFF ON/OFF  - use/respect XON/XOFF handshake');
  296.     writeln;
  297.     SwitchWindow( TermWindow );
  298. end;
  299.  
  300.  
  301. {----------------------------------------------------------------------------}
  302.  
  303. procedure   Terminal( EscChar : char );
  304.  
  305. var GetC, SendC         :   char;   
  306.     done, HelpPrompt    :   boolean;
  307.     TComm               :   TermCommType;
  308.     
  309.     function    GetTermComm : TermCommType;
  310.     begin
  311.         GetTermComm:=recast(GetMenuAnswer(TermMenu,150),TermCommType);
  312.     end;
  313.  
  314.     procedure DoTermComm( TComm : TermCommType );
  315.     begin
  316.         case TComm of
  317.             TermHelp        :   GiveHelp;
  318.             TermSetBaud     :   DoSetBaud;
  319.             TermSetParity   :   DoSetParity;
  320.             TermSetStop     :   DoSetStop;
  321.             TermQuit        :   ;
  322.             TermOnSave      :   FileSave := true;
  323.             TermOffSave     :   FileSave := false;
  324.             TermSaveFile    :   ChangeSaveFile;
  325.             TermOnXonXoff   :   XonXoff := true;
  326.             TermOffXonXoff  :   XonXoff := false;
  327.         end;
  328.     end;
  329.     
  330.     handler IOWrErr( IOStatus : integer );
  331.     begin
  332.        PutMessage('Write error on line (possibly unplugged RS232 connector)');
  333.     end;
  334.  
  335.     handler IORdErr( IOStatus : integer );
  336.     begin
  337.        PutMessage('Read error on line (possibly wrong speed or parity)');
  338.     end;
  339.  
  340.     handler CtlC;
  341.     begin
  342.         ctrlcpending := false;
  343.     end;
  344.  
  345.  
  346. begin                       
  347.     XonXoff := true;    { enable handshake }
  348.     BlockNumber := FirstBlk;
  349.     new(BuffPtr);      {   Set up pointer to buffer    }
  350.     InitTermScreen;
  351.     InitTMenu;
  352.     LineIndex := 0;
  353.     done:=false;
  354.     repeat
  355.  
  356.         if GetChar( Idev, GetC ) then
  357.         { IO Complete on RS232-line }
  358.             TreatIncoming(GetC);
  359.  
  360.         if IOCRead(KeyBoard,SendC) = IOEIOC then
  361.         { IO Complete on keyboard }
  362.         begin
  363.             if SendC <> EscChar then begin
  364.                     { Must handle conversion to ctrl-chars myself.
  365.                         ^DEL = BREAK
  366.                     }
  367.                 SendC:=Xlat(SendC);
  368.  
  369.                     { Send character on RS232-line }
  370.                 if SendC <> BreakKey then  { not a break? }
  371.                     Outbt( Odev, SendC)
  372.                 else
  373.                     SendBreak( 500 { milliseconds });
  374.             end else begin
  375.                 HelpPrompt := false; 
  376.                 repeat
  377.                     while IOCRead( KeyBoard, SendC ) <> IOEIOC do ;
  378.                     if HelpPrompt then begin
  379.                         writeln;
  380.                         ChangeWindow( TermWindow );
  381.                     end;
  382.                     if SendC=EscChar then begin
  383.                         SendC := Xlat( SendC );
  384.                         Outbt( Odev, SendC );
  385.                     end else
  386.                     begin
  387.                         SendC := MakeUpper( SendC );
  388.                         case SendC of
  389.                             '0':    OutBt( Odev, chr(0) );
  390.                             'B':    SendBreak( 500 );
  391.                             'C':    TComm := TermQuit;
  392.                             'Q':    FileSave := FALSE;
  393.                             'R':    FileSave := TRUE;
  394.                             '?':    begin
  395.                                         EscHelp;
  396.                                         HelpPrompt := true;
  397.                                     end;
  398.                             otherwise: write(Chr(7));
  399.                         end;
  400.                     end;
  401.                 until SendC<>'?';
  402.             end;
  403.         end;
  404.  
  405.         if TabSwitch then
  406.         begin
  407.             TComm:= GetTermComm;
  408.             DoTermComm( TComm );
  409.         end;
  410.  
  411.     until TComm = TermQuit;
  412.     CleanupTermScreen;
  413.     DestroyNameDescr( TermMenu);
  414. end.
  415.  
  416.