1 /* G P R O T O
-- Protocol module for gkermit
*/ /* -*-C-
*- */
9 New York NY
10025-7799 USA
10 http
://www.columbia.edu
/kermit
/
14 The Trustees of Columbia University in the City of New York.
16 This program is free software
; you can redistribute it and
/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation
; either version
2 of the License
, or
19 (at your option
) any later version.
21 This program is distributed in the hope that it will be useful
,
22 but WITHOUT
ANY WARRANTY
; without even the implied warranty of
23 MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program
; if not
, write to the Free Software
28 Foundation
, Inc.
, 59 Temple Place
, Suite
330, Boston
, MA
02111-1307 USA
33 _MYPROTOTYPE
( int closof
, (void
) ); /* Close output file
*/
34 _MYPROTOTYPE
( VOID errpkt
, (char
*) ); /* Send Error packet
*/
36 extern char
* xdata
, *rdatap
, **cmlist
, *cmarg
, *rpar
(), strbuf
[], filnam
[];
37 extern int start
, bctu
, bctr
, delay
, cx
, cz
, failure
, attributes
, datalen
;
38 extern int streamok
, streaming
, timint
;
44 streamon
() { /* Start streaming if negotiated
*/
52 /* Declare gwart states
(like lex
) */
54 %states ssini ssfil ssdat ssatt sseot sseof sipkt
55 %states srini srfil srdat sratt
57 /* Packets are read by the input
() function
, which returns the packet type
*/
58 /* that serves as the input to the state machine
, which follows...
*/
61 /* Sending states...
*/
63 s
{ /* Start state for Send.
*/
64 tinit
(); /* Initialize transaction.
*/
65 if
(sinit
('S'
) < 0) { errpkt
("sinit"); } /* Build and send the S packet.
*/
68 <ssini
>Y { /* Receive ACK to I packet
*/
69 spar
(rdatap
); /* Set parameters from it
*/
70 bctu
= bctr
; /* Switch to negotiated block check
*/
71 if
(gnfile
() > 0) { /* Is there a file to send?
*/
72 if
(sfile
() < 0) { /* Yes
, open it
, send F packet
, */
74 } else
{ /* No error
*/
78 } else
{ /* No files to send
, */
79 if
(seot
() < 0) { errpkt
("seot"); } /* so send EOT packet.
*/
83 <ssfil
>Y { /* Receive ACK to File header packet
*/
84 if
(attributes
) { /* If attributes negotiated
*/
85 if
(sattr
() < 0) { /* Send file attributes
*/
89 } else if
((x
= sdata
()) == 0) { /* Otherwise send first Data packet
*/
90 if
(seof
("") < 0) { /* Empty file
- send EOF
*/
95 } else if
(x
< 0) { /* Error
*/
97 } else
{ /* OK - switch to Data state
*/
101 <ssatt
>Y { /* Receive ACK to Attribute packet
*/
102 if
(*rdatap
== 'N'
) { /* Check for refusal
*/
105 } else if
((x
= sdata
()) == 0) { /* Otherwise send first Data packet
*/
106 if
(seof
("") < 0) { /* Empty file
- send EOF
*/
111 } else if
(x
< 0) { /* Error
*/
113 } else
{ /* OK - switch to Data state
*/
117 <ssdat
>Y { /* Receive ACK to Data packet
*/
118 if
(*rdatap
== '
X'
) /* Check for file cancellation
*/
120 else if
(*rdatap
== 'Z'
) /* Check for batch cancellation
*/
122 if
((x
= sdata
()) == 0) { /* Send data packet if data left.
*/
123 if
(seof
((cx | cz
) ?
"D" : "") < 0) { /* If not
, send Z packet
*/
128 } else if
(x
< 0) /* Fatal error sending data
*/
131 <sseof
>Y { /* Receive ACK to EOF
*/
132 if
(gnfile
() > 0) { /* Get next file from list
*/
135 else
{ errpkt
("sfile"); }
136 } else
{ /* No more files
*/
137 seot
(); /* Send EOT
*/
141 <sseot
>Y { return
(failure
); } /* Send ACK to EOT
- done
*/
143 /* Receiving states...
*/
145 v
{ tinit
(); rinit
(); BEGIN srini
; } /* Start-state for Receive
*/
147 <srini
>S
{ /* Receive S packet
*/
148 spar
(rdatap
); /* Set parameters from it
*/
149 ack1
(rpar
()); /* ACK with our parameters
*/
150 bctu
= bctr
; /* Switch to negotiated block check
*/
152 BEGIN srfil
; /* Wait for file or EOT
*/
155 <srfil
>B
{ ack
(); return
(failure
); } /* Receive EOT packet
*/
157 <srfil
>F
{ /* Receive File header packet
*/
167 <sratt
>A
{ /* Receive Attribute packet
*/
168 if
(gattr
(rdatap
) == 0) {
174 <sratt>D { /* Receive first Data packet */
175 if (decode(datalen) < 0) {
176 errpkt("Packet decoding error
");
182 <sratt>Z { /* Empty file */
183 if (*rdatap == 'D') /* Check for Discard directive */
185 if (closof() < 0) { /* Close the output file */
188 ack(); /* Send ACK */
189 BEGIN srfil; /* Wait for another file or EOT */
192 <srdat>D { /* Receive Data packet */
193 if (decode(datalen) < 0)
194 errpkt("Packet decoding error
");
198 <srdat>Z { /* Receive EOF packet */
199 if (*rdatap == 'D') /* Check for Discard directive */
201 if (closof() < 0) { /* Close the output file */
204 ack(); /* Send ACK */
205 BEGIN srfil; /* Wait for another file or EOT */
209 /* GET files from a Kermit server... */
211 r { /* Start state for Get */
212 tinit(); /* Initialize transaction */
213 ginit(); /* Initialize Get */
214 sinit('I'); /* Send I packet */
217 <sipkt>Y { /* Receive ACK for I packet */
218 spar(rdatap); /* Set parameters from it */
219 if (scmd('R',cmarg) < 0) /* Send GET packet file filespec */
222 BEGIN srini; /* Wait for S packet */
225 E { return(failure = 1); } /* Receive an Error packet */
227 . { errpkt("Unknown packet type
"); } /* Handle unwanted packet types. */