home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / perqb / pq2sen.pas < prev    next >
Pascal/Delphi Source File  |  2020-01-01  |  20KB  |  719 lines

  1. module KermitSend;
  2.  
  3. { the module contains routines for sending files to a remote kermit }
  4.  
  5. {=========================} exports {========================================}
  6.  
  7. imports KermitGlobals from KermitGlobals;
  8.  
  9. function    SendSwitch :   KermitStates;
  10.  
  11. {=========================} private {========================================}
  12.  
  13. const
  14.         ACKExp = '?Illegal packet type received - expected ACK packet';
  15.         RecvrAborted = 'Transfer aborted by error packet from receiver';
  16.  
  17. imports KermitFile from KermitFile;
  18. imports KermitParameters from KermitParameters;
  19. imports KermitLineIO from KermitLineIO; 
  20. imports System from System;
  21. imports UtilProgress from UtilProgress;
  22.  
  23. {-----------------------------------------------------------------------------}
  24.  
  25. var     FNPacket, FDPacket      : Packet;
  26.         FileName                : FNameType;
  27.  
  28. {-----------------------------------------------------------------------------}
  29.  
  30. function SendInitiate : KermitStates;
  31.  
  32. var     RetVal   : KermitStates;
  33.         Pack     : Packet;
  34.         num      : integer;
  35.         len      : integer;
  36.         status   : integer;
  37.         message  : string;
  38.  
  39.         handler CtlC;
  40.         begin
  41.             CtrlCPending := false;
  42.             SendInitiate := AbortCtlC;
  43.             exit( SendInitiate );
  44.         end;
  45.  
  46. begin
  47.     if Debug then begin
  48.         DbgWrite('Enter SendInit');
  49.         DbgNL;
  50.     end;
  51.  
  52.     NumTry := NumTry + 1;
  53.     if NumTry>1 then
  54.         TotTry := TotTry + 1;
  55.     if NumTry > MaxTryInit then begin
  56.         LocalError( '?Unable to send initiate' );
  57.         RetVal := AbortAll
  58.     end
  59.     else
  60.     begin
  61.  
  62.         if Debug then begin
  63.             DbgWrite(' n =');
  64.             DbgInt( n );
  65.             DbgNL;
  66.         end;
  67.  
  68.         SetInitPars ( Pack );
  69.         SendPacket (    SInitPack,
  70.                         n,
  71.                         -1,
  72.                         Pack );
  73.  
  74.         case ReadPacket( num, len, Pack ) of
  75.  
  76.             NAKPack :
  77.                 begin
  78.                     RetVal := CurrState;
  79.                 end;
  80.  
  81.             ACKPack :
  82.                 begin
  83.                     if num <> n then            (* Wrong ACK ? *)
  84.                         RetVal := CurrState     (* Stay in current state *)
  85.                     else
  86.                     begin
  87.                         ReadPars( Pack );
  88.                         Succeeded;
  89.                         case NextReadFile(FileName) of
  90.                         
  91.                         FNoFile, FNoReadPriv, FReadErr, FCantOpen:
  92.                             begin
  93.                                 Message := concat('?Cannot open: ',FileName );
  94.                                 SendErrPack( Message );
  95.                                 Writeln( Message );
  96.                                 RetVal := AbortAll;
  97.                             end;
  98.  
  99.                         FEndDir:
  100.                             begin
  101.                                 Message := Concat('?No files matching: ', 
  102.                                                         FileName );
  103.                                 Writeln( Message );
  104.                                 RetVal := Break;
  105.                             end;
  106.  
  107.                         FNoError:
  108.                             begin
  109.                                 RetVal := FileHeader;
  110.                                 PutFileName( FileName, FNPacket );
  111.                             end;
  112.                                 
  113.                         end;
  114.                     end;
  115.                 end;
  116.  
  117.             ErrPack:
  118.                 begin
  119.                     RetVal := AbortAll;
  120.                     TreatErrPack( Pack, Num );
  121.                     writeln( RecvrAborted );
  122.                 end;
  123.  
  124.             DataPack, SInitPack, BrkPack,
  125.             FHeadPack, EOFPack,
  126.             IllPack :
  127.                 begin
  128.                     RetVal := AbortAll;
  129.                     LocalError( ACKExp );
  130.                 end;
  131.  
  132.             ChkIllPack :
  133.                 begin
  134.                     if Debug then begin
  135.                         DbgWrite('Illegal checksum read - retrying');
  136.                         DbgNL;
  137.                     end;
  138.                     RetVal := CurrState;
  139.                 end;
  140.  
  141.             TimOutPack  :
  142.                 begin
  143.                     if Debug then begin
  144.                         DbgWrite('Timed out waiting for ACK for SendInit');
  145.                         DbgNL;
  146.                     end;
  147.                     RetVal := CurrState;
  148.                 end;
  149.  
  150.         end;
  151.     end;
  152.     SendInitiate := RetVal;
  153. end;
  154.  
  155. {-----------------------------------------------------------------------------}
  156.  
  157. function    SendFileHeader : KermitStates;
  158.  
  159. var     RetVal  : KermitStates;
  160.         len, i  : integer;
  161.         num     : integer;
  162.         Treated : boolean;
  163.         Pack    : Packet;
  164.         Answer  : PacketType;
  165.         SaveTime: integer;
  166.         
  167.         handler CtlC;
  168.         begin
  169.             CtrlCPending := false;
  170.             SendFileHeader := AbortCtlC;
  171.             exit( SendFileHeader );
  172.         end;
  173.  
  174. begin
  175.     if Debug then begin
  176.         DbgWrite('Enter SendFileHeader');
  177.         DbgNL;
  178.     end;
  179.  
  180.     NumTry := NumTry + 1;
  181.     if NumTry>1 then
  182.         TotTry := TotTry + 1;
  183.     if NumTry > MaxTryPack then begin
  184.         LocalError( '?Unable to receive an ACK for file header' );
  185.         RetVal := AbortAll;     { No use trying a new file header }
  186.     end
  187.     else
  188.     begin
  189.  
  190.         SendPacket( FHeadPack,
  191.                     n,
  192.                     -1,
  193.                     FNPacket    );
  194.  
  195.         SaveTime := SendTimeOut;
  196.         SendTimeOut := SendTimeOut * LongWait;
  197.         Answer := ReadPacket( num, len, Pack );
  198.         SendTimeOut := SaveTime;
  199.         Treated := false;
  200.  
  201.         if Answer = NAKPack then
  202.         begin
  203.             Treated := True;
  204.             Num := Prev( Num );
  205.             if n <> Num then         (* is it a NAK for the next packet? *)
  206.                 RetVal := CurrState  (* NO - stay in current state       *)
  207.             else
  208.                 Answer := ACKPack;   (* YES - treat as ACK for current   *)
  209.         end; 
  210.  
  211.         if Answer = ACKPack then
  212.         begin
  213.             Treated := true;
  214.             if n <> num then
  215.                 RetVal := CurrState
  216.             else
  217.             begin
  218.                 Succeeded;
  219.                 if FillBuffer( FDPacket ) >= FNoError then
  220.                     RetVal := FileData
  221.                 else
  222.                     RetVal := Abort1;
  223.             end;
  224.         end; 
  225.  
  226.         if not Treated then
  227.         begin
  228.             if Answer = TimOutPack then
  229.             begin
  230.                 if Debug then begin
  231.                     DbgWrite('Timed out waiting for ACK for File-header');
  232.                     DbgNL;
  233.                 end;
  234.                 RetVal := CurrState;
  235.             end else
  236.                 if Answer = ChkIllPack then begin
  237.                     if Debug then begin
  238.                         DbgWrite('Illegal checksum read - retrying');
  239.                         DbgNL;
  240.                     end;
  241.                     RetVal := CurrState;
  242.                 end else
  243.  
  244.                     if Answer = ErrPack then begin
  245.                         RetVal := AbortAll;
  246.                         TreatErrPack( Pack, Num );
  247.                         writeln( RecvrAborted );
  248.                     end else                      
  249.                     begin
  250.                         writeln( ACKExp );
  251.                         SendErrPack( ACKExp );
  252.                         RetVal := AbortAll;
  253.                     end;
  254.         end;
  255.     end;
  256.     SendFileHeader := RetVal;
  257. end;
  258.  
  259. {-----------------------------------------------------------------------------}
  260.  
  261. function   SendData : KermitStates;
  262. var     RetVal : KermitStates;
  263.         RecPack: Packet;
  264.         Answer : PacketType;
  265.         len    : integer;
  266.         num    : integer;
  267.         Treated: boolean;
  268.         
  269.         handler CtlC;
  270.         begin
  271.             CtrlCPending := false;
  272.             SendData := AbortCtlC;
  273.             exit( SendData );
  274.         end;
  275.  
  276. begin
  277.     NumTry := NumTry + 1;
  278.     if NumTry>1 then
  279.         TotTry := TotTry + 1;
  280.     if NumTry > MaxTryPack then begin
  281.         if LocalKermit then
  282.             LocalError( '?Unable to receive an ACK for data packet' );
  283.         RetVal := Abort1;
  284.     end
  285.     else
  286.     begin
  287.  
  288.         SendPacket( DataPack,
  289.                     n,
  290.                     -1,
  291.                     FDPacket   );
  292.  
  293.         Answer := ReadPacket( Num, Len, RecPack );
  294.         Treated := false;
  295.  
  296.         if Answer = NAKPack then
  297.         begin
  298.             Treated := true;
  299.             Num := Prev( Num );
  300.             if n <> Num then
  301.                 RetVal := CurrState
  302.             else
  303.                 Answer := ACKPack;
  304.         end;
  305.  
  306.         if Answer = ACKPack then
  307.         begin
  308.             Treated := true;
  309.             if n <> Num then
  310.                 RetVal := CurrState
  311.             else
  312.             begin
  313.                 Succeeded;
  314.                 if EndFile then
  315.                     RetVal := EOFile
  316.                 else
  317.                 begin
  318.                     if FillBuffer( FDPacket ) >= FNoError then
  319.                         RetVal := CurrState
  320.                     else
  321.                         RetVal := Abort1;
  322.                 end;
  323.             end;
  324.         end;
  325.  
  326.         if not Treated then
  327.         begin
  328.             if Answer = TimOutPack then begin
  329.                 if Debug then begin
  330.                     DbgWrite('Timed out waiting for ACK for FileData');
  331.                     DbgNL;
  332.                 end;
  333.                 RetVal := CurrState;
  334.             end else
  335.                 if Answer = ChkIllPack then begin
  336.                     if Debug then begin
  337.                         DbgWrite('Illegal checksum read - retrying');
  338.                         DbgNL;
  339.                     end;
  340.                     RetVal := CurrState;
  341.                 end else 
  342.                     if Answer = ErrPack then begin
  343.                         RetVal := AbortAll;
  344.                         TreatErrPack( RecPack, Num );
  345.                         writeln( RecvrAborted );
  346.                     end else
  347.                     begin
  348.                         SendErrPack( ACKExp );
  349.                         writeln( ACKExp );
  350.                         RetVal := Abort1;
  351.                     end;
  352.         end;
  353.     end;
  354.     SendData := RetVal;
  355. end; (* SendData *)
  356.  
  357. {-----------------------------------------------------------------------------}
  358.  
  359. function    SendEof : KermitStates;
  360. var     Pack   : Packet;
  361.         Len    : integer;
  362.         Num    : integer;
  363.         RetVal : KermitStates;
  364.         Treated: boolean;
  365.         Answer : PacketType;
  366.         FE     : FileErrs;
  367.         
  368.         handler CtlC;
  369.         begin
  370.             CtrlCPending := false;
  371.             SendEOF := AbortCtlC;
  372.             exit( SendEOF );
  373.         end;
  374.  
  375. begin
  376.     if Debug then begin
  377.         DbgWrite('Enter SendEof');
  378.         DbgNL;
  379.     end;
  380.     NumTry := NumTry + 1;
  381.     if NumTry>1 then
  382.         TotTry := TotTry + 1;
  383.     if NumTry > MaxTryPack then begin
  384.         if LocalKermit then
  385.             LocalError( '?Unable to receive an ACK for EOF packet' );
  386.         RetVal := Abort1;
  387.     end
  388.     else
  389.     begin
  390.  
  391.         SendPacket (    EOFPack,
  392.                         n,
  393.                         0,
  394.                         Pack (* Dummy *)   );
  395.  
  396.         Answer := ReadPacket( Num , Len, Pack );
  397.         Treated := false;
  398.         if Answer = NAKPack then
  399.         begin
  400.             Treated := true;
  401.             Num := Prev( Num );
  402.             if Num <> n then
  403.                 RetVal := CurrState
  404.             else
  405.                 Answer := ACKPack;
  406.         end;
  407.  
  408.         if Answer = ACKPack then
  409.         begin
  410.             Treated := true;
  411.             if n <> Num then
  412.                 RetVal := CurrState
  413.             else
  414.             begin
  415.                 Succeeded;
  416.                 FileName := '';
  417.                 FE := NextReadFile( FileName );
  418.                 repeat
  419.                     if FE=FNoError then begin
  420.                         RetVal := FileHeader;
  421.                         PutFileName( FileName, FNPacket );
  422.                     end else if FE=FEndDir then begin
  423.                         RetVal := Break;
  424.                         FE := FNoError;
  425.                     end else if FE IN [FCantOpen,FNoReadPriv] then begin
  426.                         SendErrPack( 
  427.                             '?File open error, terminating file group');
  428.                         writeln(
  429.                             '?File open error, terminating file group');
  430.                         FE := FNoError;
  431.                     end else { Error closing prev. file, retry NextReadFile }
  432.                         FE := NextReadFile( FileName );
  433.                         
  434.                 until FE=FNoError;
  435.             end;
  436.         end;
  437.  
  438.         if not Treated then
  439.         begin
  440.             if Answer = TimOutPack then begin
  441.                 if Debug then begin
  442.                     DbgWrite('Timed out waiting for ACK for EOF-packet');
  443.                     DbgNL;
  444.                 end;
  445.                 RetVal := CurrState;
  446.             end else
  447.                 if Answer = ChkIllPack then begin
  448.                     if Debug then begin
  449.                         DbgWrite('Illegal checksum read - retrying');
  450.                         DbgNL;
  451.                     end;
  452.                     RetVal := CurrState;
  453.                 end else 
  454.                     if Answer = ErrPack then begin
  455.                         RetVal := AbortAll;
  456.                         TreatErrPack( Pack, Num );
  457.                         writeln( RecvrAborted );
  458.                     end else
  459.                     begin
  460.                         writeln( ACKExp );
  461.                         RetVal := Abort1;
  462.                     end;
  463.         end;
  464.     end;
  465.     SendEOF := RetVal;
  466. end;
  467.  
  468. {-----------------------------------------------------------------------------}
  469.  
  470. function    SendBrkP : KermitStates;
  471. var     Answer : PacketType;
  472.         Treated: boolean;
  473.         Pack   : Packet;
  474.         Len    : integer;
  475.         Num    : integer;
  476.         RetVal : KermitStates;
  477.         
  478.         handler CtlC;
  479.         begin
  480.             CtrlCPending := false;
  481.             SendBrkP := AbortCtlC;
  482.             exit( SendBrkP );
  483.         end;
  484.  
  485. begin
  486.     FileName := '';
  487.     if Debug then begin
  488.         DbgWrite('Enter Send-break');
  489.         DbgNL;
  490.     end;
  491.     NumTry := NumTry + 1;
  492.     if NumTry>1 then
  493.         TotTry := TotTry + 1;
  494.     if NumTry > MaxTryPack then begin
  495.         LocalError( '?Unable to receive an ACK for break packet' );
  496.         RetVal := AbortAll;
  497.     end
  498.     else
  499.     begin
  500.         SendPacket (    BrkPack,
  501.                         n,
  502.                         0,
  503.                         Pack (* dummy *)   );
  504.         Answer := ReadPacket ( Num, Len, Pack );
  505.         Treated := false;
  506.         if Answer = NAKPack then
  507.         begin
  508.             Treated := true;
  509.             Num := Prev( Num );
  510.             if Num <> n then
  511.                 RetVal := CurrState
  512.             else
  513.                 Answer := ACKPack;
  514.         end;
  515.         if Answer = ACKPack then
  516.         begin
  517.             Treated := true;
  518.             if n <> ord(Num) then
  519.                 RetVal := CurrState
  520.             else
  521.             begin
  522.                 Succeeded;
  523.                 RetVal := Complete;
  524.             end;
  525.         end;
  526.         if not Treated then
  527.         begin
  528.             if Answer = TimOutPack then begin
  529.                 if Debug then begin
  530.                     DbgWrite('Timed out waiting for ACK for Brk-packet');
  531.                     DbgNL;
  532.                 end;
  533.                 RetVal := CurrState;
  534.             end else
  535.                 if Answer = ChkIllPack then begin
  536.                     if Debug then begin
  537.                         DbgWrite('Illegal checksum read - retrying');
  538.                         DbgNL;
  539.                     end;
  540.                     RetVal := CurrState;
  541.                 end else 
  542.                     if Answer = ErrPack then begin
  543.                         RetVal := AbortAll;
  544.                         TreatErrPack( Pack, Num );
  545.                         writeln( RecvrAborted );
  546.                     end else 
  547.                     begin
  548.                         writeln( ACKExp );
  549.                         SendErrPack( ACKExp );
  550.                         RetVal := AbortAll;
  551.                     end;
  552.         end;
  553.     end;
  554.     SendBrkP := RetVal;
  555. end;
  556.  
  557. {-----------------------------------------------------------------------------}
  558.  
  559. function    SendDiscard : KermitStates;
  560. var     Answer : PacketType;
  561.         Treated: boolean;
  562.         Pack   : Packet;
  563.         Len    : integer;
  564.         Num    : integer;
  565.         RetVal : KermitStates;
  566.         
  567.         handler CtlC;
  568.         begin
  569.             CtrlCPending := false;
  570.             SendDiscard := AbortCtlC;
  571.             exit( SendDiscard );
  572.         end;
  573.  
  574. begin
  575.     if Debug then begin
  576.         DbgWrite('Enter SendDiscard');
  577.         DbgNL;
  578.     end;
  579.     NumTry := NumTry + 1;
  580.     if NumTry>1 then
  581.         TotTry := TotTry + 1;
  582.     if NumTry > MaxTryPack then begin
  583.         LocalError( '?Unable to receive an ACK for EOF discard packet' );
  584.         RetVal := AbortAll;
  585.     end
  586.     else
  587.     begin
  588.         Pack.Data := 'D ';      { EOF discard }
  589.         SendPacket (    EOFPack,
  590.                         n,
  591.                         0,
  592.                         Pack (* dummy *)   );
  593.         Answer := ReadPacket ( Num, Len, Pack );
  594.         Treated := false;
  595.         if Answer = NAKPack then
  596.         begin
  597.             Treated := true;
  598.             Num := Prev( Num );
  599.             if Num <> n then
  600.                 RetVal := CurrState
  601.             else
  602.                 Answer := ACKPack;
  603.         end;
  604.         if Answer = ACKPack then
  605.         begin
  606.             Treated := true;
  607.             if n <> ord(Num) then
  608.                 RetVal := CurrState
  609.             else
  610.             begin
  611.                 Succeeded;
  612.                 RetVal := Complete;
  613.             end;
  614.         end;
  615.         if not Treated then
  616.         begin
  617.             if Answer = TimOutPack then begin
  618.                 if Debug then begin
  619.                     DbgWrite(
  620.                         'Timed out waiting for ACK for EOF-discard packet');
  621.                     DbgNL;
  622.                 end;
  623.                 RetVal := CurrState;
  624.             end else
  625.                 if Answer = ChkIllPack then begin
  626.                     if Debug then begin
  627.                         DbgWrite('Illegal checksum read - retrying');
  628.                         DbgNL;
  629.                     end;
  630.                     RetVal := CurrState;
  631.                 end else 
  632.                     if Answer = ErrPack then begin
  633.                         RetVal := AbortAll;
  634.                         TreatErrPack( Pack, Num );
  635.                         writeln( RecvrAborted );
  636.                     end else 
  637.                     begin
  638.                         writeln( ACKExp );
  639.                         SendErrPack( ACKExp );
  640.                         RetVal := AbortAll;
  641.                     end;
  642.         end;
  643.     end;
  644.     SendDiscard := RetVal;
  645. end;
  646.  
  647. {-----------------------------------------------------------------------------}
  648.  
  649. function    SendSwitch :  KermitStates;
  650.  
  651. var Dummy : FileErrs;
  652.  
  653.     handler CtlCAbort;
  654.     begin
  655.         CtrlCPending := false;
  656.     end;
  657.  
  658. begin
  659.  
  660.     FileName := '';
  661.     CurrState := Init;
  662.     n := 0;
  663.     nn := 0;
  664.     NumTry := 0;
  665.     TotTry := 0;
  666.     InitProgress;
  667.     LoadBusy; 
  668.     ShowPackNum;
  669.  
  670.     while (CurrState <> Complete) and (CurrState <> AbortAll) and 
  671.           (CurrState <> AbortCtlC) do
  672.     begin
  673.  
  674.         case CurrState of
  675.             FileData:
  676.                 CurrState := SendData;
  677.  
  678.             FileHeader:
  679.                 CurrState := SendFileHeader;
  680.  
  681.             Abort1:
  682.                 CurrState := SendDiscard;
  683.  
  684.             EOFile:
  685.                 CurrState := SendEof;
  686.  
  687.             Init:
  688.                 CurrState := SendInitiate;
  689.  
  690.             Break:   
  691.                 CurrState := SendBrkP;
  692.                 
  693.         end; (* case *)
  694.  
  695.         ShowPackNum;            { Show last packet number }
  696.         ShowProgress( ProgressLines );
  697.         if Debug then begin
  698.             DbgWrite ( 'SendSwitch :  State transition to --> ' );
  699.             DbgState ( CurrState );
  700.             DbgNL;
  701.         end;
  702.  
  703.     end; (* while *)
  704.  
  705.     if CurrState = AbortAll then
  706.         Writeln( 'Transfer was aborted at ', FileName )
  707.     else
  708.         if CurrState = AbortCtlC then begin
  709.             writeln( AbortedByCtlC );
  710.             SendErrPack( AbortedByCtlC );
  711.         end;
  712.  
  713.     SendSwitch := CurrState;
  714.     Dummy := FileIdle;
  715.     QuitProgress;
  716. end.
  717.  
  718.  
  719.