|
|
1.1 root 1:
2: /* WARNING -- This C source program generated by Wart preprocessor. */
3: /* Do not edit this file; edit the Wart-format source file instead, */
4: /* and then run it through Wart to produce a new C source file. */
5:
6: /* Wart Version Info: */
7: char *wartv = "Wart Version 2A(009) 14 Jan 92";
8:
9: char *protv = "C-Kermit Protocol Module 5A(052), 23 Nov 92"; /* -*-C-*- */
10:
11: /* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */
12: /*
13: Author: Frank da Cruz ([email protected], [email protected]),
14: Columbia University Center for Computing Activities.
15: First released January 1985.
16: Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
17: York. Permission is granted to any individual or institution to use this
18: software as long as it is not sold for profit. This copyright notice must be
19: retained. This software may not be included in commercial products without
20: written permission of Columbia University.
21: */
22: #include "ckcdeb.h"
23: #include "ckcasc.h"
24: #include "ckcker.h"
25: /*
26: Note -- This file may also be preprocessed by the Unix Lex program, but
27: you must indent the above #include statements before using Lex, and then
28: restore them to the left margin in the resulting C program before compilation.
29: Also, the invocation of the "wart()" function below must be replaced by an
30: invocation of the "yylex()" function. It might also be necessary to remove
31: comments in the %%...%% section.
32: */
33:
34: /* State definitions for Wart (or Lex) */
35: #define ipkt 1
36: #define rfile 2
37: #define rattr 3
38: #define rdata 4
39: #define ssinit 5
40: #define ssfile 6
41: #define ssattr 7
42: #define ssdata 8
43: #define sseof 9
44: #define sseot 10
45: #define serve 11
46: #define generic 12
47: #define get 13
48: #define rgen 14
49:
50: /* External C-Kermit variable declarations */
51: extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist;
52: extern char filnam[], ttname[];
53: extern CHAR sstate, *rpar(), encbuf[], *srvptr, *data;
54: extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network;
55: extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl;
56: extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo;
57: extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla;
58: extern int timef;
59: extern long speed, ffc;
60: extern char *DIRCMD, *DIRCM2, *DELCMD, *TYPCMD, *SPACMD, *SPACM2, *WHOCMD;
61: extern CHAR *rdatap;
62: extern struct zattr iattr;
63: #ifdef DYNAMIC
64: extern CHAR *srvcmd;
65: #else
66: extern CHAR srvcmd[];
67: #endif /* DYNAMIC */
68:
69: #ifndef NOSPL
70: extern int cmdlvl;
71: #else
72: extern int tlevel;
73: #endif /* NOSPL */
74:
75: #ifdef NOMSEND
76: extern int sndsrc;
77: #endif /* NOMSEND */
78:
79: /* Flags for the ENABLE and DISABLE commands */
80: extern int
81: en_cwd, en_del, en_dir, en_fin, en_get, en_bye,
82: en_hos, en_sen, en_spa, en_set, en_typ, en_who;
83:
84: /* Global variables declared here */
85:
86: int what = W_NOTHING; /* What we're doing */
87:
88: /* Local variables */
89:
90: static char vstate = 0; /* Saved State */
91: static char vcmd = 0; /* Saved Command */
92:
93: static int x; /* General-purpose integer */
94: static char *s; /* General-purpose string pointer */
95:
96: /* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */
97: /* BEGIN is NOT a GOTO! */
98: #define TINIT if (tinit() < 0) return(-9)
99: #define SERVE TINIT; nakstate = 1; what = W_NOTHING; BEGIN serve
100: #define RESUME if (server) { SERVE; } else { sleep(2); return(0); }
101: #define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \
102: return(1)
103:
104:
105: #define BEGIN state =
106:
107: int state = 0;
108:
109: int
110: wart()
111: {
112: int c,actno;
113: extern char tbl[];
114: while (1) {
115: c = input() - 32;
116: if (c < 0 || c > 95) c = 0;
117: if ((actno = tbl[c + state*96]) != -1)
118: switch(actno) {
119: case 1:
120: { TINIT; /* Do Send command */
121: if (sinit()) BEGIN ssinit;
122: else RESUME; }
123: break;
124: case 2:
125: { TINIT; nakstate = 1; BEGIN get; }
126: break;
127: case 3:
128: { TINIT; vstate = get; vcmd = 0; sipkt('I'); BEGIN ipkt; }
129: break;
130: case 4:
131: { TINIT; vstate = rgen; vcmd = 'C'; sipkt('I'); BEGIN ipkt; }
132: break;
133: case 5:
134: { TINIT; vstate = rgen; vcmd = 'K'; sipkt('I'); BEGIN ipkt; }
135: break;
136: case 6:
137: { TINIT; vstate = rgen; vcmd = 'G'; sipkt('I'); BEGIN ipkt; }
138: break;
139: case 7:
140: { sleep(1); SERVE; }
141: break;
142: case 8:
143: { if (!data) TINIT; /* "ABEND" -- Tell other side. */
144: errpkt((CHAR *)"User cancelled");
145: success = 0;
146: return(0); }
147: break;
148: case 9:
149: { /* Receive Send-Init packet. */
150: if (state == serve && !en_sen) { /* Not allowed if in server mode */
151: errpkt((CHAR *)"SEND disabled"); /* and SEND is disabled. */
152: SERVE;
153: } else { /* OK to go ahead. */
154: nakstate = 1; /* Can send NAKs from here. */
155: rinit(rdatap); /* Set parameters */
156: bctu = bctr; /* Switch to agreed-upon block check */
157: bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
158: what = W_RECV; /* Remember we're receiving */
159: resetc(); /* Reset counters */
160: rtimer(); /* Reset timer */
161: BEGIN rfile; /* Go into receive-file state */
162: }
163: }
164: break;
165: case 10:
166: { /* Get ack for I-packet */
167: spar(rdatap); /* Set parameters */
168: #ifdef COMMENT
169: getsbuf(winlo = 0); /* Set window-low back to zero */
170: #else
171: winlo = 0;
172: #endif /* COMMENT */
173: if (vcmd) { /* If sending a generic command */
174: scmd(vcmd,(CHAR *)cmarg); /* Do that */
175: vcmd = 0; /* and then un-remember it. */
176: } else if (vstate == get) srinit(); /* If sending GET command, do that. */
177: rtimer(); /* Reset the elapsed seconds timer. */
178: winlo = 0; /* Window back to 0, again. */
179: nakstate = 1; /* Can send NAKs from here. */
180: BEGIN vstate; /* Switch to desired state */
181: }
182: break;
183: case 11:
184: { /* Ignore Error reply to I packet */
185: #ifdef COMMENT
186: getsbuf(winlo = 0); /* Set window-low back to zero */
187: #else
188: winlo = 0;
189: #endif /* COMMENT */
190: if (vcmd) { /* In case other Kermit doesn't */
191: scmd(vcmd,(CHAR *)cmarg); /* understand I-packets. */
192: vcmd = 0; /* Otherwise act as above... */
193: } else if (vstate == get) srinit();
194: winlo = 0; /* Back to packet 0 again. */
195: freerpkt(winlo); /* Discard the Error packet. */
196: nakstate = 1; /* Can send NAKs from here. */
197: BEGIN vstate;
198: }
199: break;
200: case 12:
201: { /* Resend of previous I-pkt ACK, same seq number! */
202: srinit();
203: }
204: break;
205: case 13:
206: { /* Get I-packet */
207: spar(rdatap); /* Set parameters from it */
208: ack1(rpar()); /* Respond with our own parameters */
209: pktinit(); /* Reinitialize packet numbers */
210: }
211: break;
212: case 14:
213: { /* Get Receive-Init (GET) */
214: debug(F100,"<serve>R","",0);
215: if (!en_get) { /* Only if not disabled! */
216: errpkt((CHAR *)"GET disabled");
217: SERVE;
218: } else { /* OK to go ahead. */
219: srvptr = srvcmd; /* Point to server command buffer */
220: decode(rdatap,putsrv,0); /* Decode the GET command into it */
221: /* Accept multiple filespecs */
222: cmarg2 = ""; /* Don't use cmarg2 */
223: cmarg = ""; /* Don't use cmarg */
224: #ifndef NOMSEND /* New way. */
225: nfils = fnparse((char *)srvcmd); /* Use cmlist instead */
226: #else
227: nfils = 0 - zxpand((char *)srvcmd);
228: #endif /* NOMSEND */
229: nakstate = 0; /* Now I'm the sender! */
230: if (sinit()) { /* Send Send-Init */
231: timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
232: BEGIN ssinit; /* If successful, switch state */
233: } else { SERVE; } /* Else back to server command wait */
234: }
235: }
236: break;
237: case 15:
238: { /* Generic server command */
239: srvptr = srvcmd; /* Point to command buffer */
240: decode(rdatap,putsrv,0); /* Decode packet data into it */
241: putsrv('\0'); /* Insert a couple nulls */
242: putsrv('\0'); /* for termination */
243: if (srvcmd[0]) {
244: sstate = srvcmd[0]; /* Set requested start state */
245: nakstate = 0; /* Now I'm the sender. */
246: what = W_REMO; /* Doing a REMOTE command. */
247: if (timint < 1)
248: timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
249: BEGIN generic; /* Switch to generic command state */
250: } else {
251: errpkt((CHAR *)"Badly formed server command"); /* report error */
252: SERVE; /* & go back to server command wait */
253: }
254: }
255: break;
256: case 16:
257: { /* Receive Host command */
258: if (!en_hos) {
259: errpkt((CHAR *)"REMOTE HOST disabled");
260: SERVE;
261: } else {
262: srvptr = srvcmd; /* Point to command buffer */
263: decode(rdatap,putsrv,0); /* Decode command packet into it */
264: putsrv('\0'); /* Null-terminate */
265: nakstate = 0; /* Now sending, not receiving */
266: if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */
267: what = W_REMO; /* Doing a REMOTE command. */
268: if (timint < 1)
269: timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
270: BEGIN ssinit; /* If OK, send back its output */
271: } else { /* Otherwise */
272: errpkt((CHAR *)"Can't do system command"); /* report error */
273: SERVE; /* & go back to server command wait */
274: }
275: }
276: }
277: break;
278: case 17:
279: { /* User typed Ctrl-C... */
280: if (!en_fin) {
281: errpkt((CHAR *)"QUIT disabled");
282: SERVE;
283: } else {
284: success = 0; QUIT;
285: }
286: }
287: break;
288: case 18:
289: { /* Server got a NAK in command-wait */
290: errpkt((CHAR *)"Did you say RECEIVE instead of GET?");
291: SERVE;
292: }
293: break;
294: case 19:
295: { /* Any other command in this state */
296: errpkt((CHAR *)"Unimplemented server function"); /* we don't know about */
297: SERVE; /* back to server command wait */
298: }
299: break;
300: case 20:
301: { /* Got REMOTE CWD command */
302: if (!en_cwd) {
303: errpkt((CHAR *)"REMOTE CD disabled");
304: SERVE;
305: } else {
306: if (!cwd((char *)(srvcmd+1))) errpkt((CHAR *)"Can't change directory");
307: SERVE; /* Back to server command wait */
308: }
309: }
310: break;
311: case 21:
312: { /* REMOTE DIRECTORY command */
313: char *n2;
314: if (!en_dir) { /* If DIR is disabled, */
315: errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */
316: SERVE;
317: } else { /* DIR is enabled. */
318: if (!en_cwd) { /* But if CWD is disabled */
319: zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
320: if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
321: errpkt((CHAR *)"Access denied");
322: SERVE; /* Remember, this is not a goto! */
323: }
324: }
325: if (state == generic) { /* It's OK to go ahead. */
326: n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2;
327: if (syscmd(n2,(char *)(srvcmd+2))) /* If it can be done */
328: BEGIN ssinit; /* send the results back */
329: else { /* otherwise */
330: errpkt((CHAR *)"Can't list directory"); /* report failure, */
331: SERVE; /* return to server command wait */
332: }
333: }
334: }
335: }
336: break;
337: case 22:
338: { /* REMOTE DELETE (Erase) command */
339: char *n2;
340: if (!en_del) {
341: errpkt((CHAR *)"REMOTE DELETE disabled");
342: SERVE;
343: } else {
344: if (!en_cwd) { /* But if CWD is disabled */
345: zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
346: if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
347: errpkt((CHAR *)"Access denied");
348: SERVE; /* Remember, this is not a goto! */
349: }
350: }
351: if (state == generic) { /* It's OK to go ahead. */
352: if (syscmd(DELCMD,(char *)(srvcmd+2))) /* Try to do it */
353: BEGIN ssinit; /* If OK send results back */
354: else { /* otherwise */
355: errpkt((CHAR *)"Can't remove file"); /* report failure */
356: SERVE; /* & return to server command wait */
357: }
358: }
359: }
360: }
361: break;
362: case 23:
363: { /* FINISH */
364: if (!en_fin) {
365: errpkt((CHAR *)"FINISH disabled");
366: SERVE;
367: } else {
368: ack(); /* Acknowledge */
369: screen(SCR_TC,0,0l,""); /* Display */
370: return(0); /* Done */
371: }
372: }
373: break;
374: case 24:
375: { /* BYE (LOGOUT) */
376: if (!en_bye) {
377: errpkt((CHAR *)"BYE disabled");
378: SERVE;
379: } else {
380: ack(); /* Acknowledge */
381: ttres(); /* Reset the terminal */
382: screen(SCR_TC,0,0l,""); /* Display */
383: doclean(); /* Clean up files, etc */
384: return(zkself()); /* Try to log self out */
385: }
386: }
387: break;
388: case 25:
389: { /* REMOTE HELP */
390: if (sndhlp()) BEGIN ssinit; /* Try to send it */
391: else { /* If not ok, */
392: errpkt((CHAR *)"Can't send help"); /* send error message instead */
393: SERVE; /* and return to server command wait */
394: }
395: }
396: break;
397: case 26:
398: { /* REMOTE SET */
399: if (!en_set) {
400: errpkt((CHAR *)"REMOTE SET disabled");
401: SERVE;
402: } else {
403: if (remset((char *)(srvcmd+1))) /* Try to do what they ask */
404: ack(); /* If OK, then acknowledge */
405: else /* Otherwise */
406: errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */
407: SERVE; /* Return to server command wait */
408: }
409: }
410: break;
411: case 27:
412: { /* REMOTE TYPE */
413: char *n2;
414: if (!en_typ) {
415: errpkt((CHAR *)"REMOTE TYPE disabled");
416: SERVE;
417: } else {
418: if (!en_cwd) { /* But if CWD is disabled */
419: zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
420: if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
421: errpkt((CHAR *)"Access denied");
422: SERVE; /* Remember, this is not a goto! */
423: }
424: }
425: if (state == generic) { /* It's OK to go ahead. */
426: if (syscmd(TYPCMD,(char *)(srvcmd+2))) /* Try */
427: BEGIN ssinit; /* OK */
428: else { /* not OK */
429: errpkt((CHAR *)"Can't type file"); /* give error message */
430: SERVE; /* wait for next server command */
431: }
432: }
433: }
434: }
435: break;
436: case 28:
437: { /* REMOTE SPACE */
438: if (!en_spa) {
439: errpkt((CHAR *)"REMOTE SPACE disabled");
440: SERVE;
441: } else {
442: x = *(srvcmd+1); /* Get area to check */
443: x = ((x == '\0') || (x == SP)
444: #ifdef OS2
445: || (x == '!')
446: #endif /* OS2 */
447: );
448: if (!x && !en_cwd) { /* If CWD disabled and they gave */
449: errpkt((CHAR *)"Access denied"); /* a non-default area, */
450: SERVE; /* refuse. */
451: } else {
452: #ifdef OS2
453: _PROTOTYP(int sndspace,(int));
454: if (sndspace(x ? toupper(srvcmd[2]) : 0))
455: BEGIN ssinit; /* Try to send it */
456: else { /* If not ok, */
457: errpkt((CHAR *)"Can't send space"); /* send error message */
458: SERVE; /* and return to server command wait */
459: }
460: #else
461: x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2)));
462: if (x) { /* If we got the info */
463: BEGIN ssinit; /* send it */
464: } else { /* otherwise */
465: errpkt((CHAR *)"Can't check space"); /* send error message */
466: SERVE; /* and await next server command */
467: }
468: #endif /* OS2 */
469: }
470: }
471: }
472: break;
473: case 29:
474: { /* REMOTE WHO */
475: if (!en_who) {
476: errpkt((CHAR *)"REMOTE WHO disabled");
477: SERVE;
478: } else {
479: if (syscmd(WHOCMD,(char *)(srvcmd+2))) /* The now-familiar scenario. */
480: BEGIN ssinit;
481: else {
482: errpkt((CHAR *)"Can't do who command");
483: SERVE;
484: }
485: }
486: }
487: break;
488: case 30:
489: {
490: if (!en_fin) { /* Ctrl-C typed */
491: errpkt((CHAR *)"QUIT disabled");
492: SERVE;
493: } else {
494: success = 0; QUIT;
495: }
496: }
497: break;
498: case 31:
499: { /* Anything else in this state... */
500: errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */
501: SERVE; /* and return to server command wait */
502: }
503: break;
504: case 32:
505: { /* Short-Form reply */
506: decode(rdatap,puttrm,0); /* in ACK Data field */
507: if (rdatap && *rdatap) conoll(""); /* Maybe add a CRLF */
508: RESUME;
509: }
510: break;
511: case 33:
512: { /* File header */
513: xflg = 0; /* Not screen data */
514: if (!rcvfil(filnam)) { /* Figure out local filename */
515: errpkt((CHAR *)"Can't transform filename"); /* Trouble */
516: RESUME;
517: } else { /* OK to receive */
518: encstr((CHAR *)filnam); /* Encode the name */
519: ack1((CHAR *)(encbuf+7)); /* Send it back in ACK */
520: initattr(&iattr); /* Clear file attribute structure */
521: if (window(wslotn) < 0) { /* Allocate negotiated window slots */
522: errpkt((CHAR *)"Can't open window");
523: RESUME;
524: }
525: BEGIN rattr; /* Now expect Attribute packets */
526: }
527: }
528: break;
529: case 34:
530: { /* X-packet instead of file header */
531: xflg = 1; /* Screen data */
532: ack(); /* Acknowledge the X-packet */
533: initattr(&iattr); /* Initialize attribute structure */
534: if (window(wslotn) < 0) { /* allocate negotiated window slots */
535: errpkt((CHAR *)"Can't open window");
536: RESUME;
537: }
538: what = W_REMO; /* we're doing a REMOTE command */
539: BEGIN rattr; /* Expect Attribute packets */
540: }
541: break;
542: case 35:
543: { /* Attribute packet */
544: if (discard) { /* If SET FILE COLLISION DISCARD */
545: ack1((CHAR *)"N"); /* refuse it */
546: screen(SCR_ST,ST_REFU,0L,"file collision setting");
547: } else if (gattr(rdatap,&iattr) == 0) { /* Read into attribute structure */
548: ack(); /* If OK, acknowledge */
549: } else { /* Otherwise */
550: ack1((CHAR *)iattr.reply.val); /* refuse to accept the file */
551: screen(SCR_ST,ST_REFU,0L,getreason(iattr.reply.val)); /* give reason */
552: }
553: }
554: break;
555: case 36:
556: { /* First data packet */
557: if (discard) { /* if we're discarding the file */
558: ack1((CHAR *)"X"); /* just ack the data like this. */
559: BEGIN rdata; /* and wait for more data packets. */
560: } else { /* Not discarding. */
561: if (xflg) /* If screen data */
562: x = opent(&iattr); /* "open" the screen */
563: else /* otherwise */
564: x = opena(filnam,&iattr); /* open the file, with attributes */
565: if (x) { /* If file was opened ok */
566: if (decode(rdatap,putfil,1) < 0) { /* decode first data packet */
567: errpkt((CHAR *)"Error writing data");
568: RESUME;
569: }
570: ack(); /* acknowledge it */
571: BEGIN rdata; /* and switch to receive-data state */
572: } else { /* otherwise */
573: errpkt((CHAR *)"Can't open file"); /* send error message */
574: RESUME; /* and quit. */
575: }
576: }
577: }
578: break;
579: case 37:
580: { /* EOT, no more files */
581: ack(); /* Acknowledge */
582: tsecs = gtimer(); /* Get timing for statistics */
583: reot(); /* Do EOT things */
584: RESUME; /* and quit */
585: }
586: break;
587: case 38:
588: { /* Data packet */
589: if (cxseen || discard) /* If file interrupt */
590: ack1((CHAR *)"X"); /* put "X" in ACK */
591: else if (czseen) /* If file-group interrupt */
592: ack1((CHAR *)"Z"); /* put "Z" in ACK */
593: else if (decode(rdatap,putfil,1) < 0) { /* Normal case, decode to file */
594: errpkt((CHAR *)"Error writing data"); /* If failure, */
595: clsof(!keep); /* Close & keep/discard the file */
596: RESUME; /* Send ACK only after data */
597: } else ack(); /* written to file OK. */
598: }
599: break;
600: case 39:
601: { /* EOF immediately after A-Packet. */
602: if (xflg) /* Zero-length file. If screen data */
603: x = opent(&iattr); /* "open" the screen */
604: else /* otherwise */
605: x = opena(filnam,&iattr); /* open the file, with attributes. */
606: if (!x || reof(filnam, &iattr) < 0) { /* Now close & dispose of the file */
607: errpkt((CHAR *)"Can't create file"); /* If problem, send error msg */
608: RESUME; /* and quit */
609: } else { /* otherwise */
610: ack(); /* acknowledge the EOF packet */
611: BEGIN rfile; /* and await another file */
612: }
613: }
614: break;
615: case 40:
616: { /* End Of File (EOF) Packet */
617: /* wslots = 1; */ /* Window size back to 1 */
618: #ifndef COHERENT
619: /*
620: Coherent compiler blows up on this switch() statement.
621: */
622: x = reof(filnam, &iattr); /* Handle the EOF packet */
623: switch (x) { /* reof() sets the success flag */
624: case -3: /* If problem, send error msg */
625: errpkt((CHAR *)"Can't print file"); /* Fatal */
626: RESUME;
627: break;
628: case -2:
629: errpkt((CHAR *)"Can't mail file"); /* Fatal */
630: RESUME;
631: break;
632: case 2:
633: case 3:
634: screen(SCR_EM,0,0l,"Can't delete temp file"); /* Not fatal */
635: RESUME;
636: break;
637: default:
638: if (x < 0) { /* Fatal */
639: errpkt((CHAR *)"Can't close file");
640: RESUME;
641: } else { /* Success */
642: ack(); /* Acknowledge the EOF packet */
643: BEGIN rfile; /* and await another file */
644: }
645: }
646: #else
647: if (reof(filnam, &iattr) < 0) { /* Close and dispose of the file */
648: errpkt((CHAR *)"Error at end of file");
649: RESUME;
650: } else { /* reof() sets success flag */
651: ack();
652: BEGIN rfile;
653: }
654: #endif /* COHERENT */
655: }
656: break;
657: case 41:
658: { /* ACK for Send-Init */
659: spar(rdatap); /* set parameters from it */
660: bctu = bctr; /* switch to agreed-upon block check */
661: bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
662: what = W_SEND; /* Remember we're sending */
663: x = sfile(xflg); /* Send X or F header packet */
664: if (x) { /* If the packet was sent OK */
665: resetc(); /* reset per-transaction counters */
666: rtimer(); /* reset timers */
667: BEGIN ssfile; /* and switch to receive-file state */
668: } else { /* otherwise send error msg & quit */
669: s = xflg ? "Can't execute command" : "Can't open file";
670: errpkt((CHAR *)s);
671: RESUME;
672: }
673: }
674: break;
675: case 42:
676: { /* R packet was retransmitted. */
677: xsinit(); /* Resend packet 0 */
678: }
679: break;
680: case 43:
681: { /* Same deal if G packet comes again */
682: xsinit();
683: }
684: break;
685: case 44:
686: { /* Same deal if C packet comes again */
687: xsinit();
688: }
689: break;
690: case 45:
691: { /* ACK for F packet */
692: srvptr = srvcmd; /* Point to string buffer */
693: decode(rdatap,putsrv,0); /* Decode data field, if any */
694: putsrv('\0'); /* Terminate with null */
695: ffc = 0L; /* Reset file byte counter */
696: if (*srvcmd) { /* If remote name was recorded */
697: if (fdispla == XYFD_C) screen(SCR_AN,0,0L,(char *)srvcmd);
698: tlog(F110," stored as",(char *) srvcmd,0L); /* Transaction log. */
699: }
700: if (atcapu) { /* If attributes are to be used */
701: if (sattr(xflg) < 0) { /* set and send them */
702: errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */
703: RESUME; /* and quit */
704: } else BEGIN ssattr; /* if ok, switch to attribute state */
705: } else {
706: if (window(wslotn) < 0) {
707: errpkt((CHAR *)"Can't open window");
708: RESUME;
709: }
710: if (sdata() < 0) { /* No attributes, send data */
711: clsif(); /* If not ok, close input file, */
712: window(1); /* put window size back to 1, */
713: seof((CHAR *)""); /* send EOF packet, */
714: BEGIN sseof; /* and switch to EOF state. */
715: } else BEGIN ssdata; /* All ok, switch to send-data state */
716: }
717: }
718: break;
719: case 46:
720: { /* Got ACK to A packet */
721: ffc = 0L; /* Reset file byte counter */
722: if (rsattr(rdatap) < 0) { /* Was the file refused? */
723: discard = 1; /* Set the discard flag */
724: clsif(); /* Close the file */
725: sxeof((CHAR *)"D"); /* send EOF with "discard" code */
726: BEGIN sseof; /* switch to send-EOF state */
727: } else {
728: if (window(wslotn) < 0) { /* Allocate negotiated window slots */
729: errpkt((CHAR *)"Can't open window");
730: RESUME;
731: }
732: if (sdata() < 0) { /* File accepted, send data */
733: clsif(); /* If problem, close input file */
734: window(1); /* Window size back to 1... */
735: seof((CHAR *)""); /* send EOF packet */
736: BEGIN sseof; /* and switch to send-EOF state. */
737: } else { /* All ok, enter send-data state. */
738: BEGIN ssdata;
739: }
740: }
741: }
742: break;
743: case 47:
744: { /* Got ACK to Data packet */
745: canned(rdatap); /* Check if file transfer cancelled */
746: if (sdata() < 0) { /* Try to send next data */
747: clsif(); /* If no more data, close file */
748: window(1); /* Window size back to 1... */
749: if (cxseen || czseen) /* If interrupted */
750: seof((CHAR *)"D"); /* send special EOF packet */
751: else seof((CHAR *)""); /* Otherwise regular EOF packet */
752: BEGIN sseof; /* And enter send-eof state */
753: }
754: }
755: break;
756: case 48:
757: { /* Got ACK to EOF */
758: success = (cxseen == 0 && czseen == 0); /* Set this for IF command */
759: cxseen = 0; /* This goes back to zero. */
760: if (gnfile() > 0) { /* Any more files to send? */
761: if (sfile(xflg)) /* Yes, try to send next file header */
762: BEGIN ssfile; /* if ok, enter send-file state */
763: else { /* otherwise */
764: errpkt((CHAR *)"Can't open file"); /* send error message */
765: RESUME; /* and quit */
766: }
767: } else { /* No next file */
768: tsecs = gtimer(); /* get statistics timers */
769: seot(); /* send EOT packet */
770: BEGIN sseot; /* enter send-eot state */
771: }
772: }
773: break;
774: case 49:
775: { /* Got ACK to EOT */
776: RESUME; /* All done, just quit */
777: }
778: break;
779: case 50:
780: { /* Got Error packet, in any state */
781: ermsg((char *)rdatap); /* Issue message. */
782: success = 0; /* For IF SUCCESS/FAIL. */
783: debug(F101,"ckcpro.w sstate at E pkt","",sstate);
784: x = quiet; quiet = 1; /* Close files silently, */
785: clsif(); clsof(1); /* discarding any output file. */
786: tsecs = gtimer(); /* Get timers */
787: quiet = x; /* restore quiet state */
788: /*
789: If we are executing commands from a command file or macro, let the command
790: file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR.
791: */
792: if (
793: #ifndef NOSPL
794: cmdlvl == 0
795: #else
796: tlevel < 0
797: #endif /* NOSPL */
798: )
799: if (backgrd && !server)
800: fatal("Protocol error");
801: xitsta |= what; /* Save this for doexit(). */
802: RESUME;
803: }
804: break;
805: case 51:
806: { QUIT; }
807: break;
808: case 52:
809: { /* Anything not accounted for above */
810: errpkt((CHAR *)"Unexpected packet type"); /* Give error message */
811: xitsta |= what; /* Save this for doexit(). */
812: RESUME; /* and quit */
813: }
814: break;
815:
816: }
817: }
818: }
819:
820: char tbl[] = {
821: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
822: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
823: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
824: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
825: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
826: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
827: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
828: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
829: 52, 52, 52, 52, 52, 11, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
830: 52, 52, 52, 52, 52, 52, 52, 52, 52, 10, 52, 52, 52, 52, 52, 52,
831: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
832: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
833: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
834: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
835: 52, 52, 37, 52, 52, 50, 33, 52, 52, 52, 52, 52, 52, 52, 52, 52,
836: 52, 52, 52, 52, 52, 52, 52, 52, 34, 52, 52, 52, 52, 52, 52, 52,
837: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
838: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
839: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
840: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
841: 52, 35, 52, 52, 36, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
842: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 39, 52, 52, 52, 52, 52,
843: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
844: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
845: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
846: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
847: 52, 52, 52, 52, 38, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
848: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 40, 52, 52, 52, 52, 52,
849: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
850: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
851: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
852: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
853: 52, 52, 52, 44, 52, 50, 52, 43, 52, 52, 52, 52, 52, 52, 52, 52,
854: 52, 52, 42, 52, 52, 52, 52, 52, 52, 41, 52, 52, 52, 52, 52, 52,
855: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
856: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
857: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
858: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
859: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
860: 52, 52, 52, 52, 52, 52, 52, 52, 52, 45, 52, 52, 52, 52, 52, 52,
861: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
862: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
863: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
864: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
865: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
866: 52, 52, 52, 52, 52, 52, 52, 52, 52, 46, 52, 52, 52, 52, 52, 52,
867: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
868: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
869: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
870: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
871: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
872: 52, 52, 52, 52, 52, 52, 52, 52, 52, 47, 52, 52, 52, 52, 52, 52,
873: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
874: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
875: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
876: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
877: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
878: 52, 52, 52, 52, 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 52,
879: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
880: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
881: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
882: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
883: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
884: 52, 52, 52, 52, 52, 52, 52, 52, 52, 49, 52, 52, 52, 52, 52, 52,
885: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
886: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
887: -1, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
888: 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
889: 19, 19, 19, 16, 19, 19, 19, 15, 19, 13, 19, 19, 19, 19, 18, 19,
890: 19, 19, 14, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
891: 19, 8, 19, 4, 19, 19, 19, 6, 19, 19, 19, 5, 19, 19, 19, 19,
892: 19, 17, 3, 1, 19, 19, 2, 19, 7, 19, 19, 19, 19, 19, 19, 19,
893: -1, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
894: 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
895: 31, 31, 31, 20, 21, 22, 23, 31, 25, 31, 31, 31, 24, 31, 31, 31,
896: 31, 31, 31, 26, 27, 28, 31, 29, 31, 31, 31, 31, 31, 31, 31, 31,
897: 31, 8, 31, 4, 31, 31, 31, 6, 31, 31, 31, 5, 31, 31, 31, 31,
898: 31, 30, 3, 1, 31, 31, 2, 31, 7, 31, 31, 31, 31, 31, 31, 31,
899: -1, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
900: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
901: 52, 52, 52, 52, 52, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
902: 52, 52, 52, 9, 52, 52, 52, 52, 52, 12, 52, 52, 52, 52, 52, 52,
903: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
904: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52,
905: 0, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
906: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
907: 52, 52, 52, 52, 52, 50, 33, 52, 52, 52, 52, 52, 52, 52, 52, 52,
908: 52, 52, 52, 9, 52, 52, 52, 52, 34, 32, 52, 52, 52, 52, 52, 52,
909: 52, 8, 52, 4, 52, 52, 52, 6, 52, 52, 52, 5, 52, 52, 52, 52,
910: 52, 51, 3, 1, 52, 52, 2, 52, 7, 52, 52, 52, 52, 52, 52, 52 };
911:
912:
913: /* P R O T O -- Protocol entry function */
914:
915: VOID
916: proto() {
917:
918: int x;
919: long lx;
920:
921: /* Set up the communication line for file transfer. */
922:
923: if (local && (speed < 0L) && (network == 0)) {
924: screen(SCR_EM,0,0l,"Sorry, you must 'set speed' first");
925: return;
926: }
927: x = -1;
928: if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) {
929: debug(F111,"failed: proto ttopen local",ttname,local);
930: screen(SCR_EM,0,0l,"Can't open line");
931: return;
932: }
933: if (x > -1) local = x;
934: debug(F111,"proto ttopen local",ttname,local);
935:
936: lx = (local && !network) ? speed : -1;
937: if (ttpkt(lx,flow,parity) < 0) { /* Put line in packet mode, */
938: screen(SCR_EM,0,0l,"Can't condition line");
939: return;
940: }
941: if (!local) connoi(); /* No console interrupts if remote */
942:
943: if (sstate == 'x') { /* If entering server mode, */
944: server = 1; /* set flag, */
945: debug(F101,"server backgrd","",backgrd);
946: debug(F101,"server quiet","",quiet);
947: if (!quiet && !backgrd) {
948: debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0);
949: if (!local) { /* and issue appropriate message. */
950: conoll(srvtxt);
951: conoll("KERMIT READY TO SERVE...");
952: } else {
953: conol("Entering server mode on ");
954: conoll(ttname);
955: conoll("Type Ctrl-C to quit.");
956: if (srvdis) intmsg(-1L);
957: }
958: }
959: } else server = 0;
960: #ifdef VMS
961: if (!quiet && !backgrd) /* So message doesn't overwrite prompt */
962: conoll("");
963: if (local) conres(); /* So Ctrl-C will work */
964: #endif /* VMS */
965: /*
966: If in remote mode, not shushed, not in background, and at top command level,
967: issue a helpful message telling what to do...
968: */
969: if (!local && !quiet && !backgrd &&
970: #ifndef NOSPL
971: cmdlvl == 0
972: #else
973: tlevel < 0
974: #endif /* NOSPL */
975: ) {
976: if (sstate == 'v') {
977: conoll("Return to your local Kermit and give a SEND command.");
978: conoll("");
979: conoll("KERMIT READY TO RECEIVE...");
980: } else if (sstate == 's') {
981: conoll("Return to your local Kermit and give a RECEIVE command.");
982: conoll("");
983: conoll("KERMIT READY TO SEND...");
984: } else if ( sstate == 'g' || sstate == 'r' || sstate == 'c' ) {
985: conoll("Return to your local Kermit and give a SERVER command.");
986: conoll("");
987: conoll((sstate == 'r') ?
988: "KERMIT READY TO GET..." :
989: "KERMIT READY TO SEND SERVER COMMAND...");
990: }
991: }
992: sleep(1);
993: /*
994: The 'wart()' function is generated by the wart program. It gets a
995: character from the input() routine and then based on that character and
996: the current state, selects the appropriate action, according to the state
997: table above, which is transformed by the wart program into a big case
998: statement. The function is active for one transaction.
999: */
1000: wart(); /* Enter the state table switcher. */
1001:
1002: if (server) { /* Back from packet protocol. */
1003: if (!quiet && !backgrd) { /* Give appropriate message */
1004: conoll("");
1005: conoll("C-Kermit server done");
1006: }
1007: }
1008: /*
1009: Note: the following is necessary in case we have just done a remote-mode
1010: file transfer, in which case the controlling terminal modes have been
1011: changed by ttpkt(). In particular, special characters like Ctrl-C and
1012: Ctrl-\ might have been turned off (see ttpkt). So this call to ttres() is
1013: essential.
1014: */
1015: #ifndef OS2
1016: if (!local)
1017: #endif /* OS2 */
1018: ttres(); /* Reset the communication device */
1019: screen(SCR_TC,0,0l,""); /* Transaction complete */
1020: server = 0; /* Not a server any more */
1021: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.