home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / pibterm / pibt41s2.arc / PIBHOSTC.MOD < prev   
Text File  |  1988-02-07  |  49KB  |  1,290 lines

  1. (*----------------------------------------------------------------------*)
  2. (*      Reset_The_Port --- Reset serial port to issue modem commands    *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Reset_The_Port;
  6.  
  7. BEGIN (* Reset_The_Port *)
  8.  
  9.    IF ( Baud_Rate <> 300 ) THEN
  10.       New_Baud := 300
  11.    ELSE
  12.       New_Baud := 150;
  13.  
  14.    Async_Reset_Port( Comm_Port, New_Baud, Parity, Data_Bits, Stop_Bits );
  15.  
  16.    Set_Status_Line_Name( Short_Terminal_Name );
  17.    Write_To_Status_Line( Status_Line_Name, 1 );
  18.  
  19.    Host_Status( Cur_Host_Status );
  20.  
  21. END   (* Reset_The_Port *);
  22.  
  23. (*----------------------------------------------------------------------*)
  24. (*      Jump_To_Dos --- allow privileged users to access DOS directly   *)
  25. (*----------------------------------------------------------------------*)
  26.  
  27. PROCEDURE Jump_To_Dos;
  28.  
  29. (*----------------------------------------------------------------------*)
  30. (*                                                                      *)
  31. (*     Procedure:  Jump_To_Dos                                          *)
  32. (*                                                                      *)
  33. (*     Purpose:    Allows use of DOS remotely.                          *)
  34. (*                                                                      *)
  35. (*     Calling Sequence:                                                *)
  36. (*                                                                      *)
  37. (*        Jump_To_Dos;                                                  *)
  38. (*                                                                      *)
  39. (*     Remarks:                                                         *)
  40. (*                                                                      *)
  41. (*         A batch file is constructed which executes the CTTY command. *)
  42. (*         This batch file is executed using the Dos EXEC function.     *)
  43. (*         When the remote user types EXIT, control is returned here.   *)
  44. (*         Note:  A user must have a privilege level of "S" (Special)   *)
  45. (*                to use this function.                                 *)
  46. (*                                                                      *)
  47. (*----------------------------------------------------------------------*)
  48.  
  49. VAR
  50.    Batch_File : Text_File;
  51.    Save_Close : BOOLEAN;
  52.    I          : INTEGER;
  53.    CTTY_Device: STRING[8];
  54.  
  55. BEGIN (* Jump_To_Dos *)
  56.  
  57.    Host_Status('Jump to DOS');
  58.  
  59.    Write_Log( 'Jump to DOS.' , FALSE, FALSE );
  60.  
  61.                                    (* Open batch file *)
  62.  
  63.    ASSIGN( Batch_File , 'PIBTCTTY.BAT' );
  64.       (*!I-*)
  65.    REWRITE( Batch_File );
  66.       (*!I+*)
  67.  
  68.    IF ( Int24Result <> 0 ) THEN
  69.       BEGIN
  70.          Host_Send_String_With_CR('Can''t jump to DOS.');
  71.          Host_Section := Last_Host_Sect;
  72.          EXIT;
  73.       END;
  74.                                    (* Construct MODE and CTTY statements *)
  75.  
  76.    IF ( LENGTH( Host_CTTY_Device ) > 0 ) THEN
  77.       CTTY_Device := Host_CTTY_Device
  78.    ELSE
  79.       CTTY_Device := 'COM';
  80.  
  81.    WRITELN( Batch_File , 'ECHO OFF');
  82.    WRITELN( Batch_File , 'MODE COM', Comm_Port,':',Baud_Rate,',',
  83.                          Parity,',',Data_Bits,',',Stop_Bits );
  84.    WRITELN( Batch_File , 'CTTY ', CTTY_Device, Comm_Port );
  85.    WRITELN( Batch_File , 'COMMAND' );
  86.  
  87.       (*!I-*)
  88.    CLOSE( Batch_File );
  89.       (*!I+*)
  90.  
  91.    IF ( Int24Result <> 0 ) THEN
  92.       BEGIN
  93.          Host_Send_String_With_CR('Can''t jump to DOS.');
  94.          Host_Section := Last_Host_Sect;
  95.          EXIT;
  96.       END;
  97.                                    (* Make sure async interrupts closed down *)
  98.  
  99.    Save_Close         := Close_Comm_For_Dos;
  100.    Close_Comm_For_Dos := TRUE;
  101.                                    (* Reset modem in case of line drop *)
  102.  
  103.    IF ( NOT ( Hard_Wired OR Local_Host ) ) THEN
  104.       BEGIN
  105.  
  106.          Host_Send_String_With_CR(' ');
  107.          Host_Send_String_With_CR('Resetting modem.  Ignore any garbage that appears.');
  108.          Host_Send_String_With_CR(' ');
  109.  
  110.                                    (* Wait for remote to get message *)
  111.  
  112.          Async_Drain_Output_Buffer( Five_Seconds );
  113.  
  114.                                    (* Reset comm parameters so that *)
  115.                                    (* modem commands don't go to    *)
  116.                                    (* remote.                       *)
  117.          Reset_The_Port;
  118.                                    (* Restore startup mode on modem *)
  119.  
  120.          Send_Modem_Command( Modem_Host_UnSet );
  121.  
  122.                                    (* Wait for remote to get message *)
  123.  
  124.          Async_Drain_Output_Buffer( Five_Seconds );
  125.  
  126.                                    (* Reset port *)
  127.  
  128.          Async_Reset_Port( Comm_Port, Baud_Rate, Parity, Data_Bits, Stop_Bits );
  129.  
  130.          Set_Status_Line_Name( Short_Terminal_Name );
  131.          Write_To_Status_Line( Status_Line_Name, 1 );
  132.  
  133.       END;
  134.                                    (* Send message message indicating *)
  135.                                    (* attempt to jump to DOS          *)
  136.  
  137.    Host_Send_String_With_CR(' ');
  138.    Host_Send_String_With_CR('Jumping to DOS.');
  139.    Host_Send_String_With_Cr('Type EXIT to return to PibTerm.');
  140.    Host_Send_String_With_CR(' ');
  141.                                    (* Wait for remote to get message *)
  142.  
  143.    Async_Drain_Output_Buffer( Five_Seconds );
  144.  
  145.                                    (* Execute batch file *)
  146.    DosJump( 'PIBTCTTY' );
  147.                                    (* Erase batch file *)
  148.       (*!I-*)
  149.    ERASE( Batch_File );
  150.       (*!I+*)
  151.  
  152.    I := Int24Result;
  153.                                    (* Reinitialize modem for host mode *)
  154.  
  155.    IF ( NOT ( Hard_Wired OR Local_Host ) ) THEN
  156.       BEGIN
  157.          Reset_The_Port;
  158.          Send_Modem_Command( Modem_Host_Set );
  159.          Async_Drain_Output_Buffer( Five_Seconds );
  160.          Async_Reset_Port( Comm_Port, Baud_Rate, Parity, Data_Bits, Stop_Bits );
  161.          Set_Status_Line_Name( Short_Terminal_Name );
  162.          Write_To_Status_Line( Status_Line_Name, 1 );
  163.          DELAY( Two_Second_Delay );
  164.       END;
  165.                                    (* Restore previous close_comm flag *)
  166.  
  167.    Close_Comm_For_Dos := Save_Close;
  168.  
  169.                                    (* Return to last section used *)
  170.    Host_Section := Last_Host_Sect;
  171.  
  172.    Host_Status(Cur_Host_Status);
  173.  
  174. END   (* Jump_To_Dos *);
  175.  
  176. (*----------------------------------------------------------------------*)
  177. (*         Process_Host_Commands --- Process main menu commands         *)
  178. (*----------------------------------------------------------------------*)
  179.  
  180. PROCEDURE Process_Host_Commands( VAR Done: BOOLEAN );
  181.  
  182. (*----------------------------------------------------------------------*)
  183. (*                                                                      *)
  184. (*     Procedure:  Process_Host_Commands                                *)
  185. (*                                                                      *)
  186. (*     Purpose:    Controls processing of main menu commands.           *)
  187. (*                                                                      *)
  188. (*     Calling Sequence:                                                *)
  189. (*                                                                      *)
  190. (*        Process_Host_Commands( VAR Done: BOOLEAN );                   *)
  191. (*                                                                      *)
  192. (*           Done --- set TRUE if quit command entered or carrier       *)
  193. (*                    dropped.                                          *)
  194. (*                                                                      *)
  195. (*----------------------------------------------------------------------*)
  196.  
  197. VAR
  198.    Back        : BOOLEAN;
  199.    Ch          : CHAR;
  200.    Sysop_Found : BOOLEAN;
  201.    Found_Ch    : BOOLEAN;
  202.  
  203. LABEL
  204.    ReadChar;
  205.  
  206. (*----------------------------------------------------------------------*)
  207. (*   Display_Host_Commands --- Display command list for remote user     *)
  208. (*----------------------------------------------------------------------*)
  209.  
  210. PROCEDURE Display_Host_Commands;
  211.  
  212. (*----------------------------------------------------------------------*)
  213. (*                                                                      *)
  214. (*     Procedure: Display_Host_Commands                                 *)
  215. (*                                                                      *)
  216. (*     Purpose:   Displays menu of PibTerm host commands and prompts    *)
  217. (*                for command entry.                                    *)
  218. (*                                                                      *)
  219. (*     Calling sequence:                                                *)
  220. (*                                                                      *)
  221. (*        Display_Host_Commands;                                        *)
  222. (*                                                                      *)
  223. (*----------------------------------------------------------------------*)
  224.  
  225. BEGIN (* Display_Host_Commands *)
  226.  
  227.    IF ( NOT Expert_On ) THEN
  228.       BEGIN
  229.          Host_Send_String_With_CR(' ');
  230.          Host_Send_String_With_CR('======================================================');
  231.          Host_Send_String_With_CR('=             PibTerm Host Mode Main Menu            =');
  232.          Host_Send_String_With_CR('======================================================');
  233.          Host_Send_String_With_CR(' ');
  234.          Host_Send_String_With_CR('     E=Enter message');
  235.          Host_Send_String_With_CR('     R=Read message');
  236.          Host_Send_String_With_CR('     S=Scan messages');
  237.          Host_Send_String_With_CR('     P=Personal message scan');
  238.          Host_Send_String_With_CR('     Q=Quit and logoff');
  239.          Host_Send_String_With_CR('     F=File transfers');
  240.          Host_Send_String_With_CR('     G=Gossip mode');
  241.          Host_Send_String_With_CR('     X=Expert mode');
  242.          Host_Send_String_With_CR('     C=Send comments');
  243.          Host_Send_String_With_CR('     W=Read welcome message');
  244.          IF ( Privilege = 'S' ) THEN
  245.             Host_Send_String_With_CR('     J=Jump to DOS');
  246.          Host_Send_String_With_CR(' ');
  247.          Host_Send_String_With_CR('======================================================');
  248.          Host_Send_String_And_Echo('Enter command ? ');
  249.       END
  250.    ELSE
  251.       BEGIN
  252.          Host_Send_String_With_CR(' ');
  253.          IF ( Privilege = 'S' ) THEN
  254.             Host_Send_String_And_Echo('Main (E,R,S,P,Q,F,G,X,C,W,J) ? ')
  255.          ELSE
  256.             Host_Send_String_And_Echo('Main (E,R,S,P,Q,F,G,X,C,W) ? ');
  257.       END;
  258.  
  259.    IF ( NOT Local_Host ) THEN
  260.       Async_Purge_Buffer;
  261.  
  262. END   (* Display_Host_Commands *);
  263.  
  264. (*----------------------------------------------------------------------*)
  265. (*            Page_Sysop --- Page sysop to enter gossip mode            *)
  266. (*----------------------------------------------------------------------*)
  267.  
  268. PROCEDURE Page_Sysop( VAR Sysop_Found : BOOLEAN );
  269.  
  270. (*----------------------------------------------------------------------*)
  271. (*                                                                      *)
  272. (*     Procedure:  Page_Sysop                                           *)
  273. (*                                                                      *)
  274. (*     Purpose:    Pages Sysop to enter gossip mode.                    *)
  275. (*                                                                      *)
  276. (*     Calling Sequence:                                                *)
  277. (*                                                                      *)
  278. (*        Page_Sysop( VAR Sysop_Found : BOOLEAN );                      *)
  279. (*                                                                      *)
  280. (*           Sysop_Found --- TRUE if sysop responds.                    *)
  281. (*                                                                      *)
  282. (*     Remarks:                                                         *)
  283. (*                                                                      *)
  284. (*        If silent mode is on (Alt_M) then this page is not performed. *)
  285. (*                                                                      *)
  286. (*----------------------------------------------------------------------*)
  287.  
  288. VAR
  289.    Timer: LONGINT;
  290.    I    : INTEGER;
  291.    Ch   : CHAR;
  292.  
  293. BEGIN (* Page_Sysop *)
  294.  
  295.    Write_Log('Page SYSOP.', FALSE, FALSE );
  296.  
  297.    Host_Status('Paging SYSOP');
  298.  
  299.    Host_Send_String_With_CR(' ');
  300.  
  301.    Sysop_Found := FALSE;
  302.  
  303.    IF ( NOT Silent_Mode ) THEN
  304.       BEGIN
  305.  
  306.          Host_Send_String_With_CR('Summoning Sysop (^X cancels) ...');
  307.  
  308.          Timer := 30;
  309.  
  310.          REPEAT
  311.  
  312.             FOR I := 1 TO 5 DO
  313.                WRITE( CHR( BELL ) );
  314.  
  315.             IF Async_Receive( Ch ) THEN
  316.                IF ( Ch = ^X ) THEN
  317.                   Timer := 0;
  318.  
  319.             IF PibTerm_KeyPressed THEN
  320.                BEGIN
  321.                   Read_Kbd( Ch );
  322.                   IF ( Ch = CHR( ESC ) ) AND PibTerm_KeyPressed THEN
  323.                      Read_Kbd( Ch );
  324.                   IF ( Ch <> ^X ) THEN
  325.                      Sysop_Found := TRUE
  326.                   ELSE
  327.                      Timer := 0;
  328.                END;
  329.  
  330.             DELAY( One_Second_Delay );
  331.  
  332.             DEC( Timer );
  333.  
  334.          UNTIL ( Timer <= 0 ) OR ( Sysop_Found );
  335.  
  336.       END
  337.    ELSE
  338.       Host_Send_String_With_CR('Sysop not available, gossip cancelled.');
  339.  
  340.    Host_Status(Cur_Host_Status);
  341.  
  342. END   (* Page_Sysop *);
  343.  
  344. (*----------------------------------------------------------------------*)
  345. (*           Get_A_Message  --- Get text of message from user           *)
  346. (*----------------------------------------------------------------------*)
  347.  
  348. PROCEDURE Get_A_Message( VAR F: Text_File );
  349.  
  350. (*----------------------------------------------------------------------*)
  351. (*                                                                      *)
  352. (*     Procedure:  Get_A_Message                                        *)
  353. (*                                                                      *)
  354. (*     Purpose:    Prompts for line by line message entry.              *)
  355. (*                                                                      *)
  356. (*     Calling Sequence:                                                *)
  357. (*                                                                      *)
  358. (*        Get_A_Message( VAR F: Text_File );                            *)
  359. (*                                                                      *)
  360. (*           F --- file to write message to.                            *)
  361. (*                                                                      *)
  362. (*     Remarks:                                                         *)
  363. (*                                                                      *)
  364. (*        This routine handles text entry for both regular messages and *)
  365. (*        comments.                                                     *)
  366. (*                                                                      *)
  367. (*----------------------------------------------------------------------*)
  368.  
  369. BEGIN (* Get_A_Message *)
  370.  
  371.    WITH User_List^[Cur_User] DO
  372.       WRITELN( F, '== From:    ', Fname, ' ', Lname );
  373.    WRITELN( F, '== To:      ',Recipient_Name );
  374.    WRITELN( F, '== Date:    ',DateString );
  375.    WRITELN( F, '== Time:    ',TimeString( TimeOfDay , Military_Time ) );
  376.    WRITELN( F, '== Subject: ',Message_Subject );
  377.  
  378.    Host_Send_String( CR_LF_Host );
  379.    Host_Send_String_With_CR('Enter message.   Empty line terminates.');
  380.  
  381.    REPEAT
  382.       Host_Send_String( CR_LF_Host );
  383.       Host_Prompt_And_Read_String('> ', Message_Line, TRUE );
  384.       IF LENGTH( Message_Line ) > 0 THEN
  385.          WRITELN( F, ' ', Message_Line );
  386.    UNTIL ( LENGTH( Message_Line ) = 0 );
  387.  
  388.    WRITELN( F, '== End');
  389.  
  390.    Host_Send_String( CR_LF_Host );
  391.    Host_Send_String_With_CR('Message entered.');
  392.  
  393. END   (* Get_A_Message *);
  394.  
  395. (*----------------------------------------------------------------------*)
  396. (*           Enter_Message  --- Enter a message into message base       *)
  397. (*----------------------------------------------------------------------*)
  398.  
  399. PROCEDURE Enter_Message;
  400.  
  401. (*----------------------------------------------------------------------*)
  402. (*                                                                      *)
  403. (*     Procedure:  Enter_Message                                        *)
  404. (*                                                                      *)
  405. (*     Purpose:    Enters message into message base.                    *)
  406. (*                                                                      *)
  407. (*     Calling Sequence:                                                *)
  408. (*                                                                      *)
  409. (*        Enter_Message;                                                *)
  410. (*                                                                      *)
  411. (*     Calls:                                                           *)
  412. (*                                                                      *)
  413. (*        Open_For_Append                                               *)
  414. (*        Get_A_Message                                                 *)
  415. (*                                                                      *)
  416. (*----------------------------------------------------------------------*)
  417.  
  418. VAR
  419.    Quit: BOOLEAN;
  420.    Ierr: INTEGER;
  421.  
  422. BEGIN (* Enter_Message *)
  423.  
  424.    Host_Status('Enter message');
  425.  
  426.    Quit := FALSE;
  427.                                    (* Open message file *)
  428.  
  429.    ASSIGN( Message_File, Home_Dir + 'PIBTERM.MSG' );
  430.       (*!I-*)
  431.    RESET ( Message_File );
  432.       (*!I+*)
  433.                                    (* If it exists, open for append.       *)
  434.                                    (* If it doesn't exist, open for write. *)
  435.    IF Int24Result <> 0 THEN
  436.       BEGIN
  437.          WRITELN('Creating message file PIBTERM.MSG');
  438.             (*!I-*)
  439.          REWRITE( Message_File );
  440.             (*!I+*)
  441.          IF Int24Result <> 0 THEN
  442.             BEGIN
  443.                Host_Send_String_With_CR('Sorry, no more room for messages');
  444.                Quit := TRUE;
  445.             END;
  446.       END
  447.    ELSE
  448.       BEGIN
  449.  
  450.             (*!I-*)
  451.          CLOSE( Message_File );
  452.             (*!I+*)
  453.  
  454.          Host_IO_Error := Int24Result;
  455.  
  456.          IF ( NOT Open_For_Append( Message_File , Home_Dir + 'PIBTERM.MSG' , Ierr ) ) THEN
  457.             BEGIN
  458.                Host_Send_String( CR_LF_Host );
  459.                Host_Send_String_With_CR('Sorry, no more room for messages');
  460.                Quit := TRUE;
  461.             END;
  462.  
  463.       END;
  464.  
  465.    Host_Send_String( CR_LF_Host );
  466.    Host_Prompt_And_Read_String('Enter recipient''s name or ALL: ',
  467.                                   Recipient_Name, TRUE );
  468.  
  469.    Recipient_Name := UpperCase( TRIM( Recipient_Name ) );
  470.  
  471.    IF Recipient_Name = '' THEN
  472.       Recipient_Name := 'ALL';
  473.  
  474.    Host_Send_String( CR_LF_Host );
  475.    Host_Prompt_And_Read_String('Enter title for message: ',
  476.                                Message_Subject, TRUE );
  477.  
  478.    IF ( NOT Quit ) THEN
  479.       Get_A_Message( Message_File );
  480.  
  481.       (*!I-*)
  482.    CLOSE ( Message_File );
  483.       (*!I+*)
  484.  
  485.    Host_IO_Error := Int24Result;
  486.                                    (* Increment message count *)
  487.    INC( NMessages );
  488.  
  489.    Write_Log('Enter message.', FALSE, FALSE );
  490.  
  491.    Host_Status(Cur_Host_Status);
  492.  
  493. END   (* Enter_Message *);
  494.  
  495. (*----------------------------------------------------------------------*)
  496. (*    Skip_To_Message  --- Skip to specified message in message base    *)
  497. (*----------------------------------------------------------------------*)
  498.  
  499. PROCEDURE Skip_To_Message( Msg_No : INTEGER );
  500.  
  501. (*----------------------------------------------------------------------*)
  502. (*                                                                      *)
  503. (*     Procedure:  Skip_To_Message                                      *)
  504. (*                                                                      *)
  505. (*     Purpose:    Skip to specified message in message base.           *)
  506. (*                                                                      *)
  507. (*     Calling Sequence:                                                *)
  508. (*                                                                      *)
  509. (*        Skip_To_Message( Msg_No : INTEGER );                          *)
  510. (*                                                                      *)
  511. (*           Msg_No --- Message to skip to.                             *)
  512. (*                                                                      *)
  513. (*     Remarks:                                                         *)
  514. (*                                                                      *)
  515. (*        The message file must be opened before this routine is        *)
  516. (*        called.                                                       *)
  517. (*                                                                      *)
  518. (*----------------------------------------------------------------------*)
  519.  
  520. VAR
  521.    Msg_Count : INTEGER;
  522.  
  523. BEGIN (* Skip_To_Message *)
  524.  
  525.    Msg_Count := 0;
  526.  
  527.    REPEAT
  528.  
  529.       READLN( Message_File , Message_Line );
  530.  
  531.       IF COPY( Message_Line, 1, 6 ) = '== End' THEN
  532.          INC( Msg_Count );
  533.  
  534.    UNTIL ( Msg_Count = PRED( Msg_No ) );
  535.  
  536. END   (* Skip_To_Message *);
  537.  
  538. (*----------------------------------------------------------------------*)
  539. (*             Read_Messages  --- Read messages from message base       *)
  540. (*----------------------------------------------------------------------*)
  541.  
  542. PROCEDURE Read_Messages;
  543.  
  544. (*----------------------------------------------------------------------*)
  545. (*                                                                      *)
  546. (*     Procedure:  Read_Messages                                        *)
  547. (*                                                                      *)
  548. (*     Purpose:    Reads messages currently in message base.            *)
  549. (*                                                                      *)
  550. (*     Calling Sequence:                                                *)
  551. (*                                                                      *)
  552. (*        Read_Messages;                                                *)
  553. (*                                                                      *)
  554. (*----------------------------------------------------------------------*)
  555.  
  556. VAR
  557.    Message_No   : INTEGER;
  558.    CMessage_No  : STRING[5];
  559.    I            : INTEGER;
  560.    Line_Count   : INTEGER;
  561.    Read_Done    : BOOLEAN;
  562.    Start_Msg    : INTEGER;
  563.    Start_M_Str  : AnyStr;
  564.    OK_Number    : BOOLEAN;
  565.  
  566. LABEL
  567.    Reading_Done;
  568.  
  569. BEGIN (* Read_Messages *)
  570.  
  571.    Host_Status('Read message');
  572.                                    (* Open message file *)
  573.  
  574.    ASSIGN( Message_File , Home_Dir + 'PIBTERM.MSG' );
  575.       (*!I-*)
  576.    RESET( Message_File );
  577.       (*!I+*)
  578.                                    (* Not there -- no messages *)
  579.    IF Int24Result <> 0 THEN
  580.       BEGIN
  581.          Host_Send_String( CR_LF_Host );
  582.          Host_Send_String_With_CR('No messages in message file.');
  583.          EXIT;
  584.       END;
  585.                                    (* Find where to start *)
  586.    REPEAT
  587.  
  588.       OK_Number := TRUE;
  589.  
  590.       Host_Send_String_With_CR(' ');
  591.  
  592.       STR( NMessages , Start_M_Str );
  593.  
  594.       IF ( NMessages = 1 ) THEN
  595.          Start_M_Str := 'There is 1 message in message base.'
  596.       ELSE
  597.          Start_M_Str := 'There are ' + Start_M_Str + ' messages in message base.';
  598.  
  599.       Host_Send_String_With_CR(Start_M_Str);
  600.  
  601.       Host_Prompt_And_Read_String('Enter message to start at or <CR> for all: ',
  602.                                    Start_M_Str, TRUE );
  603.       Start_Msg := 0;
  604.       FOR I := 1 TO LENGTH( Start_M_Str ) DO
  605.          IF ( Start_M_Str[I] IN ['0'..'9'] ) THEN
  606.             Start_Msg := Start_Msg * 10 + ORD( Start_M_Str[I] ) - ORD('0')
  607.          ELSE
  608.             OK_Number := FALSE;
  609.  
  610.       IF Start_Msg = 0 THEN Start_Msg := 1;
  611.       IF Start_Msg > NMessages THEN Start_Msg := NMessages;
  612.  
  613.    UNTIL ( NOT Host_Carrier_Detect ) OR ( OK_Number );
  614.  
  615.    IF ( NOT Host_Carrier_Detect ) THEN GOTO Reading_Done;
  616.  
  617.                                    (* Skip to desired message *)
  618.    Skip_To_Message( Start_Msg );
  619.  
  620.                                    (* Messages always start at one *)
  621.    Message_No := PRED( Start_Msg );
  622.    Read_Done  := FALSE;
  623.    Line_Count := 0;
  624.                                    (* Loop over messages *)
  625.    REPEAT
  626.                                    (* Increment message number *)
  627.  
  628.       INC( Message_No );
  629.  
  630.       STR( Message_No : 5 , CMessage_No );
  631.  
  632.       Host_Send_String( CR_LF_Host );
  633.       List_Prompt( Line_Count , Read_Done );
  634.       IF Read_Done THEN GOTO Reading_Done;
  635.  
  636.       Host_Send_String_With_CR('Message #' + CMessage_No);
  637.       List_Prompt( Line_Count , Read_Done );
  638.       IF Read_Done THEN GOTO Reading_Done;
  639.  
  640.                                    (* Display message # and header info *)
  641.       FOR I := 1 TO 5 DO
  642.          BEGIN
  643.             READLN( Message_File , Message_Line );
  644.             Message_Line := COPY( Message_Line, 4,
  645.                                   LENGTH( Message_Line ) - 3 );
  646.             Host_Send_String_With_CR( Message_Line );
  647.             List_Prompt( Line_Count , Read_Done );
  648.             IF Read_Done THEN GOTO Reading_Done;
  649.          END;
  650.  
  651.       Host_Send_String_With_CR(' ');
  652.       List_Prompt( Line_Count , Read_Done );
  653.       IF Read_Done THEN GOTO Reading_Done;
  654.  
  655.                                    (* Display body of message *)
  656.       REPEAT
  657.  
  658.          READLN( Message_File , Message_Line );
  659.  
  660.          IF ( COPY( Message_Line, 1, 6 ) <> '== End' ) THEN
  661.             BEGIN
  662.                Host_Send_String_With_CR( COPY( Message_Line, 2,
  663.                                                 PRED( LENGTH( Message_Line ) ) ) );
  664.                List_Prompt( Line_Count , Read_Done );
  665.             END;
  666.  
  667.       UNTIL ( COPY( Message_Line, 1, 6 ) = '== End' ) OR ( Read_Done );
  668.  
  669.    UNTIL ( Message_No >= NMessages ) OR Read_Done;
  670.  
  671. Reading_Done:
  672.  
  673.    Host_Send_String_With_CR(' ');
  674.    Host_Prompt_And_Read_String('Finished reading messages, hit <CR> to continue: ',
  675.                                Start_M_Str, TRUE );
  676.    Host_Send_String_With_CR(' ');
  677.  
  678.       (*!I-*)
  679.    CLOSE( Message_File );
  680.       (*!I+*)
  681.  
  682.    Host_IO_Error := Int24Result;
  683.  
  684.    Write_Log('Read messages.', FALSE, FALSE );
  685.  
  686.    Host_Status(Cur_Host_Status);
  687.  
  688. END   (* Read_Messages *);
  689.  
  690. (*----------------------------------------------------------------------*)
  691. (*             Scan_Messages  --- Scan messages from message base       *)
  692. (*----------------------------------------------------------------------*)
  693.  
  694. PROCEDURE Scan_Messages( Personal_Only : BOOLEAN );
  695.  
  696. (*----------------------------------------------------------------------*)
  697. (*                                                                      *)
  698. (*     Procedure:  Scan_Messages                                        *)
  699. (*                                                                      *)
  700. (*     Purpose:    Scans message headers currently in message base.     *)
  701. (*                                                                      *)
  702. (*     Calling Sequence:                                                *)
  703. (*                                                                      *)
  704. (*        Scan_Messages( Personal_Only : BOOLEAN );                     *)
  705. (*                                                                      *)
  706. (*           Personal_Only --- Return messages addressed to current     *)
  707. (*                             user only.                               *)
  708. (*                                                                      *)
  709. (*----------------------------------------------------------------------*)
  710.  
  711. VAR
  712.    Message_Title: AnyStr;
  713.    Message_No   : INTEGER;
  714.    CMessage_No  : STRING[5];
  715.    I            : INTEGER;
  716.    Line_Count   : INTEGER;
  717.    Scan_Done    : BOOLEAN;
  718.    OK_Number    : BOOLEAN;
  719.    Start_Msg    : INTEGER;
  720.    Start_M_Str  : AnyStr;
  721.    Message_L1   : AnyStr;
  722.    Message_L2   : AnyStr;
  723.    Msg_Count    : INTEGER;
  724.  
  725. LABEL
  726.    Scanning_Done;
  727.  
  728. BEGIN (* Scan_Messages *)
  729.  
  730.    Host_Status('Scan messages');
  731.                                    (* Open message file *)
  732.  
  733.    ASSIGN( Message_File , Home_Dir + 'PIBTERM.MSG' );
  734.       (*!I-*)
  735.    RESET( Message_File );
  736.       (*!I+*)
  737.                                    (* Not there -- no messages *)
  738.    IF Int24Result <> 0 THEN
  739.       BEGIN
  740.          Host_Send_String( CR_LF_Host );
  741.          Host_Send_String_With_CR('No messages in message file.');
  742.          GOTO Scanning_Done;
  743.       END;
  744.                                    (* Find where to start -- if only *)
  745.                                    (* personal messages, always scan *)
  746.                                    (* entire message base.           *)
  747.    Start_Msg := 1;
  748.  
  749.    IF ( NOT Personal_Only ) THEN
  750.       REPEAT
  751.                                    (* Request starting message number *)
  752.          OK_Number := TRUE;
  753.  
  754.          Host_Send_String_With_CR(' ');
  755.  
  756.          STR( NMessages , Start_M_Str );
  757.          IF ( NMessages = 1 ) THEN
  758.             Start_M_Str := 'There is 1 message in message base.'
  759.          ELSE
  760.             Start_M_Str := 'There are ' + Start_M_Str + ' messages in message base.';
  761.          Host_Send_String_With_CR(Start_M_Str);
  762.  
  763.          Host_Prompt_And_Read_String('Enter message to start at or <CR> for all: ',
  764.                                       Start_M_Str, TRUE );
  765.  
  766.                                    (* Convert response to message number *)
  767.          Start_Msg := 0;
  768.  
  769.          FOR I := 1 TO LENGTH( Start_M_Str ) DO
  770.             IF ( Start_M_Str[I] IN ['0'..'9'] ) THEN
  771.                Start_Msg := Start_Msg * 10 + ORD( Start_M_Str[I] ) - ORD('0')
  772.             ELSE
  773.                OK_Number := FALSE;
  774.                                    (* Ensure message is in range *)
  775.  
  776.          IF Start_Msg = 0 THEN Start_Msg := 1;
  777.          IF Start_Msg > NMessages THEN Start_Msg := NMessages;
  778.  
  779.       UNTIL ( NOT Host_Carrier_Detect ) OR ( OK_Number );
  780.  
  781.    IF ( NOT Host_Carrier_Detect ) THEN GOTO Scanning_Done;
  782.  
  783.                                    (* Skip to desired message *)
  784.    Skip_To_Message( Start_Msg );
  785.                                    (* Messages always start at one *)
  786.    Message_No := PRED( Start_Msg );
  787.    Line_Count := 0;
  788.    Scan_Done  := FALSE;
  789.    Msg_Count  := 0;
  790.                                    (* Loop over messages *)
  791.    REPEAT
  792.                                    (* Increment message number *)
  793.       INC( Message_No );
  794.  
  795.                                    (* Read 1st two lines of message *)
  796.  
  797.       READLN( Message_File , Message_L1 );
  798.       READLN( Message_File , Message_L2 );
  799.  
  800.                                    (* Check if recipient is current user *)
  801.  
  802.       IF ( COPY( Message_L2, 13, LENGTH( Message_L2 ) - 12 ) =
  803.            UpperCase( Cur_User_Name ) ) OR ( NOT Personal_Only ) THEN
  804.  
  805.          BEGIN (* Display this message *)
  806.  
  807.                                    (* Increment personal messages count *)
  808.  
  809.             INC( Msg_Count );
  810.  
  811.             STR( Message_No : 5 , CMessage_No );
  812.  
  813.             Host_Send_String( CR_LF_Host );
  814.             List_Prompt( Line_Count , Scan_Done );
  815.             IF Scan_Done THEN GOTO Scanning_Done;
  816.  
  817.                                    (* Display message number *)
  818.  
  819.             Host_Send_String_With_CR('Message #' + CMessage_No );
  820.             List_Prompt( Line_Count , Scan_Done );
  821.             IF Scan_Done THEN GOTO Scanning_Done;
  822.  
  823.                                    (* Display 1st 2 header lines *)
  824.  
  825.             Host_Send_String_With_CR( COPY( Message_L1, 4,
  826.                                        LENGTH( Message_L1 ) - 3 ) );
  827.             List_Prompt( Line_Count , Scan_Done );
  828.             IF Scan_Done THEN GOTO Scanning_Done;
  829.  
  830.             Host_Send_String_With_CR( COPY( Message_L2, 4,
  831.                                        LENGTH( Message_L2 ) - 3 ) );
  832.             List_Prompt( Line_Count , Scan_Done );
  833.             IF Scan_Done THEN GOTO Scanning_Done;
  834.  
  835.                                    (* Display remaining header info *)
  836.             FOR I := 3 TO 5 DO
  837.                BEGIN
  838.                   READLN( Message_File , Message_Line );
  839.                   Message_Line := COPY( Message_Line, 4,
  840.                                         LENGTH( Message_Line ) - 3 );
  841.                   Host_Send_String_With_CR( Message_Line );
  842.                   List_Prompt( Line_Count , Scan_Done );
  843.                   IF Scan_Done THEN GOTO Scanning_Done;
  844.                END;
  845.  
  846.             Host_Send_String_With_CR(' ');
  847.             List_Prompt( Line_Count , Scan_Done );
  848.  
  849.          END (* Display this message *);
  850.  
  851.                                    (* Scan for end of message *)
  852.       IF ( NOT Scan_Done ) THEN
  853.          REPEAT
  854.             READLN( Message_File , Message_Line );
  855.          UNTIL ( COPY( Message_Line, 1, 6 ) = '== End' );
  856.  
  857.    UNTIL ( Message_No >= NMessages ) OR ( Scan_Done );
  858.  
  859. Scanning_Done:
  860.  
  861.       (*!I-*)
  862.    CLOSE( Message_File );
  863.       (*!I+*)
  864.  
  865.    Host_IO_Error := Int24Result;
  866.  
  867.                                    (* Notify user if no personal messages *)
  868.    IF Personal_Only THEN
  869.       IF Msg_Count = 0 THEN
  870.          BEGIN
  871.             Host_Send_String_With_CR(' ');
  872.             Host_Send_String_With_CR('You have no personal messages waiting.');
  873.          END;
  874.  
  875.    Host_Send_String_With_CR(' ');
  876.    Host_Prompt_And_Read_String('Finished scanning messages, hit <CR> to continue: ',
  877.                                Start_M_Str, TRUE );
  878.    Host_Send_String_With_CR(' ');
  879.  
  880.    Write_Log('Scan messages.', FALSE, FALSE );
  881.  
  882.    Host_Status(Cur_Host_Status);
  883.  
  884. END   (* Scan_Messages *);
  885.  
  886. (*----------------------------------------------------------------------*)
  887. (*                   Enter_Comment  --- Enter a comment                 *)
  888. (*----------------------------------------------------------------------*)
  889.  
  890. PROCEDURE Enter_Comment;
  891.  
  892. (*----------------------------------------------------------------------*)
  893. (*                                                                      *)
  894. (*     Procedure:  Enter_Comment                                        *)
  895. (*                                                                      *)
  896. (*     Purpose:    Enters comment into comment file.                    *)
  897. (*                                                                      *)
  898. (*     Calling Sequence:                                                *)
  899. (*                                                                      *)
  900. (*        Enter_Comment;                                                *)
  901. (*                                                                      *)
  902. (*     Calls:                                                           *)
  903. (*                                                                      *)
  904. (*        Open_For_Append                                               *)
  905. (*        Get_A_Message                                                 *)
  906. (*                                                                      *)
  907. (*     Remarks:                                                         *)
  908. (*                                                                      *)
  909. (*        The comments file is PIBTERM.CMT.                             *)
  910. (*                                                                      *)
  911. (*----------------------------------------------------------------------*)
  912.  
  913. VAR
  914.    Quit          : BOOLEAN;
  915.    Ierr          : INTEGER;
  916.    Comments_File : Text_File;
  917.  
  918. BEGIN (* Enter_Comment *)
  919.  
  920.    Host_Status('Enter comment');
  921.  
  922.    Quit := FALSE;
  923.                                    (* Open comments file *)
  924.  
  925.    ASSIGN( Comments_File, Home_Dir + 'PIBTERM.CMT' );
  926.       (*!I-*)
  927.    RESET ( Comments_File );
  928.       (*!I+*)
  929.                                    (* If it exists, open for append.       *)
  930.                                    (* If it doesn't exist, open for write. *)
  931.    IF Int24Result <> 0 THEN
  932.       BEGIN
  933.          WRITELN('Creating comments file PIBTERM.CMT');
  934.             (*!I-*)
  935.          REWRITE( Comments_File );
  936.             (*!I+*)
  937.          IF Int24Result <> 0 THEN
  938.             BEGIN
  939.                Host_Send_String( CR_LF_Host );
  940.                Host_Send_String_With_CR('Sorry, can''t accept comments now.');
  941.                Quit := TRUE;
  942.             END;
  943.       END
  944.    ELSE
  945.       BEGIN
  946.             (*!I-*)
  947.          CLOSE( Comments_File );
  948.             (*!I+*)
  949.  
  950.          Host_IO_Error := Int24Result;
  951.  
  952.          IF ( NOT Open_For_Append( Comments_File ,
  953.                                    Home_Dir + 'PIBTERM.CMT', Ierr ) ) THEN
  954.             BEGIN
  955.                Host_Send_String( CR_LF_Host );
  956.                Host_Send_String_With_CR('Sorry, can''t accept comments now.');
  957.                Quit := TRUE;
  958.             END;
  959.  
  960.       END;
  961.  
  962.    Recipient_Name  := 'SYSOP';
  963.    Message_Subject := ' ';
  964.  
  965.    IF ( NOT Quit ) THEN
  966.       Get_A_Message( Comments_File );
  967.  
  968.       (*!I-*)
  969.    CLOSE ( Comments_File );
  970.       (*!I+*)
  971.  
  972.    Host_IO_Error := Int24Result;
  973.  
  974.    Write_Log('Enter comment to SYSOP.', FALSE, FALSE );
  975.  
  976.    Host_Status(Cur_Host_Status);
  977.  
  978. END   (* Enter_Comment *);
  979.  
  980. (*----------------------------------------------------------------------*)
  981. (*   Display_Welcome_Message --- Display welcome message after login    *)
  982. (*----------------------------------------------------------------------*)
  983.  
  984. PROCEDURE Display_Welcome_Message;
  985.  
  986. (*----------------------------------------------------------------------*)
  987. (*                                                                      *)
  988. (*     Procedure:  Display_Welcome_Message                              *)
  989. (*                                                                      *)
  990. (*     Purpose:    Displays welcome message after successful login      *)
  991. (*                                                                      *)
  992. (*     Calling Sequence:                                                *)
  993. (*                                                                      *)
  994. (*        Display_Welcome_Message;                                      *)
  995. (*                                                                      *)
  996. (*     Calls:                                                           *)
  997. (*                                                                      *)
  998. (*        Open_For_Append                                               *)
  999. (*        Get_A_Message                                                 *)
  1000. (*                                                                      *)
  1001. (*     Remarks:                                                         *)
  1002. (*                                                                      *)
  1003. (*        The welcome text is in file PIBTERM.WEL.                      *)
  1004. (*                                                                      *)
  1005. (*----------------------------------------------------------------------*)
  1006.  
  1007. VAR
  1008.    Welcome_File : Text_File;
  1009.    Welcome_Line : AnyStr;
  1010.    Line_Count   : INTEGER;
  1011.    List_Done    : BOOLEAN;
  1012.  
  1013. BEGIN (* Display_Welcome_Message *)
  1014.  
  1015.    ASSIGN( Welcome_File , Home_Dir + 'PIBTERM.WEL' );
  1016.       (*!I-*)
  1017.    RESET( Welcome_File );
  1018.       (*!I+*)
  1019.  
  1020.    IF ( INT24Result = 0 ) THEN
  1021.       BEGIN
  1022.  
  1023.          Line_Count  := 0;
  1024.          List_Done   := FALSE;
  1025.  
  1026.          REPEAT
  1027.             READLN( Welcome_File , Welcome_Line );
  1028.             Host_Send_String_With_Cr( Welcome_Line );
  1029.             List_Prompt( Line_Count , List_Done );
  1030.          UNTIL ( EOF( Welcome_File ) OR List_Done );
  1031.  
  1032.             (*!I-*)
  1033.          CLOSE( Welcome_File );
  1034.             (*!I+*)
  1035.  
  1036.          Host_IO_Error := Int24Result;
  1037.  
  1038.          End_Prompt('End of welcome, hit <CR> to continue: ');
  1039.  
  1040.       END;
  1041.  
  1042. END   (* Display_Welcome_Message *);
  1043.  
  1044. (*----------------------------------------------------------------------*)
  1045.  
  1046. BEGIN (* Process_Host_Commands *)
  1047.  
  1048.                                    (* Scan for personal mail on *)
  1049.                                    (* first entry here.         *)
  1050.    IF Host_Section = 'I' THEN
  1051.       BEGIN
  1052.  
  1053.          Display_Welcome_Message;
  1054.          Host_Send_String_With_CR(' ');
  1055.  
  1056.          Host_Send_String_With_CR(' ');
  1057.          Host_Send_String_With_CR('Scanning for personal messages ... ');
  1058.  
  1059.          Scan_Messages( TRUE );
  1060.  
  1061.          Host_Section := 'M';
  1062.  
  1063.       END;
  1064.  
  1065.    Cur_Host_Status := 'Message section';
  1066.    Host_Status( Cur_Host_Status );
  1067.  
  1068.                                    (* Prompt for commands *)
  1069.    Display_Host_Commands;
  1070.                                    (* Assume input from remote *)
  1071.  
  1072. ReadChar:
  1073.  
  1074.    Kbd_Input := FALSE;
  1075.                                    (* Wait for command to be entered *)
  1076.    REPEAT
  1077.       Done     := Done OR ( NOT Host_Carrier_Detect );
  1078.       Found_Ch := Async_Receive( Ch ) OR PibTerm_KeyPressed;
  1079.       IF ( NOT Found_Ch ) THEN
  1080.          GiveAwayTime( 2 );
  1081.    UNTIL Done OR Found_Ch;
  1082.  
  1083.                                    (* Process input from keyboard *)
  1084.    IF PibTerm_KeyPressed THEN
  1085.       BEGIN
  1086.          Read_Kbd( Ch );
  1087.          Kbd_Input := TRUE;
  1088.          IF ( ORD( Ch ) = ESC ) AND PibTerm_KeyPressed THEN
  1089.             BEGIN
  1090.                Read_Kbd( Ch );
  1091.                CASE ORD( Ch ) OF
  1092.                   F1 : Ch := 'G';
  1093.                   F2 : Ch := 'Q';
  1094.                   F3 : BEGIN
  1095.                           DosJump('');
  1096.                           Ch := ' ';
  1097.                        END;
  1098.                   F5 : BEGIN
  1099.                           WRITELN;
  1100.                           WRITELN('Current caller is ',Cur_User_Name);
  1101.                           Ch := ' ';
  1102.                        END;
  1103.                END (* CASE *);
  1104.             END;
  1105.       END;
  1106.  
  1107.    IF ( Ch = ' ' ) THEN GOTO ReadChar;
  1108.  
  1109.    IF ( Not DONE ) THEN
  1110.                                    (* Echo command *)
  1111.  
  1112.       Host_Send_String( Ch + CR_LF_Host );
  1113.       WRITELN;
  1114.       IF Printer_On THEN
  1115.          Write_Prt_Str( Ch + CRLF_String );
  1116.       IF Capture_On THEN
  1117.          WRITELN( Capture_File, Ch );
  1118.  
  1119.                                    (* Process command request *)
  1120.       CASE UpCase( Ch ) OF
  1121.  
  1122.          'E':  Enter_Message;
  1123.          'R':  Read_Messages;
  1124.          'Q':  BEGIN
  1125.                   IF Kbd_Input THEN
  1126.                      BEGIN
  1127.                         Host_Send_String_With_CR('System operator shutting ' +
  1128.                                                   'down system.');
  1129.                         Host_Send_String_With_CR('Thanks for calling.');
  1130.                         Done := TRUE;
  1131.                      END
  1132.                   ELSE
  1133.                      BEGIN
  1134.                         Host_Send_String_With_CR('Quit and logoff');
  1135.                         Done := TRUE;
  1136.                      END;
  1137.                END;
  1138.          'F':  Host_Section := 'F';
  1139.          'G':  BEGIN
  1140.                   IF Kbd_Input THEN
  1141.                      BEGIN
  1142.                         Host_Send_String_With_CR(' ... System operator wishes' +
  1143.                                                   ' to chat, please wait ...');
  1144.                         Host_Send_String_With_CR(' ');
  1145.                         Host_Section   := 'G';
  1146.                         Last_Host_Sect := 'M';
  1147.                      END
  1148.                   ELSE
  1149.                      BEGIN
  1150.                         Page_Sysop( Sysop_Found );
  1151.                         IF Sysop_Found THEN
  1152.                            BEGIN
  1153.                               Host_Section   := 'G';
  1154.                               Last_Host_Sect := 'M';
  1155.                            END;
  1156.                      END;
  1157.                END;
  1158.          'C':  Enter_Comment;
  1159.          'P':  Scan_Messages( TRUE );
  1160.          'X':  Expert_On := NOT Expert_On;
  1161.          'S':  Scan_Messages( FALSE );
  1162.          'J':  IF ( Privilege = 'S' ) THEN
  1163.                   BEGIN
  1164.                      Host_Section   := 'D';
  1165.                      Last_Host_Sect := 'M';
  1166.                   END
  1167.                ELSE
  1168.                   Host_Send_String( ^G );
  1169.  
  1170.          'W':  Display_Welcome_Message;
  1171.  
  1172.          ELSE  Host_Send_String( ^G );
  1173.  
  1174.       END (* CASE *)
  1175.  
  1176. END   (* Process_Host_Commands *);
  1177.  
  1178. (*----------------------------------------------------------------------*)
  1179. (*           Get_UserInfo --- Read in user name and password            *)
  1180. (*----------------------------------------------------------------------*)
  1181.  
  1182. PROCEDURE Get_UserInfo( VAR Found: BOOLEAN );
  1183.  
  1184. (*----------------------------------------------------------------------*)
  1185. (*                                                                      *)
  1186. (*     Procedure:  Get_UserInfo                                         *)
  1187. (*                                                                      *)
  1188. (*     Purpose:    Gets user name and password from remote user.        *)
  1189. (*                                                                      *)
  1190. (*     Calling Sequence:                                                *)
  1191. (*                                                                      *)
  1192. (*        Get_UserInfo( VAR Found: BOOLEAN );                           *)
  1193. (*                                                                      *)
  1194. (*           Done --- set TRUE if user name found and carrier not       *)
  1195. (*                    dropped.                                          *)
  1196. (*                                                                      *)
  1197. (*----------------------------------------------------------------------*)
  1198.  
  1199. VAR
  1200.    MyPass   : AnyStr;
  1201.    CallLine : AnyStr;
  1202.    Ierr     : INTEGER;
  1203.  
  1204. BEGIN (* Get_UserInfo *)
  1205.  
  1206.    Host_Status('Get user info');
  1207.  
  1208.                                    (* Prompt for first name *)
  1209.  
  1210.    Host_Send_String_With_CR(' ');
  1211.    Host_Prompt_And_Read_String('Enter first name: ', Fname, TRUE );
  1212.    Fname := TRIM( UpperCase( Fname ) );
  1213.  
  1214.                                    (* Prompt for second name *)
  1215.  
  1216.    Host_Send_String_With_CR(' ');
  1217.    Host_Prompt_And_Read_String('Enter last name:  ', Lname, TRUE );
  1218.    Lname := TRIM( UpperCase( Lname ) );
  1219.  
  1220.                                    (* See if valid user name *)
  1221.    Cur_User      := 0;
  1222.    Found         := FALSE;
  1223.    Privilege     := 'N';
  1224.    Cur_User_Name := '';
  1225.  
  1226.    IF ( LENGTH( Fname ) > 0 ) AND ( LENGTH( Lname ) > 0 ) THEN
  1227.       REPEAT
  1228.          INC( Cur_User );
  1229.          WITH User_List^[Cur_User] DO
  1230.             Found := ( Fname = First_Name ) AND ( Lname = Last_Name );
  1231.       UNTIL ( Found OR ( Cur_User >= NUsers ) );
  1232.  
  1233.                                    (* Remember name for message scans *)
  1234.  
  1235.    Cur_User_Name := Fname + ' ' + Lname;
  1236.  
  1237.                                    (* Error if name not in user file *)
  1238.    IF ( NOT Found ) THEN
  1239.       BEGIN
  1240.          Host_Send_String_With_CR(' ');
  1241.          Host_Send_String_With_CR('Not a valid user name.');
  1242.       END;
  1243.                                    (* Prompt for password *)
  1244.  
  1245.    IF ( Found AND Host_Carrier_Detect ) THEN
  1246.       BEGIN
  1247.  
  1248.          Host_Send_String_With_CR(' ');
  1249.          Host_Prompt_And_Read_String('Enter Password:   ', MyPass, FALSE );
  1250.          Host_Send_String_With_CR(' ');
  1251.  
  1252.                                    (* Check if password valid *)
  1253.  
  1254.          IF MyPass = User_List^[Cur_User].PassWord THEN
  1255.             BEGIN
  1256.  
  1257.                Host_Send_String_With_CR('Password OK');
  1258.  
  1259.                Found := TRUE;
  1260.  
  1261.                Write_Log( Fname + ' ' + Lname + ' logged in.', FALSE, FALSE );
  1262.  
  1263.                                    (* Pick up privilege of user *)
  1264.  
  1265.                Privilege := User_List^[Cur_User].Privilege[1];
  1266.  
  1267.             END
  1268.          ELSE
  1269.             BEGIN
  1270.  
  1271.                Host_Send_String_With_CR('Password wrong');
  1272.  
  1273.                Found := FALSE;
  1274.  
  1275.                Write_Log( Fname + ' ' + Lname +
  1276.                           ' logon try with bad password = ' + MyPass,
  1277.                           FALSE, FALSE );
  1278.  
  1279.             END;
  1280.  
  1281.    END;
  1282.                                    (* Update status line *)
  1283.    IF Found THEN
  1284.       BEGIN
  1285.          Cur_Host_Status := Cur_User_Name;
  1286.          Host_Status( Cur_Host_Status );
  1287.       END;
  1288.  
  1289. END   (* Get_UserInfo *);
  1290.