home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ucsdpecan.zip / client.text next >
Text File  |  1990-08-05  |  11KB  |  332 lines

  1.  
  2. unit client;
  3.  
  4. interface
  5.  
  6. {Change log:
  7. 13 May 89, V1.1: Misc. cleanups to debug messages   RTC
  8. 30 Apr 89, V1.1: Fixed failure to terminate on maxtry bug   RTC
  9. 26 Apr 89, V1.1: minor cleanups   RTC
  10. 16 Apr 89, V1.1: Fixed "garbage in buffer" bug        RTC
  11. 16 Apr 89, V1.1: Adapted CLIENT Unit from RECEIVE Unit         RTC
  12. }
  13.  
  14.   procedure clientsw(var cli_ok: boolean; ptype: char; data: string);
  15.  
  16.   procedure cli_version;
  17.  
  18.  
  19. implementation
  20.  
  21. uses
  22.    screenops,   {RTC, 10 Jul 88}
  23.    {$U kermglob.code} kermglob,
  24.    {$U kermutil.code} kermutil,
  25.    {$U kermpack.code} kermpack;
  26.  
  27. const
  28.   my_version = '   Client Unit V1.1, 13 May 89';
  29.  
  30. var
  31.   f_save : boolean;             { save area for f_is_binary }
  32.  
  33. procedure clientsw{(var cli_ok: boolean; ptype: char; data: string)};
  34.  
  35. function cdata: char;
  36.  
  37. (* client text data *)
  38.  
  39. var dummy, num, len: integer;
  40.     ch: char;
  41.     i: integer;
  42.  
  43.   begin
  44.  
  45.     repeat
  46.         debugwrite('cdata');
  47.  
  48.         if numtry > maxtry then
  49.           begin
  50.             currstate := 'a';
  51.             exit(cdata)
  52.           end;
  53.         num_try := num_try + 1;
  54.  
  55.         ch := rpack(len,num,recpkt);   (* receive a packet *)
  56.  
  57.         refresh_screen(numtry,n);
  58.  
  59.         if (ch = 'D') then             (* got data packet *)
  60.           begin
  61.             if (num <> (n mod 64)) then (* wrong packet *)
  62.               begin
  63.                 if (oldtry > maxtry) then
  64.                   begin
  65.                     cdata := 'a';      (* too many tries, abort *)
  66.                     exit(cdata)
  67.                   end; (* if *)
  68.  
  69.                 if (num = (pred(n) mod 64)) then (* previous packet again *)
  70.                   begin                (* so re-ACK it *)
  71.                     spack('Y',num,0,packet);
  72.                     numtry := 0;       (* reset try counter *)
  73.                                        (* stay in same state *)
  74.                   end (* if *)
  75.                 else                   (* wrong number *)
  76.                     currstate := 'a'       (* so abort *)
  77.               end (* if *)
  78.             else                       (* right packet *)
  79.               begin
  80.                 bufemp(recpkt,len);  (* write data to file *)
  81.                 if read_ch(keyport, ch) then {check if user wants to can}
  82.                   packet[0] := ctl(ch);
  83.                 spack('Y',(n mod 64),ord(ord(ch) in [can_cur,can_all]),
  84.                       packet); (* ACK packet *)
  85.                 oldtry := numtry;      (* reset try counters *)
  86.                 numtry := 0;
  87.                 n := n + 1             (* bump packet number *)
  88.                                        (* stay in data receive state *)
  89.               end (* else *)
  90.           end (* if 'D' *)
  91.         else if (ch = 'X') then        (* text header *)
  92.           begin
  93.             if (oldtry > maxtry) then
  94.               begin
  95.                 cdata := 'a';          (* too many tries, abort *)
  96.                 exit(cdata)
  97.               end; (* if *)
  98.  
  99.             if (num = (pred(n) mod 64)) then (* previous packet again *)
  100.               begin                    (* so re-ACK it *)
  101.                 spack('Y',num,0,packet);
  102.                 numtry := 0;           (* reset try counter *)
  103.                                                (* stay in same state *)
  104.               end (* if *)
  105.             else
  106.                 currstate := 'a'           (* not previous packet, abort *)
  107.           end (* if 'X' *)
  108.         else if (ch = 'Z') then        (* end of file *)
  109.           begin
  110.             if (num <> (n mod 64)) then(* wrong packet, abort *)
  111.               begin
  112.                 cdata := 'a';
  113.                 exit(cdata)
  114.               end; (* if *)
  115.             spack('Y',n mod 64,0,packet); (* ok, ACK it *)
  116.             close(t_file);
  117.             n :=  n + 1;               (* bump packet counter *)
  118.             currstate := 'f';              (* go to complete state *)
  119.           end (* else if 'Z' *)
  120.         else if (ch = 'E') then        (* error packet *)
  121.           begin
  122.             error(recpkt,len);         (* display error *)
  123.             currstate := 'a'               (* and abort *)
  124.           end (* if 'E' *)
  125.         else if (ch <> chr(0)) then    (* some other packet type, *)
  126.             currstate := 'a'               (* abort *)
  127.     until (currstate <> 'd');
  128.     cdata := currstate
  129.   end; (* cdata *)
  130.  
  131. function cfile: char;
  132.  
  133. (* client text header *)
  134.  
  135. var num, len: integer;
  136.     ch: char;
  137.     i: integer;
  138.  
  139.   begin (* cfile *)
  140.     debugwrite('cfile');
  141.  
  142.     if (numtry > maxtry) then         (* if too many tries, give up *)
  143.       begin
  144.         cfile := 'a';
  145.         exit(cfile)
  146.       end;
  147.     numtry := numtry + 1;
  148.  
  149.     ch := rpack(len,num,recpkt);      (* receive a packet *)
  150.  
  151.     refresh_screen(numtry,n);
  152.  
  153.     if ch = 'S' then                  (* send init, maybe our ACK lost *)
  154.       begin
  155.         if (oldtry > maxtry) then     (* too many tries, abort *)
  156.           begin
  157.             cfile := 'a';
  158.             exit(cfile)
  159.           end; (* if *)
  160.  
  161.         if num = (pred(n) mod 64) then      (* previous packet mod 64? *)
  162.           begin                       (* yes, ACK it again *)
  163.             spar(packet);             (* with our send init params *)
  164.             spack('Y',num,10,packet);
  165.             numtry := 0;              (* reset try counter *)
  166.             cfile := currstate;           (* stay in same state *)
  167.           end (* if *)
  168.         else                          (* not previous packet, abort *)
  169.           cfile := 'a'
  170.       end (* if 'S' *)
  171.     else if (ch = 'Z') then           (* end of file *)
  172.       begin
  173.         if (oldtry > maxtry) then     (* too many tries, abort *)
  174.           begin
  175.             cfile := 'a';
  176.             exit(cfile)
  177.           end; (* if *)
  178.  
  179.         if num = (pred(n) mod 64) then       (* previous packet mod 64? *)
  180.           begin                       (* yes, ACK it again *)
  181.             spack('Y',num,0,packet);
  182.             numtry := 0;
  183.             cfile := currstate            (* stay in same state *)
  184.           end (* if *)
  185.         else
  186.             cfile := 'a'              (* no, abort *)
  187.       end (* else if *)
  188.     else if (ch = 'X') then           (* text header *)
  189.       begin                           (* which is what we really want *)
  190.         if (num <> (n mod 64)) then   (* if wrong packet, abort *)
  191.           begin
  192.             cfile := 'a';
  193.             exit(cfile)
  194.           end;
  195.  
  196.         if not getfil('console:') then  { try to open console output }
  197.           begin
  198.             ioerror(ioresult);          { if unsuccessful, tell them }
  199.             cfile := 'a';               { and abort }
  200.             exit(cfile)
  201.           end;
  202.  
  203.         spack('Y',n mod 64,0,packet); (* ACK file header *)
  204.  
  205.         oldtry := numtry;             (* reset try counters *)
  206.         numtry := 0;
  207.         n := n + 1;                   (* bump packet number *)
  208.         cfile := 'd';                 (* switch to data state *)
  209.       end (* else if *)
  210.     else if ch = 'B' then             (* break transmission *)
  211.       begin
  212.         if (num <> (n mod 64)) then            (* wrong packet, abort *)
  213.           begin
  214.             cfile := 'a';
  215.             exit(cfile)
  216.           end;
  217.         spack('Y',n mod 64,0,packet); (* say ok *)
  218.         cfile := 'c'                  (* go to complete state *)
  219.       end (* else if *)
  220.     else if (ch = 'E') then
  221.       begin
  222.         error(recpkt,len);
  223.         cfile := 'a'
  224.       end
  225.     else if (ch = chr(0)) then        (* returned false *)
  226.         cfile := currstate                (* so stay in same state *)
  227.     else                              (* some weird state, so abort *)
  228.         cfile := 'a'
  229.   end; (* cfile *)
  230.  
  231. function cinit: char;
  232.  
  233. (* client initialization *)
  234.  
  235. var num, len: integer;  (* packet number and length *)
  236.     ch: char;
  237.     cmdpkt : packettype;
  238.  
  239.   begin
  240.     debugwrite('cinit');
  241.  
  242.     if (numtry > maxtry) then         (* if too many tries, give up *)
  243.       begin
  244.         cinit := 'a';
  245.         exit(cinit)
  246.       end;
  247.     numtry := numtry + 1;
  248.     len := length(data);
  249.     moveleft(data[1],cmdpkt[0],len);
  250.     spack(ptype, n mod 64, len, cmdpkt);
  251.  
  252.     ch := rpack(len,num,recpkt); (* receive a packet *)
  253.     refresh_screen(num_try,n);
  254.  
  255.     if (ch = 'S') then           (* send init packet *)
  256.       begin
  257.         rpar(recpkt,len);            (* get other side's init data *)
  258.         spar(packet);            (* fill packet with my init data *)
  259.         ctl_set := [chr(0)..chr(31),chr(del),quote];
  260.         if en_qbin then ctl_set := ctl_set + [qbin];
  261.         spack('Y',n mod 64,10,packet); (* ACK with my params *)
  262.         oldtry := numtry;        (* save old try count *)
  263.         numtry := 0;             (* start a new counter *)
  264.         n := n + 1;              (* bump packet number *)
  265.         cinit := 'f';            (* enter file receive state *)
  266.       end (* if 'S' *)
  267.     else if ch = 'Y' then
  268.       begin
  269.         cinit := 'c';
  270.         if n mod 64 = num then {we have the right ACK}
  271.           begin
  272.             numtry := 0;
  273.             n := n + 1
  274.           end
  275.       end {if 'Y'}
  276.     else if (ch = 'N') then
  277.       cinit := 'r'
  278.     else if (ch = 'E') then
  279.       begin
  280.         cinit := 'a';
  281.         error(recpkt,len)
  282.       end (* if 'E' *)
  283.     else if (ch = chr(0)) then
  284.         cinit := 'r'             (* stay in same state *)
  285.     else
  286.         cinit := 'a'             (* abort *)
  287.   end; (* cinit *)
  288.  
  289. (* state table switcher for receiving packets *)
  290.  
  291.   begin (* clientsw *)
  292.     cli_ok := false;
  293.     writescreen('Talking to Server');
  294.     f_save := f_is_binary; {save for later restore}
  295.     f_is_binary := false;  {client ONLY recieves text}
  296.     currstate := 'r';            (* initial state is receive *)
  297.     n := 0;                  (* set packet # *)
  298.     numtry := 0;             (* no tries yet *)
  299.     flush_comm;         {flush any garbage in buffer}
  300.  
  301.     while true do
  302.         if currstate in ['d', 'f', 'r', 'c', 'a'] then
  303.           case currstate of
  304.               'd': currstate := cdata;
  305.               'f': currstate := cfile;
  306.               'r': currstate := cinit;
  307.               'c': begin
  308.                      f_is_binary := f_save;
  309.                      cli_ok := true;
  310.                      exit(clientsw)
  311.                    end; (* case c *)
  312.               'a': begin
  313.                      f_is_binary := f_save;
  314.                      exit(clientsw)
  315.                    end (* case a *)
  316.             end (* case *)
  317.         else (* state not in legal states *)
  318.           begin
  319.             debugwrite('Unknown State');
  320.             f_is_binary := f_save;
  321.             exit(clientsw)
  322.           end (* else *)
  323.   end; (* clientsw *)
  324.  
  325. procedure cli_version;
  326.  
  327.   begin
  328.     writeln(my_version)
  329.   end {cli_version};
  330.  
  331. end. { client }
  332.