home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
ucsdpecan
/
client.text
next >
Wrap
Text File
|
2020-01-01
|
11KB
|
332 lines
unit client;
interface
{Change log:
13 May 89, V1.1: Misc. cleanups to debug messages RTC
30 Apr 89, V1.1: Fixed failure to terminate on maxtry bug RTC
26 Apr 89, V1.1: minor cleanups RTC
16 Apr 89, V1.1: Fixed "garbage in buffer" bug RTC
16 Apr 89, V1.1: Adapted CLIENT Unit from RECEIVE Unit RTC
}
procedure clientsw(var cli_ok: boolean; ptype: char; data: string);
procedure cli_version;
implementation
uses
screenops, {RTC, 10 Jul 88}
{$U kermglob.code} kermglob,
{$U kermutil.code} kermutil,
{$U kermpack.code} kermpack;
const
my_version = ' Client Unit V1.1, 13 May 89';
var
f_save : boolean; { save area for f_is_binary }
procedure clientsw{(var cli_ok: boolean; ptype: char; data: string)};
function cdata: char;
(* client text data *)
var dummy, num, len: integer;
ch: char;
i: integer;
begin
repeat
debugwrite('cdata');
if numtry > maxtry then
begin
currstate := 'a';
exit(cdata)
end;
num_try := num_try + 1;
ch := rpack(len,num,recpkt); (* receive a packet *)
refresh_screen(numtry,n);
if (ch = 'D') then (* got data packet *)
begin
if (num <> (n mod 64)) then (* wrong packet *)
begin
if (oldtry > maxtry) then
begin
cdata := 'a'; (* too many tries, abort *)
exit(cdata)
end; (* if *)
if (num = (pred(n) mod 64)) then (* previous packet again *)
begin (* so re-ACK it *)
spack('Y',num,0,packet);
numtry := 0; (* reset try counter *)
(* stay in same state *)
end (* if *)
else (* wrong number *)
currstate := 'a' (* so abort *)
end (* if *)
else (* right packet *)
begin
bufemp(recpkt,len); (* write data to file *)
if read_ch(keyport, ch) then {check if user wants to can}
packet[0] := ctl(ch);
spack('Y',(n mod 64),ord(ord(ch) in [can_cur,can_all]),
packet); (* ACK packet *)
oldtry := numtry; (* reset try counters *)
numtry := 0;
n := n + 1 (* bump packet number *)
(* stay in data receive state *)
end (* else *)
end (* if 'D' *)
else if (ch = 'X') then (* text header *)
begin
if (oldtry > maxtry) then
begin
cdata := 'a'; (* too many tries, abort *)
exit(cdata)
end; (* if *)
if (num = (pred(n) mod 64)) then (* previous packet again *)
begin (* so re-ACK it *)
spack('Y',num,0,packet);
numtry := 0; (* reset try counter *)
(* stay in same state *)
end (* if *)
else
currstate := 'a' (* not previous packet, abort *)
end (* if 'X' *)
else if (ch = 'Z') then (* end of file *)
begin
if (num <> (n mod 64)) then(* wrong packet, abort *)
begin
cdata := 'a';
exit(cdata)
end; (* if *)
spack('Y',n mod 64,0,packet); (* ok, ACK it *)
close(t_file);
n := n + 1; (* bump packet counter *)
currstate := 'f'; (* go to complete state *)
end (* else if 'Z' *)
else if (ch = 'E') then (* error packet *)
begin
error(recpkt,len); (* display error *)
currstate := 'a' (* and abort *)
end (* if 'E' *)
else if (ch <> chr(0)) then (* some other packet type, *)
currstate := 'a' (* abort *)
until (currstate <> 'd');
cdata := currstate
end; (* cdata *)
function cfile: char;
(* client text header *)
var num, len: integer;
ch: char;
i: integer;
begin (* cfile *)
debugwrite('cfile');
if (numtry > maxtry) then (* if too many tries, give up *)
begin
cfile := 'a';
exit(cfile)
end;
numtry := numtry + 1;
ch := rpack(len,num,recpkt); (* receive a packet *)
refresh_screen(numtry,n);
if ch = 'S' then (* send init, maybe our ACK lost *)
begin
if (oldtry > maxtry) then (* too many tries, abort *)
begin
cfile := 'a';
exit(cfile)
end; (* if *)
if num = (pred(n) mod 64) then (* previous packet mod 64? *)
begin (* yes, ACK it again *)
spar(packet); (* with our send init params *)
spack('Y',num,10,packet);
numtry := 0; (* reset try counter *)
cfile := currstate; (* stay in same state *)
end (* if *)
else (* not previous packet, abort *)
cfile := 'a'
end (* if 'S' *)
else if (ch = 'Z') then (* end of file *)
begin
if (oldtry > maxtry) then (* too many tries, abort *)
begin
cfile := 'a';
exit(cfile)
end; (* if *)
if num = (pred(n) mod 64) then (* previous packet mod 64? *)
begin (* yes, ACK it again *)
spack('Y',num,0,packet);
numtry := 0;
cfile := currstate (* stay in same state *)
end (* if *)
else
cfile := 'a' (* no, abort *)
end (* else if *)
else if (ch = 'X') then (* text header *)
begin (* which is what we really want *)
if (num <> (n mod 64)) then (* if wrong packet, abort *)
begin
cfile := 'a';
exit(cfile)
end;
if not getfil('console:') then { try to open console output }
begin
ioerror(ioresult); { if unsuccessful, tell them }
cfile := 'a'; { and abort }
exit(cfile)
end;
spack('Y',n mod 64,0,packet); (* ACK file header *)
oldtry := numtry; (* reset try counters *)
numtry := 0;
n := n + 1; (* bump packet number *)
cfile := 'd'; (* switch to data state *)
end (* else if *)
else if ch = 'B' then (* break transmission *)
begin
if (num <> (n mod 64)) then (* wrong packet, abort *)
begin
cfile := 'a';
exit(cfile)
end;
spack('Y',n mod 64,0,packet); (* say ok *)
cfile := 'c' (* go to complete state *)
end (* else if *)
else if (ch = 'E') then
begin
error(recpkt,len);
cfile := 'a'
end
else if (ch = chr(0)) then (* returned false *)
cfile := currstate (* so stay in same state *)
else (* some weird state, so abort *)
cfile := 'a'
end; (* cfile *)
function cinit: char;
(* client initialization *)
var num, len: integer; (* packet number and length *)
ch: char;
cmdpkt : packettype;
begin
debugwrite('cinit');
if (numtry > maxtry) then (* if too many tries, give up *)
begin
cinit := 'a';
exit(cinit)
end;
numtry := numtry + 1;
len := length(data);
moveleft(data[1],cmdpkt[0],len);
spack(ptype, n mod 64, len, cmdpkt);
ch := rpack(len,num,recpkt); (* receive a packet *)
refresh_screen(num_try,n);
if (ch = 'S') then (* send init packet *)
begin
rpar(recpkt,len); (* get other side's init data *)
spar(packet); (* fill packet with my init data *)
ctl_set := [chr(0)..chr(31),chr(del),quote];
if en_qbin then ctl_set := ctl_set + [qbin];
spack('Y',n mod 64,10,packet); (* ACK with my params *)
oldtry := numtry; (* save old try count *)
numtry := 0; (* start a new counter *)
n := n + 1; (* bump packet number *)
cinit := 'f'; (* enter file receive state *)
end (* if 'S' *)
else if ch = 'Y' then
begin
cinit := 'c';
if n mod 64 = num then {we have the right ACK}
begin
numtry := 0;
n := n + 1
end
end {if 'Y'}
else if (ch = 'N') then
cinit := 'r'
else if (ch = 'E') then
begin
cinit := 'a';
error(recpkt,len)
end (* if 'E' *)
else if (ch = chr(0)) then
cinit := 'r' (* stay in same state *)
else
cinit := 'a' (* abort *)
end; (* cinit *)
(* state table switcher for receiving packets *)
begin (* clientsw *)
cli_ok := false;
writescreen('Talking to Server');
f_save := f_is_binary; {save for later restore}
f_is_binary := false; {client ONLY recieves text}
currstate := 'r'; (* initial state is receive *)
n := 0; (* set packet # *)
numtry := 0; (* no tries yet *)
flush_comm; {flush any garbage in buffer}
while true do
if currstate in ['d', 'f', 'r', 'c', 'a'] then
case currstate of
'd': currstate := cdata;
'f': currstate := cfile;
'r': currstate := cinit;
'c': begin
f_is_binary := f_save;
cli_ok := true;
exit(clientsw)
end; (* case c *)
'a': begin
f_is_binary := f_save;
exit(clientsw)
end (* case a *)
end (* case *)
else (* state not in legal states *)
begin
debugwrite('Unknown State');
f_is_binary := f_save;
exit(clientsw)
end (* else *)
end; (* clientsw *)
procedure cli_version;
begin
writeln(my_version)
end {cli_version};
end. { client }