home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / pibterm / pibt41s4.arc / XMODCOMO.MOD < prev    next >
Encoding:
Text File  |  1988-03-06  |  19.6 KB  |  644 lines

  1. VAR
  2.    Alt_S_Pressed     : BOOLEAN     (* TRUE if Alt_S entered             *);
  3.    Alt_R_Pressed     : BOOLEAN     (* TRUE if Alt_R entered             *);
  4.    Sending_Files     : BOOLEAN     (* TRUE if sending file(s)           *);
  5.    Menu_Title        : AnyStr      (* Title for transfer                *);
  6.    Menu_Length       : INTEGER     (* # of rows in transfer display     *);
  7.    XFile_Name        : AnyStr      (* Full file name including path     *);
  8.    Blocks_To_Send    : LONGINT     (* Number of blocks to send          *);
  9.    Time_To_Send      : LONGINT     (* Time in seconds to transfer file  *);
  10.    Saved_Time_To_Send: LONGINT     (* Time in seconds to transfer file  *);
  11.    Start_Time        : LONGINT     (* Starting time of transfer         *);
  12.    End_Time          : LONGINT     (* Ending time of transfer           *);
  13.    Time_Per_Block    : LONGINT     (* Time for one block                *);
  14.    CRC_Used          : BOOLEAN     (* TRUE if CRC used                  *);
  15.    Display_Time      : BOOLEAN     (* Display time remaining for trans. *);
  16.    Transfer_Protocol : Transfer_Type   (* Protocol for transfer         *);
  17.    Do_Acks           : BOOLEAN     (* TRUE to send ACKs for blocks      *);
  18.  
  19. (* STRUCTURED *) CONST
  20.    Days_Per_Month : ARRAY[1..12] OF BYTE
  21.                     = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
  22.  
  23. (*----------------------------------------------------------------------*)
  24. (*             Cancel_Transfer --- Cancel transfer                      *)
  25. (*----------------------------------------------------------------------*)
  26.  
  27. PROCEDURE Cancel_Transfer;
  28.  
  29. BEGIN (* Cancel_Transfer *)
  30.                                    (* Purge reception unless G protocol *)
  31.    IF Do_Acks THEN
  32.       Async_Purge_Buffer;
  33.                                    (* Send five cancels, then five *)
  34.                                    (* backspaces.                  *)
  35.    Async_Send( CHR( CAN ) );
  36.    Async_Send( CHR( CAN ) );
  37.    Async_Send( CHR( CAN ) );
  38.    Async_Send( CHR( CAN ) );
  39.    Async_Send( CHR( CAN ) );
  40.  
  41.    Async_Send( CHR( BS  ) );
  42.    Async_Send( CHR( BS  ) );
  43.    Async_Send( CHR( BS  ) );
  44.    Async_Send( CHR( BS  ) );
  45.    Async_Send( CHR( BS  ) );
  46.  
  47.    Write_Log('Transfer cancelled.' , TRUE, FALSE );
  48.  
  49. END   (* Cancel_Transfer *);
  50.  
  51. (*----------------------------------------------------------------------*)
  52. (*   Initialize_Receive_Display --- Set up display of Xmodem reception  *)
  53. (*----------------------------------------------------------------------*)
  54.  
  55. PROCEDURE Initialize_Receive_Display;
  56.  
  57. BEGIN (* Initialize_Receive_Display *)
  58.  
  59.    TextColor( Menu_Text_Color_2 );
  60.  
  61.    GoToXY( 1 , 1 );
  62.    WRITE(' Blocks received      :');
  63.    ClrEol;
  64.  
  65.    GoToXY( 1 , 2 );
  66.    WRITE(' Block length errors  :');
  67.    ClrEol;
  68.  
  69.    GoToXY( 1 , 3 );
  70.    WRITE(' SOH errors           :');
  71.    ClrEol;
  72.  
  73.    GoToXY( 1 , 4 );
  74.    WRITE(' Block number errors  :');
  75.    ClrEol;
  76.  
  77.    GoToXY( 1 , 5 );
  78.    WRITE(' Complement errors    :');
  79.    ClrEol;
  80.  
  81.    GoToXY( 1 , 6 );
  82.    WRITE(' Timeout errors       :');
  83.    ClrEol;
  84.  
  85.    GoToXY( 1 , 7 );
  86.    WRITE(' Resend block errors  :');
  87.    ClrEol;
  88.  
  89.    GoToXY( 1 , 8 );
  90.  
  91.    IF ( NOT CRC_Used ) THEN
  92.       WRITE(' Checksum errors      :')
  93.    ELSE
  94.       WRITE(' CRC errors           :');
  95.  
  96.    ClrEol;
  97.  
  98.    GoToXY( 1 , 9 );
  99.  
  100.    IF Display_Time THEN
  101.       WRITE(' Approx. time left    :')
  102.    ELSE
  103.       WRITE(' ');
  104.  
  105.    ClrEol;
  106.  
  107.    GoToXY( 1 , 10 );
  108.    WRITE  (' Last status message  :');
  109.    ClrEol;
  110.  
  111.    TextColor( Menu_Text_Color );
  112.  
  113. END   (* Initialize_Receive_Display *);
  114.  
  115. (*----------------------------------------------------------------------*)
  116. (*        Initialize_Send_Display --- initialize send status display    *)
  117. (*----------------------------------------------------------------------*)
  118.  
  119. PROCEDURE Initialize_Send_Display;
  120.  
  121. BEGIN (* Initialize_Send_Display *)
  122.  
  123.    TextColor( Menu_Text_Color_2 );
  124.    WRITE  (' Blocks to send        : ');
  125.    TextColor( Menu_Text_Color   );
  126.    WRITE  ( Blocks_To_Send );
  127.    GoToXY( 35 , WhereY );
  128.    WRITE  ( Blocks_To_Send SHR 3, 'K' );
  129.    WRITELN;
  130.  
  131.    TextColor( Menu_Text_Color_2 );
  132.    WRITE  (' Approx. transfer time : ');
  133.    TextColor( Menu_Text_Color );
  134.    WRITELN( TimeString( Time_To_Send , Military_Time ) );
  135.    WRITELN(' ');
  136.  
  137.    TextColor( Menu_Text_Color_2 );
  138.    WRITELN(' Sending block         : ');
  139.    WRITELN(' Errors                : ');
  140.    WRITE  (' Time remaining        : ');
  141.  
  142.    TextColor( Menu_Text_Color );
  143.    WRITELN(TimeString( Time_To_Send , Military_Time ) );
  144.    WRITELN(' ');
  145.  
  146.    TextColor( Menu_Text_Color_2 );
  147.    WRITE  (' Last status message   : ');
  148.  
  149.    TextColor( Menu_Text_Color );
  150.  
  151. END   (* Initialize_Send_Display *);
  152.  
  153. (*----------------------------------------------------------------------*)
  154. (*   Get_Transfer_Name  --- Get transfer name for display window        *)
  155. (*----------------------------------------------------------------------*)
  156.  
  157. FUNCTION Get_Transfer_Name( Transfer_Protocol : Transfer_Type ) : ShortStr;
  158.  
  159. VAR
  160.    TName : ShortStr;
  161.  
  162. BEGIN (* Get_Transfer_Name *)
  163.  
  164.    CASE Transfer_Protocol OF
  165.       Xmodem_Chk   : TName := 'Xmodem (Checksum)';
  166.       Xmodem_Crc   : TName := 'Xmodem (CRC)';
  167.       Telink       : TName := 'Telink';
  168.       Modem7_Chk   : TName := 'Modem7 (Checksum)';
  169.       Modem7_CRC   : TName := 'Modem7 (CRC)';
  170.       Xmodem_1K    : TName := 'Xmodem 1K';
  171.       Xmodem_1KG   : TName := 'Xmodem 1K G';
  172.       Ymodem_Batch : TName := 'Ymodem Batch';
  173.       Ymodem_G     : TName := 'Ymodem G Batch';
  174.    END (* CASE *);
  175.  
  176.    Get_Transfer_Name := TName;
  177.  
  178. END   (* Get_Transfer_Name *);
  179.  
  180. (*----------------------------------------------------------------------*)
  181. (*   Display_Batch_Transfer_Window --- Display batch transfer window    *)
  182. (*----------------------------------------------------------------------*)
  183.  
  184. PROCEDURE Display_Batch_Window;
  185.  
  186. (*----------------------------------------------------------------------*)
  187. (*                                                                      *)
  188. (*     Procedure:  Display_Batch_Window;                                *)
  189. (*                                                                      *)
  190. (*     Purpose:    Initializes display for batch transfer window        *)
  191. (*                                                                      *)
  192. (*     Calling Sequence:                                                *)
  193. (*                                                                      *)
  194. (*        Display_Batch_Window                                          *)
  195. (*                                                                      *)
  196. (*----------------------------------------------------------------------*)
  197.  
  198. VAR
  199.    TName       : ShortStr;
  200.    Batch_Title : AnyStr;
  201.    Direction   : ShortStr;
  202.  
  203. BEGIN (* Display_Batch_Window *)
  204.                                    (* Save current screen image *)
  205.    Save_Screen( Batch_Screen_Ptr );
  206.                                    (* Construct title based upon *)
  207.                                    (* transfer type              *)
  208.  
  209.    TName := Get_Transfer_Name( Transfer_Protocol );
  210.  
  211.                                    (* Draw menu frame            *)
  212.  
  213.    IF Sending_Files THEN
  214.       Direction := 'send'
  215.    ELSE
  216.       Direction := 'receive';
  217.  
  218.    Batch_Title := 'Batch file ' + Direction + ' using ' + TName;
  219.  
  220.    Draw_Menu_Frame( 2, 2, 79, 24, Menu_Frame_Color, Menu_Title_Color,
  221.                     Menu_Text_Color, Batch_Title );
  222.  
  223.    Write_Log( Batch_Title , FALSE , FALSE );
  224.  
  225.    PibTerm_Window( 3, 3, 78, 23 );
  226.  
  227. END   (* Display_Batch_Window *);
  228.  
  229. (*----------------------------------------------------------------------*)
  230. (*        Flip_Display_Status --- turn status display on/off            *)
  231. (*----------------------------------------------------------------------*)
  232.  
  233. PROCEDURE Flip_Display_Status;
  234.  
  235. BEGIN (* Flip_Display_Status *)
  236.  
  237.    CASE Display_Status OF
  238.  
  239.       TRUE:   BEGIN
  240.                                    (* Indicate no display   *)
  241.  
  242.                  Display_Status := FALSE;
  243.  
  244.                                    (* Remove XMODEM window  *)
  245.  
  246.                  Restore_Screen( Saved_Screen );
  247.  
  248.                                    (* Remove batch transfer window *)
  249.  
  250.                  Restore_Screen( Batch_Screen_Ptr );
  251.  
  252.                                    (* Turn cursor back on *)
  253.                  CursorOn;
  254.  
  255.               END;
  256.  
  257.       FALSE:  BEGIN
  258.                                    (* Indicate display will be done *)
  259.  
  260.                  Display_Status := TRUE;
  261.  
  262.                                    (* Turn cursor off *)
  263.                  CursorOff;
  264.  
  265.                                    (* Initialize batch transfer display *)
  266.                                    (* if needed.                        *)
  267.  
  268.                  IF ( NOT Single_File_Protocol[Transfer_Protocol] ) THEN
  269.                     Display_Batch_Window;
  270.  
  271.                                    (* Save screen image *)
  272.  
  273.                  Save_Screen( Saved_Screen );
  274.  
  275.                                    (* Set up transfer display box *)
  276.  
  277.                  Draw_Menu_Frame( 10, 10, 78, Menu_Length,
  278.                                   Menu_Frame_Color,
  279.                                   Menu_Title_Color,
  280.                                   Menu_Text_Color,
  281.                                   Menu_Title );
  282.  
  283.                  PibTerm_Window( 11, 11, 77, PRED( Menu_Length ) );
  284.  
  285.                                    (* Set up titles *)
  286.  
  287.                  CASE Sending_Files OF
  288.                     TRUE:   Initialize_Send_Display;
  289.                     FALSE:  Initialize_Receive_Display;
  290.                  END (* CASE *);
  291.  
  292.               END;
  293.  
  294.    END (* CASE *);
  295.  
  296. END   (* Flip_Display_Status *);
  297.  
  298. (*----------------------------------------------------------------------*)
  299. (*         Check_Keyboard_Input --- Check for keyboard input            *)
  300. (*----------------------------------------------------------------------*)
  301.  
  302. PROCEDURE Check_Keyboard;
  303.  
  304. VAR
  305.    Kbd_Ch : CHAR;
  306.  
  307. BEGIN (* Check_Keyboard *)
  308.                                    (* Check for keyboard input *)
  309.    WHILE PibTerm_KeyPressed DO
  310.       BEGIN
  311.  
  312.          Read_Kbd( Kbd_Ch );
  313.  
  314.          IF ( Kbd_Ch = CHR( ESC ) ) THEN
  315.             IF PibTerm_KeyPressed THEN
  316.                BEGIN
  317.                   Read_Kbd( Kbd_Ch );
  318.                   CASE ORD( Kbd_Ch ) OF
  319.                      Alt_R     : Alt_R_Pressed := TRUE;
  320.                      Alt_S     : Alt_S_Pressed := TRUE;
  321.                      Shift_Tab : Flip_Display_Status;
  322.                      ELSE        Handle_Function_Key( Kbd_Ch );
  323.                   END (* CASE *);
  324.                   Stop_Receive   := Stop_Receive OR Alt_R_Pressed;
  325.                   Stop_Send      := Stop_Send    OR Alt_S_Pressed;
  326.                END
  327.            ELSE
  328.                IF Async_XOff_Received THEN
  329.                   Clear_XOFF_Received;
  330.  
  331.       END;
  332.  
  333. END   (* Check_Keyboard *);
  334.  
  335. (*----------------------------------------------------------------------*)
  336. (*         Get_Xmodem_Titles --- Get title for Xmodem transfer          *)
  337. (*----------------------------------------------------------------------*)
  338.  
  339. PROCEDURE Get_Xmodem_Titles;
  340.  
  341. VAR
  342.    Direction : ShortStr;
  343.    TName     : ShortStr;
  344.  
  345. BEGIN (* Get_Xmodem_Titles *)
  346.                                    (* Open display window for transfer  *)
  347.    Save_Screen( Saved_Screen );
  348.                                    (* Hide cursor *)
  349.    CursorOff;
  350.                                    (* Get protocol name *)
  351.  
  352.    TName := Get_Transfer_Name( Transfer_Protocol );
  353.  
  354.    IF Sending_Files THEN
  355.       BEGIN
  356.          Direction   := 'Send ';
  357.          Menu_Length := 19;
  358.       END
  359.    ELSE
  360.       BEGIN
  361.          Direction   := 'Receive ';
  362.          Menu_Length := 22;
  363.       END;
  364.  
  365.    IF FileName = '' THEN
  366.       Menu_Title := Direction + 'file using ' + TName
  367.    ELSE
  368.       Menu_Title := Direction + 'file ' + XFile_Name + ' using ' + TName;
  369.  
  370.    Draw_Menu_Frame( 10, 10, 78, Menu_Length, Menu_Frame_Color,
  371.                     Menu_Title_Color,
  372.                     Menu_Text_Color, Menu_Title );
  373.  
  374.    Write_Log( Menu_Title, FALSE, FALSE );
  375.  
  376.    PibTerm_Window( 11, 11, 77, PRED( Menu_Length ) );
  377.  
  378. END   (* Get_Xmodem_Titles *);
  379.  
  380. (*----------------------------------------------------------------------*)
  381. (*      Save_Comm_For_Xmodem --- Save and reset comm parms for Xmodem   *)
  382. (*----------------------------------------------------------------------*)
  383.  
  384. PROCEDURE Save_Comm_For_Xmodem;
  385.  
  386. BEGIN (* Save_Comm_For_Xmodem *)
  387.                                    (* Set comm. parms to 8,n,1 *)
  388.  
  389.    Xmodem_Bits_Save   := Data_Bits;
  390.    Xmodem_Parity_Save := Parity;
  391.  
  392.    IF ( Data_Bits <>  8  ) OR
  393.       ( Parity    <> 'N' ) THEN
  394.          BEGIN
  395.             Parity    := 'N';
  396.             Data_Bits := 8;
  397.             Async_Reset_Port( Comm_Port, Baud_Rate, Parity, Data_Bits, Stop_Bits );
  398.          END;
  399.  
  400.                                    (* Reset status line *)
  401.    IF Do_Status_Line THEN
  402.       BEGIN
  403.          Set_Status_Line_Name( Short_Terminal_Name );
  404.          Write_To_Status_Line( Status_Line_Name, 1 );
  405.       END;
  406.  
  407. END   (* Save_Comm_For_Xmodem *);
  408.  
  409. (*----------------------------------------------------------------------*)
  410. (*      Restore_Comm_For_Xmodem --- Restore comm parms after Xmodem     *)
  411. (*----------------------------------------------------------------------*)
  412.  
  413. PROCEDURE Restore_Comm_For_Xmodem;
  414.  
  415. BEGIN (* Restore_Comm_For_Xmodem *)
  416.  
  417.                                    (* Reset comm parms to saved values *)
  418.  
  419.    IF ( Xmodem_Bits_Save   <>  8  ) OR
  420.       ( Xmodem_Parity_Save <> 'N' ) THEN
  421.          BEGIN
  422.             Parity    := Xmodem_Parity_Save;
  423.             Data_Bits := Xmodem_Bits_Save;
  424.             Async_Reset_Port( Comm_Port, Baud_Rate, Parity,
  425.                               Data_Bits, Stop_Bits );
  426.          END;
  427.  
  428.                                    (* Reset status line *)
  429.    IF Do_Status_Line THEN
  430.       BEGIN
  431.          Set_Status_Line_Name( Short_Terminal_Name );
  432.          Write_To_Status_Line( Status_Line_Name, 1 );
  433.       END;
  434.  
  435. END   (* Restore_Comm_For_Xmodem *);
  436.  
  437. (*----------------------------------------------------------------------*)
  438. (*           Get_Unix_Style_Date --- Get date in Unix style             *)
  439. (*----------------------------------------------------------------------*)
  440.  
  441. PROCEDURE Get_Unix_Style_Date(     Date  : LONGINT;
  442.                                VAR Year  : WORD;
  443.                                VAR Month : WORD;
  444.                                VAR Day   : WORD;
  445.                                VAR Hour  : WORD;
  446.                                VAR Mins  : WORD;
  447.                                VAR Secs  : WORD );
  448.  
  449. CONST
  450.    Secs_Per_Year      = 31536000;
  451.    Secs_Per_Leap_Year = 31622400;
  452.    Secs_Per_Day       = 86400;
  453.    Secs_Per_Hour      = 3600;
  454.    Secs_Per_Minute    = 60;
  455.  
  456. VAR
  457.    RDate     : LONGINT;
  458.    T         : LONGINT;
  459.  
  460. BEGIN (* Get_Unix_Style_Date *)
  461.  
  462.    Year  := 1970;
  463.    Month := 1;
  464. {
  465.    IF ( Transfer_Protocol <> SEALink ) THEN
  466.       RDate := Date - GMT_Difference * Secs_Per_Hour
  467.    ELSE
  468.       RDate := Date;
  469. }
  470.    RDate := Date - GMT_Difference * Secs_Per_Hour;
  471.  
  472.    WHILE( RDate > 0 ) DO
  473.       BEGIN
  474.  
  475.          IF ( Year MOD 4 ) = 0 THEN
  476.             T := Secs_Per_Leap_Year
  477.          ELSE
  478.             T := Secs_Per_Year;
  479.  
  480.          RDate := RDate - T;
  481.  
  482.          INC( Year );
  483.  
  484.       END;
  485.  
  486.    RDate := RDate + T;
  487.  
  488.    DEC( Year );
  489.  
  490.    IF ( Year MOD 4 ) = 0 THEN
  491.       Days_Per_Month[2] := 29
  492.    ELSE
  493.       Days_Per_Month[2] := 28;
  494.  
  495.    WHILE( RDate > 0 ) DO
  496.       BEGIN
  497.  
  498.          T     := Days_Per_Month[Month] * Secs_Per_Day;
  499.  
  500.          RDate := RDate - T;
  501.  
  502.          INC( Month );
  503.  
  504.       END;
  505.  
  506.    RDate := RDate + T;
  507.  
  508.    DEC( Month );
  509.  
  510.    Day   := TRUNC( INT( ( RDate + PRED( Secs_Per_Day ) ) / Secs_Per_Day  ) );
  511.    RDate := RDate - LONGINT( PRED( Day ) ) * Secs_Per_Day;
  512.  
  513.    Hour  := TRUNC( INT( RDate / Secs_Per_Hour ) );
  514.    RDate := RDate - LONGINT( Hour ) * Secs_Per_Hour;
  515.  
  516.    Mins  := TRUNC( INT( RDate / Secs_Per_Minute ) );
  517.    Secs  := TRUNC( RDate - LONGINT( Mins ) * Secs_Per_Minute );
  518.  
  519. END   (* Get_Unix_Style_Date *);
  520.  
  521. (*----------------------------------------------------------------------*)
  522. (*          Set_Unix_Style_Date --- Set UNIX style date                 *)
  523. (*----------------------------------------------------------------------*)
  524.  
  525. PROCEDURE Set_Unix_Style_Date( VAR Date  : LONGINT;
  526.                                    Year  : WORD;
  527.                                    Month : WORD;
  528.                                    Day   : WORD;
  529.                                    Hour  : WORD;
  530.                                    Mins  : WORD;
  531.                                    Secs  : WORD );
  532.  
  533. CONST
  534.    Secs_Per_Year      = 31536000;
  535.    Secs_Per_Leap_Year = 31622400;
  536.    Secs_Per_Day       = 86400;
  537.    Secs_Per_Hour      = 3600;
  538.    Secs_Per_Minute    = 60;
  539.  
  540. VAR
  541.    RDate     : LONGINT;
  542.    T         : LONGINT;
  543.    Leap_Year : BOOLEAN;
  544.    I         : INTEGER;
  545.  
  546. BEGIN (* Set_Unix_Style_Date *)
  547. {
  548.    IF ( Transfer_Protocol = SEALink ) THEN
  549.       Date := 0
  550.    ELSE
  551.       Date := GMT_Difference * Secs_Per_Hour;
  552. }
  553.  
  554.    Date := GMT_Difference * Secs_Per_Hour;
  555.  
  556.    FOR I := 1970 TO PRED( Year ) DO
  557.       BEGIN
  558.  
  559.          IF ( I MOD 4 ) = 0 THEN
  560.             T := Secs_Per_Leap_Year
  561.          ELSE
  562.             T := Secs_Per_Year;
  563.  
  564.          Date := Date + T;
  565.  
  566.       END;
  567.  
  568.    IF ( Year MOD 4 ) = 0 THEN
  569.       Days_Per_Month[2] := 29
  570.    ELSE
  571.       Days_Per_Month[2] := 28;
  572.  
  573.    FOR I := 1 TO PRED( Month ) DO
  574.       Date := Date + LONGINT( Days_Per_Month[I] ) * Secs_Per_Day;
  575.  
  576.    Date  := Date + LONGINT( PRED( Day ) ) * Secs_Per_Day    +
  577.                    LONGINT( Hour        ) * Secs_Per_Hour   +
  578.                    LONGINT( Mins        ) * Secs_Per_Minute +
  579.                    Secs;
  580.  
  581. END   (* Set_Unix_Style_Date *);
  582.  
  583. (*----------------------------------------------------------------------*)
  584. (*    Extract_Upload_Path_Name --- Extract the upload path name         *)
  585. (*----------------------------------------------------------------------*)
  586.  
  587. PROCEDURE Extract_Upload_Path_Name( VAR File_Pattern    : AnyStr;
  588.                                     VAR Upload_Dir_Path : AnyStr );
  589.  
  590. VAR
  591.    I   : INTEGER;
  592.    Done: BOOLEAN;
  593.  
  594. BEGIN (* Extract_Upload_Path_Name *)
  595.  
  596.    I    := LENGTH( File_Pattern ) + 1;
  597.    Done := FALSE;
  598.  
  599.    WHILE ( NOT Done ) DO
  600.       BEGIN
  601.          DEC( I );
  602.          Done := ( File_Pattern[I] = ':' ) OR
  603.                  ( File_Pattern[I] = '\' ) OR
  604.                  ( I = 1 );
  605.       END;
  606.  
  607.    IF ( I > 1 ) THEN
  608.       Upload_Dir_Path := COPY( File_Pattern, 1, I )
  609.    ELSE
  610.       BEGIN
  611.          GetDir( 0 , Upload_Dir_Path );
  612.          IF ( Int24Result <> 0 ) THEN
  613.             Upload_Dir_Path := '';
  614.       END;
  615.  
  616.    IF ( POS( '\', Upload_Dir_Path ) <> 0 ) THEN
  617.       IF ( Upload_Dir_Path[LENGTH( Upload_Dir_Path )] <> '\' ) THEN
  618.          Upload_Dir_Path := Upload_Dir_Path + '\';
  619.  
  620. END   (* Extract_Upload_Path_Name *);
  621.  
  622. (*----------------------------------------------------------------------*)
  623. (*    End_Batch_Transfer --- Display messages at end of batch transfer  *)
  624. (*----------------------------------------------------------------------*)
  625.  
  626. PROCEDURE End_Batch_Transfer;
  627.  
  628. BEGIN (* End_Batch_Transfer *)
  629.                                    (* Indicate end of transfer    *)
  630.    WRITELN(' ');
  631.    RvsVideoOn ( Menu_Text_Color, BLACK );
  632.  
  633.    WRITELN('  Batch transfer complete.');
  634.    Write_Log('Batch transfer complete.', FALSE, FALSE );
  635.  
  636.    RvsVideoOff( Menu_Text_Color, BLACK );
  637.  
  638.    Window_Delay;
  639.                                    (* Remove batch transfer window *)
  640.  
  641.    Restore_Screen_And_Colors( Batch_Screen_Ptr );
  642.  
  643. END   (* End_Batch_Transfer *);
  644.