home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-11-27 | 27.8 KB | 1,157 lines |
- 00 07:12:00 11/27/1990
-
-
-
-
- "Super_Z" definitions and specifications:
-
-
- Super_Z is a trademark name of Personalized Computer
- Programming Company "PC²" denoting a method of zmodem file
- transfer enhancement.
-
- You may/should use the name to refer to this enhancement
- method in your own zmodem application without concern. All
- we ask is that you inform everyone in your documentation
- that Super_Z was developed and the name coined by PC².
-
- If you use Super_Z in a commercial environment, great! We
- hope you have much success but we don't want your money.
-
- It's payment enough just knowing you appreciate the work I
- put into it.
-
-
- "Super_Z" works it's magic by NOT working so hard. Zmodem
- adapts itself to environments that require an XON/XOFF
- handshake by "escaping" them along with several packet
- switching and ASCII communication control characters. Thus
- the nets work properly and zmodem transfers the binary data
- successfully. Knowing this then, it is easy to see why
- Super_Z will not function over nets that use XON/XOFF
- protocol or require other special triggers etc... Super_Z
- is implemented in such a way that it will only work over
- nets that do not eat comm ctrl characters. Basically, if a
- Ymodem-g transfer will work Super_Z will work better.
-
-
- The first and hardest "method setup" is the implementation
- of variable header lengths as described by Chuck Forsberg.
- Throughout this document we will use terminology and
- constant naming set forth by him in the P.D. release of
- zmodem. We will not attempt to highlight our own from his
- since that's not what we're about.
-
-
- When I say the "hardest", I do not mean difficult. Below is
- some commented sections of Turbo Pascal code showing
- variables and the various constant values needed to
- implement variable headers, super_z etc...
-
- {Global Constant Values Common To Send & Rcvr}
-
- CANVHDR = 01; {can use variable header flag}
-
- FrameTypes = 20; {number of zmodem header types allowed att}
-
- CANSUPERZ = 04; {wants to use super_z transfer}
-
- GOFORSUPZ = 01; {rcvr says we can transfer Super_Z}
-
-
-
-
- {Global "Static for 'C' folks" Turbo Pascal Typed Constants}
-
- RXHDRLEN : integer = 4; {specifies the header length common to both
- send and receive routines}
-
- USEVHDR : boolean = false; {true/false value determines the use of
- variable length headers for both send
- and receive routines}
-
- VHDRTYPE : byte = 0; {contains on of the six zmodem header
- values}
-
- WANTSUPERZ : boolean = false; {sets to TRUE if rcvr requests a }
- {Super_Z transfer }
-
- TRYSUPERZ : boolean = false; {sets to true if user wants to try}
- {for Super_Z transfer }
-
-
-
-
- {Turbo Pascal Data Types}
- TYPE
- hdrtype = ARRAY[ 0..15 ] OF byte; {16 byte maximum header length}
-
-
-
-
-
- {you may elect to add this procedure or simply put it in your}
- {sendzbyte routine. Either way will work fine. Below are my}
- {byte send routines as used in PCZ}
-
- PROCEDURE S_SendByte(b : byte);
- BEGIN
- IF (lo(b) = zdle) THEN {escape only the zdle sequence}
- BEGIN
- SendByte(zdle);
- lastsent := (zdle XOR $40); {send "zdle" as "zdlee"}
- END
- ELSE
- lastsent := lo(b);
-
- SendByte(lastsent);
- END;
-
-
- PROCEDURE SendZByte(b : byte);
- BEGIN
- IF Super_Z Then {if super_z is active then jumb to}
- Begin {the "S"uper SendByte routine }
- S_SendByte(b);
- Exit;
- End;
-
- IF ((b AND $60) <> 0) THEN
- BEGIN
- lastsent := b;
- END
- ELSE
- BEGIN
- CASE (b AND $7F) OF {determine a set of known comm ctrl}
- 24, {characters. You could just as easily}
- 16, {include all of them but be prepared for}
- 17, {a decrease in performance}
- 19 : BEGIN
- SendByte(zdle);
- lastsent := (b XOR $40);
- END;
-
- 13 : IF (NOT zctlesc) AND ((lastsent AND $7F) <> $40) THEN
- lastsent := b
- ELSE
- BEGIN
- SendByte(zdle);
- lastsent := (b XOR $40);
- END;
-
- ELSE
- BEGIN
- IF (zctlesc) AND ((b AND $60) <= 0) THEN
- BEGIN
- SendByte(zdle);
- lastsent := (b XOR $40);
- END
- ELSE
- lastsent := b;
- END;
- END;
-
- END;
-
- SendByte(lastsent);
- END;
-
-
-
-
- {The next three procedures demonstrate the sending of variable length}
- {headers. Your naming convention may be different but that should }
- {be no problem if you're adding this to your implementation }
-
-
-
- PROCEDURE SendHexHeader(len, {Hdr length "4 - 15" bytes}
- htype : byte; {zmodem frame indicator }
- {"zrqinit etc... }
- VAR hdr : hdrtype);{actual header buffer }
-
- VAR
- crc : word;
- n, i : integer;
- BEGIN
- SendByte(zpad);
- SendByte(zpad);
- SendByte(zdle);
-
- If USEVHDR Then {If we're using variable header lengths then}
- Begin {send HDRTYPE 'zvhex' byte and length 'len' }
- SendByte(zvhex);
- SendHexByte(len);
- End
- Else {otherwise send standard 'zhex' HDRTYPE}
- SendByte(zhex);
-
- SendHexByte(htype);
-
- crc := updcrc(htype, 0);
-
- FOR n := 0 TO (len-1) DO {'len' is header length. My buffer is}
- BEGIN {0-15 so len-1 corrects offset }
- SendHexByte(hdr[n]);
- crc := updcrc(hdr[n], crc)
- END;
-
- crc := updcrc(0, crc);
- crc := updcrc(0, crc);
-
-
- etc...
-
- END;
-
-
-
- PROCEDURE SendBinaryHeader32(len, {ditto above}
- htype : byte; { " " }
- VAR hdr : hdrtype); { " " }
- VAR
- crc : longint;
- n : integer;
- BEGIN
-
- IF USEVHDR THEN {this method is the same as for the }
- BEGIN {hex header procedure }
- SendByte(zvbin32);
- SendZByte(len);
- END
- ELSE
- SendByte(zbin32);
-
- SendZByte(htype);
-
- crc := updc32(htype, $ffffffff);
- FOR n := 0 TO (len-1) DO
- BEGIN
- SendZByte(hdr[n]);
- crc := updc32(hdr[n], crc)
- END;
-
-
- etc...
-
- END;
-
-
-
- PROCEDURE SendBinaryHeader(len, {ditto}
- htype : byte; { " }
- VAR hdr : hdrtype); { " }
- VAR
- crc : word;
- n : integer;
- BEGIN
- SendByte(zpad);
- SendByte(zdle);
-
- IF (usecrc32) THEN
- BEGIN
- SendBinaryHeader32(len, htype, hdr);
- exit;
- END;
-
- IF USEVHDR THEN { same as above }
- BEGIN
- SendByte(zvbin);
- SendZByte(len);
- END
- ELSE
- SendByte(zbin);
-
- SendZByte(htype);
-
- crc := updcrc(htype, 0);
-
- FOR n := 0 TO (len-1) DO
- BEGIN
- SendZByte(hdr[n]);
- crc := updcrc(hdr[n], crc)
- END;
-
- etc...
-
- END;
-
-
-
-
-
- {these routines retrieve and place values in the first 4 positions}
- {of the header. The entire header is zero'd out in the case of }
- {put long in. Our other cell values are add after the call to }
- {this routine }
-
-
- FUNCTION PullLongFromHeader(VAR thishdr : hdrtype) : longint;
- VAR
- l : longint;
- BEGIN
- l := longint(0);
- l := thishdr[zp3];
- l := (l SHL 8) OR thishdr[zp2];
- l := (l SHL 8) OR thishdr[zp1];
- l := (l SHL 8) OR thishdr[zp0];
- PullLongFromHeader := l;
- END;
-
- PROCEDURE PutLongInHeader(l : longint);
- BEGIN
- txhdr[zp0] := byte(l);
- txhdr[zp1] := byte(l SHR 8);
- txhdr[zp2] := byte(l SHR 16);
- txhdr[zp3] := byte(l SHR 24)
- txhdr[4] := byte(0); {clear entire header}
- txhdr[5] := byte(0);
- txhdr[6] := byte(0);
- txhdr[7] := byte(0);
- txhdr[8] := byte(0);
- txhdr[9] := byte(0);
- txhdr[10] := byte(0);
- txhdr[11] := byte(0);
- txhdr[12] := byte(0);
- txhdr[13] := byte(0);
- txhdr[14] := byte(0);
- txhdr[15] := byte(0);
- END;
-
-
-
- {there are a couple of changes to the zdl get routine that need}
- {to be made in order to pass the comm ctrl characters}
-
- FUNCTION GetZdlSeq : integer;
- LABEL
- loop, loopa;
- VAR
- c : integer;
- BEGIN
- loop:
- c := GetZByte(defaultwaittime);
-
- IF ((c AND $60) > 0) THEN
- BEGIN
- GetZdlSeq := c;
- exit;
- END;
-
- IF (c = zdle) THEN
- GOTO loopa
-
- ELSE
-
- IF ((NOT Super_Z) AND (c IN [19, 17])) OR {not super_z}
- ((zctlesc) AND (((c AND $60) = 0))) THEN
- GOTO loop
-
- ELSE
- BEGIN
- GetZdlSeq := c;
- exit;
- END;
-
- loopa:
- c := GetZByte(defaultwaittime);
-
- IF (c = can) THEN
- BEGIN
- c := GetZByte(defaultwaittime);
- IF (c = can) THEN
- BEGIN
- c := GetZByte(defaultwaittime);
- IF (c = can) THEN
- c := GetZByte(defaultwaittime);
- END
- END;
-
- CASE c OF
- can : GetZdlSeq := gotcan;
- zcrce,
- zcrcg,
- zcrcq,
- zcrcw : GetZdlSeq := (c OR gotor);
- zrub0 : GetZdlSeq := $7f;
- zrub1 : GetZdlSeq := $ff;
- {not super_z}
- 19, 17 : IF (NOT super_z) THEN GOTO loopa ELSE GetZdlSeq := c;
-
- ELSE
- BEGIN
-
- IF ((zctlesc) AND (((c AND $60) = 0))) THEN
- GOTO loopa;
-
-
- IF ((c AND $60) = $40) THEN
- GetZdlSeq := (c XOR $40)
- ELSE
- IF (c IN [1..31]) Then
- GetZdlSeq := c
- ELSE
- GetZdlSeq := zerror;
- END;
- END; {case}
-
- END;
-
-
-
-
-
-
- {The next three routines are the receive portion of the variable}
- {header scheme. They amount to nothing more than getting a byte}
- {for the header RXHDRLEN-1 times}
-
-
- FUNCTION GetHexHeader(VAR hdr : hdrtype) : integer;
- VAR
- crc : word;
- c, n : integer;
- BEGIN
- c := GetHexByte;
- IF (c < 0) THEN
- BEGIN
- GetHexHeader := c;
- exit
- END;
- rxtype := c;
- crc := updcrc(rxtype, 0);
-
- {get the header}
- FOR n := 0 TO (RXHDRLEN-1) DO {global value length of header-1}
- BEGIN {allow for 0- offset}
- c := GetHexByte;
- IF (c < 0) THEN
- BEGIN
- GetHexHeader := c;
- exit
- END;
- hdr[n] := lo(c);
- crc := updcrc(lo(c), crc)
- END;
-
-
- etc...
-
- END;
-
-
-
- FUNCTION GetBinaryHeader(VAR hdr : hdrtype) : integer;
- VAR
- crc : word;
- c, n : integer;
- BEGIN
- c := GetZdlSeq;
- IF (c < 0) THEN
- BEGIN
- GetBinaryHeader := c;
- exit
- END;
- rxtype := c;
- crc := updcrc(rxtype, 0);
-
- {get the header}
- FOR n := 0 TO (RXHDRLEN-1) DO {ditto}
- BEGIN
- c := GetZdlSeq;
- IF (hi(c) <> 0) THEN
- BEGIN
- GetBinaryHeader := c;
- exit
- END;
- hdr[n] := lo(c);
- crc := updcrc(lo(c), crc)
- END;
-
-
- etc...
-
- END;
-
-
-
-
- FUNCTION GetBinaryHeader32(VAR hdr : hdrtype) : integer;
- VAR
- crc : longint;
- c, n : integer;
- BEGIN
- c := GetZdlSeq;
- IF (c < 0) THEN
- BEGIN
- GetBinaryHeader32 := c;
- exit
- END;
- rxtype := c;
-
- crc := updc32(rxtype, $ffffffff);
-
- {get the header}
- FOR n := 0 TO (RXHDRLEN-1) DO {ditto}
- BEGIN
- c := GetZdlSeq;
- IF (hi(c) <> 0) THEN
- BEGIN
- GetBinaryHeader32 := c;
- exit;
- END;
- hdr[n] := lo(c);
- crc := updc32(lo(c), crc)
- END;
-
-
- etc...
-
- END;
-
-
-
-
-
- FUNCTION GetHeader(VAR hdr : hdrtype) : integer;
- LABEL
- gotcan, again, agn2, splat, done;
- VAR
- c, n, cancount : integer;
- BEGIN
- n := zbaud * 2;
- cancount := 5;
- again:
-
- IF (escape) THEN
- BEGIN
- CanThisXfer;
- Say('transfer cancelled from keyboard');
- GetHeader := zcan;
- exit;
- END;
-
- frameindicator := 0;
- rxtype := 0;
-
- c := GetNoCtrlByte;
-
- CASE c OF
- zpad :;
- fubar,
- rcdo,
- ztimeout : GOTO done;
-
- can : BEGIN
- gotcan:
- dec(cancount);
- IF (cancount < 0) THEN
- BEGIN
- c := zcan;
- GOTO done
- END;
- c := GetZByte(10);
- CASE c OF
- ztimeout : GOTO again;
- zcrcw : BEGIN
- c := zerror;
- GOTO done
- END;
- fubar,
- rcdo : GOTO done;
- can : BEGIN
- dec(cancount);
- IF (cancount < 0) THEN
- BEGIN
- c := zcan;
- GOTO done
- END;
- GOTO again
- END
- END;
- END;
- ELSE
-
- agn2:
- BEGIN
- dec(n);
- IF (n < 0) THEN
- BEGIN
- inc(zerrors);
- ShowErrors(zerrors);
- Say('header got trashed');
- GetHeader := zerror;
- exit;
- END;
-
- IF (c <> can) THEN
- cancount := 5;
-
- GOTO again;
- END;
- END;
-
- cancount := 5;
-
- splat:
- c := GetNoCtrlByte;
-
- CASE c OF
- zdle :;
- zpad : GOTO splat;
- fubar,
- rcdo,
- ztimeout : GOTO done;
- ELSE
- GOTO agn2;
- END;
-
- c := GetNoCtrlByte;
-
- RXHDRLEN := 4; {Set global hdrlen to std value of 4}
-
- CASE c OF
- zbin32 : BEGIN
- frameindicator := zbin32;
- c := GetBinaryHeader32(hdr);
- END;
- zbin : BEGIN
- frameindicator := zbin;
- c := GetBinaryHeader(hdr);
- END;
- zhex : BEGIN
- frameindicator := zhex;
- c := GetHexHeader(hdr);
- END;
-
- {These 3 types signal a variable length header is coming}
- zvbin32: BEGIN
- RXHDRLEN := GetZByte(defaultwaittime); {get length}
- If (RXHDRLEN < 0) Then goto done; {ensure range is}
- If (RXHDRLEN > 16) Then goto agn2;{valid }
- frameindicator := zvbin32; {set global type frame}
- c := GetBinaryHeader32(hdr);{go get the header }
- END;
- zvbin : BEGIN
- RXHDRLEN := GetZByte(defaultwaittime); {ditto}
- If (RXHDRLEN < 0) Then goto done;
- If (RXHDRLEN > 16) Then goto agn2;
- frameindicator := zvbin;
- c := GetBinaryHeader(hdr);
- END;
- zvhex : BEGIN
- RXHDRLEN := GetHexByte; {ditto}
- If (RXHDRLEN < 0) Then goto done;
- If (RXHDRLEN > 16) Then goto agn2;
- frameindicator := zvhex;
- c := GetHexHeader(hdr);
- END;
- can : GOTO gotcan;
- fubar,
- rcdo,
- ztimeout : GOTO done
- ELSE
- GOTO agn2
- END;
-
- rxpos := PullLongFromHeader(hdr);
-
- done:
-
- {this portion of code basically says that if the headertype is}
- {a valid type and the FrameType is in the alpha lower case range}
- {then we must have received a variable header so set the global}
- {flag to reflect the status ... either/or}
-
- If (c >= 0) AND (c <= FrameTypes) AND ((frameindicator and 32)<>0) Then
- USEVHDR := TRUE;
-
- GetHeader := c
- END;
-
-
-
-
-
- {------------------------------------------------------------------}
- (* until otherwise stated the following routines are transmitter *)
- (* specific routines *)
- {------------------------------------------------------------------}
-
-
-
- {GetRcvrInfo is the first xmitting done to the rcvr from the xmiter}
- {We use this routine to first signal the rcvr that we can use}
- {variable headers. This is done by placing the value CANVHDR in}
- {header position zf3 of the zrqinit header}
-
- {This is where we will also see that the rcvr can use variable hdr}
- {lengths as well as the rcvr's call for a Super_Z transfer. }
- {Examine the code and you will understand the method used here.}
-
-
- FUNCTION GetRcvrInfo : integer;
- VAR
- n, c : integer;
- BEGIN
-
- Say('getting receiver status info.');
- n := 0;
-
- FOR n := 1 TO 10 DO
- BEGIN
-
-
- txhdr[zf3] := CANVHDR; {signal we can xmit variable headers}
-
-
- SendHexHeader(4, zrqinit, txhdr); {std hdrlen of 4}
-
- fillchar(rxhdr, sizeof(rxhdr), #0);
-
- c := GetHeader(rxhdr); {get the rcvr's header which should be}
- {for our concern a zrinit header}
- ShowHdrInfo(c);
-
- CASE c OF
- zchallenge : BEGIN
- PutLongInHeader(rxpos);
- SendHexHeader(4, zack, txhdr)
- END;
- zcommand : BEGIN
- PutLongInHeader(longint(0));
- SendHexHeader(4, zrqinit, txhdr)
- END;
-
- zrinit : BEGIN {all good info is here}
-
- {get length of rcvr input buffer here}
-
- rxbuflen := ((rxhdr[zp1]) SHL 8) OR rxhdr[zp0];
-
-
- {can the rcvr handle 32bit crc checks}
-
- usecrc32 := ((rxhdr[zf0] AND canfc32)<>0);
-
-
- {can the rcvr handle variable header lengths}
- {if true the rcvr will have placed CANVHDR value}
- {in header cell "zf1" }
-
- USEVHDR := ((rxhdr[zf1] AND canvhdr)<>0);
-
-
- {is the rcvr requesting a Super_Z transfer?}
- {if true the rcvr will have OR'd CANSUPERZ value}
- {into header cell "zf1". WantSuperZ will flag }
- {us later to respond }
-
- WantSuperZ := ((rxhdr[zf1] AND cansuperz)<>0);
-
-
-
- GetRcvrInfo := zok;
- ShowTransferType(usecrc32);
- exit;
-
- END;
- zcan,
- fubar,
- rcdo : BEGIN
- GetRcvrInfo := zerror;
- exit
- END;
- ztimeout : {just let it loop} ;
- ELSE
- IF ( (c<>zrinit) OR (rxhdr[zf0]<>zcommand) ) THEN
- BEGIN
- SendHexHeader(4, znak, txhdr)
- END;
- END; {case}
-
- IF (NOT carrier) OR (escape) THEN n := 10;
-
- END; {for}
- GetRcvrInfo := zerror;
- END;
-
-
-
-
-
-
-
-
- FUNCTION SendFile(VAR blen : integer) : integer;
- VAR
- c : integer;
- done : boolean;
- BEGIN
- zerrors := word(0);
- done := false;
-
- REPEAT
-
- fillchar(txhdr, sizeof(txhdr), 0);
-
- IF recover THEN
- txhdr[zf0] := zcresum {resume crashed file }
- ELSE
- txhdr[zf0] := zcbin; {normal file xfer}
-
-
- {signal we still want variable header lengths used}
-
- txhdr[zf3] := canvhdr;
-
-
-
- {This is where we really find out what we can do. If the}
- {user wants to TRYSUPERZ or the rcvr WANTSUPERZ and we can}
- {USEVHDRs then we make the attempt to do so}
-
- IF ((trysuperz) OR (wantsuperz)) AND (USEVHDR) THEN
- BEGIN
- txhdr[zf3] := cansuperz OR canvhdr;
- SendBinaryHeader(8, zfile, txhdr);
- END
- ELSE
- SendBinaryHeader(4, zfile, txhdr);
-
-
- SendData(txbuf, blen, zcrcw);
-
- REPEAT
-
- IF (escape) THEN
- BEGIN
- CanThisXfer;
- Say('aborted from keyboard');
- SendFile := zerror;
- exit;
- END;
-
- IF (NOT carrier) THEN
- BEGIN
- Say('lost carrier');
- SendFile := zerror;
- exit;
- END;
-
- fillchar(rxhdr, sizeof(rxhdr), #0);
- c := GetHeader(rxhdr);
- ShowHdrInfo(c);
- CASE c OF
- zcan,
- fubar,
- rcdo,
- ztimeout,
- zfin,
- fubar : BEGIN
- SendFile := zerror;
- exit
- END;
-
- zrinit : {loopback} ;
-
- zcrc : BEGIN
- PutLongInHeader(z_ckcrc32(infile));
- SendHexHeader(4, zcrc, txhdr)
- END;
-
- zskip : BEGIN
- SendFile := c;
- exit
- END;
-
-
- {This rcvr header is the last flag for Super_Z transfers}
- {If the rcvr has read our header correctly it }
- {responds here in the zrpos header}
-
- zrpos : BEGIN
- IF (NOT z_seekfile(infile, rxpos)) THEN
- BEGIN
- Say('file positioning error');
- SendHexHeader(4, zferr, txhdr);
- SendFile := zerror;
- exit;
- END;
-
- Say('setting start position');
- ShowFilePos(rxpos);
- strtpos := rxpos;
- txpos := rxpos;
-
-
- {here is our long awaited response}
- {rcvr signals Super_Z ok by placing value}
- {GOFORSUPZ in zrpos header cell "zf4" }
-
- Super_Z := ((rxhdr[zf4] AND GOFORSUPZ)<>0);
-
- If Super_Z Then
- Begin
- updatewindow(szver);
- ShowTransferType(usecrc32);
- End;
-
- {send the file}
- SendFile := SendFiledata;
-
- exit;
- END
-
- END
- UNTIL (c <> zrinit)
-
- UNTIL (done)
- END;
-
-
-
-
- {-----------------------------------------------------------------------}
- (* the following routines are for the receiver side of zmodem for data *)
- (* and header receiving *)
- {-----------------------------------------------------------------------}
-
-
-
-
-
- FUNCTION RecvData(VAR buf : buftype; buf_length : integer) : integer;
- LABEL
- crcfoo;
- VAR
- c, d, buflen : integer;
- crc : word;
- done : boolean;
- BEGIN
-
- Say('');
-
- {if we are using 32bit crc or vhdrs and 32bit crc then doit that way}
-
- IF (frameindicator=zbin32) OR (frameindicator=zvbin32) THEN
- BEGIN
- z_showtype(true);
- RecvData := RecvData32(buf, buf_length);
- exit;
- END;
-
-
- etc...
-
- END;
-
-
-
-
-
-
- {SendRcvrInfo is the first xmitting done to the sender from the rcvr}
- {We use this routine to first signal the sender that we can use}
- {variable headers. This is done by placing the value CANVHDR in}
- {header cell zf1 of the zrinit header}
-
- {This is where we can also see that the sender can use variable hdr}
- {Examine the code and you will understand the method used here.}
-
-
-
-
- FUNCTION SendRcvrInfo : integer;
- LABEL
- again;
- VAR
- x, c, n, errors : integer;
- ch : char;
- teststr : STRING[33];
- thdr : hdrtype;
- BEGIN
-
- fillchar(attn, sizeof(attn), 0);
- zerrors := 0;
- x := 0;
-
- FOR n := 10 DOWNTO 0 DO
- BEGIN
-
-
- ShowHdrInfo(tryzhdrtype);
-
- fillchar(secbuf, sizeof(secbuf), #0);
-
- PutLongInHeader(longint(0));
-
- txhdr[zf0] := canfdx OR canovio OR canfc32 OR canbrk; {full dplx, overlay i/o and crc32}
-
-
- {signal xmitr we can use variable headers}
- txhdr[zf1] := CANVHDR;
-
-
- {if user wants to TRYSUPERZ then we simply or CANSUPERZ}
- {with header cell "zf1". Xmitr will respond with it's }
- {zfile header }
-
- If TRYSUPERZ Then
- Begin
- txhdr[zf1] := CANVHDR OR CANSUPERZ;
- SendHexHeader(4, tryzhdrtype, txhdr);
- End
- Else
- SendHexHeader(4, tryzhdrtype, txhdr);
-
-
- IF (tryzhdrtype = zskip) THEN
- tryzhdrtype := zrinit;
-
- again:
- IF (NOT carrier) THEN
- BEGIN
- Say('lost carrier');
- SendRcvrInfo := zerror;
- exit;
- END;
-
- IF (escape) THEN
- BEGIN
- CanThisXfer;
- Say('transfer cancelled from keyboard');
- SendRcvrInfo := zcan;
- exit;
- END;
-
-
- fillchar(rxhdr, sizeof(rxhdr), #0);
-
- c := GetHeader(rxhdr);
-
- ShowHdrInfo(c);
-
- CASE c OF
- zrqinit : BEGIN
- {if by chance we catch the xmitrs zrqinit}
- {header check for variable header usage}
-
- USEVHDR := ((rxhdr[zf3] AND CANVHDR)<>0);
-
- END;
- zfile : BEGIN
- zconv := rxhdr[zf0];
-
- c := RecvData(secbuf, zbuffersize);
- ShowHdrInfo(c);
-
-
- {if we didn't get usevhdr from the zrqinit}
- {header try for it again now}
-
- If (NOT USEVHDR) Then
- USEVHDR := ((rxhdr[zf3] AND CANVHDR)<>0);
-
-
- {if we are using variable headers then check}
- {if xmitr has requested super_z or is responding}
- {to our request }
-
- If USEVHDR Then
- Super_Z := ((rxhdr[zf3] AND CANSUPERZ) <> 0);
-
- {we can safely say Super_Z will work so }
- {Super_Z will be TRUE}
-
-
- tryzhdrtype := zrinit;
-
- IF (c = gotcrcw) THEN
- BEGIN
- SendRcvrInfo := zfile;
- exit;
- END;
-
- SendHexHeader(4, znak, txhdr);
- GOTO again;
- END;
-
- etc...
-
- {zrqinit and zfile types are all that concern us here}
-
- END;
-
-
-
-
- {this is where we tell the sender that his request for, or his}
- {response to our request is either go or nogo for Super_Z }
-
- FUNCTION ReceiveFile : integer;
- LABEL
- err, nxthdr, moredata, baddata;
- VAR
- c, n : integer;
- rxbytes : longint;
- sptr : STRING;
- done : boolean;
- BEGIN
- zerrors := 0;
- done := false;
- eofseen := false;
-
- c := GetZeroHeader;
-
- IF (c <> zok) THEN
- BEGIN
- IF (c = zskip) THEN
- tryzhdrtype := zskip;
- ReceiveFile := c;
- exit;
- END;
-
- c := zok;
- n := 10;
- rxbytes := filestart;
- rxpos := filestart;
-
- fillChar(attn,sizeof(attn),#32);
-
- PutLongInHeader(rxbytes);
-
-
- {if we have determined Super_Z is ok then flag the xmitr}
- {by placing value GOFORSUPZ in zrpos header cell "zf4"}
-
- IF Super_Z Then
- Begin
- txhdr[zf4] := GOFORSUPZ;
- SendHexHeader(8, zrpos, txhdr);
- updatewindow(SzVer);
- End
- Else
- SendHexHeader(4, zrpos, txhdr);
-
-
- etc...
-
-
-
- END;
-
-
-
-
- Print out the code above and look over it. You should be able to
- translate most of what you see into your own application.
-
-
-
-
-
-
-
-
-