-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- SloshSend.mesa, HGM, 18-Feb-83  1:04:37

DIRECTORY
  Ascii USING [CR],
  Environment USING [Byte, bytesPerPage],
  Put USING [Text],
  String USING [AppendLongDecimal, AppendChar, AppendString],
  Stream USING [CompletionCode, Delete, GetBlock, Handle],
  System USING [GetGreenwichMeanTime],
  Time USING [AppendCurrent],
  Window USING [Handle],

  Slosh USING [SendStatus],
  EFTPDefs USING [
    EFTPAbortSending, EFTPFinishSending, EFTPOpenForSending, EFTPSendBlock,
    EFTPSetSendTimeout, EFTPTimeOut, EFTPTroubleSending],
  PupDefs USING [AppendHostName, FastPath],
  PupTypes USING [PupAddress];

SloshSend: PROGRAM
  IMPORTS Put, Stream, String, System, Time, EFTPDefs, PupDefs
  EXPORTS Slosh =
  BEGIN

  verbose: BOOLEAN = TRUE;

  SendFile: PUBLIC PROCEDURE [
    who: Window.Handle, fileName: LONG STRING, file: Stream.Handle,
    him: PupTypes.PupAddress] RETURNS [what: Slosh.SendStatus] =
    BEGIN OPEN EFTPDefs;
    page: CARDINAL;
    buffer: PACKED ARRAY [0..Environment.bytesPerPage) OF Environment.Byte;
    message: LONG STRING;
    trouble: STRING = [100];
    seconds: LONG CARDINAL;
    slowly: BOOLEAN ← ~PupDefs.FastPath[him];
    seconds ← System.GetGreenwichMeanTime[];
    -- Yetch, at 2400 baud it takes 2 sec/page
    IF slowly THEN EFTPSetSendTimeout[6000, 10] ELSE EFTPSetSendTimeout[2000, 10];
    BEGIN
    EFTPOpenForSending[
      him, FALSE ! EFTPTimeOut, EFTPTroubleSending => GOTO NeverStarted];
    FOR page ← 0, page + 1 DO
      bytes: CARDINAL;
      why: Stream.CompletionCode;
      [bytes, why] ← Stream.GetBlock[file, [@buffer, 0, Environment.bytesPerPage]];
      EFTPSendBlock[
        @buffer, bytes !
        EFTPTimeOut =>
          BEGIN message ← "Timeout while sending "L; GOTO Trouble; END;
        EFTPTroubleSending =>
          BEGIN
          message ← "Troubles while sending "L;
          String.AppendString[trouble, s];
          GOTO Trouble;
          END];
      IF why # normal THEN EXIT;
      ENDLOOP;
    EFTPFinishSending[
      !
      EFTPTimeOut =>
        BEGIN message ← "Timeout while finishing "L; GOTO Trouble; END;
      EFTPTroubleSending =>
        BEGIN
        message ← "Troubles while finishing "L;
        String.AppendString[trouble, s];
        GOTO Trouble;
        END];
    seconds ← System.GetGreenwichMeanTime[] - seconds;
    message ← "Sent "L;
    what ← ok;
    EXITS
      Trouble =>
        BEGIN
        EFTPAbortSending[message];
        seconds ← System.GetGreenwichMeanTime[] - seconds;
        what ← troubles;
        END;
      NeverStarted =>
        BEGIN
        message ← "Never started sending "L;
        EFTPAbortSending[message];
        seconds ← System.GetGreenwichMeanTime[] - seconds;
        what ← neverStarted;
        END;
    END;
    Stream.Delete[file];
    IF verbose THEN
      BEGIN OPEN String;
      text: STRING = [200];
      Time.AppendCurrent[text];
      AppendString[text, "  "L];
      AppendString[text, message];
      IF trouble.length # 0 THEN
        BEGIN
        AppendString[text, "("L];
        AppendString[text, trouble];
        AppendString[text, ") "L];
        END;
      AppendString[text, fileName];
      AppendString[text, " to "L];
      PupDefs.AppendHostName[text, him];
      IF what # ok AND what # neverStarted THEN
        BEGIN AppendString[text, ", page="L]; AppendLongDecimal[text, page]; END;
      AppendString[text, ", sec="L];
      AppendLongDecimal[text, seconds];
      IF slowly THEN AppendString[text, " (slowly)"L];
      LogString[who, text];
      END;
    END;

  LogString: PROCEDURE [msg: Window.Handle, text: LONG STRING] =
    BEGIN
    String.AppendChar[text, '.];
    String.AppendChar[text, Ascii.CR];
    Put.Text[NIL, text];
    IF msg # NIL THEN Put.Text[msg, text];
    END;

  END.