|
|
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.