home *** CD-ROM | disk | FTP | other *** search
- (*----------------------------------------------------------------------*)
- (* Send_Modem7_File --- Upload file with Modem7/Telink *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Send_Modem7_File( Use_CRC: BOOLEAN );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Send_Modem7_File *)
- (* *)
- (* Purpose: Uploads file using Modem7/Telink batch *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Send_Modem7_File( Use_CRC: BOOLEAN); *)
- (* *)
- (* Use_CRC --- TRUE to use CRC checking; *)
- (* FALSE to use Checksum checking. *)
- (* *)
- (* Calls: KeyPressed *)
- (* Async_Send *)
- (* Async_Receive_With_TimeOut *)
- (* Get_Modem7_File_Name *)
- (* Check_KeyBoard *)
- (* RvsVideoOn *)
- (* RvsVideoOff *)
- (* Wait_For_Nak *)
- (* Send_File_Name *)
- (* Perform_Upload *)
- (* *)
- (* Remarks: *)
- (* *)
- (* This routine performs wildcard directory searches and *)
- (* implements the Modem7 and Telink batch file transfer *)
- (* protocols. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- File_Pattern : AnyStr;
- SFileName : PACKED ARRAY[1..11] OF CHAR;
- Int_Ch : INTEGER;
- Ch : CHAR;
- CheckSum : INTEGER;
- EndFName : BOOLEAN;
- I : INTEGER;
- J : INTEGER;
- Local_Save : Saved_Screen_Ptr;
- Tname : STRING[10];
- File_Entry : Directory_Record;
- Ack_OK : BOOLEAN;
- OK_File : BOOLEAN;
- Batch_Title : AnyStr;
-
- (*----------------------------------------------------------------------*)
- (* Check_KeyBoard --- Check for keyboard input *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Check_KeyBoard;
-
- BEGIN (* Check_KeyBoard *)
- (* If Alt_R found, stop transfer *)
- IF KeyPressed THEN
- BEGIN
-
- READ( Kbd, Ch );
-
- IF ( Ch = CHR( ESC ) ) AND KeyPressed THEN
- BEGIN
- READ( Kbd, Ch );
- IF ORD( Ch ) = Alt_S THEN
- BEGIN
- Stop_Send := TRUE;
- WRITELN(' Alt_S accepted, transfer cancelled.');
- END;
- END;
-
- END;
-
- END (* Check_KeyBoard *);
-
- (*----------------------------------------------------------------------*)
- (* Make_Telink_Header --- Send special TELINK header block *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Make_Telink_Header;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Make_Telink_Header *)
- (* *)
- (* Purpose: Makes special TELINK header block *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Make_Telink_Header; *)
- (* *)
- (* Calls: None *)
- (* *)
- (* Remarks: *)
- (* *)
- (* The Telink header block is ALWAYS sent in Checksum mode, *)
- (* regardless of whether or not the files are to be sent in *)
- (* CRC or checksum mode. *)
- (* *)
- (* Format of Telink block: *)
- (* *)
- (* Bytes Contents *)
- (* ----- --------------------------------------- *)
- (* *)
- (* 1 SYN *)
- (* 2 0 *)
- (* 3 255 *)
- (* 4-7 File size in MS DOS directory form *)
- (* 8-9 Creation date in MS DOS form *)
- (* 10-11 Creation time in MS DOS form *)
- (* 12-27 Name of file in 'name.ext' form *)
- (* 28 Version number (always zero here) *)
- (* 29-44 PIBTERM -- sending program's name *)
- (* 45-131 All zeroes *)
- (* 132 Checksum of block *)
- (* *)
- (* The first three bytes are added later by the Xmodem send *)
- (* routine. The rest are constructed here. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- I : INTEGER;
- J : INTEGER;
- L : INTEGER;
- CheckSum : INTEGER;
- ACK_Ok : BOOLEAN;
- Int_Ch : INTEGER;
-
- BEGIN (* Make_Telink_Header *)
- (* Zero out block *)
- FOR I := 1 TO 130 DO
- Sector_Data[I] := 0;
- (* File size in 32-bit MS DOS form *)
-
- Sector_Data[1] := LO( File_Entry.File_Size[1] );
- Sector_Data[2] := HI( File_Entry.File_Size[1] );
- Sector_Data[3] := LO( File_Entry.File_Size[2] );
- Sector_Data[4] := HI( File_Entry.File_Size[2] );
-
- (* Creation date in MS DOS form *)
-
- Sector_Data[5] := LO( File_Entry.File_Time );
- Sector_Data[6] := HI( File_Entry.File_Time );
-
- (* Creation time in MS DOS form *)
-
- Sector_Data[7] := LO( File_Entry.File_Date );
- Sector_Data[8] := HI( File_Entry.File_Date );
-
- (* File name *)
- L := LENGTH( FileName );
-
- FOR I := 1 TO L DO
- Sector_Data[I+8] := ORD( FileName[I] );
-
- FOR I := ( L + 1 ) TO 16 DO
- Sector_Data[I+8] := ORD(' ');
-
- (* Sending program's name *)
- FOR I := 1 TO 16 DO
- Sector_Data[I+25] := ORD( COPY( 'PIBTERM ', I, 1 ) );
-
- (* Compute checksum *)
- CheckSum := 0;
-
- FOR I := 1 TO 128 DO
- CheckSum := ( CheckSum + Sector_Data[I] ) AND 255;
-
- Sector_Data[129] := CheckSum;
-
- END (* Make_Telink_Header *);
-
- (*----------------------------------------------------------------------*)
- (* Get_Modem7_File_Name --- Construct file name to MODEM7 form *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Get_Modem7_File_Name( VAR OK_File : BOOLEAN );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Remarks: *)
- (* *)
- (* The filename for Modem7 is 11 characters long. The filename *)
- (* is left-justified and blank-filled in the first 8 characters. *)
- (* The extension appears left-justified and blank-filled in *)
- (* positions 9 through 11. *)
- (* *)
- (* Examples: *)
- (* 12345678901 *)
- (* 'root.dat' becomes: root dat *)
- (* 'root' becomes: root *)
- (* *)
- (* Note that the checksum INCLUDES the terminating Ctrl-z (SUB) *)
- (* character of the file name. *)
- (* *)
- (* In host mode, a check is made to ensure that the file to be *)
- (* sent is on the transfer list. If not, it is not sent. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Get_Modem7_File_Name *)
-
- I := 1;
- J := 0;
- SFileName := ' ';
- FileName := '';
-
- WHILE( File_Entry.File_Name[I] <> CHR( 0 ) ) AND ( I <= 12 ) DO
- BEGIN
-
- Ch := File_Entry.File_Name[I];
-
- IF Ch = '.' THEN
- J := 8
- ELSE
- BEGIN
- J := J + 1;
- SFileName[J] := Ch;
- END;
-
- FileName := FileName + Ch;
-
- I := I + 1;
-
- END;
- (* Get checksum *)
- CheckSum := 0;
-
- FOR I := 1 TO 11 DO
- CheckSum := ( CheckSum + ORD( SFileName[I] ) ) AND 255;
-
- CheckSum := ( CheckSum + SUB ) AND 255;
-
- OK_File := ( File_Entry.File_Attr AND
- ( Dir_Attr_Volume_Label + Dir_Attr_Subdirectory ) = 0 );
-
- (* If host mode, make sure file *)
- (* is on xferlist! *)
- IF Host_Mode THEN
- OK_File := Scan_Xfer_List( FileName );
-
- END (* Get_Modem7_File_Name *);
-
- (*----------------------------------------------------------------------*)
- (* Wait_For_Nak --- Wait for NAK at start of file name *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Wait_For_Nak;
-
- BEGIN (* Wait_For_Nak *)
-
- I := 0;
- (* Wait up to minute for NAK *)
- REPEAT
- Async_Receive_With_Timeout( One_Second , Int_Ch );
- Check_KeyBoard;
- I := I + 1;
- UNTIL ( Int_Ch = NAK ) OR
- ( I >= 60 ) OR
- Stop_Send;
-
- IF ( Int_Ch <> NAK ) THEN
- BEGIN
- Stop_Send := TRUE;
- WRITELN(' NAK for start of file name not received;');
- WRITELN(' Received Ascii ',Int_Ch,' instead.');
- END
- ELSE (* If NAK found, ACK it *)
- BEGIN
- WRITELN(' NAK for start of file name received.');
- Async_Send( CHR( ACK ) );
- END;
- (* Wait for com line to clear *)
- Async_Purge_Buffer;
-
- END (* Wait_For_Nak *);
-
- (*----------------------------------------------------------------------*)
- (* Send_File_Name --- Send file name characters *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Send_File_Name;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Remarks: *)
- (* *)
- (* The file name characters are sent one at a time. After *)
- (* each is sent, we wait for an ACK. To end the file name *)
- (* we send an SUB (ctrl-z) character. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Send_File_Name *)
-
- I := 0;
-
- WHILE( NOT Stop_Send ) AND ( I < 11 ) DO
- BEGIN
-
- I := I + 1;
-
- Async_Send( SFileName[I] );
-
- Async_Receive_With_TimeOut( Ten_Seconds , Int_Ch );
-
- Ack_OK := ( Int_Ch = ACK );
-
- Check_KeyBoard;
-
- Stop_Send := Stop_Send OR ( NOT Ack_OK );
-
- END;
- (* Send End of file name character *)
- (* and await receiver to send *)
- (* checksum. *)
- IF NOT Stop_Send THEN
- BEGIN
-
- Async_Send( CHR( SUB ) );
-
- Async_Receive_With_TimeOut( Ten_Seconds , Int_Ch );
-
- IF ( Int_Ch <> CheckSum ) THEN
- BEGIN
- Stop_Send := TRUE;
- WRITELN(' Received checksum for filename not correct;');
- WRITELN(' Correct checksum = ',CheckSum,', received ',Int_Ch);
- END
- ELSE
- Async_Send( CHR( ACK ) );
-
- END;
-
- END (* Send_File_Name *);
-
- (*----------------------------------------------------------------------*)
- (* Perform_Upload --- Do the upload *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Perform_Upload;
-
- BEGIN (* Perform_Upload *)
-
- Writelne(' Uploading: ' + FileName , TRUE );
-
- IF Transfer_Protocol = Telink THEN
- Make_Telink_Header;
-
- IF ( NOT Stop_Send ) THEN
- Send_Xmodem_File( Use_CRC );
-
- TextColor( Menu_Text_Color );
-
- END (* Perform_Upload *);
-
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Send_Modem7_File *)
- (* Open display window for transfers *)
- Save_Screen( Local_Save );
-
- CASE Transfer_Protocol OF
- Telink : Tname := 'Telink';
- Modem7_Chk : Tname := 'Modem7 (Checksum)';
- Modem7_CRC : Tname := 'Modem7 (CRC)';
- END (* CASE *);
-
- (* Always CRC for Telink *)
-
- Use_CRC := Use_CRC OR ( Transfer_Protocol = Telink );
-
- Batch_Title := 'Batch file upload using ' + Tname;
-
- Draw_Menu_Frame( 2, 2, 79, 24, Menu_Frame_Color,
- Menu_Text_Color, Batch_Title );
-
- Writelne( Batch_Title , FALSE );
-
- Window( 3, 3, 78, 23 );
- (* Get file name pattern to send *)
- File_Pattern := FileName;
- (* See if we can find anything to *)
- (* be sent. *)
-
- Stop_Send := ( Dir_Find_First_File( File_Pattern, File_Entry ) <> 0 );
-
- IF Stop_Send THEN
- WRITELN(' No files found to send.');
-
- (* Loop over file names *)
- WHILE( NOT Stop_Send ) DO
- BEGIN
- (* Get file name *)
-
- Get_Modem7_File_Name( OK_File );
-
- (* If file can be sent, do it *)
- IF OK_File THEN
- BEGIN
- (* Wait for NAK indicating host *)
- (* is ready for the file name. *)
- IF NOT Stop_Send THEN
- Wait_For_Nak;
- (* Send file name characters *)
- IF NOT Stop_Send THEN
- Send_File_Name;
- (* Send the file itself *)
- IF NOT Stop_Send THEN
- Perform_Upload;
-
- END;
- (* See if more files to transfer *)
-
- Stop_Send := Stop_Send OR ( Dir_Find_Next_File( File_Entry ) <> 0 );
-
- END (* While *);
-
- (* Purge reception *)
- REPEAT
- Async_Receive_With_Timeout( One_Second , Int_Ch );
- UNTIL ( Int_Ch = TimeOut );
- (* Send EOT to indicate no more files *)
- Async_Send( CHR( EOT ) );
- (* Wait for ACK *)
-
- Async_Receive_With_TimeOut( Ten_Seconds , Int_Ch );
-
- IF ( Int_Ch = ACK ) THEN
- BEGIN
- Writelne(' ', TRUE);
- Writelne(' Host system ACKnowledged EOT.', TRUE);
- END;
- (* Indicate end of transfer *)
- Writelne(' ', TRUE);
-
- RvsVideoOn ( Menu_Text_Color, BackGround_Color );
-
- Writelne(' Batch transfer complete.' , TRUE);
-
- RvsVideoOff( Menu_Text_Color, BackGround_COlor );
-
- DELAY( Two_Second_Delay );
- (* Remove batch transfer window *)
- Restore_Screen( Local_Save );
-
- Reset_Global_Colors;
-
- END (* Send_Modem7_File *);
- ə