home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ucsdmagiscan2.zip / recsw.text < prev    next >
Text File  |  2011-08-11  |  16KB  |  475 lines

  1.  
  2. (* RECEIVE SECTION *)
  3. UCSD Pascal KERMIT for the Terak p-System, from Kate MacGregor, Cornell U
  4. Modified for the Magiscan 2 by H Balen, Lancaster U 
  5.  
  6. segment procedure recsw(var rec_ok: boolean);
  7.  
  8. function rdata: char;
  9.  
  10. (* send file data *)
  11.  
  12. var Blk, num, len: integer;
  13.     ch: char;
  14.  
  15.   begin
  16.  
  17.     repeat
  18.         if numtry > maxtry then
  19.           begin
  20.             debugwrite('too many intial retries in rdata');
  21.             state := 'a';
  22.             exit(rdata)
  23.           end;
  24.  
  25.         num_try := num_try + 1;
  26.  
  27.         ch := rpack(len,num,recpkt);   (* receive a packet *)
  28.         if debug and (ch<>chr(0)) then packetwrite(recpkt,len);
  29.  
  30.         refresh_screen(numtry,n);
  31.  
  32.         if (ch = 'D') then             (* got data packet *)
  33.           begin
  34.             if (num <> (n mod 64)) then (* wrong packet *)
  35.               begin
  36.                 if (oldtry > maxtry) then
  37.                   begin
  38.                     debugwrite('too many data retries in rdata');
  39.                     rdata := 'a';      (* too many tries, abort *)
  40.                     exit(rdata)
  41.                   end; (* if *)
  42.  
  43.                 n := n - 1;
  44.  
  45.                 if (num = (n mod 64)) then (* previous packet again *)
  46.                   begin                (* so re-ACK it *)
  47.                     debugint('re-acking ',num);
  48.                     spack('Y',num,6,packet);
  49.                     numtry := 0;       (* reset try counter *)
  50.                                        (* stay in same state *)
  51.                   end (* if *)
  52.                 else begin             (* wrong number *)
  53.                     debugwrite('wrong data sequence no. in rdata');
  54.                     state := 'a'       (* so abort *)
  55.                     end
  56.               end (* if *)
  57.             else                       (* right packet *)
  58.               begin
  59.                 if TranState = TxtFile then
  60.                   bufemp(recpkt,f,len)  (* write data to file *)
  61.                  else
  62.                    Bbufemp(recpkt,len);
  63.                 spack('Y',(n mod 64),0,packet); (* ACK packet *)
  64.                 oldtry := numtry;      (* reset try counters *)
  65.                 if numtry > 1 then
  66.                     if istbrr then     (* clear buffer *)
  67.                       begin
  68.                         ch:=rcvbbt;
  69.                         ch:='D';
  70.                       end;
  71.                 numtry := 0;
  72.                 n := n + 1             (* bump packet number *)
  73.                                        (* stay in data send state *)
  74.               end (* else *)
  75.           end (* if 'D' *)
  76.         else if (ch = 'F') then        (* file header *)
  77.           begin
  78.             if (oldtry > maxtry) then
  79.               begin
  80.                 debugwrite('too many file head tries in rdata');
  81.                 rdata := 'a';          (* too many tries, abort *)
  82.                 exit(rdata)
  83.               end; (* if *)
  84.  
  85.             n := n - 1;
  86.  
  87.             if (num = (n mod 64)) then (* previous packet again *)
  88.               begin                    (* so re-ACK it *)
  89.                 debugint('re-acking file header ',num);
  90.                 spack('Y',num,0,packet);
  91.                 if istbrr then begin
  92.                   ch:=rcvbbt; (* and empty out buffer *)
  93.                   ch:='F';
  94.                   end;
  95.                 numtry := 0;           (* reset try counter *)
  96.                 state := state;        (* stay in same state *)
  97.               end (* if *)
  98.             else begin
  99.               debugwrite('file info not previous packet in rdata');
  100.                 state := 'a'           (* not previous packet, abort *)
  101.                 end
  102.           end (* if 'F' *)
  103.         else if (ch = 'Z') then        (* end of file *)
  104.           begin
  105.             if (num <> (n mod 64)) then(* wrong packet, abort *)
  106.               begin
  107.                 debugwrite('wrong eof packet in rdata');
  108.                 rdata := 'a';
  109.                 exit(rdata)
  110.               end; (* if *)
  111.             spack('Y',n mod 64,0,packet); (* ok, ACK it *)
  112.             { CloseF(filename,True); }
  113.             n :=  n + 1;               (* bump packet counter *)
  114.             state := 'b';              (* go to break state *)
  115.             oldtry := numtry;
  116.             numtry := 0;
  117.           end (* else if 'Z' *)
  118.         else if (ch = 'E') then        (* error packet *)
  119.           begin
  120.             error(recpkt,len);         (* display error *)
  121.             state := 'a'               (* and abort *)
  122.           end (* if 'E' *)
  123.         else if (ch <> chr(0)) then begin (* some other packet type, *)
  124.             state := 'a';                 (* abort *)
  125.             debugwrite('wierd rdata packet');
  126.             end
  127.     until (state <> 'd');
  128.     rdata := state
  129.   end; (* rdata *)
  130.  
  131. function rfile: char;
  132.  
  133. (* receive file header *)
  134.  
  135. var num, len: integer;
  136.     ch: char;
  137.     oldfn: string;
  138.     i: integer;
  139.  
  140. procedure makename(recpkt: packettype; var fn: string; l: integer);
  141.  
  142. function exist(fn: string): boolean;
  143.  
  144. (* returns true if file named fn exists *)
  145.  
  146. var f: file;
  147.     OK : boolean;
  148.  
  149.   begin
  150.     (*$I-*) (* turn off i/o checking *)
  151.     reset(f,concat(disk,fn));
  152.     OK := (ioresult = 0);
  153.     if OK then
  154.       close(f);
  155.     Exist := OK
  156.     (*$I+*)
  157.   end; (* exist *)
  158.  
  159. procedure checkname(var fn: string);
  160.  
  161. (* if file fn exists, makes a new name which doesn't *)
  162. (* does this by changing letters in file name until it *)
  163. (* finds some combination which doesn't exitst *)
  164.  
  165. var ch: char;
  166.     i: integer;
  167.  
  168.   begin
  169.     i := 1;
  170.     while (i <= length(fn)) and exist(fn) do
  171.       begin
  172.         ch := 'A';
  173.         while (ch in ['A'..'Z']) and exist(fn) do
  174.           begin
  175.             fn[i] := ch;
  176.             ch := succ(ch);
  177.           end; (* while *)
  178.         i := i + 1
  179.       end; (* while *)
  180.     end; (* checkname *)
  181.  
  182.   begin (* makename *)
  183.     fn := copy('               ',1,15);    (* stretch length *)
  184.     moveleft(recpkt[0],fn[1],l);           (* get filename from packet *)
  185.     oldfn := copy(fn, 1,l);                (* save fn sent to show user *)
  186.     fn := copy(fn,1,min(15,l));            (* set length of filename *)
  187.                                            (* and make sure <= 15 *)
  188.     uppercase(fn);
  189.     {
  190.     if length(fn) > 10 then
  191.       fn := copy(fn,1,10);           (* can only be 15 long in all *)
  192.     }
  193.     if TranState = TxtFile then
  194.       begin
  195.       if pos('.TEXT',fn) <> (length(fn)-4) then
  196.         begin
  197.         if length(fn) > 10 then
  198.           fn := copy(fn,1,10);           (* can only be 15 long in all *)
  199.         fn := concat(fn,'.TEXT');          (* and we'll add .TEXT *)
  200.         end; (* if *)
  201.       end
  202.      else
  203.        if TranState = CodeFile then
  204.          begin{ Same as above except this is a code file }
  205.          if pos('.CODE',fn) <> (length(fn)-4) then
  206.            begin
  207.            if length(fn) > 10 then
  208.              fn := copy(fn,1,10);
  209.            fn := concat(fn,'.CODE')
  210.            end
  211.          end
  212.         else
  213.           begin { Same as last two but this is a data file }
  214.           if pos('.DATA',fn) <> (length(fn)-4) then
  215.             begin
  216.             if length(fn) > 10 then
  217.               fn := copy(fn,1,10);
  218.             fn := concat(fn,'.DATA')
  219.             end;
  220.           end;
  221.     if fwarn then                          (* if file warning is on *)
  222.         checkname(fn);                       (* must check that name unique *)
  223.   end; (* makename *)
  224.  
  225.   begin (* rfile *)
  226.     if debug then
  227.         debugwrite('rfile');
  228.  
  229.     if (numtry > maxtry) then         (* if too many tries, give up *)
  230.       begin
  231.         rfile := 'a';
  232.         exit(rfile)
  233.       end;
  234.     numtry := numtry + 1;
  235.  
  236.     ch := rpack(len,num,recpkt);      (* receive a packet *)
  237.     if debug and (ch<>chr(0)) then packetwrite(recpkt,len);
  238.     refresh_screen(numtry,n);
  239.  
  240.     if ch = 'S' then                  (* send init, maybe our ACK lost *)
  241.       begin
  242.         if (oldtry > maxtry) then     (* too many tries, abort *)
  243.           begin
  244.             debugwrite('too many tries in rfile init');
  245.             rfile := 'a';
  246.             exit(rfile)
  247.           end; (* if *)
  248.  
  249.         n := n - 1;
  250.  
  251.         if num = (n mod 64) then      (* previous packet mod 64? *)
  252.           begin                       (* yes, ACK it again *)
  253.             debugint('re-acking init ',num);
  254.             spar(packet);             (* with our send init params *)
  255.             spack('Y',num,7,packet);
  256.             numtry := 0;              (* reset try counter *)
  257.             rfile := state;           (* stay in same state *)
  258.           end (* if *)
  259.         else                          (* not previous packet, abort *)
  260.           state := 'a'
  261.       end (* if 'S' *)
  262.     else if (ch = 'Z') then           (* end of file *)
  263.       begin
  264.         if (oldtry > maxtry) then     (* too many tries, abort *)
  265.           begin
  266.             debugwrite('too many tries in filehead eof');
  267.             rfile := 'a';
  268.             exit(rfile)
  269.           end; (* if *)
  270.  
  271.         n := n - 1;
  272.  
  273.         if num = (n mod 64) then       (* previous packet mod 64? *)
  274.           begin                       (* yes, ACK it again *)
  275.             debugint('re-acking eof ',num);
  276.             spack('Y',num,0,packet);
  277.             numtry := 0;
  278.             rfile := state            (* stay in same state *)
  279.           end (* if *)
  280.         else
  281.             rfile := 'a'              (* no, abort *)
  282.       end (* else if *)
  283.     else if (ch = 'F') then           (* file header *)
  284.       begin                           (* which is what we really want *)
  285.         if (num <> (n mod 64)) then   (* if wrong packet, abort *)
  286.           begin
  287.             debugwrite('wrong seq. of file header');
  288.             rfile := 'a';
  289.             exit(rfile)
  290.           end;
  291.  
  292.         makename(recpkt,filename,len); (* get filename, make unique if filew *)
  293.         gotoxy(filepos,fileline);
  294.         write(oldfn,' ==> ',filename);
  295.  
  296.         if not getfil(filename) then  (* try to open new file *)
  297.           begin
  298.             inoerror(ioresult);        (* if unsuccessful, tell them *)
  299.             rfile := 'a';             (* and abort *)
  300.             exit(rfile)
  301.           end; (* if *)
  302.  
  303.         spack('Y',n mod 64,0,packet); (* ACK file header *)
  304.         oldtry := numtry;             (* reset try counters *)
  305.         numtry := 0;
  306.         n := n + 1;                   (* bump packet number *)
  307.         rfile := 'd';                 (* switch to data state *)
  308.       end (* else if *)
  309.     else if ch = 'B' then             (* break transmission *)
  310.       begin
  311.         if (num <> (n mod 64)) then            (* wrong packet, abort *)
  312.           begin
  313.             debugwrite('wrong sequence in break packet');
  314.             rfile := 'a';
  315.             exit(rfile)
  316.           end;
  317.         spack('Y',n mod 64,0,packet); (* say ok *)
  318.         rfile := 'c'                  (* go to complete state *)
  319.       end (* else if *)
  320.     else if (ch = 'E') then
  321.       begin
  322.         error(recpkt,len);
  323.         rfile := 'a'
  324.       end
  325.     else if (ch = chr(0)) then        (* returned false *)
  326.         rfile := state                (* so stay in same state *)
  327.     else begin                        (* some weird state, so abort *)
  328.         rfile := 'a';
  329.         debugwrite('wierd rfile packet');
  330.         end
  331.   end; (* rfile *)
  332.  
  333. function rbreak: char;
  334.  
  335. (* receive file header *)
  336.  
  337. var num, len: integer;
  338.     ch: char;
  339.     i: integer;
  340.  
  341.   begin (* rbreak *)
  342.     if debug then
  343.         debugwrite('rbreak');
  344.  
  345.     if (numtry > maxtry) then         (* if too many tries, give up *)
  346.       begin
  347.         rbreak := 'a';
  348.         exit(rbreak)
  349.       end;
  350.     numtry := numtry + 1;
  351.  
  352.     ch := rpack(len,num,recpkt);      (* receive a packet *)
  353.     if debug and (ch<>chr(0)) then packetwrite(recpkt,len);
  354.     refresh_screen(numtry,n);
  355.  
  356.     if (ch = 'Z') then
  357.       begin{ is previous eof packet }
  358.  
  359.       n := n -1;
  360.       if (num = (n mod 64)) then (* previous packet again *)
  361.         begin                (* so re-ACK it *)
  362.           debugint('re-acking ',num);
  363.           spack('Y',num,6,packet);
  364.           numtry := 0;       (* reset try counter *)
  365.                              (* stay in same state *)
  366.         end (* if *)
  367.       else begin             (* wrong number *)
  368.           debugwrite('wrong data sequence no. in rbreak');
  369.           state := 'a'       (* so abort *)
  370.           end
  371.       end
  372.    else
  373.     if ch = 'B' then             (* break transmission *)
  374.       begin
  375.         if (num <> (n mod 64)) then            (* wrong packet, abort *)
  376.           begin
  377.             debugwrite('wrong sequence in break packet');
  378.             rbreak := 'a';
  379.             exit(rbreak)
  380.           end;
  381.         spack('Y',n mod 64,0,packet); (* say ok *)
  382.         rbreak := 'c'                  (* go to complete state *)
  383.       end (* else if *)
  384.     else if (ch = 'E') then
  385.       begin
  386.         error(recpkt,len);
  387.         rbreak := 'a'
  388.       end
  389.     else if (ch = chr(0)) then        (* returned false *)
  390.         rbreak := state                (* so stay in same state *)
  391.     else begin                        (* some weird state, so abort *)
  392.         rbreak := 'a';
  393.         debugwrite('wierd break packet');
  394.         end
  395.   end; (* rbreak *)
  396.  
  397. function rinit: char;
  398.  
  399. (* receive initialization *)
  400.  
  401. var num, len: integer;  (* packet number and length *)
  402.     ch: char;
  403.  
  404.   begin
  405.     if debug then
  406.         debugwrite('rinit');
  407.  
  408.     numtry := numtry + 1;
  409.  
  410.     ch := rpack(len,num,recpkt); (* receive a packet *)
  411.     if debug and (ch<>chr(0)) then packetwrite(recpkt,len);
  412.     refresh_screen(num_try,n);
  413.  
  414.     if (ch = 'S') then           (* send init packet *)
  415.       begin
  416.         rpar(recpkt);            (* get other side's init data *)
  417.         spar(packet);            (* fill packet with my init data *)
  418.         if TranState <> TxtFile then
  419.           ctl_set := [chr(1)..chr(31),chr(del),quote,bquote]
  420.          else
  421.            ctl_set := [chr(1)..chr(31),chr(del),quote];
  422.         spack('Y',n mod 64,7,packet); (* ACK with my params *)
  423.         oldtry := numtry;        (* save old try count *)
  424.         numtry := 0;             (* start a new counter *)
  425.         n := n + 1;              (* bump packet number *)
  426.         rinit := 'f';            (* enter file send state *)
  427.       end (* if 'S' *)
  428.     else if (ch = 'E') then
  429.       begin
  430.         rinit := 'a';
  431.         error(recpkt,len)
  432.       end (* if 'E' *)
  433.     else if (ch = chr(0)) then
  434.         rinit := 'r'             (* stay in same state *)
  435.     else begin
  436.         rinit := 'a';             (* abort *)
  437.         debugwrite('wierd rinit packet');
  438.         end
  439.   end; (* rinit *)
  440.  
  441. (* state table switcher for receiving packets *)
  442.  
  443.   begin (* recswok *)
  444.     writescreen('Receiving');
  445.     state := 'r';            (* initial state is send *)
  446.     n := 0;                  (* set packet # *)
  447.     numtry := 0;             (* no tries yet *)
  448.  
  449.     while true do
  450.         if state in ['d', 'f', 'r', 'c', 'a', 'b'] then
  451.           case state of
  452.               'd': state := rdata;
  453.               'f': state := rfile;
  454.               'r': state := rinit;
  455.               'b': state := rbreak;
  456.               'c': begin
  457.                      rec_ok := true;
  458.                      CloseF(filename,true);
  459.                      exit(recsw)
  460.                    end; (* case c *)
  461.               'a': begin
  462.                      rec_ok := false;
  463.                      CloseF(filename,false);
  464.                      exit(recsw)
  465.                    end (* case a *)
  466.             end (* case *)
  467.         else (* state not in legal states *)
  468.           begin
  469.             rec_ok := false;
  470.             CloseF(filename,False);
  471.             exit(recsw)
  472.           end (* else *)
  473.   end; (* recsw *)
  474.  
  475.