home *** CD-ROM | disk | FTP | other *** search
- (*----------------------------------------------------------------------*)
- (* UPDOWN.PAS --- File Upload/Download Routines for Turbo Pascal *)
- (*----------------------------------------------------------------------*)
- (* *)
- (* Author: Philip R. Burns *)
- (* Date: January, 1985 *)
- (* Version: 1.0 *)
- (* Systems: For MS-DOS on IBM PCs and close compatibles only. *)
- (* Note: I have checked these on Zenith 151s under *)
- (* MSDOS 2.1 and IBM PCs under PCDOS 2.0. *)
- (* Needs: The Menu routines from MENUS.PAS, the communications *)
- (* routines from ASYNC.PAS, and some global variables from *)
- (* PIBTERM.PAS. *)
- (* *)
- (* History: Original with me, but the XMODEM is based upon the *)
- (* famous (X)MODEM(7) programs of Christiansen, et. al. *)
- (* Note that both the Checksum and CRC versions of XMODEM *)
- (* are available here. *)
- (* *)
- (* Suggestions for improvements or corrections are welcome. *)
- (* Please leave messages on Gene Plantz's BBS (312) 882 4145 *)
- (* or Ron Fox's BBS (312) 940 6496. *)
- (* *)
- (* If you use this code in your own programs, please be nice *)
- (* and give proper credit. *)
- (* *)
- (*----------------------------------------------------------------------*)
- (* *)
- (* Routines: *)
- (* *)
- (* DownLoad --- Download a file (control routine) *)
- (* UpLoad --- Upload a file (control routine) *)
- (* *)
- (* Receive_Ascii_File --- Receive Ascii file from another computer *)
- (* Send_Ascii_File --- Send Ascii file to another computer *)
- (* *)
- (* Compute_Crc --- Compute CRC for XMODEM *)
- (* Receive_Xmodem_File --- Receive file with XMODEM *)
- (* Send_Xmodem_File --- Send file with XMODEM *)
- (* *)
- (* Get_File_Transfer_Protocol --- Determines type of transfer *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- (* Xmodem Declarations *)
- Const
-
- Sector_Size = 130 (* Xmodem sector size *);
-
- (* Special characters used in XMODEM *)
-
- SOH = $01; (* Start of XMODEM block *)
- EOT = $04; (* End of XMODEM transmission *)
- ACK = $06; (* Acknowledge an XMODEM block *)
- NAK = $15; (* Refuse an XMODEM block *)
- CAN = $18; (* Cancel XMODEM transfer *)
-
- Type
-
- Sector_Type = Array[ 1 .. Sector_Size ] Of Byte;
-
- Var
- (* One sector of data *)
- Sector_Data : Sector_Type;
-
- Sector_Number : Integer (* Current sector number being sent *);
-
-
- (* Transfer Declarations *)
- Type
-
- Transfer_Type = ( Ascii, Xmodem_Chk, Xmodem_Crc, None );
- Transfer_Str = STRING[255];
-
- Const
-
- Transfers : Array[ 1 .. 3 ] Of Transfer_Type
- = ( Ascii, Xmodem_Chk, Xmodem_Crc );
-
- (* Files for transfers *)
- Var
-
- AFile : Text (* Ascii File uploaded/downloaded *);
- XFile : File (* Xmodem File uploaded/downloaded *);
- FileName : String[30] (* Name of file *);
-
-
- (* Timing/Delay Constants and Variables *)
- Const
-
- Ten_Seconds = 10 (* Ten seconds *);
- Twenty_Seconds = 20 (* Twenty seconds *);
- One_Second = 1 (* One second *);
-
- Var
-
- Char_Delay : Integer (* Character delay for Ascii trans. *);
- Line_Delay : Integer (* Line delay for Ascii transfers *);
- Pacing_Char : Char (* Pacing character for uploads *);
-
- (* Save/restore transmission params during XMODEM *)
-
- Var
- Xmodem_Bits_Save: Integer (* Save # bits per character *);
- Xmodem_Parity_Save: Char (* Save parity *);
- Xmodem_Stop_Save: Integer (* Save stop bits *);
-
- (*----------------------------------------------------------------------*)
- (* Compute_CRC --- Compute cyclic redundancy check *)
- (*----------------------------------------------------------------------*)
-
- Procedure Compute_Crc( Sector : Sector_Type;
- Var HiCrc : Integer;
- Var LoCrc : Integer );
-
-
- (* *)
- (* Procedure: Compute_Crc *)
- (* *)
- (* Purpose: Computes cyclic redundancy check for XMODEM sector *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Compute_Crc( Sector : Sector_Type; Var HiCrc: Integer; *)
- (* Var LoCrc: Integer ); *)
- (* *)
- (* Sector --- 130 byte sector for which CRC is computed. *)
- (* The first 128 bytes contain actual data, the *)
- (* last two bytes are either zero (when a file is *)
- (* being sent) or the CRC for the sector (when a *)
- (* file is being received). *)
- (* HiCrc --- High byte of resultant CRC value *)
- (* LoCrc --- Low byte of resultant CRC value *)
- (* *)
- (* Remarks: *)
- (* *)
- (* The polynomial X^16 + X^12 + X^5 + 1 is used, which should *)
- (* match that implemented in most other XMODEM programs. *)
- (* *)
- (* Calls: None *)
- (* *)
-
- Const
- Crc_Poly_Low = 33;
- Crc_Poly_High = 16;
-
- Var
- I: Integer;
- C: Integer;
- J: Integer;
- SaveC: Integer;
-
- Begin (* Compute_Crc *)
-
- HiCrc := 0;
- LoCrc := 0;
-
- For I := 1 To 130 Do
- Begin
-
- C := ORD( Sector[I] );
-
- For J := 1 To 8 Do
- Begin
-
- C := C * 2;
- SaveC := C;
- C := C AND $FF;
-
- HiCrc := HICrc * 2;
- LoCrc := LOCrc * 2;
-
- If SaveC > 255 Then LoCrc := LoCrc OR 1;
- If LoCrc > 255 Then HiCrc := HiCrc OR 1;
-
- If HiCrc > 255 Then
- Begin
- HiCrc := HiCrc XOR Crc_Poly_High;
- LoCrc := LoCrc XOR Crc_Poly_Low;
- End;
-
- Hicrc := HiCrc AND $FF;
- Locrc := LoCrc AND $FF;
-
- End;
-
- End;
-
- End (* Compute_Crc *);
-
- (*----------------------------------------------------------------------*)
- (* Send_Xmodem_File --- Upload file using XMODEM *)
- (*----------------------------------------------------------------------*)
-
- Procedure Send_Xmodem_File( Use_CRC : Boolean );
-
- (* *)
- (* Procedure: Send_Xmodem_File *)
- (* *)
- (* Purpose: Uploads file to remote host using XMODEM protocol. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Send_Xmodem_File( Use_CRC ); *)
- (* *)
- (* Use_CRC --- TRUE to use Cyclic redundancy check version *)
- (* of XMODEM; FALSE to use Checksum version. *)
- (* *)
- (* Remarks: *)
- (* *)
- (* The file's existence should have been already checked *)
- (* prior to calling this routine. *)
- (* *)
- (* The transmission parameters are automatically set to: *)
- (* *)
- (* Current baud rate, 8 bits, No parity, 1 stop *)
- (* *)
- (* and then they are automatically restored to the previous *)
- (* values when the transfer is complete. *)
- (* *)
- (* Calls: KeyPressed *)
- (* Async_Send *)
- (* Async_Receive *)
- (* Compute_Crc *)
- (* Draw_Menu_Frame *)
- (* Save_Screen *)
- (* Restore_Screen *)
- (* Async_Open *)
- (* *)
-
- Const
- Max_Tries = 10 (* Maximum # of times to try sending *)
- (* a given sector *);
- Var
- I : Integer (* Loop index *);
- Tries : Integer (* # of tries sending current sector *);
- Checksum : Integer (* Sector checksum *);
- HiCrc : Integer (* High byte, cyclic redund. check *);
- LoCrc : Integer (* Low byte, cyclic redund. check *);
- Ch : Integer (* Character received from COM port *);
- Sector_Length : Integer (* # chars to send *);
- OK_Init : Boolean (* Flag for reinitialization of com. *);
- Stop_Send : Boolean (* If user cancels sending of file. *);
- Kbd_Ch : Char (* Absorbs keyboard characters *);
-
- Begin (* Send_Xmodem_File *)
- (* Reset comm. parameters for XMODEM *)
- Xmodem_Bits_Save := Data_Bits;
- Xmodem_Parity_Save := Parity;
- Xmodem_Stop_Save := Stop_Bits;
-
- OK_Init := Async_Open( Comm_Port, Baud_Rate, 'N', 8, 1 );
-
- (* Open display window for transfer *)
- Save_Screen( Saved_Screen );
-
- Draw_Menu_Frame( 15, 10, 68, 21, Menu_Frame_Color,
- Menu_Text_Color,
- 'Send file ' + FileName + ' using XMODEM' );
-
- Window( 16, 11, 67, 20 );
-
- (* Open file to send -- assume OK *)
- Assign( XFile , FileName );
- Reset( XFile );
- (* Determine Sector Size *)
- If Use_Crc Then
- Sector_Length := 130
- Else
- Sector_Length := 129;
-
- (* Sector #s start at 1, wrap at 255 *)
- Sector_Number := 0;
-
- (* Purge buffer before sending *)
- Async_Purge_Buffer;
-
- (* Set TRUE if PgUp pressed *)
- Stop_Send := FALSE;
- (* Loop until done (EOT sent) or too *)
- (* many errors found. *)
- Repeat
- (* See if PgUp hit, ending transfer *)
- If KeyPressed Then
- Begin
- Read( Kbd, Kbd_Ch );
- If Kbd_Ch = CHR( 27 ) Then
- Begin
- Read( Kbd_Ch, Ch );
- Stop_Send := ( ORD( Kbd_Ch ) = 73 );
- End;
- End;
-
- If Stop_Send Then
- Async_Send( CHR( Can ))
- Else
- Begin (* Send the next sextor *)
-
- (* Increment sector number *)
- Sector_Number := Sector_Number + 1;
-
- (* Reset error count to zero *)
- Tries := 0;
- (* Read 128 characters from file to *)
- (* be sent. Note: MSDOS files have *)
- (* a 128 character sector size. *)
-
- Blockread( XFile, Sector_Data, 1 );
-
- (* Compute Checksum or Crc *)
- If Use_Crc Then
- Begin (* Use CRC *)
-
- Sector_Data[ 129 ] := 0;
- Sector_data[ 130 ] := 0;
-
- Compute_Crc( Sector_Data , HiCrc, LoCrc );
-
- Sector_Data[ 129 ] := HiCrc;
- Sector_Data[ 130 ] := LoCrc;
-
- End (* Use CRC *)
- Else
- Begin (* Use Checksum *)
-
- Checksum := 0;
-
- For I := 1 To ( Sector_Size - 2 ) Do
- Checksum := ( Checksum + Sector_Data[ I ] ) MOD 256;
-
- Sector_Data[ 129 ] := Checksum;
-
- End (* Use Checksum *);
-
- (* Begin send loop for this sector. *)
- Repeat
-
- Writeln( 'Sending sector: ', Sector_Number );
-
- Async_Send( CHR ( SOH ) );
- Async_Send( CHR( Sector_Number ) );
- Async_Send( CHR( 255 - Sector_Number ) );
-
- (* Transmit Sector Data *)
-
- For I := 1 To Sector_Length Do
- Async_Send( CHR( Sector_Data[ I ] ) );
-
- (* Increment count of tries to send *)
- (* for this sector. *)
- Tries := Tries + 1;
-
- (* Pick up a character -- should be ACK *)
- Async_Receive_With_Timeout( Ten_Seconds , Ch );
-
- Until ( Ch = ACK ) OR ( Ch = CAN ) OR ( Tries = Max_Tries );
-
-
- End (* Send Next Sector *);
-
- Until ( Eof( XFile ) ) OR ( Tries = Max_Tries ) OR ( Ch = CAN ) OR
- ( Stop_Send );
-
- If Tries = Max_Tries Then (* We failed to send a sector correctly *)
- Writeln('No ACK for sector ', Sector_Number - 1 )
- Else If ( Ch = CAN ) Then (* Receiver cancelled transmission *)
- Writeln('Receiver cancelled transmission.')
- Else If Stop_Send Then (* User cancelled transmission *)
- Writeln('PgUp key hit, transfer cancelled.')
- Else (* We sent everything, now try sending EOT *)
- Begin
-
- Tries := 0;
-
- Repeat
- Async_Send( CHR( EOT ) );
- Tries := Tries + 1;
- Async_Receive_With_Timeout( Ten_Seconds , Ch );
- Until ( Ch = ACK ) OR ( Tries = Max_Tries ) OR ( Ch = CAN );
-
- If Tries = Max_Tries Then
- Writeln('No ACK on EOT (end of transmission)')
- Else If ( Ch = CAN ) Then
- Writeln('Receiver cancelled transmission.')
- Else
- Writeln('EOT acknowledged, transfer complete');
-
- End;
- (* Close transferred file *)
- Close( XFile );
- (* Reset comm parms to saved values *)
-
- OK_Init := Async_Open( Comm_Port, Baud_Rate, Xmodem_Parity_Save,
- Xmodem_Bits_Save, Xmodem_Stop_Save );
-
- (* Remove XMODEM window *)
- Restore_Screen( Saved_Screen );
-
- Reset_Global_Colors;
-
- End (* Send_Xmodem_File *);
-
- (*----------------------------------------------------------------------*)
- (* Receive_Xmodem_File --- Download file using XMODEM *)
- (*----------------------------------------------------------------------*)
-
- Procedure Receive_Xmodem_File( Use_CRC : Boolean );
-
- (* *)
- (* Procedure: Receive_Xmodem_File *)
- (* *)
- (* Purpose: Downloads file from remote host using XMODEM *)
- (* protocol. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Receive_Xmodem_File( Use_CRC ); *)
- (* *)
- (* Use_CRC --- TRUE to use Cyclic redundancy check version *)
- (* of XMODEM; FALSE to use Checksum version. *)
- (* *)
- (* Remarks: *)
- (* *)
- (* The transmission parameters are automatically set to: *)
- (* *)
- (* Current baud rate, 8 bits, No parity, 1 stop *)
- (* *)
- (* and then they are automatically restored to the previous *)
- (* values when the transfer is complete. *)
- (* *)
- (* *)
- (* Calls: KeyPressed *)
- (* Async_Send *)
- (* Async_Receive *)
- (* Compute_Crc *)
- (* *)
-
- Const
- Max_Errors = 10 (* Maximum errors before aborting *)
- (* reception *);
- Var
- Sector_Count : Integer (* Sector count -- no wrap at 255 *);
- Sector_Comp : Byte (* Complement of current sector # *);
- Sector_Prev : Byte (* Previous sector number *);
- I : Integer (* Loop index *);
- Checksum : Integer (* Sector checksum *);
- HiCrc : Integer (* High byte, cyclic redund. check *);
- LoCrc : Integer (* Low byte, cyclic redund. check *);
- Error_count : Integer (* # of errors encountered *);
- Ch : Integer (* Character read from COM port *);
- Error_Flag : Boolean (* If an error is found *);
- Initial_Ch : Integer (* Initial character *);
- Sector_Length : Integer (* Sector Length *);
- Checksum_OK : Boolean (* CRC/Checksum is OK *);
- OK_Init : Boolean (* Flag for reinitialization of com. *);
- Sector_Prev1 : Byte (* Previous sector + 1 *);
- Stop_Receive : Boolean (* TRUE if transfer to be stopped *);
- Kbd_Ch : Char (* Absorbs KeyPressed Characters *);
-
- Begin (* Receive_Xmodem_File *)
-
- (* Reset comm. parameters for XMODEM *)
- Xmodem_Bits_Save := Data_Bits;
- Xmodem_Parity_Save := Parity;
- Xmodem_Stop_Save := Stop_Bits;
-
- OK_Init := Async_Open( Comm_Port, Baud_Rate, 'N', 8, 1 );
-
- (* Open display window for transfer *)
- Save_Screen( Saved_Screen );
-
- Draw_Menu_Frame( 15, 10, 68, 21, Menu_Frame_Color,
- Menu_Text_Color,
- 'Receive file ' + FileName + ' using XMODEM' );
-
- Window( 16, 11, 67, 20 );
- (* Open reception file *)
- Assign( XFile , FileName );
- Rewrite( XFile );
- (* Current sector = 0 *)
- Sector_Number := 0;
- Sector_Count := 0;
- Sector_Prev := 0;
- (* Overall error count = 0 *)
- Error_Count := 0;
- (* Fire up XMODEM *)
- If Use_Crc Then
- Async_Send( 'C' )
- Else
- Async_Send( CHR( NAK ) );
-
- (* User intervention flag *)
- Stop_Receive := FALSE;
-
- Repeat
- (* Reset error flag *)
- Error_flag := FALSE;
- (* Look for SOH *)
- Repeat
-
- Async_Receive_With_Timeout( Twenty_Seconds, Initial_Ch );
-
- If KeyPressed Then
- Begin
- Read( Kbd, Kbd_Ch );
- If Kbd_Ch = CHR( 27 ) Then
- Begin
- Read( Kbd, Kbd_Ch );
- Stop_Receive := ( ORD( Kbd_Ch ) = 81 );
- End;
- End;
-
- Until ( Initial_Ch = SOH ) OR
- ( Initial_Ch = EOT ) OR
- ( Initial_Ch = CAN ) OR
- ( Initial_Ch = TimeOut ) OR
- ( Stop_Receive );
-
- (* KeyBoard input -- send CAN *)
- If Stop_Receive Then
- Begin
- Async_Send( CHR( CAN ) );
- End
- (* Timed out -- no SOH found *)
- Else If Initial_Ch = Timeout Then
- Writeln( 'Error - No starting SOH, reception cancelled.')
-
- (* SOH found -- start of XMODEM block *)
- Else If Initial_Ch = SOH Then
- Begin (* SOH found *)
- (* Pick up sector number *)
-
- Async_Receive_With_Timeout( One_Second , Ch );
- Sector_Number := Ch;
- (* Complement of sector number *)
-
- Async_Receive_With_Timeout( One_Second , Ch );
- Sector_Comp := Ch;
-
- (* See if they add up properly *)
-
- If ( ( Sector_Number + Sector_Comp ) = 255 ) Then
-
- Begin (* Sector number and complement match *)
-
- Sector_Prev1 := Sector_Prev + 1;
-
- If ( Sector_Number = Sector_Prev1 ) Then
-
- Begin (* Correct sector found *)
-
- (* Pick up sector data, calculate *)
- (* checksum or CRC *)
-
- Checksum_OK := False;
-
- For I := 1 to ( Sector_Size - 2 ) Do
- Begin
- Async_Receive_With_Timeout( One_Second , Ch );
- Sector_Data[I] := Ch;
- End;
-
- If Use_Crc Then
- Begin (* Compute CRC *)
-
- Async_Receive_With_Timeout( One_Second , Ch );
- If Ch <> Timeout Then
- Begin
- Sector_Data[ 129 ] := Ch;
- Async_Receive_With_Timeout( One_Second , Ch );
- If Ch <> Timeout Then
- Begin
- Sector_Data[ 130 ] := Ch;
- Compute_Crc( Sector_data , HiCrc, LoCrc );
- Checksum_OK := ( HiCrc = 0 ) AND
- ( LoCrc = 0 );
- End;
- End;
-
- End (* Compute CRC *)
-
- Else
- Begin (* Compute Checksum *)
-
- Checksum := 0;
-
- For I := 1 to ( Sector_Size - 2 ) Do
- Checksum := ( Checksum + Sector_Data[I] ) AND 255;
-
- (* Read sector checksum, see if it matches *)
- (* what we computed from sector read. *)
-
- Async_Receive_With_Timeout( One_Second , Ch );
-
- Checksum_OK := ( Checksum = Ch );
-
- End (* Compute Checksum *);
-
- If Checksum_OK Then
- Begin (* Checksum/CRC OK *)
-
- Blockwrite( XFile, Sector_Data, 1 );
-
- Error_Count := 0;
-
- Sector_Count := Sector_Count + 1;
-
- Writeln('Received sector ',Sector_Count);
-
- Sector_Prev := Sector_Number;
-
- Async_Send( CHR( ACK ) );
-
- End (* Checksum/CRC OK *)
- Else
- Begin (* Checksum/CRC error *)
- If Use_Crc Then
- Writeln('CRC Error --- Hi = ',HiCrc,
- ' Lo = ',LoCrc)
- Else
- Writeln('Checksum Error');
- Error_Flag := TRUE;
- End (* Checksum/CRC error *)
-
- End (* Correct sector found *)
-
- Else
- If ( Sector_Number = Sector_Prev ) Then
- Begin (* Duplicate sector *)
-
- Repeat
- Async_Receive_With_Timeout( One_Second , Ch );
- Until ( Ch = TimeOut );
-
- Writeln('Received duplicate sector ', Sector_Number );
- Async_send( CHR( ACK ) );
-
- End (* Duplicate sector *)
- Else
- Begin
- Writeln('Synchronization error');
- Error_Flag := TRUE;
- End;
-
- End (* Sector # and complement match *)
-
- Else
- Begin (* Sector # and complement do not match *)
- Writeln('Sector number error');
- Error_Flag := TRUE
- End (* Sector # and complement do not match *);
-
- End (* SOH Found *);
-
- If Error_Flag Then
- Begin
- Error_Count := Error_Count + 1;
- Repeat
- Async_Receive_With_Timeout( One_Second , Ch );
- Until ( Ch = TimeOut );
- Async_Send( CHR( NAK ) );
- End;
-
- Until ( Initial_Ch = EOT ) OR
- ( Initial_Ch = TimeOut ) OR
- ( Initial_Ch = CAN ) OR
- ( Stop_Receive ) OR
- ( Error_Count >= Max_Errors );
-
- If ( Initial_Ch = EOT ) AND ( Error_Count < Max_Errors ) Then
- Begin
- Async_Send( CHR( ACK ) );
- Writeln('Transfer complete');
- End
- Else If ( Initial_Ch = CAN ) Then
- Writeln('Transmitter cancelled file transfer.')
- Else If ( Stop_Receive ) Then
- Writeln('PdDn key hit -- reception cancelled.')
- Else
- Writeln('Transfer Cancelled');
-
- (* Close transferred file *)
- Close( XFile );
- (* Reset comm parms to saved values *)
-
- OK_Init := Async_Open( Comm_Port, Baud_Rate, Xmodem_Parity_Save,
- Xmodem_Bits_Save, Xmodem_Stop_Save );
-
- (* Remove XMODEM window *)
- Restore_Screen( Saved_Screen );
-
- Reset_Global_Colors;
-
- End (* Receive_Xmodem_File *) ;
-
- (*----------------------------------------------------------------------*)
- (* Receive_Ascii_File --- Download ASCII file *)
- (*----------------------------------------------------------------------*)
-
- Procedure Receive_Ascii_File;
-
- (* *)
- (* Procedure: Receive_Ascii_File *)
- (* *)
- (* Purpose: Downloads ASCII file to PC *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Receive_Ascii_File; *)
- (* *)
- (* Calls: KeyPressed *)
- (* Async_Send *)
- (* Async_Receive *)
- (* Async_Percentage_Used *)
- (* *)
- (* Remarks: *)
- (* *)
- (* XON/XOFF is assumed to be supported by the host. *)
- (* *)
-
- Var
- Ch : Char;
- Fin : Boolean;
- XOFF_Sent : Boolean (* TRUE if XOFF sent to host *);
- X, Y: Integer;
- N_Xoff: Integer;
- Begin (* Receive_Ascii_File *)
-
- Fin := FALSE;
- XOFF_Sent := FALSE;
- N_Xoff := 0;
-
- Repeat
-
- If Async_Percentage_Used > 0.75 Then
- Begin (* Buffer too full -- send XOFF if we already haven't *)
- If ( NOT XOFF_Sent ) Then
- Begin
- Async_Send( CHR( XOFF ) );
- XOFF_Sent := TRUE;
- X := WhereX;
- Y := WhereY;
- GoToXY( 1 , 25 );
- TextColor( Red );
- Write(' Xoff sent, percentage = ',Async_Percentage_Used );
- TextColor( Yellow );
- GoToXY( X , Y );
- N_Xoff := N_Xoff + 1;
- End
- End (* Buffer too full *)
- Else If Async_Percentage_Used < 0.25 Then
- Begin (* Buffer reasonably empty -- send XON if needed *)
- If XOFF_Sent Then
- Begin
- Async_Send( CHR( XON ) );
- XOFF_Sent := FALSE;
- X := WhereX;
- Y := WhereY;
- GoToXY( 1 , 25 );
- TextColor( Red );
- Write(' Xon sent, percentage = ',Async_Percentage_Used );
- TextColor( Yellow );
- GoToXY( X , Y );
- End;
- End;
-
- If KeyPressed Then
- Begin
- Read( Kbd , Ch );
- If Ch = CHR(27) Then
- Begin
- Read( kbd , Ch );
- If ORD( Ch ) = 81 Then
- Fin := TRUE;
- End
- Else
- Async_Send( Ch );
- End;
-
- If Async_Receive( Ch ) Then
- Begin
- Write( AFile , Ch );
- Write( Ch );
- End;
-
- Until ( Fin );
-
- Save_Screen( Saved_Screen );
-
- Draw_Menu_Frame( 5, 5, 55, 10, Menu_Frame_Color,
- Menu_Text_Color, '' );
-
- Writeln;
- Writeln('Finished receiving ASCII file ',FileName);
- Writeln('Number of XOFFs sent: ',N_Xoff);
- Delay( 2000 );
-
- Close( AFile );
- (* Remove this window *)
- Restore_Screen( Saved_Screen );
-
- Reset_Global_Colors;
-
- End (* Receive_Ascii_File *);
-
- (*----------------------------------------------------------------------*)
- (* Send_Ascii_File --- Upload ASCII file *)
- (*----------------------------------------------------------------------*)
-
- Procedure Send_Ascii_File;
-
- (* *)
- (* Procedure: Send_Ascii_File *)
- (* *)
- (* Purpose: Uploads ASCII file to remote host *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Send_Ascii_File; *)
- (* *)
- (* Calls: KeyPressed *)
- (* Async_Send_String *)
- (* Async_Receive *)
- (* *)
-
- Var
- Ch : Char;
- Fin : Boolean;
- TextLine : String[255];
- Esc_Found : Boolean;
- B : Boolean;
- Pace_Found : Boolean;
-
- Begin (* Send_Ascii_File *)
- (* FIN is true when upload complete *)
- Fin := False;
-
- Repeat
- (* Read a line from the file to upload *)
- Readln( AFile , TextLine );
- TextLine := TextLine + CHR( 13 );
-
- (* If pacing character specified, wait *)
- (* for it to show up from com port *)
- Esc_Found := FALSE;
- Pace_Found := FALSE;
-
- If Pacing_Char <> CHR( NUL ) Then
- Repeat
- If KeyPressed Then
- Begin
- Read( Kbd, Ch );
- If Ch = CHR( 27 ) Then
- Esc_Found := TRUE
- Else
- Async_Send( Ch );
- End;
- If Async_Buffer_Check Then
- Begin
- B := Async_Receive( Ch );
- Write( Ch );
- Pace_Found := ( Ch = Pacing_Char );
- End;
- Until ( Pace_Found OR Esc_Found )
- Else
- Repeat
- If KeyPressed Then
- Begin
- Read( Kbd, Ch );
- If Ch = CHR( 27 ) Then
- Esc_Found := TRUE
- Else
- Async_Send( Ch );
- End;
- If Async_Buffer_Check Then
- Begin
- B := Async_Receive( Ch );
- Write( Ch );
- Pace_Found := ( Ch = CHR( 13 ) );
- End;
- Until ( Pace_Found OR Esc_Found );
-
- (* Check if PgUp hit again -- *)
- (* end transfer if so. *)
- If ( KeyPressed OR Esc_Found ) Then
- Begin
- Read( Kbd , Ch );
- If Ch = CHR( 27 ) Then
- Begin
- Read( Kbd , Ch );
- If ORD( Ch ) = 73 Then
- Fin := TRUE
- Else
- Begin
- Async_Send( CHR( 27 ) );
- Async_Send( Ch );
- End;
- End
- Else
- Async_Send( Ch );
- End;
- (* Send the next line to the host *)
-
- If ( NOT Fin ) Then
- Async_Send_String_With_Delays( TextLine, Char_Delay, Line_Delay );
-
- Until ( Fin OR EOF( AFile ) );
-
- Save_Screen( Saved_Screen );
-
- Draw_Menu_Frame( 5, 5, 55, 10, Menu_Frame_Color,
- Menu_Text_Color, '' );
-
- Writeln;
- Writeln('Finished Sending ASCII file ',FileName);
- Delay( 2000 );
-
- Close( AFile );
-
- (* Remove this window *)
- Restore_Screen( Saved_Screen );
-
- Reset_Global_Colors;
-
- End (* Send_Ascii_File *);
-
- (*----------------------------------------------------------------------*)
- (* DownLoad --- Download a file from a remote host *)
- (*----------------------------------------------------------------------*)
-
- Procedure DownLoad( Transfer_Protocol : Transfer_Type ) ;
-
- (* *)
- (* Procedure: Download *)
- (* *)
- (* Purpose: Controls downloading of files from remote hosts. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* DownLoad( Transfer_Protocol : Transfer_Type ); *)
- (* *)
- (* Transfer_Protocol --- the type of transfer protocol *)
- (* be used. *)
- (* Remarks: *)
- (* *)
- (* Currently, the only available protocols are: *)
- (* *)
- (* Ascii file transfer (no error-correction) *)
- (* Xmodem with Checksum *)
- (* Xmodem with CRC *)
- (* *)
- (* Calls: Receive_Ascii_File *)
- (* Receive_Xmodem_File *)
- (* *)
-
-
- Begin (* DownLoad *)
-
- Case Transfer_Protocol Of
- Ascii: Receive_Ascii_File;
- Xmodem_Chk: Receive_Xmodem_File( FALSE );
- Xmodem_Crc: Receive_Xmodem_File( TRUE );
- Else ;
- End (* Case *);
-
- End (* DownLoad *);
-
- (*----------------------------------------------------------------------*)
- (* UpLoad --- Upload a file to a remote host *)
- (*----------------------------------------------------------------------*)
-
- Procedure UpLoad( Transfer_Protocol : Transfer_Type ) ;
-
- (* *)
- (* Procedure: Upload *)
- (* *)
- (* Purpose: Controls uploading of files to remote hosts. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* UpLoad( Transfer_Protocol : Transfer_Type ); *)
- (* *)
- (* Transfer_Protocol --- the type of transfer protocol *)
- (* be used. *)
- (* Remarks: *)
- (* *)
- (* Currently, the only available protocols are: *)
- (* *)
- (* Ascii file transfer (no error-correction) *)
- (* Xmodem with Checksum *)
- (* Xmodem with CRC *)
- (* *)
- (* Calls: Send_Ascii_File *)
- (* Send_Xmodem_File *)
- (* *)
-
- Begin (* UpLoad *)
-
- Case Transfer_Protocol Of
- Ascii: Send_Ascii_File;
- Xmodem_Chk: Send_Xmodem_File( FALSE );
- Xmodem_Crc: Send_Xmodem_File( TRUE );
- Else ;
- End (* Case *);
-
- If Transfer_Protocol <> None Then Close( AFile );
-
- End (* UpLoad *);
-
- (*----------------------------------------------------------------------*)
- (* Get_File_Transfer_Protocol --- Get File Transfer Protocol *)
- (*----------------------------------------------------------------------*)
-
- Function Get_File_Transfer_Protocol( Transfer_direction: Transfer_Str )
- : Transfer_Type ;
-
- (* *)
- (* Function: Get_File_Transfer_Protocol *)
- (* *)
- (* Purpose: Gets file name and transfer protocol for upload/ *)
- (* download. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Transtyp := Get_File_Transfer_Protocol( Transfer_Direction: *)
- (* Transfer_Str ) : Transfer_Type; *)
- (* *)
- (* *)
- (* Remarks: *)
- (* *)
- (* Calls: KeyPressed *)
- (* Async_Send *)
- (* Async_Receive *)
- (* *)
-
- Var
- Transfer_Kind : Transfer_Type;
- Transfer_Menu : Menu_Type;
- I : Integer;
- Pacing_String : String[1];
-
- Begin (* Get_File_Transfer_Protocol *)
-
- Transfer_Menu.Menu_Size := 3;
- Transfer_Menu.Menu_Default := 1;
- Transfer_Menu.Menu_Row := 11;
- Transfer_Menu.Menu_Column := 20;
- Transfer_Menu.Menu_Tcolor := Menu_Text_Color;
- Transfer_Menu.Menu_Bcolor := BackGround_Color;
- Transfer_Menu.Menu_Fcolor := Menu_Frame_Color;
- Transfer_Menu.Menu_Width := 50;
- Transfer_Menu.Menu_Height := 10;
-
- For I := 1 To 3 Do
- With Transfer_Menu.Menu_Entries[I] Do
- Begin
- Menu_Item_Row := I;
- Menu_Item_Column := 2;
- Case I Of
- 1: Menu_Item_Text := 'Ascii';
- 2: Menu_Item_Text := 'Xmodem (Checksum)';
- 3: Menu_Item_Text := 'Xmodem (CRC)';
- End (* Case *);
- End;
-
- Transfer_Menu.Menu_Title := 'Choose file transfer protocol for ' +
- Transfer_Direction + ':';
-
- Menu_Display_Choices( Transfer_Menu );
- Transfer_Kind := Transfers[ Menu_Get_Choice( Transfer_Menu ,
- Dont_Erase_Menu ) ];
-
- GoToXY( 2 , 5 );
- Write('Filename.Ext ? ');
- Readln(FileName);
-
- Assign(AFile,FileName);
- If Transfer_direction[1] = 'r' Then
- (*$I- *)
- Rewrite(AFile)
- (*$I+ *)
- Else
- (*$I- *)
- Reset(AFile);
- (*$I+ *)
-
- If IOResult <> 0 Then
- Begin
- Transfer_Kind := None;
- Case Transfer_Direction[1] Of
- 'r' : Writeln('*** Can''t open output file, download cancelled ***');
- 's' : Writeln('*** File to send doesn''t exist, upload cancelled ***');
- End (* Case *);
- End;
-
- (* Get delays for Ascii transfers *)
- Char_Delay := 0;
- Line_Delay := 0;
-
- Case Transfer_Kind Of
-
- Xmodem_Crc,
- Xmodem_Chk : Close( AFile );
-
- Ascii : If Transfer_Direction[1] = 's' Then
- Begin
- GoToXY( 2 , 6 );
- Write('Delay between characters (milliseconds)? ');
- Readln( Char_Delay );
- GoToXY( 2 , 7 );
- Write('Delay between lines (milleseconds)? ');
- Readln( Line_Delay );
- GoToXY( 2 , 8 );
- Write('Pacing character? ');
- Readln( Pacing_String );
- If LENGTH( Pacing_String ) > 0 Then
- Pacing_Char := Pacing_String[1]
- Else
- Pacing_Char := CHR( NUL );
- GoToXY( 2 , 9 );
- Write('Sending file ', FileName );
- GoToXY( 2 , 10 );
- Write('Hit PgUp to stop transfer.');
- Delay( 3000 );
- End
- Else
- Begin
- GoToXY( 2 , 6 );
- Write('Receiving file ', FileName );
- GoToXY( 2 , 7 );
- Write('Hit PgUp to stop transfer.');
- Delay( 3000 );
- End;
-
- None : ;
-
- End (* Case *);
-
- (* Return transfer protocol type *)
- Get_File_Transfer_Protocol := Transfer_Kind;
-
- Delay( 3000 );
- (* Remove this window *)
- Restore_Screen( Saved_Screen );
-
- Reset_Global_Colors;
-
- End (* Get_File_Transfer_Protocol *);