home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / bbs / pibterm / pibt3sp3 / receivk2.pas < prev    next >
Pascal/Delphi Source File  |  1985-10-04  |  32KB  |  875 lines

  1. (*----------------------------------------------------------------------*)
  2. (*   Initialize_Receive_Display --- Set up display of Kermit reception  *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Initialize_Receive_Display;
  6.  
  7. BEGIN (* Initialize_Receive_Display *)
  8.  
  9.    GoToXY( 1 , 1 );
  10.  
  11.    WRITE(' Packets received     :');
  12.    ClrEol;
  13.  
  14.    GoToXY( 1 , 2 );
  15.    WRITE(' Bytes received       :');
  16.    ClrEol;
  17.  
  18.    GoToXY( 1 , 3 );
  19.    WRITE(' Retries              :');
  20.    ClrEol;
  21.  
  22.    GoToXY( 1 , 5 );
  23.    WRITE(' Last status message  :');
  24.    ClrEol;
  25.  
  26. END   (* Initialize_Receive_Display *);
  27.  
  28. (*----------------------------------------------------------------------*)
  29. (*    Kermit_Receive_Header --- get file header packet for Kermit       *)
  30. (*----------------------------------------------------------------------*)
  31.  
  32. PROCEDURE Kermit_Receive_Header;
  33.  
  34. (*----------------------------------------------------------------------*)
  35. (*                                                                      *)
  36. (*     Procedure:  Kermit_Receive_Header                                *)
  37. (*                                                                      *)
  38. (*     Purpose:    Get file header packet for Kermit                    *)
  39. (*                                                                      *)
  40. (*     Calling Sequence:                                                *)
  41. (*                                                                      *)
  42. (*        Kermit_Receive_Header;                                        *)
  43. (*                                                                      *)
  44. (*     Remarks:                                                         *)
  45. (*                                                                      *)
  46. (*        This procedure receives packets and looks for the file header *)
  47. (*        packet.  If a good file header packet is found, this routine  *)
  48. (*        tries to open the file.  If the file opens successfully, the  *)
  49. (*        state changes to 'Receive_File'.  If the file cannot be       *)
  50. (*        opened (the file open procedure attempts to create a unique   *)
  51. (*        filename if the specified file already exists) an error       *)
  52. (*        packet is returned to the requesting kermit.  This procedure  *)
  53. (*        also handles 'Send Init' and 'Break' packets as specified in  *)
  54. (*        the Kermit Protocol Manual.                                   *)
  55. (*                                                                      *)
  56. (*----------------------------------------------------------------------*)
  57.  
  58. VAR
  59.    Try      : INTEGER;
  60.    Get_Pack : BOOLEAN;
  61.  
  62. BEGIN (* Kermit_Receive_Header *)
  63.                                    (* If we alerady have header, use it *)
  64.  
  65.    Get_Pack := ( Kermit_Packet_Type <> Header_Pack );
  66.  
  67.    REPEAT                          (* Get a packet *)
  68.  
  69.       IF Get_Pack THEN
  70.          Receive_Packet
  71.       ELSE
  72.          Get_Pack := TRUE;
  73.                                    (* If recognized, perform required *)
  74.                                    (* function based upon packet type *)
  75.       IF Packet_OK THEN
  76.  
  77.          CASE Kermit_Packet_Type OF
  78.  
  79.             Header_Pack : BEGIN
  80.                                     (* Try opening file *)
  81.  
  82.                              Open_File( Write_Open,
  83.                                         Fix_File_Name( Rec_Packet ) );
  84.  
  85.                                     (* If OK, then shift to receive state *)
  86.  
  87.                              IF Open_OK THEN
  88.                                 BEGIN
  89.                                    Buffer_Pos := 0;
  90.                                    Packet_Num := Rec_Packet_Num;
  91.                                    Display_Kermit_Message('Receiving ' +
  92.                                                           Rec_Packet );
  93.                                    Send_ACK;
  94.                                    Kermit_State := Receive_File;
  95.                                 END
  96.  
  97.                                    (* Not ok open -- send error packet *)
  98.                                    (* to remote Kermit.                *)
  99.                              ELSE
  100.                                 BEGIN
  101.                                    Packet_Buffer := 'ECannot open file';
  102.                                    Build_Packet;
  103.                                    Send_Packet;
  104.                                    Kermit_Abort := TRUE;
  105.                                    Display_Kermit_Message( 'Cannot open file: '
  106.                                                            + Rec_Packet );
  107.                                END;
  108.  
  109.                           END;
  110.  
  111.             Send_Pack   : BEGIN
  112.                              Packet_Num := Rec_Packet_Num;
  113.                              Send_ACK;
  114.                           END;
  115.  
  116.             Break_Pack  : BEGIN
  117.                              Packet_Num := Rec_Packet_Num;
  118.                              Send_ACK;
  119.                              Receive_Done := TRUE;
  120.                              Display_Kermit_Message('Completed.');
  121.                           END;
  122.  
  123.             End_Pack    : BEGIN
  124.                             Packet_Num := Rec_Packet_Num;
  125.                             Send_ACK;
  126.                           END;
  127.  
  128.             Unknown     : BEGIN
  129.                              Kermit_Abort  := TRUE;
  130.                              Packet_Num    := Rec_Packet_Num;
  131.                              Packet_Buffer := 'EUnknown packet type.';
  132.                              Build_Packet;
  133.                              Send_Packet;
  134.                              Display_Kermit_Message('Abort -- unknown packet type.');
  135.                           END;
  136.  
  137.          END (* CASE *)
  138.  
  139.       ELSE
  140.  
  141.          BEGIN
  142.             Try         := Try + 1;
  143.             Packets_Bad := Packets_Bad + 1;
  144.             Send_NAK;
  145.             IF ( Try = Kermit_MaxTry ) THEN
  146.                BEGIN
  147.                   Kermit_Abort  := TRUE;
  148.                   Packet_Num    := 0;
  149.                   Packet_Buffer := 'ECannot get file header.';
  150.                   Build_Packet;
  151.                   Send_Packet;
  152.                   Display_Kermit_Message('Cannot get file header.');
  153.                END;
  154.          END;
  155.  
  156.    UNTIL Kermit_Abort OR ( Kermit_State = Receive_File ) OR Receive_Done;
  157.  
  158. END   (* Kermit_Receive_Header *);
  159.  
  160. (*----------------------------------------------------------------------*)
  161. (*      Kermit_Get --- Initiate server mode receive for Kermit          *)
  162. (*----------------------------------------------------------------------*)
  163.  
  164. PROCEDURE Kermit_Get;
  165.  
  166. (*----------------------------------------------------------------------*)
  167. (*                                                                      *)
  168. (*     Procedure:  Kermit_Get                                           *)
  169. (*                                                                      *)
  170. (*     Purpose:    Initiate server mode receive for Kermit              *)
  171. (*                                                                      *)
  172. (*     Calling Sequence:                                                *)
  173. (*                                                                      *)
  174. (*        Kermit_Get;                                                   *)
  175. (*                                                                      *)
  176. (*     Remarks:                                                         *)
  177. (*                                                                      *)
  178. (*        This procedure attempts to initiate a server receive.         *)
  179. (*        First, Kermit_Get sends an 'R' packet with the selected       *)
  180. (*        file name.  If a valid 'Send Init' packet is received, then   *)
  181. (*        the Kermit state is changed to Receive_Header.  If a valid    *)
  182. (*        'Send Init' is NOT received, then an error packet is sent to  *)
  183. (*        the other Kermit after the specified number of retries.       *)
  184. (*                                                                      *)
  185. (*----------------------------------------------------------------------*)
  186.  
  187. VAR
  188.    Try     : INTEGER;
  189.    Init_OK : BOOLEAN;
  190.  
  191. BEGIN (* Kermit_Get *)
  192.                                    (* Send 'Get File' packet *)
  193.    Packet_Num         := 0;
  194.    Packet_Buffer_Data := 'R' + FileName;
  195.  
  196.    Build_Packet;
  197.  
  198.    Try := 0;
  199.  
  200.    REPEAT
  201.  
  202.       Send_Packet;
  203.       Receive_Packet;
  204.  
  205.       IF Packet_OK AND ( Kermit_Packet_Type = Send_Pack ) THEN
  206.          BEGIN
  207.  
  208.             Packet_Num := Rec_Packet_Num;
  209.  
  210.             Check_Init( Init_OK );
  211.  
  212.             IF Init_OK THEN
  213.                BEGIN
  214.                   Send_ACK;
  215.                   Kermit_State := Receive_Header;
  216.                END;
  217.  
  218.          END;
  219.  
  220.       IF ( Kermit_Packet_Type = Error_Pack ) THEN
  221.          BEGIN
  222.             Display_Kermit_Message( Rec_Packet );
  223.             Kermit_Abort := TRUE;
  224.          END;
  225.  
  226.       IF NOT ( Init_OK OR Kermit_Abort ) THEN
  227.          BEGIN
  228.             Packets_Bad := Packets_Bad + 1;
  229.             Try         := Try + 1;
  230.             Send_NAK;
  231.          END;
  232.  
  233.       IF ( ( Try = Kermit_MaxTry ) OR Kermit_Abort ) THEN
  234.          BEGIN
  235.             Kermit_Abort       := TRUE;
  236.             Packet_Buffer_Data := 'ECannot get send init packet';
  237.             Build_Packet;
  238.             Send_Packet;
  239.             Display_Kermit_Message('Cannot get send_init packet.');
  240.          END;
  241.  
  242.    UNTIL Kermit_Abort OR ( Kermit_State = Receive_Header );
  243.  
  244. END    (* Kermit_Get *);
  245.  
  246. (*----------------------------------------------------------------------*)
  247. (*   Kermit_Receive_Init --- get Send Init packet for Kermit receives   *)
  248. (*----------------------------------------------------------------------*)
  249.  
  250. PROCEDURE Kermit_Receive_Init;
  251.  
  252. (*----------------------------------------------------------------------*)
  253. (*                                                                      *)
  254. (*     Procedure:  Kermit_Receive_Init                                  *)
  255. (*                                                                      *)
  256. (*     Purpose:    get 'Send Init' for Kermit receives                  *)
  257. (*                                                                      *)
  258. (*     Calling Sequence:                                                *)
  259. (*                                                                      *)
  260. (*        Kermit_Receive_Init;                                          *)
  261. (*                                                                      *)
  262. (*     Remarks:                                                         *)
  263. (*                                                                      *)
  264. (*        This procedure waits for a 'Send Init' packet; it will hang   *)
  265. (*        here UNTIL a valid 'Send Init' packet is received, or an      *)
  266. (*        Alt-R is entered at the keyboard to abort the transfer.       *)
  267. (*                                                                      *)
  268. (*----------------------------------------------------------------------*)
  269.  
  270. VAR
  271.    Try     : INTEGER;
  272.    Init_OK : BOOLEAN;
  273.    Save_CHK: CHAR;
  274.  
  275. BEGIN (* Kermit_Receive_Init *)
  276.                                    (* Initialize display *)
  277.    Initialize_Receive_Display;
  278.  
  279.    Try := 0;
  280.  
  281.    REPEAT
  282.                                    (* Init packet always has block *)
  283.                                    (* check type one.              *)
  284.  
  285.       Save_CHK        := His_Chk_Type;
  286.       His_Chk_Type := '1';
  287.  
  288.       Receive_Packet;
  289.  
  290.       His_Chk_Type := Save_CHK;
  291.  
  292.       IF Packet_OK AND ( Kermit_Packet_Type = Send_Pack ) THEN
  293.          BEGIN
  294.  
  295.             Packet_Num := Rec_Packet_Num;
  296.  
  297.             Check_Init( Init_OK );
  298.  
  299.             IF Init_OK THEN
  300.                BEGIN
  301.                   Send_ACK;
  302.                   Kermit_State := Receive_Header;
  303.                END
  304.             ELSE
  305.                BEGIN
  306.  
  307.                   Packets_Bad := Packets_Bad + 1;
  308.  
  309.                   Send_NAK;
  310.  
  311.                   Try := Try + 1;
  312.  
  313.                   IF ( Try = Kermit_MaxTry ) THEN
  314.                      BEGIN
  315.                         Kermit_Abort := TRUE;
  316.                         Packet_Buffer_Data := 'ECannot get send init packet';
  317.                         Build_Packet;
  318.                         Send_Packet;
  319.                         GoToXY(1,9);
  320.                         WRITELN('Cannot get send_init packet.');
  321.                      END;
  322.  
  323.                END;
  324.  
  325.          END;
  326.  
  327.    UNTIL Kermit_Abort OR ( Kermit_State = Receive_Header );
  328.  
  329. END    (* Kermit_Receive_Init *);
  330.  
  331. (*----------------------------------------------------------------------*)
  332. (*             Expand_Packet --- Expand data in Kermit packet           *)
  333. (*----------------------------------------------------------------------*)
  334.  
  335. PROCEDURE Expand_Packet;
  336.  
  337. (*----------------------------------------------------------------------*)
  338. (*                                                                      *)
  339. (*     Procedure:  Expand_Packet                                        *)
  340. (*                                                                      *)
  341. (*     Purpose:    Expands data in Kermit packet                        *)
  342. (*                                                                      *)
  343. (*     Calling Sequence:                                                *)
  344. (*                                                                      *)
  345. (*        Expand_Packet;                                                *)
  346. (*                                                                      *)
  347. (*----------------------------------------------------------------------*)
  348.  
  349. VAR
  350.    InPos   : INTEGER;
  351.    Q8Bit   : BOOLEAN;
  352.    Temp    : CHAR;
  353.    B_Temp  : BYTE ABSOLUTE Temp;
  354.  
  355. BEGIN (* Expand_Packet *)
  356.  
  357.    Received_Data := '';
  358.    InPos         := 1;
  359.  
  360.    WHILE ( InPos <= LENGTH( Rec_Packet ) ) DO
  361.       BEGIN
  362.                                    (* Get next character in packet *)
  363.  
  364.          Temp   := Rec_Packet[ InPos ];
  365.  
  366.                                    (* Check for 8-bit quote character *)
  367.  
  368.          IF ( Temp = His_Quote_8_Char ) AND Quoting THEN
  369.             BEGIN
  370.                Q8Bit := TRUE;
  371.                InPos := InPos + 1;
  372.                Temp  := Rec_Packet[ InPos ];
  373.             END
  374.          ELSE
  375.             Q8Bit := FALSE;
  376.                                    (* Check for control quote character *)
  377.  
  378.          IF ( Temp = His_Quote_Char ) THEN
  379.             BEGIN
  380.  
  381.                InPos := InPos + 1;
  382.                Temp  := Rec_Packet[ InPos ];
  383.  
  384.                                    (* Convert to control character EXCEPT  *)
  385.                                    (* for 8-bit quote character or control *)
  386.                                    (* quote character.                     *)
  387.  
  388.                IF ( CHR( B_Temp AND $7F ) <> His_Quote_Char ) AND
  389.                   ( NOT ( Quoting AND ( Temp = His_Quote_8_Char ) ) ) THEN
  390.                   B_Temp := B_Temp XOR 64;
  391.  
  392.             END;
  393.                                    (* Turn on 8th bit if required *)
  394.          IF Q8Bit THEN
  395.             B_Temp := B_Temp OR $80;
  396.  
  397.                                    (* Append character to result string *)
  398.  
  399.          Received_Data := Received_Data + Temp;
  400.  
  401.                                    (* Point to next character *)
  402.          InPos := InPos + 1;
  403.  
  404.       END (* WHILE *);
  405.  
  406. END    (* Expand_Packet *);
  407.  
  408. (*----------------------------------------------------------------------*)
  409. (*     Kermit_Receive_File --- get file data from remote Kermit         *)
  410. (*----------------------------------------------------------------------*)
  411.  
  412. PROCEDURE Kermit_Receive_File;
  413.  
  414. (*----------------------------------------------------------------------*)
  415. (*                                                                      *)
  416. (*     Procedure:  Kermit_Receive_File                                  *)
  417. (*                                                                      *)
  418. (*     Purpose:    Gets file data from remote Kermit                    *)
  419. (*                                                                      *)
  420. (*     Calling Sequence:                                                *)
  421. (*                                                                      *)
  422. (*        Kermit_Receive_File;                                          *)
  423. (*                                                                      *)
  424. (*     Remarks:                                                         *)
  425. (*                                                                      *)
  426. (*        This procedure receives file data from the remote Kermit      *)
  427. (*        until a Break packet, and End packet, or an Unknown packet    *)
  428. (*        is received.  It will also abort if there are too many        *)
  429. (*        retries.                                                      *)
  430. (*                                                                      *)
  431. (*----------------------------------------------------------------------*)
  432.  
  433. VAR
  434.    Count : INTEGER;
  435.    Try   : INTEGER;
  436.  
  437. (*----------------------------------------------------------------------*)
  438. (*             Handle_Data_Pack --- handle one data packet              *)
  439. (*----------------------------------------------------------------------*)
  440.  
  441. PROCEDURE Handle_Data_Pack;
  442.  
  443. VAR
  444.    Err         : INTEGER;
  445.    Write_Count : INTEGER;
  446.  
  447. BEGIN (* Handle_Data_Pack *)
  448.                                    (* Expand data packet -- do quoting, *)
  449.                                    (* repeats, etc.                     *)
  450.    Expand_Packet;
  451.                                    (* Stuff data into output file buffer *)
  452.  
  453.    FOR Count := 1 TO LENGTH( Received_Data ) DO
  454.       BEGIN
  455.  
  456.          IF ( Buffer_Pos >= Buffer_Size ) THEN
  457.             BEGIN
  458.  
  459.                Write_Count := Buffer_Size;
  460.                Err         := Write_File_Handle( XFile_Handle, Write_Buffer^,
  461.                                                  Write_Count );
  462.                Buffer_Pos  := 0;
  463.  
  464.             END;
  465.  
  466.          Buffer_Pos                := Buffer_Pos + 1;
  467.          Write_Buffer^[Buffer_Pos] := ORD( Received_Data[Count] );
  468.  
  469.       END;
  470.                                    (* Increment received bytes count *)
  471.  
  472.    Buffer_Num  := Buffer_Num + LENGTH( Received_Data );
  473.  
  474.                                    (* Acknowledge this packet *)
  475.    Send_ACK;
  476.  
  477. END   (* Handle_Data_Pack *);
  478.  
  479. (*----------------------------------------------------------------------*)
  480. (*             Handle_End_Pack --- handle end of file packet            *)
  481. (*----------------------------------------------------------------------*)
  482.  
  483. PROCEDURE Handle_End_Pack;
  484.  
  485. VAR
  486.    Write_Count   : INTEGER;
  487.    Err           : INTEGER;
  488.    Ctrl_Z_Written: BOOLEAN;
  489.  
  490. BEGIN (* Handle_End_Pack *)
  491.                                    (* Write any remaining characters *)
  492.                                    (* in file buffer to file and     *)
  493.                                    (* close it.                      *)
  494.    IF File_Open THEN
  495.       BEGIN
  496.                                    (* Add a Ctrl-Z to file if in     *)
  497.                                    (* text mode to mark end of file. *)
  498.  
  499.          IF ( Kermit_File_Type_Var = Kermit_Ascii ) THEN
  500.             IF ( Buffer_Pos < Buffer_Size ) THEN
  501.                BEGIN
  502.                   Buffer_Pos                := Buffer_Pos + 1;
  503.                   Write_Buffer^[Buffer_Pos] := ORD( ^Z );
  504.                   Ctrl_Z_Written            := TRUE;
  505.                END
  506.             ELSE
  507.                Ctrl_Z_Written := FALSE;
  508.  
  509.                                    (* Write any remaining characters in *)
  510.                                    (* buffer.                           *)
  511.  
  512.          Write_Count := Buffer_Pos;
  513.  
  514.          Err         := Write_File_Handle( XFile_Handle, Write_Buffer^,
  515.                                            Write_Count );
  516.  
  517.                                    (* Write a Ctrl-Z to file if in     *)
  518.                                    (* text mode and no room in buffer. *)
  519.  
  520.          IF ( Kermit_File_Type_Var = Kermit_Ascii ) AND
  521.             ( NOT Ctrl_Z_Written ) THEN
  522.             BEGIN
  523.                Write_Buffer^[1] := ORD( ^Z );
  524.                Write_Count      := 1;
  525.                Err              := Write_File_Handle( XFile_Handle, Write_Buffer^,
  526.                                                       Write_Count );
  527.             END;
  528.  
  529.                                    (* Close the file *)
  530.  
  531.          Err         := Close_File_Handle( XFile_Handle );
  532.  
  533.                                    (* Mark file as closed. *)
  534.          File_Open   := FALSE;
  535.  
  536.       END;
  537.                                    (* Acknowledge last record *)
  538.    Send_ACK;
  539.                                    (* And go back to waiting for *)
  540.                                    (* start of next file.        *)
  541.  
  542.    Kermit_State := Receive_Header;
  543.  
  544. END   (* Handle_End_Pack *);
  545.  
  546. (*----------------------------------------------------------------------*)
  547. (*             Handle_Break_Packet --- Handle break packet              *)
  548. (*----------------------------------------------------------------------*)
  549.  
  550. PROCEDURE Handle_Break_Pack;
  551.  
  552. VAR
  553.    Write_Count   : INTEGER;
  554.    Err           : INTEGER;
  555.    Ctrl_Z_Written: BOOLEAN;
  556.  
  557. BEGIN (* Handle_Break_Pack *)
  558.                                    (* Write any remaining characters *)
  559.                                    (* in file buffer to file and     *)
  560.                                    (* close it.                      *)
  561.    IF File_Open THEN
  562.       BEGIN
  563.                                    (* Add a Ctrl-Z to file if in     *)
  564.                                    (* text mode to mark end of file. *)
  565.  
  566.          IF ( Kermit_File_Type_Var = Kermit_Ascii ) THEN
  567.             IF ( Buffer_Pos < Buffer_Size ) THEN
  568.                BEGIN
  569.                   Buffer_Pos                := Buffer_Pos + 1;
  570.                   Write_Buffer^[Buffer_Pos] := ORD( ^Z );
  571.                   Ctrl_Z_Written            := TRUE;
  572.                END
  573.             ELSE
  574.                Ctrl_Z_Written := FALSE;
  575.  
  576.                                    (* Write any remaining characters in *)
  577.                                    (* buffer.                           *)
  578.  
  579.          Write_Count := Buffer_Pos;
  580.  
  581.          Err         := Write_File_Handle( XFile_Handle, Write_Buffer^,
  582.                                            Write_Count );
  583.  
  584.                                    (* Write a Ctrl-Z to file if in     *)
  585.                                    (* text mode and no room in buffer. *)
  586.  
  587.          IF ( Kermit_File_Type_Var = Kermit_Ascii ) AND
  588.             ( NOT Ctrl_Z_Written ) THEN
  589.             BEGIN
  590.                Write_Buffer^[1] := ORD( ^Z );
  591.                Write_Count      := 1;
  592.                Err              := Write_File_Handle( XFile_Handle, Write_Buffer^,
  593.                                                       Write_Count );
  594.             END;
  595.  
  596.                                    (* Close the file *)
  597.  
  598.          Err         := Close_File_Handle( XFile_Handle );
  599.  
  600.                                    (* Mark file as closed. *)
  601.          File_Open   := FALSE;
  602.  
  603.       END;
  604.                                    (* Acknowledge this packet *)
  605.    Send_ACK;
  606.                                    (* We're done with this batch of files. *)
  607.    Receive_Done := TRUE;
  608.  
  609. END   (* Handle_Break_Pack *);
  610.  
  611. (*----------------------------------------------------------------------*)
  612.  
  613. BEGIN (* Kermit_Receive_File *)
  614.                                    (* Loop over packets in file being *)
  615.                                    (* received.                       *)
  616.    REPEAT
  617.                                    (* Get next packet *)
  618.       Receive_Packet;
  619.                                    (* Number of tries this packet     *)
  620.       Try := 0;
  621.  
  622.       CASE Packet_OK OF
  623.                                    (* If packet bad *)
  624.          FALSE : BEGIN
  625.                     Try := Try + 1;
  626.                     IF ( Try = Kermit_MaxTry ) THEN
  627.                        BEGIN
  628.                           Kermit_Abort  := TRUE;
  629.                           Packet_Buffer := 'EToo many retries.';
  630.                           Build_Packet;
  631.                           Send_Packet;
  632.                        END
  633.                     ELSE
  634.                        Send_NAK;
  635.                  END;
  636.                                    (* If packet OK *)
  637.           TRUE : BEGIN
  638.                     IF ( Packet_Num = Rec_Packet_Num ) THEN
  639.                        Send_ACK
  640.                     ELSE
  641.                        BEGIN
  642.  
  643.                           Packet_Num := Rec_Packet_Num;
  644.  
  645.                           CASE Kermit_Packet_Type OF
  646.                              Data_Pack  : Handle_Data_Pack;
  647.                              End_Pack   : Handle_End_Pack;
  648.                              Break_Pack : Handle_Break_Pack;
  649.                              Header_Pack: ;
  650.                              Unknown    : Send_NAK;
  651.                              ELSE
  652.                                           Kermit_Abort := TRUE;
  653.                           END  (* CASE *);
  654.  
  655.                        END;
  656.                  END;
  657.  
  658.       END (* CASE *);
  659.  
  660.    UNTIL ( Kermit_Abort OR Receive_Done OR
  661.            ( Kermit_Packet_Type = Header_Pack ) );
  662.  
  663. END    (* Kermit_Receive_File *);
  664.  
  665. (*----------------------------------------------------------------------*)
  666.  
  667. PROCEDURE Do_Kermit_Receive;
  668.  
  669. BEGIN  (* Do_Kermit_Receive *)
  670.                                    (* Open display window for transfer  *)
  671.    Save_Screen( Local_Save );
  672.  
  673.    IF FileName <> '' THEN
  674.       Menu_Title := 'Receive file ' + FileName + ' using Kermit'
  675.    ELSE
  676.       Menu_Title := 'Receive file using Kermit';
  677.  
  678.    Draw_Menu_Frame( 15, 10, 78, 21, Menu_Frame_Color,
  679.                     Menu_Text_Color, Menu_Title );
  680.  
  681.    Window( 16, 11, 77, 20 );
  682.                                    (* Allocate buffer if requested   *)
  683.                                    (* otherwise use sector data area *)
  684.                                    (* directly.                      *)
  685.    IF Max_Write_Buffer > 1024 THEN
  686.       BEGIN
  687.          Buffer_Length  := Max_Write_Buffer;
  688.          Long_Buffer    := TRUE;
  689.          GetMem( Write_Buffer , Buffer_Length );
  690.       END
  691.    ELSE
  692.       BEGIN
  693.          Long_Buffer  := FALSE;
  694.          Write_Buffer := ADDR( Sector_Data );
  695.       END;
  696.  
  697.                                    (* Initialize status display information *)
  698.    Packets_Received := 0;
  699.    Packets_Sent     := 0;
  700.    Packets_Bad      := 0;
  701.    Buffer_Num       := 0.0;
  702.    Receive_Done     := FALSE;
  703.    Kermit_MaxTry    := 5;
  704.    Kermit_Abort     := FALSE;
  705.    Kermit_Retry     := FALSE;
  706.    Buffer_Size      := Buffer_Length;
  707.    Quoting          := FALSE;
  708.                                    (* Initialize status display              *)
  709.    Initialize_Receive_Display;
  710.                                    (* Choose reception method depending upon *)
  711.                                    (* whether remote system in server mode   *)
  712.                                    (* or not.                                *)
  713.  
  714.    IF Kermit_Remote_Server THEN
  715.       Kermit_State := Get_File
  716.    ELSE
  717.       Kermit_State := Receive_Init;
  718.  
  719.                                    (* Loop over received packets             *)
  720.    REPEAT
  721.                                    (* Take action depending upon current *)
  722.                                    (* Kermit state.                      *)
  723.       CASE Kermit_State OF
  724.  
  725.          Get_File        : Kermit_Get;
  726.          Receive_Init    : Kermit_Receive_Init;
  727.          Receive_Header  : Kermit_Receive_Header;
  728.          Receive_File    : Kermit_Receive_File;
  729.  
  730.       END (* CASE *);
  731.  
  732.    UNTIL ( Kermit_Abort OR Receive_Done );
  733.  
  734.    IF Receive_Done THEN
  735.       Display_Kermit_Message('Completed.');
  736.  
  737.    DELAY( Two_Second_Delay );
  738.                                    (* Remove download buffer           *)
  739.  
  740.    IF Long_Buffer THEN
  741.       FREEMEM( Write_Buffer , Buffer_Length );
  742.  
  743.                                    (* Remove Kermit window             *)
  744.    Restore_Screen( Local_Save );
  745.  
  746.    Reset_Global_Colors;
  747.  
  748. END    (* Do_Kermit_Receive *);
  749.  
  750. (*----------------------------------------------------------------------*)
  751.  
  752. PROCEDURE Get_File_Pattern;
  753.  
  754. BEGIN (* Get_File_Pattern *)
  755.  
  756.    GoToXY( 2 , 8 );
  757.  
  758.    WRITE('File to receive: ');
  759.  
  760.    IF ( NOT Host_Mode ) THEN
  761.       READLN( FileName )
  762.    ELSE
  763.       WRITELN( FileName );
  764.  
  765. END   (* Get_File_Pattern *);
  766.  
  767. (*----------------------------------------------------------------------*)
  768.  
  769. BEGIN (* Receive_Kermit_File *)
  770.                                    (* Save screen     *)
  771.    Save_Screen( Local_Save_2 );
  772.                                    (* Get Kermit menu *)
  773.    WITH Kermit_Menu DO
  774.       BEGIN
  775.  
  776.          Menu_Size    := 6;
  777.          Menu_Default := 1;
  778.          Menu_Row     := 11;
  779.          Menu_Column  := 20;
  780.          Menu_Tcolor  := Menu_Text_Color;
  781.          Menu_Bcolor  := BackGround_Color;
  782.          Menu_Fcolor  := Menu_Frame_Color;
  783.          Menu_Width   := 40;
  784.          Menu_Height  := 10;
  785.  
  786.       END (* WITH Kermit_Menu *);
  787.  
  788.    FOR I := 1 TO 6 DO
  789.       WITH Kermit_Menu.Menu_Entries[I] DO
  790.       BEGIN
  791.          Menu_Item_Row    := I;
  792.          Menu_Item_Column := 2;
  793.          CASE I OF
  794.             1:  Menu_Item_Text := 'a) GET Text File';
  795.             2:  Menu_Item_Text := 'b) GET Binary File';
  796.             3:  Menu_Item_Text := 'c) RECEIVE Text File';
  797.             4:  Menu_Item_Text := 'd) RECEIVE Binary File';
  798.             5:  Menu_Item_Text := 'L) Logout Remote Server';
  799.             6:  Menu_Item_Text := 'Q) Quit Kermit';
  800.          END (* CASE *);
  801.       END;
  802.  
  803.    Kermit_Menu.Menu_Title := 'Choose Kermit function: ';
  804.    Kermit_Done            := FALSE;
  805.    Sending_File           := FALSE;
  806.    Host_Count             := 0;
  807.  
  808.    REPEAT
  809.                                    (* Reinitialize Kermit variables *)
  810.       Kermit_Init;
  811.                                    (* Display Kermit receive menu  *)
  812.       IF ( NOT Host_Mode ) THEN
  813.          BEGIN
  814.             Menu_Display_Choices( Kermit_Menu );
  815.             Menu_Choice := Menu_Get_Choice( Kermit_Menu , Dont_Erase_Menu );
  816.          END
  817.       ELSE
  818.          BEGIN
  819.             Host_Count := Host_Count + 1;
  820.             IF ( Host_Count = 1 ) THEN
  821.                IF Kermit_File_Type_Var <> Kermit_Binary THEN
  822.                   Menu_Choice := 3
  823.                ELSE
  824.                   Menu_Choice := 4
  825.             ELSE
  826.                Menu_Choice := 6;
  827.          END;
  828.                                    (* Perform desired Kermit function *)
  829.  
  830.       CASE Menu_Choice OF
  831.  
  832.          1: BEGIN
  833.                Kermit_File_Type_Var := Kermit_Ascii;
  834.                Get_File_Pattern;
  835.                Kermit_Remote_Server := TRUE;
  836.                IF ( LENGTH( FileName ) > 0 ) THEN
  837.                   Do_Kermit_Receive;
  838.             END;
  839.  
  840.          2: BEGIN
  841.                Kermit_File_Type_Var := Kermit_Binary;
  842.                Get_File_Pattern;
  843.                Kermit_Remote_Server := TRUE;
  844.                IF ( LENGTH( FileName ) > 0 ) THEN
  845.                   Do_Kermit_Receive;
  846.             END;
  847.  
  848.          3: BEGIN
  849.                Kermit_File_Type_Var := Kermit_Ascii;
  850.                FileName := '';
  851.                Kermit_Remote_Server := FALSE;
  852.                Do_Kermit_Receive;
  853.             END;
  854.  
  855.          4: BEGIN
  856.                Kermit_File_Type_Var := Kermit_Binary;
  857.                FileName := '';
  858.                Kermit_Remote_Server := FALSE;
  859.                Do_Kermit_Receive;
  860.             END;
  861.  
  862.          5: Kermit_Finish_Server;
  863.  
  864.          6: Kermit_Done := TRUE;
  865.  
  866.       END (* CASE *);
  867.  
  868.    UNTIL Kermit_Done;
  869.  
  870.    Restore_Screen( Local_Save_2 );
  871.  
  872.    Reset_Global_Colors;
  873.  
  874. END   (* Receive_Kermit_File *);
  875. ə