|
|
1.1 root 1: char *protv = "C-Kermit Protocol Module 4E(031), 31 Jul 87"; /* -*-C-*- */
2:
3: /* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */
4: /*
5: Authors: Frank da Cruz (SY.FDC@CU20B), Bill Catchings, Jeff Damens;
6: Columbia University Center for Computing Activities, January 1985.
7: Copyright (C) 1985, Trustees of Columbia University in the City of New York.
8: Permission is granted to any individual or institution to use, copy, or
9: redistribute this software so long as it is not sold for profit, provided this
10: copyright notice is retained.
11: */
12: #include "ckcdeb.h"
13: #include "ckcker.h"
14: /*
15: Note -- This file may also be preprocessed by the Unix Lex program, but
16: you must indent the above #include statements before using Lex, and then
17: restore them to the left margin in the resulting C program before compilation.
18: Also, the invocation of the "wart()" function below must be replaced by an
19: invocation of the "yylex()" function. It might also be necessary to remove
20: comments in the %%...%% section.
21: */
22:
23: /* State definitions for Wart (or Lex) */
24: %states ipkt rfile rdata ssinit ssfile ssdata sseof sseot
25: %states serve generic get rgen
26:
27: /* External C-Kermit variable declarations */
28: extern char sstate, *versio, *srvtxt, *cmarg, *cmarg2, *rpar();
29: extern char data[], filnam[], srvcmd[], ttname[], *srvptr;
30: extern int pktnum, timint, nfils, hcflg, xflg, speed, flow, mdmtyp;
31: extern int prvpkt, cxseen, czseen, server, local, displa, bctu, bctr, quiet;
32: extern int tsecs, parity, backgrd;
33: extern int putsrv(), puttrm(), putfil(), errpkt();
34: extern char *DIRCMD, *DELCMD, *TYPCMD, *SPACMD, *SPACM2, *WHOCMD;
35: extern char *rdatap;
36:
37: /* Local variables */
38: static char vstate = 0; /* Saved State */
39: static char vcmd = 0; /* Saved Command */
40: int x; /* General-purpose integer */
41: char *s; /* General-purpose string pointer */
42:
43: /* Macros - Note, BEGIN is predefined by Wart (and Lex) */
44: #define SERVE tinit(); BEGIN serve
45: #define RESUME if (server) { SERVE; } else { sleep(2); return; }
46:
47: %%
48: /* Protocol entry points, one for each start state (sstate) */
49:
50: s { tinit(); /* Do Send command */
51: if (sinit()) BEGIN ssinit;
52: else RESUME; }
53:
54: v { tinit(); BEGIN get; } /* Receive */
55: r { tinit(); vstate = get; vcmd = 0; sipkt('I'); BEGIN ipkt; } /* Get */
56: c { tinit(); vstate = rgen; vcmd = 'C'; sipkt('I'); BEGIN ipkt; } /* Host */
57: g { tinit(); vstate = rgen; vcmd = 'G'; sipkt('I'); BEGIN ipkt; } /* Generic */
58:
59: x { sleep(1); SERVE; } /* Be a Server */
60:
61: a { errpkt("User cancelled transaction"); /* "Abort" -- Tell other side. */
62: x = quiet; quiet = 1; /* Close files silently. */
63: clsif(); clsof(1);
64: quiet = x; return(0); } /* Return from protocol. */
65:
66: /* Dynamic states: <current-states>input-character { action } */
67:
68: <rgen,get,serve>S { rinit(rdatap); bctu = bctr; /* Get Send-Init */
69: resetc(); /* Reset counters */
70: rtimer(); /* Reset timer */
71: BEGIN rfile; }
72:
73: <ipkt>Y { spar(rdatap); /* Get ack for I-packet */
74: if (vcmd) { scmd(vcmd,cmarg); vcmd = 0; }
75: if (vstate == get) srinit();
76: BEGIN vstate; }
77:
78: <ipkt>E { if (vcmd) scmd(vcmd,cmarg); /* Get E for I-packet (ignore) */
79: vcmd = 0; if (vstate == get) srinit();
80: BEGIN vstate; }
81:
82: <serve>R { srvptr = srvcmd; decode(rdatap,putsrv); /* Get Receive-Init */
83: cmarg = srvcmd; nfils = -1;
84: if (sinit()) BEGIN ssinit; else { SERVE; } }
85:
86: <serve>I { spar(rdatap); ack1(rpar()); /* Get Init Parameters */
87: pktnum = 0; prvpkt = -1; }
88:
89: <serve>G { srvptr = srvcmd; decode(rdatap,putsrv); /* Get & decode command. */
90: putsrv('\0'); putsrv('\0');
91: sstate = srvcmd[0]; BEGIN generic; }
92:
93: <serve>C { srvptr = srvcmd; /* Get command for shell */
94: decode(rdatap,putsrv); putsrv('\0');
95: if (syscmd(srvcmd,"")) BEGIN ssinit;
96: else { errpkt("Can't do system command"); SERVE; } }
97:
98: <serve>. { errpkt("Unimplemented server function"); SERVE; } /* Other */
99:
100: <generic>C { if (!cwd(srvcmd+1)) errpkt("Can't change directory"); /* CWD */
101: SERVE; }
102:
103: <generic>D { if (syscmd(DIRCMD,srvcmd+2)) BEGIN ssinit; /* Directory */
104: else { errpkt("Can't list directory"); SERVE; } }
105:
106: <generic>E { if (syscmd(DELCMD,srvcmd+2)) BEGIN ssinit; /* Erase */
107: else { errpkt("Can't remove file"); SERVE; } }
108:
109: <generic>F { ack(); screen(SCR_TC,0,0l,""); return(0); } /* Finish and Bye */
110: <generic>L { ack(); ttres(); screen(SCR_TC,0,0l,""); return(zkself()); }
111:
112: <generic>H { if (sndhlp()) BEGIN ssinit;
113: else { errpkt("Can't send help"); SERVE; } }
114:
115: <generic>T { if (syscmd(TYPCMD,srvcmd+2)) BEGIN ssinit;
116: else { errpkt("Can't type file"); SERVE; } }
117:
118: <generic>U { x = *(srvcmd+1); /* Disk Usage query */
119: x = ((x == '\0') || (x == SP));
120: x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,srvcmd+2));
121: if (x) BEGIN ssinit; else { errpkt("Can't check space"); SERVE; }}
122:
123: <generic>W { if (syscmd(WHOCMD,srvcmd+2)) BEGIN ssinit;
124: else { errpkt("Can't do who command"); SERVE; } }
125:
126: <generic>. { errpkt("Unimplemented generic server function"); SERVE; }
127:
128: /* Dynamic states, cont'd */
129:
130:
131: <rgen>Y { decode(rdatap,puttrm); RESUME; } /* Got reply in ACK data */
132:
133: <rgen,rfile>F { if (rcvfil()) { ack1(filnam); BEGIN rdata; } /* File header */
134: else { errpkt("Can't open file"); RESUME; } }
135:
136: <rgen,rfile>X { opent(); ack(); BEGIN rdata; } /* Screen data is coming */
137:
138: <rfile>B { ack(); tsecs = gtimer(); reot(); RESUME; } /* Got EOT */
139:
140: <rdata>D { if (cxseen) ack1("X"); /* Got data. */
141: else if (czseen) ack1("Z");
142: else ack();
143: decode(rdatap,putfil); }
144:
145: <rdata>Z { if (reof() < 0) { /* Got End Of File */
146: errpkt("Can't close file"); RESUME;
147: } else { ack(); BEGIN rfile; } }
148:
149: <ssinit>Y { spar(rdatap); bctu = bctr; /* Got ACK to Send-Init */
150: x = sfile(xflg); /* Send X or F header packet */
151: if (x) { resetc(); rtimer(); BEGIN ssfile; }
152: else { s = xflg ? "Can't execute command" : "Can't open file";
153: errpkt(s); RESUME; }
154: }
155:
156: <ssfile>Y { srvptr = srvcmd; /* Got ACK to F */
157: decode(rdatap,putsrv); putsrv('\0');
158: if (*srvcmd) tlog(F110," stored as",srvcmd,0);
159: if (sdata() < 0) { clsif(); seof(""); BEGIN sseof; }
160: else BEGIN ssdata; }
161:
162: <ssdata>Y { if (canned(rdatap)) { clsif(); seof("D"); BEGIN sseof; }
163: else if (sdata() < 0) { clsif(); seof(""); BEGIN sseof; } }
164:
165: <sseof>Y { if (gnfile() > 0) { /* Got ACK to EOF, get next file */
166: if (sfile(xflg)) BEGIN ssdata;
167: else { errpkt("Can't open file") ; RESUME; }
168: } else { /* If no next file, EOT */
169: tsecs = gtimer();
170: seot();
171: BEGIN sseot; }
172: }
173:
174: <sseot>Y { RESUME; } /* Got ACK to EOT */
175:
176: E { ermsg(rdatap); /* Error packet, issue message. */
177: x = quiet; quiet = 1; /* Close files silently, */
178: clsif(); clsof(1); /* discarding any output file. */
179: tsecs = gtimer();
180: quiet = x;
181: if (backgrd && !server) fatal("Protocol error");
182: RESUME; }
183:
184: . { errpkt("Unknown packet type"); RESUME; } /* Anything else, send error */
185: %%
186:
187: /* P R O T O -- Protocol entry function */
188:
189: proto() {
190:
191: extern int sigint();
192: int x;
193:
194: conint(sigint); /* Enable console interrupts */
195:
196: /* Set up the communication line for file transfer. */
197:
198: if (local && (speed < 0)) {
199: screen(SCR_EM,0,0l,"Sorry, you must 'set speed' first");
200: return;
201: }
202:
203: x = -1;
204: if (ttopen(ttname,&x,mdmtyp) < 0) {
205: debug(F111,"failed: proto ttopen local",ttname,local);
206: screen(SCR_EM,0,0l,"Can't open line");
207: return;
208: }
209: if (x > -1) local = x;
210: debug(F111,"proto ttopen local",ttname,local);
211:
212: x = (local) ? speed : -1;
213: if (ttpkt(x,flow,parity) < 0) { /* Put line in packet mode, */
214: screen(SCR_EM,0,0l,"Can't condition line");
215: return;
216: }
217: if (sstate == 'x') { /* If entering server mode, */
218: server = 1; /* set flag, */
219: if (!quiet) {
220: if (!local) /* and issue appropriate message. */
221: conol(srvtxt);
222: else {
223: conol("Entering server mode on ");
224: conoll(ttname);
225: }
226: }
227: } else server = 0;
228: if (sstate == 'v' && !local && !quiet)
229: conoll("Escape back to your local system and give a SEND command...");
230: if (sstate == 's' && !local && !quiet)
231: conoll("Escape back to your local system and give a RECEIVE command...");
232: sleep(1);
233: /*
234: The 'wart()' function is generated by the wart program. It gets a
235: character from the input() routine and then based on that character and
236: the current state, selects the appropriate action, according to the state
237: table above, which is transformed by the wart program into a big case
238: statement. The function is active for one transaction.
239: */
240: wart(); /* Enter the state table switcher. */
241:
242: if (server) { /* Back from packet protocol. */
243: server = 0;
244: if (!quiet) /* Give appropriate message */
245: conoll("C-Kermit server done");
246: }
247: ttres();
248: screen(SCR_TC,0,0l,""); /* Transaction complete */
249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.