Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gkermit / gproto.w
blob02ebb959bcec0bc3aa83ffa5cfcc3dbfce03eb50
1 /* G P R O T O -- Protocol module for gkermit */ /* -*-C-*- */
3 /*
4 Author:
5 Frank da Cruz
6 The Kermit Project
7 Columbia University
8 612 West 115th Street
9 New York NY 10025-7799 USA
10 http://www.columbia.edu/kermit/
11 kermit@columbia.edu
13 Copyright (C) 1999,
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
30 #include <stdio.h>
31 #include "gkermit.h"
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;
39 extern FILE * db;
41 static int x;
43 static VOID
44 streamon() { /* Start streaming if negotiated */
45 x = 0;
46 if (streamok > 0) {
47 streaming = 1;
48 timint = 0;
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. */
66 else BEGIN ssini;
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, */
73 errpkt("sfile");
74 } else { /* No error */
75 streamon();
76 BEGIN ssfil;
78 } else { /* No files to send, */
79 if (seot() < 0) { errpkt("seot"); } /* so send EOT packet. */
80 else BEGIN sseot;
83 <ssfil>Y { /* Receive ACK to File header packet */
84 if (attributes) { /* If attributes negotiated */
85 if (sattr() < 0) { /* Send file attributes */
86 errpkt("sattr");
87 } else
88 BEGIN ssatt;
89 } else if ((x = sdata()) == 0) { /* Otherwise send first Data packet */
90 if (seof("") < 0) { /* Empty file - send EOF */
91 errpkt("seof");
92 } else {
93 BEGIN sseof;
95 } else if (x < 0) { /* Error */
96 errpkt("sdata");
97 } else { /* OK - switch to Data state */
98 BEGIN ssdat;
101 <ssatt>Y { /* Receive ACK to Attribute packet */
102 if (*rdatap == 'N') { /* Check for refusal */
103 seof("D");
104 BEGIN sseof;
105 } else if ((x = sdata()) == 0) { /* Otherwise send first Data packet */
106 if (seof("") < 0) { /* Empty file - send EOF */
107 errpkt("seof");
108 } else {
109 BEGIN sseof;
111 } else if (x < 0) { /* Error */
112 errpkt("sdata");
113 } else { /* OK - switch to Data state */
114 BEGIN ssdat;
117 <ssdat>Y { /* Receive ACK to Data packet */
118 if (*rdatap == 'X') /* Check for file cancellation */
119 cx = 1;
120 else if (*rdatap == 'Z') /* Check for batch cancellation */
121 cz = 1;
122 if ((x = sdata()) == 0) { /* Send data packet if data left. */
123 if (seof((cx | cz) ? "D" : "") < 0) { /* If not, send Z packet */
124 errpkt("seof");
125 } else {
126 BEGIN sseof;
128 } else if (x < 0) /* Fatal error sending data */
129 errpkt("sdata");
131 <sseof>Y { /* Receive ACK to EOF */
132 if (gnfile() > 0) { /* Get next file from list */
133 if (sfile() > 0)
134 BEGIN ssfil;
135 else { errpkt("sfile"); }
136 } else { /* No more files */
137 seot(); /* Send EOT */
138 BEGIN sseot;
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 */
151 streamon();
152 BEGIN srfil; /* Wait for file or EOT */
155 <srfil>B { ack(); return(failure); } /* Receive EOT packet */
157 <srfil>F { /* Receive File header packet */
158 if (rcvfil() < 0) {
159 errpkt("rcvfil");
160 } else {
161 encstr(filnam);
162 ack1(xdata);
163 streamon();
164 BEGIN sratt;
167 <sratt>A { /* Receive Attribute packet */
168 if (gattr(rdatap) == 0) {
169 ack();
170 } else {
171 ack1("\"");
174 <sratt>D { /* Receive first Data packet */
175 if (decode(datalen) < 0) {
176 errpkt("Packet decoding error");
177 } else {
178 ack();
179 BEGIN srdat;
182 <sratt>Z { /* Empty file */
183 if (*rdatap == 'D') /* Check for Discard directive */
184 cx = 1;
185 if (closof() < 0) { /* Close the output file */
186 errpkt("closof");
187 } else {
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");
195 else
196 ack();
198 <srdat>Z { /* Receive EOF packet */
199 if (*rdatap == 'D') /* Check for Discard directive */
200 cx = 1;
201 if (closof() < 0) { /* Close the output file */
202 errpkt("closof");
203 } else {
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 */
215 BEGIN sipkt;
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 */
220 errpkt("scmd");
221 else
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. */