home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / rt11pascal / rtsend.pas < prev    next >
Pascal/Delphi Source File  |  1984-05-21  |  7KB  |  368 lines

  1. { This is the SendSwitch Overlay }
  2.  
  3. { Clear Buffer for input Line }
  4. PROCEDURE CLRBUF;
  5. EXTERNAL;
  6.  
  7.  
  8.   PROCEDURE GetData({ Returning }   VAR newstate:KermitStates);
  9.     { get data from file into ThisPacket }
  10.   VAR
  11.     { and return next state - data &  EOF }
  12.     x,c : character;
  13.     i: integer;
  14.    BEGIN
  15.      IF (NumTry=1)
  16.       THEN
  17.        BEGIN
  18.      i := 1;
  19.      x := BLANK;
  20.      WITH ThisPacket^ DO
  21.       BEGIN
  22.         WHILE (i< SizeSend - 8 ) AND (x <> ENDFILE)
  23.         { leave room for quote  & NEWLINE }
  24.         DO
  25.          BEGIN
  26.            x := getcf(c,DiskFile);
  27.            IF (x<>ENDFILE)
  28.         THEN
  29.         BEGIN
  30.         { Process Binary data }
  31.         IF (x < NULLCHAR) THEN
  32.            CASE BinaryMode OF 
  33.             NotSupported: BEGIN
  34.                 PutCn('Binary char (dec) = ',x,STDERR);
  35.                 ErrorPack('No Binary Support   ');
  36.                       END;
  37.             FullBinary: { nothing to do };
  38.             Quoted : BEGIN
  39.                     data[i] := QuoteForBinary;
  40.                     i := i + 1;
  41.                     x := x + 128; { convert to ASCII }
  42.                  END;
  43.            END; { case }    
  44.             
  45.         IF (IsControl(x)) OR (x=SendQuote) OR (x=QuoteForBinary)
  46.          THEN
  47.           BEGIN           { control char -- quote }
  48.             IF x=NEWLINE
  49.              THEN      { use proper EOL }
  50.              CASE EOLforFile OF
  51.                LineFeed:   { ok as is };
  52.                CrLf:
  53.             BEGIN
  54.               data[i] := SendQuote;
  55.               i := i+1;
  56.               data[i] := Ctl(CR);
  57.               i := i+1;
  58.                           { LF will sent
  59.                below }
  60.             END;
  61.                JustCR:     x := CR;
  62.               END { case };
  63.             data[i] := SendQuote;
  64.             i := i+1;
  65.             IF (x<>SendQuote) AND (x<>QuoteForBinary)
  66.              THEN
  67.              data[i] := Ctl(x)
  68.              ELSE
  69.              data[i] := x;
  70.           END
  71.          ELSE               { regular char }
  72.          data[i] := x;
  73.            END;    
  74.  
  75.            IF (x<>ENDFILE)
  76.         THEN
  77.          BEGIN
  78.            i := i+1;    { increase count for next char }
  79.            AddTo(ChInFileSend,1);
  80.          END;
  81.          END;
  82.  
  83.         data[i] := ENDSTR;   { to terminate string }
  84.  
  85.         count := i -1;       { length }
  86.         seq := n;
  87.         ptype := TYPED;
  88.  
  89.         IF (x=ENDFILE)
  90.          THEN
  91.           BEGIN
  92.         newstate := EOFile;
  93.         Sclose(DiskFile);
  94.         DiskFile := IOERROR;
  95.           END
  96.          ELSE
  97.          newstate := FileData;
  98.         SaveState := newstate;        { save state }
  99.       END
  100.        END
  101.       ELSE
  102.       newstate := SaveState;        { get old state }
  103.    END;
  104.  
  105.   FUNCTION GetNextFile: { Returning } boolean;
  106.     { get next file to send in ThisPacket }
  107.     { returns true if no more }
  108.   VAR
  109.     result: boolean;
  110.     tempstr : string;
  111.     i : integer;
  112.    BEGIN
  113.      result := true;
  114.      IF (NumTry=1)
  115.       THEN
  116.       WITH ThisPacket^ DO
  117.        BEGIN
  118.       REPEAT
  119.        IF getarg(NextArg,data,MAXSTR)
  120.         THEN
  121.          BEGIN            { open file  }
  122.            IF Exists(data)
  123.         THEN
  124.          BEGIN
  125.            DiskFile := Sopen(data,-IOREAD);
  126.            { Check for : for device -- skip it }    
  127.            i := index(data,COLON);
  128.            IF (i > 0) THEN
  129.             BEGIN 
  130.               i := i + 1;
  131.               scopy(data,i,tempstr,1);
  132.               scopy(tempstr,1,data,1);
  133.             END;    
  134.            count := length(data);
  135.            AddTo(ChInFileSend , count);
  136.            seq := n;
  137.            ptype := TYPEF;
  138.            IF DiskFile <= IOERROR
  139.             THEN
  140.             ErrorPack('Cannot open file    ');
  141.            result := false;
  142.          END;
  143.          END;
  144.        NextArg := NextArg+1;
  145.       UNTIL ( NextArg > nargs ) OR ( NOT result )
  146.        END
  147.       ELSE
  148.       result := false; { for saved packet }
  149.      GetNextFile := result;
  150.    END;
  151.  
  152.   PROCEDURE SendFile; { send file name packet }
  153.    BEGIN
  154.      Verbose( 'Sending ....        ');
  155.      IF NumTry > MaxTry
  156.       THEN
  157.        BEGIN
  158.      PutErr ('Send file - Too Many');
  159.      State := Abort;      { too many tries, abort }
  160.        END
  161.       ELSE
  162.        BEGIN
  163.      NumTry := NumTry+1;
  164.      IF GetNextFile
  165.       THEN
  166.        BEGIN
  167.          State := Break;
  168.          NumTry := 0;
  169.        END
  170.       ELSE
  171.        BEGIN
  172.          IF Verbosity
  173.           THEN
  174.            BEGIN
  175.          IF (NumTry = 1)
  176.           THEN putstr(ThisPacket^.data,STDERR)
  177.           ELSE putstr(LastPacket^.data,STDERR);
  178.          putcf(NEWLINE,STDERR);
  179.            END;
  180.  
  181.          SendPacket;     { send this packet }
  182.          IF RecvACK
  183.           THEN
  184.            BEGIN
  185.          State := FileData;
  186.          NumTry := 0;
  187.          n := (n+1) MOD 64;
  188.            END
  189.        END;
  190.        END;
  191.    END;
  192.  
  193.  
  194.   PROCEDURE SendData;  { send file data packets }
  195.   VAR
  196.     newstate: KermitStates;
  197.    BEGIN
  198.      IF Verbosity
  199.       THEN
  200.       PutCN ( 'Sending data        ',n,STDERR);
  201.      IF NumTry > MaxTry
  202.       THEN
  203.        BEGIN
  204.      State := Abort;       { too many tries, abort }
  205.      PutErr ('Send data - Too many');
  206.        END
  207.       ELSE
  208.        BEGIN
  209.      NumTry := NumTry+1;
  210.      GetData(newstate);
  211.      SendPacket;
  212.      IF RecvACK
  213.       THEN
  214.        BEGIN
  215.          State := newstate;
  216.          NumTry := 0;
  217.          n := (n+1) MOD 64;
  218.        END
  219.        END;
  220.    END;
  221.  
  222.  
  223.   PROCEDURE SendEOF;    { send EOF  packet }
  224.    BEGIN
  225.      Verbose ('Sending EOF         ');
  226.      IF NumTry > MaxTry
  227.       THEN
  228.        BEGIN
  229.      State := Abort;       { too many tries, abort }
  230.      PutErr('Send EOF - Too Many ');
  231.        END
  232.       ELSE
  233.        BEGIN
  234.      NumTry := NumTry+1;
  235.      IF (NumTry = 1)
  236.       THEN
  237.        BEGIN
  238.          WITH ThisPacket^ DO
  239.           BEGIN
  240.         ptype := TYPEZ;
  241.         seq := n;
  242.         count := 0;
  243.           END;
  244.          Sclose(DiskFile);
  245.        END;
  246.      SendPacket;
  247.      IF RecvACK
  248.       THEN
  249.        BEGIN
  250.          State := FileHeader;
  251.          NumTry := 0;
  252.          n := (n+1) MOD 64;
  253.        END
  254.        END;
  255.    END;
  256.  
  257.  
  258.   PROCEDURE SendBreak; { send break packet }
  259.    BEGIN
  260.      Verbose ('Sending break       ');
  261.      IF NumTry > MaxTry
  262.       THEN
  263.        BEGIN
  264.      State := Abort;       { too many tries, abort }
  265.      PutErr('Send break -Too Many');
  266.        END
  267.       ELSE
  268.        BEGIN
  269.      NumTry := NumTry+1;
  270.      { make up packet  }
  271.      IF NumTry = 1
  272.       THEN
  273.        BEGIN
  274.          WITH ThisPacket^ DO
  275.           BEGIN
  276.         ptype := TYPEB;
  277.         seq := n;
  278.         count := 0;
  279.           END
  280.        END;
  281.      SendPacket; { send this packet }
  282.      IF RecvACK
  283.       THEN
  284.        BEGIN
  285.          State := Complete;
  286.        END
  287.        END;
  288.    END;
  289.  
  290.  
  291.   PROCEDURE SendInit;  { send init packet }
  292.    BEGIN
  293.      Verbose ('Sending init        ');
  294.      IF NumTry > MaxTry
  295.       THEN
  296.        BEGIN
  297.      State := Abort;      { too many tries, abort }
  298.      PutErr('Cannot Initialize   ');
  299.        END
  300.       ELSE
  301.        BEGIN
  302.      NumTry := NumTry+1;
  303.      IF (NumTry = 1)
  304.       THEN
  305.        BEGIN
  306.          WITH ThisPacket^ DO
  307.           BEGIN
  308.         EnCodeParm(data);
  309.         count := NUMPARAM;
  310.         seq := n;
  311.         ptype := TYPES;
  312.           END
  313.        END;
  314.  
  315.      SendPacket; { send this packet     }
  316.      CLRBUF;     { Clear input buffer ! }
  317.      IF RecvACK
  318.       THEN
  319.        BEGIN
  320.          WITH CurrentPacket^ DO
  321.           BEGIN
  322.         IF OneWayOnly
  323.          THEN  { use same data if test mode }
  324.          data := LastPacket^.data;
  325.          DeCodeParm(data);
  326.           END;
  327.  
  328.          State := FileHeader;
  329.          NumTry := 0;
  330.          MaxTry := DEFTRY;  { use regular default now  }
  331.          n := (n+1) MOD 64;
  332.        END;
  333.        END;
  334.    END;
  335.  
  336.   {$E+}
  337.  
  338.   PROCEDURE SendSwitch;
  339.     { Send-switch is the state table switcher for sending files.
  340.       It loops until either it is finished or a fault is encountered.
  341.       Routines called by sendswitch are responsible for changing the state.
  342.      }
  343.  
  344.    BEGIN
  345.      StartRun;
  346.      IF (NOT OneWayOnly )
  347.       THEN
  348.         Sleep(Delay);
  349.      n := 0;
  350.       REPEAT
  351.        CASE State OF
  352.      FileData:     SendData;         { data-send state }
  353.      FileHeader:   SendFile;         { send file name }
  354.      EOFile:       SendEOF;          { send end-of-file }
  355.      Init:         SendInit;         { send initialize }
  356.      Break:        SendBreak;        { send break }
  357.      Complete:     { nothing };
  358.      Abort:        { nothing };
  359.     END { case };
  360.       UNTIL ( (State = Abort) OR (State=Complete) );
  361.    END;
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.