home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / pibterm / pibt41s4.arc / RECEIVK1.MOD < prev    next >
Text File  |  1988-02-26  |  29KB  |  688 lines

  1. (*----------------------------------------------------------------------*)
  2. (*          Receive_Kermit_File --- Download file using Kermit          *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Receive_Kermit_File;
  6.  
  7. (*----------------------------------------------------------------------*)
  8. (*                                                                      *)
  9. (*     Procedure:  Receive_Kermit_File                                  *)
  10. (*                                                                      *)
  11. (*     Purpose:    Downloads file to PC using Kermit protocol           *)
  12. (*                                                                      *)
  13. (*     Calling Sequence:                                                *)
  14. (*                                                                      *)
  15. (*        Receive_Kermit_File;                                          *)
  16. (*                                                                      *)
  17. (*----------------------------------------------------------------------*)
  18.  
  19. CONST
  20.    Receive_Quit_Item = 9;
  21.  
  22. VAR
  23.    Buffer_Pos     : INTEGER;
  24.    Buffer_Size    : INTEGER;
  25.    Write_Count    : INTEGER;
  26.    Err            : INTEGER;
  27.    Local_Save     : Saved_Screen_Ptr;
  28.    Local_Save_2   : Saved_Screen_Ptr;
  29.    Kermit_Menu    : Menu_Type;
  30.    I              : INTEGER;
  31.    J              : INTEGER;
  32.    Kermit_Done    : BOOLEAN;
  33.    Menu_Choice    : INTEGER;
  34.    Host_Count     : INTEGER;
  35.    Long_Buffer    : BOOLEAN;
  36.    Buffer_Length  : INTEGER;
  37.    Write_Buffer   : File_Handle_Buffer_Ptr;
  38.    Receiving_File : BOOLEAN;
  39.    Cur_Drive      : CHAR;
  40.    Cur_Path       : AnyStr;
  41.    Buffer_Total   : LONGINT;
  42.    Abort_Done     : BOOLEAN;
  43.    Toss_File      : BOOLEAN;
  44.    Full_Name      : AnyStr;
  45.    Do_A_Receive   : BOOLEAN;
  46.    Remote_Comm    : AnyStr;
  47.    Buffer_Num_Actual : LONGINT;
  48.    Total_Time        : LONGINT;
  49.  
  50. (*----------------------------------------------------------------------*)
  51. (*    Kermit_Construct_Message --- Construct message packet             *)
  52. (*----------------------------------------------------------------------*)
  53.  
  54. PROCEDURE Kermit_Construct_Message( S: AnyStr );
  55.  
  56. (*----------------------------------------------------------------------*)
  57. (*                                                                      *)
  58. (*     Procedure:  Kermit_Construct_Message                             *)
  59. (*                                                                      *)
  60. (*     Purpose:    Constructs message packet                            *)
  61. (*                                                                      *)
  62. (*     Calling Sequence:                                                *)
  63. (*                                                                      *)
  64. (*        Kermit_Construct_Message( S: AnyStr );                        *)
  65. (*                                                                      *)
  66. (*           S --- Message to be constructed                            *)
  67. (*                                                                      *)
  68. (*----------------------------------------------------------------------*)
  69.  
  70. VAR
  71.    LS : INTEGER;
  72.  
  73. BEGIN (* Kermit_Construct_Message *)
  74.  
  75.    LS := LENGTH( S );
  76.  
  77.    MOVE( S[1], Send_Packet_Ptr^[4], LS );
  78.  
  79.    Send_Packet_Length := LS + 3;
  80.  
  81.    Build_Packet;
  82.    Send_Packet;
  83.  
  84. END   (* Kermit_Construct_Message *);
  85.  
  86. (*----------------------------------------------------------------------*)
  87. (*  Expand_Packet_To_String --- Expand data in Kermit packet to string  *)
  88. (*----------------------------------------------------------------------*)
  89.  
  90. FUNCTION Expand_Packet_To_String( Rec_Packet_Ptr    : Kermit_Packet_Ptr;
  91.                                   Rec_Packet_Length : INTEGER ) : AnyStr;
  92.  
  93. (*----------------------------------------------------------------------*)
  94. (*                                                                      *)
  95. (*     Function:   Expand_Packet_To_String                              *)
  96. (*                                                                      *)
  97. (*     Purpose:    Expands data in Kermit packet to a string            *)
  98. (*                                                                      *)
  99. (*     Calling Sequence:                                                *)
  100. (*                                                                      *)
  101. (*        Rec_Str := Expand_Packet_To_String(     Rec_Packet_Ptr    :   *)
  102. (*                                              Kermit_Packet_Ptr;      *)
  103. (*                                           Rec_Packet_Length :        *)
  104. (*                                              INTEGER;                *)
  105. (*                                          ) : AnyStr;                 *)
  106. (*                                                                      *)
  107. (*           Rec_Packet_Ptr    --- points to unexpanded packet data     *)
  108. (*           Rec_Packet_Length --- length of unexpanded data            *)
  109. (*           Rec_Str           --- resultant expanded data as string    *)
  110. (*                                                                      *)
  111. (*----------------------------------------------------------------------*)
  112.  
  113. VAR
  114.    InPos             : INTEGER;
  115.    OutPos            : INTEGER;
  116.    Q8Bit             : BOOLEAN;
  117.    Temp              : CHAR;
  118.    B_Temp            : BYTE ABSOLUTE Temp;
  119.    Temp2             : CHAR;
  120.    Repeat_Count      : INTEGER;
  121.    I                 : INTEGER;
  122.    Rec_Packet_String : AnyStr;
  123.  
  124. BEGIN (* Expand_Packet_To_String *)
  125.  
  126.                                    (* Initialize *)
  127.    InPos                   := 1;
  128.    OutPos                  := 0;
  129.  
  130.    WHILE ( ( InPos <= Rec_Packet_Length ) AND ( OutPos < 256 ) ) DO
  131.       BEGIN
  132.                                    (* Repeat count 1 by default    *)
  133.          Repeat_Count := 1;
  134.                                    (* Get next character in packet *)
  135.  
  136.          Temp   := Rec_Packet_Ptr^[ InPos ];
  137.  
  138.                                    (* Check for repeat data character *)
  139.          IF Repeating THEN
  140.             IF ( Temp = His_Repeat_Char ) THEN
  141.                BEGIN
  142.                   InPos        := SUCC( InPos );
  143.                   Repeat_Count := ORD( Rec_Packet_Ptr^[ InPos ] ) - 32;
  144.                   InPos        := SUCC( InPos );
  145.                   Temp         := Rec_Packet_Ptr^[ InPos ];
  146.                END;
  147.                                    (* Check for 8-bit quote character *)
  148.  
  149.          IF ( Temp = His_Quote_8_Char ) AND Quoting THEN
  150.             BEGIN
  151.                Q8Bit := TRUE;
  152.                InPos := SUCC( InPos );
  153.                Temp  := Rec_Packet_Ptr^[ InPos ];
  154.             END
  155.          ELSE
  156.             Q8Bit := FALSE;
  157.                                    (* Check for control quote character *)
  158.  
  159.          IF ( Temp = His_Quote_Char ) THEN
  160.             BEGIN
  161.  
  162.                InPos := SUCC( InPos );
  163.                Temp  := Rec_Packet_Ptr^[ InPos ];
  164.  
  165.                                    (* Convert to control character EXCEPT  *)
  166.                                    (* for quoting characters.              *)
  167.  
  168.                Temp2 := CHR( B_Temp AND $7F );
  169.  
  170.                IF ( Temp2 <> His_Quote_Char )                             AND
  171.                   ( NOT ( Repeating AND ( Temp2 = His_Repeat_Char   ) ) ) AND
  172.                   ( NOT ( Quoting   AND ( Temp2 = His_Quote_8_Char  ) ) ) THEN
  173.                      B_Temp := B_Temp XOR 64;
  174.  
  175.             END;
  176.                                    (* Turn on 8th bit if required *)
  177.          IF Q8Bit THEN
  178.             B_Temp := B_Temp OR $80;
  179.  
  180.                                    (* Append character to output string. *)
  181.                                    (* If repeat count, add it in given   *)
  182.                                    (* number of times.                   *)
  183.  
  184.          FOR I := 1 TO Repeat_Count DO
  185.             BEGIN
  186.                OutPos := SUCC( OutPos );
  187.                IF ( OutPos < 256 ) THEN
  188.                   Rec_Packet_String[ OutPos ] := Temp;
  189.             END;
  190.                                    (* Point to next input character  *)
  191.          InPos := SUCC( InPos );
  192.  
  193.       END (* WHILE *);
  194.  
  195.    Rec_Packet_String[0]    := CHR( MIN( OutPos , 255 ) );
  196.    Expand_Packet_To_String := Rec_Packet_String;
  197.  
  198. END    (* Expand_Packet_To_String *);
  199.  
  200. (*----------------------------------------------------------------------*)
  201. (*             Expand_Packet --- Expand data in Kermit packet           *)
  202. (*----------------------------------------------------------------------*)
  203.  
  204. FUNCTION Expand_Packet( Rec_Packet_Ptr    : Kermit_Packet_Ptr;
  205.                         Rec_Packet_Length : INTEGER            ) : BOOLEAN;
  206.  
  207. (*----------------------------------------------------------------------*)
  208. (*                                                                      *)
  209. (*     Function:   Expand_Packet                                        *)
  210. (*                                                                      *)
  211. (*     Purpose:    Expands data in Kermit packet                        *)
  212. (*                                                                      *)
  213. (*     Calling Sequence:                                                *)
  214. (*                                                                      *)
  215. (*        OK := Expand_Packet : BOOLEAN;                                *)
  216. (*                                                                      *)
  217. (*----------------------------------------------------------------------*)
  218.  
  219. VAR
  220.    InPos        : INTEGER;
  221.    Q8Bit        : BOOLEAN;
  222.    Temp         : CHAR;
  223.    B_Temp       : BYTE ABSOLUTE Temp;
  224.    Temp2        : CHAR;
  225.    Repeat_Count : INTEGER;
  226.    I            : INTEGER;
  227.    L            : INTEGER;
  228.    Err          : INTEGER;
  229.    Write_Count  : INTEGER;
  230.    Len_Packet   : INTEGER;
  231.  
  232. BEGIN (* Expand_Packet *)
  233.                                    (* Start of received packet     *)
  234.    InPos         := 1;
  235.    Len_Packet    := Rec_Packet_Length;
  236.    Expand_Packet := TRUE;
  237.    Err           := 0;
  238.  
  239.    WHILE ( InPos <= Len_Packet ) DO
  240.       BEGIN
  241.                                    (* Repeat count 1 by default    *)
  242.          Repeat_Count := 1;
  243.                                    (* Get next character in packet *)
  244.  
  245.          Temp   := Rec_Packet_Ptr^[ InPos ];
  246.  
  247.                                    (* Check for repeat data character *)
  248.          IF Repeating THEN
  249.             IF ( Temp = His_Repeat_Char ) THEN
  250.                BEGIN
  251.                   InPos        := SUCC( InPos );
  252.                   Repeat_Count := ORD( Rec_Packet_Ptr^[ InPos ] ) - 32;
  253.                   InPos        := SUCC( InPos );
  254.                   Temp         := Rec_Packet_Ptr^[ InPos ];
  255.                END;
  256.                                    (* Check for 8-bit quote character *)
  257.  
  258.          IF ( Temp = His_Quote_8_Char ) AND Quoting THEN
  259.             BEGIN
  260.                Q8Bit := TRUE;
  261.                InPos := SUCC( InPos );
  262.                Temp  := Rec_Packet_Ptr^[ InPos ];
  263.             END
  264.          ELSE
  265.             Q8Bit := FALSE;
  266.                                    (* Check for control quote character *)
  267.  
  268.          IF ( Temp = His_Quote_Char ) THEN
  269.             BEGIN
  270.  
  271.                InPos := SUCC( InPos );
  272.                Temp  := Rec_Packet_Ptr^[ InPos ];
  273.  
  274.                                    (* Convert to control character EXCEPT  *)
  275.                                    (* for quoting characters.              *)
  276.  
  277.                Temp2 := CHR( B_Temp AND $7F );
  278.  
  279.                IF ( Temp2 <> His_Quote_Char )                             AND
  280.                   ( NOT ( Repeating AND ( Temp2 = His_Repeat_Char   ) ) ) AND
  281.                   ( NOT ( Quoting   AND ( Temp2 = His_Quote_8_Char  ) ) ) THEN
  282.                      B_Temp := B_Temp XOR 64;
  283.  
  284.             END;
  285.                                    (* Turn on 8th bit if required *)
  286.          IF Q8Bit THEN
  287.             B_Temp := B_Temp OR $80;
  288.  
  289.                                    (* Append character to output buffer. *)
  290.                                    (* If repeat count, add it in given   *)
  291.                                    (* number of times.                   *)
  292.  
  293.          IF ( NOT Kermit_Screen_Write ) THEN
  294.             FOR I := 1 TO Repeat_Count DO
  295.                BEGIN
  296.  
  297.                   IF ( Buffer_Pos >= Buffer_Size ) THEN
  298.                      BEGIN
  299.  
  300.                         BlockWrite( XFile, Write_Buffer^, Buffer_Size, Write_Count );
  301.  
  302.                         Err           := Int24Result;
  303.                         Buffer_Pos    := 0;
  304.                         Expand_Packet := ( Err = 0 ) AND
  305.                                          ( Write_Count = Buffer_Size );
  306.  
  307.                      END;
  308.  
  309.                   Buffer_Pos                := SUCC( Buffer_Pos );
  310.                   Write_Buffer^[Buffer_Pos] := B_Temp;
  311.  
  312.                END
  313.          ELSE
  314.             FOR I := 1 TO Repeat_Count DO
  315.                Display_Character( Temp );
  316.  
  317.                                    (* Increment received bytes count *)
  318.  
  319.          Buffer_Num        := Buffer_Num        + Repeat_Count;
  320.          Buffer_Num_Actual := Buffer_Num_Actual + 1;
  321.  
  322.                                    (* Point to next input character  *)
  323.          InPos := SUCC( InPos );
  324.  
  325.       END (* WHILE *);
  326.  
  327. END    (* Expand_Packet *);
  328.  
  329. (*----------------------------------------------------------------------*)
  330. (*    Kermit_Receive_Header --- get file header packet for Kermit       *)
  331. (*----------------------------------------------------------------------*)
  332.  
  333. PROCEDURE Kermit_Receive_Header;
  334.  
  335. (*----------------------------------------------------------------------*)
  336. (*                                                                      *)
  337. (*     Procedure:  Kermit_Receive_Header                                *)
  338. (*                                                                      *)
  339. (*     Purpose:    Get file header packet for Kermit                    *)
  340. (*                                                                      *)
  341. (*     Calling Sequence:                                                *)
  342. (*                                                                      *)
  343. (*        Kermit_Receive_Header;                                        *)
  344. (*                                                                      *)
  345. (*     Remarks:                                                         *)
  346. (*                                                                      *)
  347. (*        This procedure receives packets and looks for the file header *)
  348. (*        packet.  If a good file header packet is found, this routine  *)
  349. (*        tries to open the file.  If the file opens successfully, the  *)
  350. (*        state changes to 'Receive_File'.  If the file cannot be       *)
  351. (*        opened (the file open procedure attempts to create a unique   *)
  352. (*        filename if the specified file already exists) an error       *)
  353. (*        packet is returned to the requesting kermit.  This procedure  *)
  354. (*        also handles 'Send Init' and 'Break' packets as specified in  *)
  355. (*        the Kermit Protocol Manual.                                   *)
  356. (*                                                                      *)
  357. (*----------------------------------------------------------------------*)
  358.  
  359. VAR
  360.    Try               : INTEGER;
  361.    Get_Pack          : BOOLEAN;
  362.    Rec_Packet_String : AnyStr;
  363.  
  364. BEGIN (* Kermit_Receive_Header *)
  365.  
  366.                                    (* If we already have header, use it *)
  367.  
  368.    Get_Pack := ( Kermit_Packet_Type <> Header_Pack ) AND
  369.                ( Kermit_Packet_Type <> Text_Pack   );
  370.  
  371.    REPEAT                          (* Get a packet *)
  372.  
  373.       IF Get_Pack THEN
  374.          Receive_Packet;
  375.  
  376.       Get_Pack := TRUE;
  377.                                    (* If recognized, perform required *)
  378.                                    (* function based upon packet type *)
  379.       IF Packet_OK THEN
  380.  
  381.          CASE Kermit_Packet_Type OF
  382.  
  383.             Header_Pack : BEGIN
  384.                                     (* Try opening file *)
  385.  
  386.                              Kermit_Screen_Write := FALSE;
  387.                              Rec_Packet_String   := Expand_Packet_To_String(
  388.                                                              Rec_Packet_Ptr ,
  389.                                                              Rec_Packet_Length );
  390.  
  391.                              Open_File( Write_Open,
  392.                                         Rec_Packet_String,
  393.                                         Full_Name );
  394.  
  395.                                     (* If OK, then shift to receive state *)
  396.  
  397.                              IF Open_OK THEN
  398.                                 BEGIN
  399.                                    Buffer_Pos           := 0;
  400.                                    Toss_File            := FALSE;
  401.                                    Packet_Num           := Rec_Packet_Num;
  402.                                    Display_Kermit_Message('Receiving ' +
  403.                                                           Rec_Packet_String );
  404.                                    Send_ACK;
  405.                                    Kermit_State := Receive_File;
  406.                                 END
  407.  
  408.                                    (* Not ok open -- send error packet *)
  409.                                    (* to remote Kermit.                *)
  410.                              ELSE
  411.                                 BEGIN
  412.                                    Kermit_Construct_Message( 'ECannot open file' );
  413.                                    Kermit_Abort := TRUE;
  414.                                    IF ( Kermit_Abort_Level = No_Abort ) THEN
  415.                                       Kermit_Abort_Level := One_File;
  416.                                    Display_Kermit_Message( 'Cannot open file: '
  417.                                                            + Rec_Packet_String );
  418.                                END;
  419.  
  420.                           END;
  421.  
  422.             Text_Pack   : BEGIN
  423.                              Kermit_Screen_Write  := TRUE;
  424.                              Buffer_Pos           := 0;
  425.                              File_Open            := FALSE;
  426.                              Toss_File            := FALSE;
  427.                              Packet_Num           := Rec_Packet_Num;
  428.                              Send_ACK;
  429.                              Kermit_State := Receive_File;
  430.                              IF Display_Status THEN
  431.                                 BEGIN
  432.                                     Display_Status := FALSE;
  433.                                     Restore_Screen_And_Colors( Kermit_Local_Save );
  434.                                 END;
  435.                              PibTerm_Window( 1, 1, Max_Screen_Col, Max_Screen_Line - 1 );
  436.                              Clear_Window;
  437.                              GoToXY( 1 , 1 );
  438.                           END;
  439.  
  440.             Send_Pack   : BEGIN
  441.                              Packet_Num           := Rec_Packet_Num;
  442.                              Send_ACK;
  443.                           END;
  444.  
  445.             Break_Pack  : BEGIN
  446.                              Packet_Num           := Rec_Packet_Num;
  447.                              Send_ACK;
  448.                              Receive_Done := TRUE;
  449.                              Display_Kermit_Message('Completed.');
  450.                           END;
  451.  
  452.             End_Pack    : BEGIN
  453.                              Packet_Num           := Rec_Packet_Num;
  454.                              Send_ACK;
  455.                           END;
  456.  
  457.             ELSE          BEGIN
  458.                              Kermit_Abort         := TRUE;
  459.                              IF ( Kermit_Abort_Level = No_Abort ) THEN
  460.                                 Kermit_Abort_Level := One_File;
  461.                              Packet_Num           := Rec_Packet_Num;
  462.                              Kermit_Construct_Message( 'EUnknown packet type.' );
  463.                              Display_Kermit_Message('Error - Unknown packet type.');
  464.                           END;
  465.  
  466.          END (* CASE *);
  467.  
  468.       IF ( Kermit_Abort_Level = Entire_Protocol ) THEN
  469.          Display_Kermit_Message('Cancelling Kermit protocol.')
  470.       ELSE IF ( Kermit_Abort_Level = All_Files ) THEN
  471.          BEGIN
  472.             Packet_Num           := ( Packet_Num + 1 ) MOD 64;
  473.             Send_Packet_Ptr^[4]  := 'B';
  474.             Send_Packet_Length   := 4;
  475.             Build_Packet;
  476.             Send_Packet;
  477.             Display_Kermit_Message('Cancelling transfer of current batch of files.');
  478.          END
  479.       ELSE
  480.          IF ( NOT Packet_OK ) THEN
  481.             BEGIN
  482.                Try         := SUCC( Try );
  483.                Packets_Bad := Packets_Bad + 1;
  484.                Send_NAK;
  485.                IF ( Try = Kermit_MaxTry ) THEN
  486.                   BEGIN
  487.                      Kermit_Abort       := TRUE;
  488.                      IF ( Kermit_Abort_Level = No_Abort ) THEN
  489.                         Kermit_Abort_Level := One_File;
  490.                      Packet_Num           := 0;
  491.                      Kermit_Construct_Message( 'ECannot get file header.' );
  492.                      Display_Kermit_Message('Cannot get file header.');
  493.                   END;
  494.             END;
  495.  
  496.    UNTIL Kermit_Abort OR ( Kermit_State = Receive_File ) OR Receive_Done;
  497.  
  498. END   (* Kermit_Receive_Header *);
  499.  
  500. (*----------------------------------------------------------------------*)
  501. (*      Kermit_Get --- Initiate server mode receive for Kermit          *)
  502. (*----------------------------------------------------------------------*)
  503.  
  504. PROCEDURE Kermit_Get;
  505.  
  506. (*----------------------------------------------------------------------*)
  507. (*                                                                      *)
  508. (*     Procedure:  Kermit_Get                                           *)
  509. (*                                                                      *)
  510. (*     Purpose:    Initiate server mode receive for Kermit              *)
  511. (*                                                                      *)
  512. (*     Calling Sequence:                                                *)
  513. (*                                                                      *)
  514. (*        Kermit_Get;                                                   *)
  515. (*                                                                      *)
  516. (*     Remarks:                                                         *)
  517. (*                                                                      *)
  518. (*        This procedure attempts to initiate a server receive.         *)
  519. (*        First, Kermit_Get sends an 'R' packet with the selected       *)
  520. (*        file name.  If a valid 'Send Init' packet is received, then   *)
  521. (*        the Kermit state is changed to Receive_Header.  If a valid    *)
  522. (*        'Send Init' is NOT received, then an error packet is sent to  *)
  523. (*        the other Kermit after the specified number of retries.       *)
  524. (*                                                                      *)
  525. (*----------------------------------------------------------------------*)
  526.  
  527. VAR
  528.    Try     : INTEGER;
  529.    Init_OK : BOOLEAN;
  530.  
  531. BEGIN (* Kermit_Get *)
  532.                                    (* Send 'Get File' packet *)
  533.    Packet_Num           := 0;
  534.    Try                  := LENGTH( FileName );
  535.    His_Chk_Type         := '1';
  536.  
  537.    Send_Packet_Ptr^[4] := 'R';
  538.  
  539.    MOVE( FileName[1], Send_Packet_Ptr^[5], Try );
  540.    Send_Packet_Length  := Try + 4;
  541.  
  542.    Build_Packet;
  543.  
  544.    Try := 0;
  545.  
  546.    REPEAT
  547.  
  548.       Send_Packet;
  549.       Receive_Packet;
  550.  
  551.       IF Packet_OK AND ( Kermit_Packet_Type = Send_Pack ) THEN
  552.          BEGIN
  553.  
  554.             Packet_Num           := Rec_Packet_Num;
  555.  
  556.             Check_Init( Init_OK );
  557.  
  558.             IF Init_OK THEN
  559.                BEGIN
  560.                   Send_ACK;
  561.                   Kermit_State := Receive_Header;
  562.                END;
  563.  
  564.          END;
  565.  
  566.       IF ( Kermit_Packet_Type = Error_Pack ) THEN
  567.          BEGIN
  568.             Display_Kermit_Message( Expand_Packet_To_String( Rec_Packet_Ptr,
  569.                                                              Rec_Packet_Length ) );
  570.             Kermit_Abort       := TRUE;
  571.             IF ( Kermit_Abort_Level = No_Abort ) THEN
  572.                Kermit_Abort_Level := One_File;
  573.          END;
  574.  
  575.       IF NOT ( Init_OK OR Kermit_Abort ) THEN
  576.          BEGIN
  577.             Packets_Bad := Packets_Bad + 1;
  578.             Try         := SUCC( Try );
  579.             Send_NAK;
  580.          END;
  581.  
  582.       IF ( ( Try = Kermit_MaxTry ) OR Kermit_Abort ) THEN
  583.          BEGIN
  584.             Kermit_Abort       := TRUE;
  585.             IF ( Kermit_Abort_Level = No_Abort ) THEN
  586.                Kermit_Abort_Level := One_File;
  587.             Kermit_Construct_Message( 'ECannot get send init packet.' );
  588.             Display_Kermit_Message('Cannot get send_init packet.');
  589.          END;
  590.  
  591.    UNTIL Kermit_Abort OR ( Kermit_State = Receive_Header );
  592.  
  593. END    (* Kermit_Get *);
  594.  
  595. (*----------------------------------------------------------------------*)
  596. (*   Kermit_Receive_Init --- get Send Init packet for Kermit receives   *)
  597. (*----------------------------------------------------------------------*)
  598.  
  599. PROCEDURE Kermit_Receive_Init;
  600.  
  601. (*----------------------------------------------------------------------*)
  602. (*                                                                      *)
  603. (*     Procedure:  Kermit_Receive_Init                                  *)
  604. (*                                                                      *)
  605. (*     Purpose:    get 'Send Init' for Kermit receives                  *)
  606. (*                                                                      *)
  607. (*     Calling Sequence:                                                *)
  608. (*                                                                      *)
  609. (*        Kermit_Receive_Init;                                          *)
  610. (*                                                                      *)
  611. (*     Remarks:                                                         *)
  612. (*                                                                      *)
  613. (*        This procedure waits for a 'Send Init' packet; it will hang   *)
  614. (*        here until a valid 'Send Init' packet is received, or an      *)
  615. (*        Alt-R is entered at the keyboard to abort the transfer.       *)
  616. (*                                                                      *)
  617. (*----------------------------------------------------------------------*)
  618.  
  619. VAR
  620.    Try     : INTEGER;
  621.    Init_OK : BOOLEAN;
  622.    Save_CHK: CHAR;
  623.    Get_Pack: BOOLEAN;
  624.  
  625. BEGIN (* Kermit_Receive_Init *)
  626.                                    (* Initialize display *)
  627.    Initialize_Display;
  628.  
  629.    Try := 0;
  630.  
  631.    Get_Pack := ( Kermit_Packet_Type <> Send_Pack );
  632.  
  633.    REPEAT
  634.                                    (* Init packet always has block *)
  635.                                    (* check type one.              *)
  636.       IF Get_Pack THEN
  637.          BEGIN
  638.  
  639.             Save_CHK     := His_Chk_Type;
  640.             His_Chk_Type := '1';
  641.  
  642.             Receive_Packet;
  643.  
  644.             His_Chk_Type := Save_CHK;
  645.  
  646.          END;
  647.  
  648.       Get_Pack := TRUE;
  649.  
  650.       IF Packet_OK AND ( Kermit_Packet_Type = Send_Pack ) THEN
  651.          BEGIN
  652.  
  653.             Packet_Num           := Rec_Packet_Num;
  654.  
  655.             Check_Init( Init_OK );
  656.  
  657.             IF Init_OK THEN
  658.                BEGIN
  659.                   Send_ACK;
  660.                   Kermit_State := Receive_Header;
  661.                END
  662.             ELSE
  663.                BEGIN
  664.  
  665.                   Packets_Bad := Packets_Bad + 1;
  666.  
  667.                   IF ( NOT Kermit_Retry ) THEN
  668.                      Send_NAK;
  669.  
  670.                   Try := SUCC( Try );
  671.  
  672.                   IF ( Try = Kermit_MaxTry ) THEN
  673.                      BEGIN
  674.                         Kermit_Abort       := TRUE;
  675.                         IF ( Kermit_Abort_Level = No_Abort ) THEN
  676.                            Kermit_Abort_Level := One_File;
  677.                         Kermit_Construct_Message( 'ECannot get send init packet.' );
  678.                         Display_Kermit_Message('Cannot get send_init packet.');
  679.                      END;
  680.  
  681.                END;
  682.  
  683.          END;
  684.  
  685.    UNTIL Kermit_Abort OR ( Kermit_State = Receive_Header );
  686.  
  687. END    (* Kermit_Receive_Init *);
  688.