home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit4e / ckcpro.w < prev    next >
Text File  |  2020-01-01  |  9KB  |  253 lines

  1. char *protv = "C-Kermit Protocol Module 4E(032), 13 Jan 89"; /* -*-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. <get>Y { srinit(); } /* Resend of previous I-pkt ACK, same seq number! */
  83.  
  84. <serve>R { srvptr = srvcmd; decode(rdatap,putsrv); /* Get Receive-Init */
  85.        cmarg = srvcmd;  nfils = -1;
  86.            if (sinit()) BEGIN ssinit; else { SERVE; } }
  87.  
  88. <serve>I { spar(rdatap); ack1(rpar());               /* Get Init Parameters */
  89.        pktnum = 0; prvpkt = -1; }
  90.  
  91. <serve>G { srvptr = srvcmd; decode(rdatap,putsrv); /* Get & decode command. */
  92.        putsrv('\0'); putsrv('\0');
  93.        sstate = srvcmd[0]; BEGIN generic; }
  94.  
  95. <serve>C { srvptr = srvcmd;                 /* Get command for shell */
  96.        decode(rdatap,putsrv); putsrv('\0');
  97.        if (syscmd(srvcmd,"")) BEGIN ssinit;
  98.        else { errpkt("Can't do system command"); SERVE; } }
  99.  
  100. <serve>. { errpkt("Unimplemented server function"); SERVE; } /* Other */
  101.  
  102. <generic>C { if (!cwd(srvcmd+1)) errpkt("Can't change directory"); /* CWD */
  103.              SERVE; }
  104.  
  105. <generic>D { if (syscmd(DIRCMD,srvcmd+2)) BEGIN ssinit;    /* Directory */
  106.              else { errpkt("Can't list directory"); SERVE; } }
  107.  
  108. <generic>E { if (syscmd(DELCMD,srvcmd+2)) BEGIN ssinit;    /* Erase */
  109.              else { errpkt("Can't remove file"); SERVE; } }
  110.  
  111. <generic>F { ack(); screen(SCR_TC,0,0l,""); return(0); } /* Finish and Bye */
  112. <generic>L { ack(); ttres(); screen(SCR_TC,0,0l,""); return(zkself()); }
  113.  
  114. <generic>H { if (sndhlp()) BEGIN ssinit;
  115.              else { errpkt("Can't send help"); SERVE; } }
  116.  
  117. <generic>T { if (syscmd(TYPCMD,srvcmd+2)) BEGIN ssinit;
  118.              else { errpkt("Can't type file"); SERVE; } }
  119.  
  120. <generic>U { x = *(srvcmd+1);            /* Disk Usage query */
  121.              x = ((x == '\0') || (x == SP));
  122.          x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,srvcmd+2));
  123.              if (x) BEGIN ssinit; else { errpkt("Can't check space"); SERVE; }}
  124.  
  125. <generic>W { if (syscmd(WHOCMD,srvcmd+2)) BEGIN ssinit;
  126.              else { errpkt("Can't do who command"); SERVE; } }
  127.  
  128. <generic>. { errpkt("Unimplemented generic server function"); SERVE; }
  129.  
  130. /* Dynamic states, cont'd */
  131.  
  132.  
  133. <rgen>Y { decode(rdatap,puttrm); RESUME; }    /* Got reply in ACK data */
  134.  
  135. <rgen,rfile>F { if (rcvfil())              /* File header */
  136.           { encstr(filnam); ack1(data); BEGIN rdata; }
  137.                 else { errpkt("Can't open file"); RESUME; } }
  138.  
  139. <rgen,rfile>X { opent(); ack(); BEGIN rdata; }    /* Screen data is coming */
  140.  
  141. <rfile>B { ack(); tsecs = gtimer(); reot(); RESUME; } /* Got EOT */
  142.  
  143. <rdata>D { if (cxseen) ack1("X");    /* Got data. */
  144.                else if (czseen) ack1("Z");
  145.            else ack();
  146.        decode(rdatap,putfil); }
  147.  
  148. <rdata>Z  { if (reof() < 0) {            /* Got End Of File */
  149.               errpkt("Can't close file"); RESUME;
  150.             } else { ack(); BEGIN rfile; } }
  151.  
  152. <ssinit>Y { spar(rdatap); bctu = bctr;    /* Got ACK to Send-Init */
  153.             x = sfile(xflg);        /* Send X or F header packet */
  154.         if (x) { resetc(); rtimer(); BEGIN ssfile; }
  155.            else { s = xflg ? "Can't execute command" : "Can't open file";
  156.             errpkt(s); RESUME; }
  157.           }
  158.  
  159. <ssfile>Y { srvptr = srvcmd;                 /* Got ACK to F */
  160.         decode(rdatap,putsrv); putsrv('\0');
  161.         if (*srvcmd) tlog(F110," stored as",srvcmd,0);
  162.         if (sdata() < 0) { clsif(); seof(""); BEGIN sseof; }
  163.                 else BEGIN ssdata; }
  164.  
  165. <ssdata>Y { if (canned(rdatap)) { clsif(); seof("D"); BEGIN sseof; }
  166.             else if (sdata() < 0) { clsif(); seof(""); BEGIN sseof; } }
  167.  
  168. <sseof>Y  { if (gnfile() > 0) {        /* Got ACK to EOF, get next file */
  169.         if (sfile(xflg)) BEGIN ssdata;
  170.         else { errpkt("Can't open file") ; RESUME; }
  171.         } else {            /* If no next file, EOT */
  172.         tsecs = gtimer();
  173.         seot();
  174.         BEGIN sseot; }
  175.       }
  176.  
  177. <sseot>Y { RESUME; }            /* Got ACK to EOT */
  178.  
  179. E { ermsg(rdatap);            /* Error packet, issue message. */
  180.     x = quiet; quiet = 1;        /* Close files silently, */
  181.     clsif(); clsof(1);            /* discarding any output file. */
  182.     tsecs = gtimer();
  183.     quiet = x;
  184.     if (backgrd && !server) fatal("Protocol error");
  185.     RESUME; }
  186.  
  187. . { errpkt("Unknown packet type"); RESUME; } /* Anything else, send error */
  188. %%
  189.  
  190. /*  P R O T O  --  Protocol entry function  */
  191.  
  192. proto() {
  193.  
  194.     extern int sigint();
  195.     int x;
  196.  
  197.     conint(sigint);            /* Enable console interrupts */
  198.  
  199. /* Set up the communication line for file transfer. */
  200.  
  201.     if (local && (speed < 0)) {
  202.     screen(SCR_EM,0,0l,"Sorry, you must 'set speed' first");
  203.     return;
  204.     }
  205.  
  206.     x = -1;
  207.     if (ttopen(ttname,&x,mdmtyp) < 0) {
  208.     debug(F111,"failed: proto ttopen local",ttname,local);
  209.     screen(SCR_EM,0,0l,"Can't open line");
  210.     return;
  211.     }
  212.     if (x > -1) local = x;
  213.     debug(F111,"proto ttopen local",ttname,local);
  214.  
  215.     x = (local) ? speed : -1;
  216.     if (ttpkt(x,flow,parity) < 0) {    /* Put line in packet mode, */
  217.     screen(SCR_EM,0,0l,"Can't condition line");
  218.     return;
  219.     }
  220.     if (sstate == 'x') {        /* If entering server mode, */
  221.     server = 1;            /* set flag, */
  222.     if (!quiet) {
  223.         if (!local)            /* and issue appropriate message. */
  224.             conol(srvtxt);
  225.         else {
  226.             conol("Entering server mode on ");
  227.         conoll(ttname);
  228.         }
  229.     }
  230.     } else server = 0;
  231.     if (sstate == 'v' && !local && !quiet)
  232.       conoll("Escape back to your local system and give a SEND command...");
  233.     if (sstate == 's' && !local && !quiet)
  234.       conoll("Escape back to your local system and give a RECEIVE command...");
  235.     sleep(1);
  236. /*
  237.  The 'wart()' function is generated by the wart program.  It gets a
  238.  character from the input() routine and then based on that character and
  239.  the current state, selects the appropriate action, according to the state
  240.  table above, which is transformed by the wart program into a big case
  241.  statement.  The function is active for one transaction.
  242. */
  243.     wart();                /* Enter the state table switcher. */
  244.     
  245.     if (server) {            /* Back from packet protocol. */
  246.     server = 0;
  247.         if (!quiet)              /* Give appropriate message */
  248.         conoll("C-Kermit server done");
  249.     }
  250.     ttres();
  251.     screen(SCR_TC,0,0l,"");        /* Transaction complete */
  252. }
  253.