home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / ucsdwdme / sendsw.text < prev    next >
Text File  |  1984-12-02  |  12KB  |  449 lines

  1.  
  2. (* Send Section *)
  3. UCSD Pascal KERMIT for the Terak p-System, from Kate MacGregor, Cornell U
  4.  
  5. segment procedure sendsw(var send_ok: boolean);
  6.  
  7. var io_status: integer;
  8.  
  9. procedure openfile;
  10.  
  11. (* resets file & gets past first 2 blocks *)
  12.  
  13.   begin
  14.     (*$I-*) (* turn off compiler i/o checking temporarily *)
  15.     reset(oldf,filename);
  16.     (*$I+*) (* turn compiler i/o checking back on *)
  17.     io_status := io_result;
  18.     if (iostatus = 0) then
  19.       if (pos('.TEXT',filename) = length(filename) - 4) then
  20.                                           (* is a text file, so *)
  21.           i := blockread(oldf,filebuf,2); (* skip past 2 block header *)
  22.   end; (* openfile *)
  23.  
  24. function sinit: char;
  25.  
  26. (* send init packet & receive other side's *)
  27.  
  28. var num, len, i: integer;  (* packet number and length *)
  29.     ch: char;
  30.  
  31.   begin
  32.     if debug then
  33.         debugwrite('sinit');
  34.  
  35.     if numtry > maxtry then
  36.       begin
  37.         sinit := 'a';
  38.         exit(sinit)
  39.       end;
  40.  
  41.     num_try := num_try + 1;
  42.     spar(packet);
  43.  
  44.     if istbrr then ch:=rcvbbt; (* clear modem buffer *)
  45.  
  46.     refresh_screen(numtry,n);
  47.  
  48.     spack('S',n mod 64,6,packet);
  49.  
  50.     ch := rpack(len,num,recpkt);
  51.  
  52.     if (ch = 'N') then
  53.       begin
  54.         sinit := 's';
  55.         exit(sinit)
  56.       end (* if 'N' *)
  57.     else if (ch = 'Y') then
  58.       begin
  59.         if ((n mod 64) <> num) then       (* not the right ack *)
  60.           begin
  61.             sinit := state;
  62.             exit(sinit)
  63.           end;
  64.         rpar(recpkt);
  65.         if (eol = chr(0)) then   (* if they didn't spec eol *)
  66.             eol := chr(my_eol);    (* use mine *)
  67.         if (quote = chr(0)) then (* if they didn't spec quote *)
  68.             quote := my_quote;     (* use mine *)
  69.         ctl_set := [chr(1)..chr(31),chr(del),quote];
  70.         numtry := 0;
  71.         n := n + 1;              (* increase packet number *)
  72.         sinit := 'f';
  73.         exit(sinit)
  74.       end (* else if 'Y' *)
  75.     else if (ch = 'E') then
  76.       begin
  77.         error(recpkt,len);
  78.         sinit := 'a'
  79.       end (* if 'E' *)
  80.     else if (ch = chr(0)) then
  81.         sinit := state
  82.     else if (ch <> 'N') then
  83.         sinit := 'a'
  84.   end; (* sinit *)
  85.  
  86. function sdata: char;
  87.  
  88. (* send file data *)
  89.  
  90. var num, len: integer;
  91.     ch: char;
  92.     packarray: array[false..true] of packettype;
  93.     sizearray: array[false..true] of integer;
  94.     current: boolean;
  95.     b: boolean;
  96.  
  97. function other(b: boolean): boolean;
  98.  
  99. (* complements a boolean which is used as array index *)
  100.  
  101.   begin
  102.     if b then
  103.         other := false
  104.     else
  105.         other := true
  106.   end; (* other *)
  107.  
  108.   begin
  109.     current := true;
  110.     packarray[current] := packet;
  111.     sizearray[current] := size;
  112.     while (state = 'd') do
  113.       begin
  114.         if (numtry > maxtry) then             (* if too many tries, give up *)
  115.             state := 'a';
  116.  
  117.         b := other(current);
  118.         numtry := numtry + 1;
  119.  
  120.                                           (* send a data packet *)
  121.         spack('D',n mod 64,sizearray[current],packarray[current]);
  122.  
  123.         refresh_screen(numtry,n);
  124.                                           (* set up next packet *)
  125.         sizearray[b] := bufill(packarray[b]);
  126.  
  127.         ch := rpack(len,num,recpkt);      (* receive a packet *)
  128.         if ch = 'N' then                  (* NAK, so just stay in this state *)
  129.             if ((n+1) mod 64 <> num) then (* unless NAK for next, which *)
  130.                 sdata := state
  131.             else                          (* is just like ACK for this packet *)
  132.               begin
  133.                 if num > 0 then
  134.                     num := (num - 1)      (* in which case, decrement num *)
  135.                 else
  136.                     num := 63;
  137.                 ch := 'Y';                (* and indicate an ACK *)
  138.               end; (* else *)
  139.  
  140.         if (ch = 'Y') then
  141.            begin
  142.              if ((n mod 64) <> num) then (* if wrong ACK *)
  143.                begin
  144.                  sdata := state;         (* stay in same state *)
  145.                  exit(sdata);            (* get out of here *)
  146.                end; (* if *)
  147.              if numtry > 1 then          (* if anything in buffer, flush it *)
  148.                  if istbrr then begin
  149.                    ch:=rcvbbt;
  150.                    ch:='Y';
  151.                    end;
  152.              numtry := 0;
  153.              n := n + 1;
  154.              current := b;
  155.              if sizearray[current] = ateof then
  156.                  state := 'z'            (* set state to eof *)
  157.              else
  158.                  state := 'd'            (* else stay in data state *)
  159.            end (* if *)
  160.           else if (ch = 'E') then
  161.             begin
  162.               error(recpkt,len);
  163.               state := 'a'
  164.             end (* if 'E' *)
  165.           else if (ch = chr(0)) then      (* receive failure, so stay in d *)
  166.             begin
  167.             end
  168.           else if (ch <> 'N') then
  169.             state := 'a'                  (* on any other goto abort state *)
  170.       end; (* while *)
  171.     size := sizearray[current];
  172.     packet := packarray[current];
  173.     sdata := state
  174.   end; (* sdata *)
  175.  
  176. function sfile: char;
  177.  
  178. (* send file header *)
  179.  
  180. var num, len, i: integer;
  181.     ch: char;
  182.     fn: packettype;
  183.     oldfn: string;
  184.  
  185. procedure legalize(var fn: string);
  186.  
  187. (* make sure file name will be legal to other computer *)
  188.  
  189. var count, i, j, l: integer;
  190.  
  191. procedure uppercase(var s: string);
  192.  
  193. var i: integer;
  194.  
  195.   begin
  196.     for i := 1 to length(s) do
  197.         if s[i] in ['a'..'z'] then
  198.             s[i] := chr(ord('A') + ord(s[i]) - ord('a'))
  199.   end; (* uppercase *)
  200.  
  201.   begin
  202.     count := 0;
  203.     l := length(fn);
  204.     for i := 1 to l do                                  (* count '.'s in fn *)
  205.         if fn[i] = '.' then
  206.             count := count + 1;
  207.     for i := 1 to count-1 do                            (* remove all but 1 *)
  208.       begin
  209.         j := 1;
  210.         while (j < l) and (fn[j] <> '.') do
  211.             j := j + 1;
  212.             delete(fn,j,1);l := l - 1
  213.       end; (* for i *)
  214.     l := length(fn);
  215.     i := pos(':',fn);
  216.     if (i <> 0) then
  217.       begin
  218.         fn := copy(fn,i,l-i);
  219.         l := length(fn)
  220.       end;
  221.     i := 1;
  222.     while (i <= length(fn)) do
  223.         if not(fn[i] in ['a'..'z','A'..'Z','.','0'..'9']) then
  224.             delete(fn,i,1)
  225.         else
  226.             i := i + 1;
  227.     uppercase(fn)
  228.   end; (* legalize *)
  229.  
  230.   begin
  231.     if debug then
  232.         debugwrite('sfile');
  233.  
  234.     if (numtry > maxtry) then          (* if too many tries, give up *)
  235.       begin
  236.         sfile := 'a';
  237.         exit(sfile)
  238.       end;
  239.     numtry := numtry + 1;
  240.  
  241.     oldfn := filename;
  242.     legalize(filename);                (* make filename acceptable to remote *)
  243.     len := length(filename);
  244.  
  245.     moveleft(filename[1],fn[0],len);   (* move filename into a packettype *)
  246.  
  247.     gotoxy(filepos,fileline);
  248.     write(oldfn,' ==> ',filename);
  249.  
  250.     refresh_screen(numtry,n);
  251.  
  252.     spack('F',n mod 64,len,fn);               (* send file header packet *)
  253.  
  254.     size := bufill(packet);            (* get first data from file *)
  255.                                        (* while waiting for response *)
  256.  
  257.     ch := rpack(len,num,recpkt);
  258.     if ch = 'N' then                   (* NAK, so just stay in this state *)
  259.         if ((n+1) mod 64 <> num) then  (* unless NAK for next packet, which *)
  260.             exit(sfile)                (* is just like ACK for this packet *)
  261.         else
  262.           begin
  263.             if (num > 0) then
  264.                 num := (num - 1)       (* in which case, decrement num *)
  265.             else
  266.                 num := 63;
  267.             ch := 'Y';                 (* and indicate an ACK *)
  268.           end; (* else *)
  269.  
  270.     if (ch = 'Y') then
  271.       begin
  272.         if ((n mod 64) <> num) then  (* if wrong ACK, stay in F state *)
  273.             exit(sfile);
  274.         numtry := 0;
  275.         n := n + 1;
  276.         sfile := 'd';
  277.       end (* if *)
  278.     else if (ch = 'E') then
  279.       begin
  280.         error(recpkt,len);
  281.         sfile := 'a'
  282.       end (* if 'E' *)
  283.     else if (ch <> chr(0)) and (ch <> 'N') then (* don't recognize it *)
  284.         sfile := 'a'
  285.   end; (* sfile *)
  286.  
  287. function seof: char;
  288.  
  289. (* send end of file *)
  290.  
  291. var num, len: integer;
  292.     ch: char;
  293.  
  294.   begin
  295.     if debug then
  296.         debugwrite('seof');
  297.  
  298.     if (numtry > maxtry) then          (* if too many tries, give up *)
  299.       begin
  300.         seof := 'a';
  301.         exit(seof)
  302.       end;
  303.     numtry := numtry + 1;
  304.  
  305.     refresh_screen(numtry,n);
  306.  
  307.     spack('Z',(n mod 64),0,packet);    (* send end of file packet *)
  308.  
  309.     if debug then
  310.         debugwrite('seof1');
  311.  
  312.     ch := rpack(len,num,recpkt);
  313.     if ch = 'N' then                   (* NAK, so just stay in this state *)
  314.         if ((n+1) mod 64 <> num) then  (* unless NAK for next packet, which *)
  315.             exit(seof)                 (* is just like ACK for this packet *)
  316.         else
  317.           begin
  318.             if num > 0 then
  319.                 num := (num - 1)       (* in which case, decrement num *)
  320.             else
  321.                 num := 63;
  322.             ch := 'Y';                 (* and indicate an ACK *)
  323.           end; (* else *)
  324.  
  325.     if (ch = 'Y') then
  326.       begin
  327.         if debug then
  328.             debugwrite('seof2');
  329.         if ((n mod 64) <> num) then     (* if wrong ACK, stay in F state *)
  330.             exit(seof);
  331.         numtry := 0;
  332.         n := n + 1;
  333.         if debug then
  334.             debugwrite(concat('closing ',s));
  335.         close(oldf);
  336.         seof := 'b'
  337.       end (* if *)
  338.     else if (ch = 'E') then
  339.       begin
  340.         error(recpkt,len);
  341.         seof := 'a'
  342.       end (* if 'E' *)
  343.     else if (ch = chr(0)) then         (* receive failed, so stay in z state *)
  344.       begin
  345.       end
  346.     else if (ch <> 'N') then           (* other error, just abort *)
  347.         seof := 'a'
  348.   end; (* seof *)
  349.  
  350. function sbreak: char;
  351.  
  352. var num, len: integer;
  353.     ch: char;
  354.  
  355. (* send break (end of transmission) *)
  356.  
  357.   begin
  358.     if debug then
  359.         debugwrite('sbreak');
  360.  
  361.     if (numtry > maxtry) then          (* if too many tries, give up *)
  362.       begin
  363.         sbreak := 'a';
  364.         exit(sbreak)
  365.       end;
  366.     numtry := numtry + 1;
  367.  
  368.     refresh_screen(numtry,n);
  369.  
  370.     spack('B',(n mod 64),0,packet);    (* send end of file packet *)
  371.  
  372.     ch := rpack(len,num,recpkt);
  373.     if ch = 'N' then                   (* NAK, so just stay in this state *)
  374.         if ((n+1) mod 64 <> num) then  (* unless NAK for next packet, which *)
  375.             exit(sbreak)               (* is just like ACK for this packet *)
  376.         else
  377.           begin
  378.             if num > 0 then
  379.                 num := (num - 1)       (* in which case, decrement num *)
  380.             else
  381.                 num := 63;
  382.             ch := 'Y';                 (* and indicate an ACK *)
  383.           end; (* else *)
  384.  
  385.     if (ch = 'Y') then
  386.       begin
  387.         if ((n mod 64) <> num) then    (* if wrong ACK, stay in B state *)
  388.             exit(sbreak);
  389.         numtry := 0;
  390.         n := n + 1;
  391.         sbreak := 'c'                  (* else, switch state to complete *)
  392.       end (* if *)
  393.     else if (ch = 'E') then
  394.       begin
  395.         error(recpkt,len);
  396.         sbreak := 'a'
  397.       end (* if 'E' *)
  398.     else if (ch = chr(0)) then         (* receive failed, so stay in z state *)
  399.       begin
  400.       end
  401.     else if (ch <> 'N') then           (* other error, just abort *)
  402.         sbreak := 'a'
  403.   end; (* sbreak *)
  404.  
  405. (* state table switcher for sending *)
  406.  
  407.   begin (* sendsw *)
  408.  
  409.     if debug then
  410.         debugwrite(concat('Opening ',filename));
  411.  
  412.     openfile;
  413.     if io_status <> 0 then
  414.       begin
  415.         writeln(chr(esc),'E'{clear_screen});
  416.         io_error(io_status);
  417.         send_ok := false;
  418.         exit(sendsw)
  419.       end;
  420.  
  421.     write_screen('Sending');
  422.     state := 's';
  423.     n := 0;       (* set packet # *)
  424.     numtry := 0;
  425.     while true do
  426.         if state in ['d', 'f', 'z', 's', 'b', 'c', 'a'] then
  427.           case state of
  428.               'd': state := sdata;
  429.               'f': state := sfile;
  430.               'z': state := seof;
  431.               's': state := sinit;
  432.               'b': state := sbreak;
  433.               'c': begin
  434.                      send_ok := true;
  435.                      exit(sendsw)
  436.                    end; (* case c *)
  437.               'a': begin
  438.                      send_ok := false;
  439.                      exit(sendsw)
  440.                    end (* case a *)
  441.             end (* case *)
  442.         else (* state not in legal states *)
  443.           begin
  444.             send_ok := false;
  445.             exit(sendsw)
  446.           end (* else *)
  447.   end; (* sendsw *)
  448.  
  449.