home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / rt11pascal / rtrecv.pas < prev    next >
Pascal/Delphi Source File  |  2020-01-01  |  8KB  |  422 lines

  1. { This the ReceiveSwitch Overlay }
  2.  
  3.   PROCEDURE GetFile({ Using } data:string);
  4.     { create file from fileheader packet }
  5.   CONST    { used for GetFile }
  6.     FLEN1 = 7;       { Position of "." in    file name }
  7.     FLEN2 = 10;       { Max length    of file    name }
  8.     TEMPFILE = 'TEMP.K              ';    { Mask for temp    file }
  9.   VAR
  10.     p,strend: integer;
  11.     temp : string;
  12.    BEGIN
  13.      WITH CurrentPacket^ DO
  14.       BEGIN
  15.     IF DiskFile = IOERROR       { check if we already have a    file }
  16.      THEN
  17.       BEGIN
  18.         IF Verbosity
  19.          THEN
  20.          PutCS('Creating file ...   ',data,STDERR);
  21.                    
  22.         { check position of    '.' -- truncate    if bad }
  23.         p := index(data,PERIOD);
  24.         IF (p > FLEN1 )
  25.          THEN
  26.           BEGIN
  27.         data[FLEN1] := PERIOD;
  28.         scopy(data,p+1,temp,1);
  29.         scopy(temp,1,data,FLEN1+1);
  30.           END;
  31.          { check Max length    }
  32.         IF length(data) > FLEN2
  33.          THEN
  34.          data[FLEN2    +1] := ENDSTR;
  35.         IF (Exists(data) AND (fileWarn = oON)) 
  36.          THEN
  37.           BEGIN
  38.         IF local
  39.          THEN
  40.          PutCS('File already exists ',data,STDERR);
  41.         CtoS(TEMPFILE,data);
  42.         strend := 0;
  43.          REPEAT
  44.           strend := strend +1;
  45.          UNTIL (data[strend] = BLANK);
  46.         strend := itoc(n,data,strend);
  47.         IF local
  48.          THEN
  49.          PutCS('Creating  ...       ',data,STDERR);
  50.               END;
  51.         DiskFile :=    Sopen(data,-IOWRITE);
  52.       END;
  53.     IF (Diskfile <=    IOERROR)
  54.      THEN
  55.      ErrorPack('Cannot create file  ');
  56.       END;
  57.    END;
  58.  
  59.   PROCEDURE ReceiveInit;
  60.     { receive init packet }
  61.     { respond with ACK and  our    parameters }
  62.    BEGIN
  63.      IF    NumTry > MaxTry
  64.       THEN
  65.        BEGIN
  66.      State := Abort;
  67.      PutErr('Cannot    receive    init ');
  68.        END
  69.       ELSE
  70.        BEGIN
  71.      Verbose ( 'Receiving Init      ');
  72.      NumTry    := NumTry+1;
  73.      IF RecvPacket
  74.       AND (CurrentPacket^.ptype = TYPES)
  75.       THEN
  76.        BEGIN
  77.          WITH CurrentPacket^ DO
  78.           BEGIN
  79.         n := seq;
  80.         DeCodeParm(data);
  81.           END;
  82.  
  83.          { now send    mine }
  84.          WITH ThisPacket^ DO
  85.           BEGIN
  86.         count := NUMPARAM;
  87.         seq := n;
  88.         Ptype := TYPEY;
  89.         EnCodeParm(data);
  90.           END;
  91.  
  92.          SendPacket;
  93.          NumACK := NumACK+1;
  94.          State := FileHeader;
  95.          OldTry := NumTry;
  96.          NumTry := 0;
  97.          MaxTry := DEFTRY; { use regular default now }
  98.          n := (n+1)    MOD 64
  99.        END
  100.       ELSE
  101.        BEGIN
  102.          IF    Debug
  103.           THEN
  104.           PutCln('Received Bad init      ',STDERR);
  105.           SendNAK(n);
  106.        END;
  107.        END;
  108.    END;
  109.  
  110.   PROCEDURE DataToFile;    { output to file }
  111.   VAR
  112.     len,i : integer;
  113.     temp : string;
  114.    BEGIN
  115.      WITH CurrentPacket^ DO
  116.       BEGIN
  117.     len := length(data);
  118.     AddTo(ChInFileRecv ,len);
  119.     CASE EOLforFile    OF
  120.       LineFeed:    putstr(data,DiskFile);
  121.       CrLf:
  122.        BEGIN  { don't output  CR }
  123.          FOR i:=1 TO len DO
  124.          IF    data[i]    <> CR
  125.           THEN
  126.           putcf(data[i],DiskFile);
  127.        END;
  128.       JustCR:
  129.        BEGIN   { change CR to NEWLINE }
  130.          FOR i:=1 TO len DO
  131.          IF    data[i]=CR
  132.           THEN
  133.           data[i]:=NEWLINE;
  134.          putstr(data,DiskFile);
  135.        END;
  136.      END;
  137.     { case }
  138.       END;
  139.    END;
  140.  
  141.  
  142.   PROCEDURE Dodata;  { Process Data packet }
  143.    BEGIN
  144.      WITH CurrentPacket^ DO
  145.       BEGIN
  146.     IF  seq    = ((n +    63) MOD    64)
  147.      THEN
  148.       BEGIN               { data last one }
  149.         IF OldTry>MaxTry
  150.          { number of tries?    }
  151.          THEN
  152.           BEGIN
  153.         State := Abort;
  154.         PutErr('Old data - Too many ');
  155.           END
  156.          ELSE
  157.           BEGIN
  158.         SendACK(seq);
  159.         NumTry := 0;
  160.           END;
  161.       END
  162.      ELSE
  163.       BEGIN           { data - this one }
  164.         IF (n<>seq)
  165.          THEN
  166.          SendNAK(n)
  167.          ELSE
  168.           BEGIN
  169.         DataToFile;
  170.         SendACK(n); { ACK }
  171.         OldTry := NumTry;
  172.         NumTry := 0;
  173.         n := (n+1) MOD 64;
  174.           END;
  175.       END;
  176.       END;
  177.    END;
  178.  
  179.   PROCEDURE DoFileLast;      { Process File Packet    }
  180.    BEGIN      { File header    - last one  }
  181.      IF    OldTry > MaxTry    { tries    ? }
  182.       THEN
  183.        BEGIN
  184.      State := Abort;
  185.      PutErr('Old file - Too    many ');
  186.        END
  187.       ELSE
  188.        BEGIN
  189.      OldTry    := OldTry+1;
  190.      WITH CurrentPacket^ DO
  191.       BEGIN
  192.         IF seq = ((n + 63) MOD 64)
  193.          { packet number }
  194.          THEN
  195.           BEGIN  { send ACK    }
  196.         SendACK(seq);
  197.         NumTry := 0
  198.           END
  199.          ELSE
  200.           BEGIN
  201.         SendNAK(n);   {    NAK }
  202.           END;
  203.       END;
  204.        END;
  205.    END;
  206.  
  207.  
  208.   PROCEDURE DoEOF;  { Process EOF packet }
  209.    BEGIN         { EOF - this one }
  210.      IF    CurrentPacket^.seq<>n     { packet number ? }
  211.       THEN
  212.       SendNAK(n) { NAK }
  213.       ELSE
  214.        BEGIN           { send ACK }
  215.      Sclose(DiskFile);  { close file }
  216.      SendACK(n);
  217.      DiskFile := IOERROR;
  218.      OldTry    := NumTry;
  219.      NumTry    := 0;
  220.      n := (n+1) MOD    64; { next packet  }
  221.      State := FileHeader;    { change state }
  222.        END;
  223.    END;
  224.  
  225.   PROCEDURE ReceiveData;  { Receive data packets }
  226.   VAR
  227.     strend: integer;
  228.     good : boolean;
  229.    BEGIN
  230.      IF    NumTry > MaxTry         { check number    of tries }
  231.       THEN
  232.        BEGIN
  233.      State := Abort;
  234.      IF local
  235.       THEN
  236.       PutCN('Recv data -Too    many ',n,STDERR);
  237.        END
  238.       ELSE
  239.        BEGIN
  240.      NumTry    := NumTry+1;            { increase number of tries }
  241.      good := RecvPacket;        { get packet }
  242.      WITH CurrentPacket^ DO
  243.       BEGIN
  244.         IF Verbosity
  245.          THEN
  246.          PutCN('Receiving (Data)    ',CurrentPacket^.seq,STDERR);
  247.  
  248.         IF ((ptype = TYPED)    OR (ptype=TYPEZ)
  249.         OR (ptype=TYPEF)) AND good         { check type }
  250.          THEN
  251.          CASE ptype    OF
  252.            TYPED:  DoData;
  253.            TYPEF:  DoFileLast;
  254.            TYPEZ:  DoEOF;
  255.           END { case }
  256.          ELSE
  257.           BEGIN
  258.         IF Debug
  259.          THEN
  260.          PutCln('Expected data pack  ',STDERR);
  261.         SendNAK(n);
  262.           END;
  263.       END;
  264.        END;
  265.    END;
  266.  
  267.  
  268.   PROCEDURE DoBreak; { Process Break packet }
  269.    BEGIN            { Break transmission }
  270.      IF    CurrentPacket^.seq<>n     { packet number ? }
  271.       THEN
  272.       SendNAK(n) { NAK }
  273.       ELSE
  274.        BEGIN        { send    ACK }
  275.      SendACK(n) ;
  276.      State := Complete  { change state }
  277.        END
  278.    END;
  279.  
  280.   PROCEDURE DoFile; { Process file packet }
  281.    BEGIN         { File    Header }
  282.      WITH CurrentPacket^ DO
  283.       BEGIN
  284.     IF seq<>n        { packet number ? }
  285.      THEN
  286.      SendNAK(n)  { NAK }
  287.      ELSE
  288.       BEGIN              {    send ACK }
  289.         AddTo(ChInFileRecv,    length(data));
  290.         GetFile(data);   { get file    name }
  291.         SendACK(n);
  292.         OldTry := NumTry;
  293.         NumTry := 0;
  294.         n := (n+1) MOD 64; { next packet  }
  295.         State := FileData;     { change state    }
  296.       END;
  297.       END;
  298.    END;
  299.  
  300.   PROCEDURE DoEOFLast; { Process EOF Packet }
  301.    BEGIN           { End Of    File Last One}
  302.      IF    OldTry > MaxTry    { tries    ? }
  303.       THEN
  304.        BEGIN
  305.      State := Abort;
  306.      PutErr('Old EOF - Too many  ');
  307.        END
  308.       ELSE
  309.        BEGIN
  310.      OldTry    := OldTry+1;
  311.      WITH CurrentPacket^ DO
  312.       BEGIN
  313.         IF seq =((n    + 63 ) MOD 64)
  314.          { packet number }
  315.          THEN
  316.           BEGIN  { send ACK    }
  317.         SendACK(seq);
  318.         Numtry := 0
  319.           END
  320.          ELSE
  321.           BEGIN
  322.         SendNAK(n);  { NAK }
  323.           END
  324.       END;
  325.        END;
  326.    END;
  327.  
  328.   PROCEDURE DoInitLast;
  329.    BEGIN        { Init Packet -    last one }
  330.      IF    OldTry> DEFITRY    { number of tries? }
  331.       THEN
  332.        BEGIN
  333.      State := Abort;
  334.      PutErr('Old init - Too    many ');
  335.        END
  336.       ELSE
  337.        BEGIN
  338.      OldTry    := OldTry+1;
  339.      IF CurrentPacket^.seq = ((n + 63) MOD    64)
  340.       { packet number }
  341.       THEN
  342.        BEGIN   { send ACK }
  343.          WITH ThisPacket^ DO
  344.           BEGIN
  345.         count := NUMPARAM;
  346.         seq := CurrentPacket^.seq;
  347.         ptype := TYPEY;
  348.         EnCodeParm(data);
  349.           END;
  350.          SendPacket;
  351.          NumACK := NumACK+1;
  352.          NumTry := 0;
  353.        END
  354.       ELSE
  355.        BEGIN
  356.          SendNAK(n);  { NAK    }
  357.        END;
  358.        END;
  359.    END;
  360.  
  361.   PROCEDURE ReceiveFile; { receive file    packet }
  362.   VAR
  363.     good: boolean;
  364.    BEGIN
  365.      IF    NumTry > MaxTry         { check number    of tries }
  366.       THEN
  367.        BEGIN
  368.      State := Abort;
  369.      PutErr('Recv file - Too many');
  370.        END
  371.       ELSE
  372.        BEGIN
  373.      NumTry    := NumTry+1;            { increase number of tries }
  374.      good := RecvPacket;         { get packet }
  375.      WITH CurrentPacket^ DO
  376.       BEGIN
  377.         IF Verbosity
  378.          THEN
  379.          PutCN('Receiving (File)    ',seq,STDERR);
  380.  
  381.         IF ((ptype = TYPES)    OR (ptype=TYPEZ)
  382.         OR (ptype=TYPEF) OR (ptype=TYPEB)) { check type    }
  383.          AND good
  384.          THEN
  385.          CASE ptype    OF
  386.            TYPES:  DoInitLast;
  387.            TYPEZ:  DoEOFLast;
  388.            TYPEF:  DoFile;
  389.            TYPEB:  DoBreak;
  390.           END { case }
  391.          ELSE
  392.           BEGIN
  393.         IF Debug
  394.          THEN
  395.          PutCln('Expected File Pack  ',STDERR);
  396.         SendNAK(n);
  397.           END;
  398.       END;
  399.        END;
  400.    END;
  401.  
  402.  
  403.   {$E+}
  404.  
  405.   PROCEDURE RecvSwitch;    { this procedure is the    main receive routine }
  406.    BEGIN
  407.      StartRun;
  408.       REPEAT
  409.        CASE State OF
  410.      FileData:     ReceiveData;
  411.      Init:         ReceiveInit;
  412.      Break:         { nothing };
  413.      FileHeader:     ReceiveFile;
  414.      EOFile:     { nothing };
  415.      Complete:     { nothing };
  416.      Abort:         { nothing };
  417.     END;
  418.        { case }
  419.       UNTIL (State = Abort ) OR    ( State    = Complete );
  420.    END;
  421.  
  422.