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