home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / gproto.w < prev    next >
Text File  |  2020-01-01  |  6KB  |  229 lines

  1. /* G P R O T O  --  Protocol module for gkermit  */             /* -*-C-*- */
  2.  
  3. /*
  4.   Author:
  5.     Frank da Cruz
  6.     The Kermit Project
  7.     Columbia University
  8.     612 West 115th Street
  9.     New York NY 10025-7799  USA
  10.     http://www.columbia.edu/kermit/
  11.     kermit@columbia.edu
  12.  
  13.   Copyright (C) 1999,
  14.   The Trustees of Columbia University in the City of New York.
  15.  
  16.   This program is free software; you can redistribute it and/or modify
  17.   it under the terms of the GNU General Public License as published by
  18.   the Free Software Foundation; either version 2 of the License, or
  19.   (at your option) any later version.
  20.  
  21.   This program is distributed in the hope that it will be useful,
  22.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.   GNU General Public License for more details.
  25.  
  26.   You should have received a copy of the GNU General Public License
  27.   along with this program; if not, write to the Free Software
  28.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  29. */
  30. #include <stdio.h>
  31. #include "gkermit.h"
  32.  
  33. _MYPROTOTYPE( int closof, (void) );    /* Close output file */
  34. _MYPROTOTYPE( VOID errpkt, (char *) );    /* Send Error packet */
  35.  
  36. extern char * xdata, *rdatap, **cmlist, *cmarg, *rpar(), strbuf[], filnam[];
  37. extern int start, bctu, bctr, delay, cx, cz, failure, attributes, datalen;
  38. extern int streamok, streaming, timint;
  39. extern FILE * db;
  40.  
  41. static int x;
  42.  
  43. static VOID
  44. streamon() {                /* Start streaming if negotiated */
  45.     x = 0;
  46.     if (streamok > 0) {
  47.     streaming = 1;
  48.     timint = 0;
  49.     }
  50. }
  51.  
  52. /* Declare gwart states (like lex) */
  53.  
  54. %states ssini ssfil ssdat ssatt sseot sseof sipkt
  55. %states srini srfil srdat sratt
  56.  
  57. /* Packets are read by the input() function, which returns the packet type */
  58. /* that serves as the input to the state machine, which follows... */
  59.  
  60. %%
  61. /* Sending states... */
  62.  
  63. s {                    /* Start state for Send. */
  64.     tinit();                /* Initialize transaction. */
  65.     if (sinit('S') < 0) { errpkt("sinit"); } /* Build and send the S packet. */
  66.     else BEGIN ssini;
  67. }
  68. <ssini>Y {                /* Receive ACK to I packet */
  69.     spar(rdatap);            /* Set parameters from it */
  70.     bctu = bctr;            /* Switch to negotiated block check */
  71.     if (gnfile() > 0) {            /* Is there a file to send? */
  72.         if (sfile() < 0) {        /* Yes, open it, send F packet, */
  73.         errpkt("sfile");
  74.     } else {            /* No error */
  75.         streamon();
  76.         BEGIN ssfil;
  77.     }
  78.     } else {                /* No files to send, */
  79.         if (seot() < 0) { errpkt("seot"); } /* so send EOT packet. */
  80.         else BEGIN sseot;
  81.     }
  82. }
  83. <ssfil>Y {                /* Receive ACK to File header packet */
  84.     if (attributes) {            /* If attributes negotiated */
  85.     if (sattr() < 0) {        /* Send file attributes */
  86.         errpkt("sattr");
  87.     } else
  88.       BEGIN ssatt;
  89.     } else if ((x = sdata()) == 0) {    /* Otherwise send first Data packet */
  90.     if (seof("") < 0) {        /* Empty file - send EOF */
  91.         errpkt("seof");
  92.     } else {
  93.         BEGIN sseof;
  94.     }
  95.     } else if (x < 0) {            /* Error */
  96.     errpkt("sdata");
  97.     } else {                /* OK - switch to Data state */
  98.     BEGIN ssdat;
  99.     }
  100. }
  101. <ssatt>Y {                /* Receive ACK to Attribute packet */
  102.     if (*rdatap == 'N') {        /* Check for refusal */
  103.     seof("D");
  104.     BEGIN sseof;
  105.     } else if ((x = sdata()) == 0) {    /* Otherwise send first Data packet */
  106.     if (seof("") < 0) {        /* Empty file - send EOF */
  107.         errpkt("seof");
  108.     } else {
  109.         BEGIN sseof;
  110.     }
  111.     } else if (x < 0) {            /* Error */
  112.     errpkt("sdata");
  113.     } else {                /* OK - switch to Data state */
  114.     BEGIN ssdat;
  115.     }
  116. }
  117. <ssdat>Y {                /* Receive ACK to Data packet */
  118.     if (*rdatap == 'X')            /* Check for file cancellation */
  119.       cx = 1;
  120.     else if (*rdatap == 'Z')        /* Check for batch cancellation */
  121.       cz = 1;
  122.     if ((x = sdata()) == 0) {        /* Send data packet if data left. */
  123.     if (seof((cx | cz) ? "D" : "") < 0) { /* If not, send Z packet */
  124.         errpkt("seof");
  125.     } else {
  126.         BEGIN sseof;
  127.     }
  128.     } else if (x < 0)            /* Fatal error sending data */
  129.       errpkt("sdata");
  130. }
  131. <sseof>Y {                /* Receive ACK to EOF */
  132.     if (gnfile() > 0) {            /* Get next file from list */
  133.     if (sfile() > 0)
  134.       BEGIN ssfil;
  135.     else { errpkt("sfile"); }
  136.     } else {                /* No more files */
  137.     seot();                /* Send EOT */
  138.     BEGIN sseot;
  139.     }
  140. }
  141. <sseot>Y { return(failure); }        /* Send ACK to EOT - done */
  142.  
  143. /* Receiving states... */
  144.  
  145. v { tinit(); rinit(); BEGIN srini; }    /* Start-state for Receive */
  146.  
  147. <srini>S {                /* Receive S packet */
  148.     spar(rdatap);            /* Set parameters from it */
  149.     ack1(rpar());            /* ACK with our parameters */
  150.     bctu = bctr;            /* Switch to negotiated block check */
  151.     streamon();
  152.     BEGIN srfil;            /* Wait for file or EOT */
  153. }
  154.  
  155. <srfil>B { ack(); return(failure); }    /* Receive EOT packet */
  156.  
  157. <srfil>F {                /* Receive File header packet */
  158.     if (rcvfil() < 0) {
  159.     errpkt("rcvfil");
  160.     } else {
  161.     encstr(filnam);
  162.     ack1(xdata);
  163.     streamon();
  164.     BEGIN sratt;
  165.     }
  166. }
  167. <sratt>A {                /* Receive Attribute packet */
  168.     if (gattr(rdatap) == 0) {
  169.     ack();
  170.     } else {
  171.     ack1("\"");
  172.     }
  173. }
  174. <sratt>D {                /* Receive first Data packet */
  175.     if (decode(datalen) < 0) {
  176.     errpkt("Packet decoding error");
  177.     } else {
  178.     ack();
  179.     BEGIN srdat;
  180.     }
  181. }
  182. <sratt>Z {                /* Empty file */
  183.     if (*rdatap == 'D')            /* Check for Discard directive */
  184.       cx = 1;
  185.     if (closof() < 0) {            /* Close the output file */
  186.     errpkt("closof");
  187.     } else {
  188.     ack();                /* Send ACK */
  189.     BEGIN srfil;            /* Wait for another file or EOT */
  190.     }
  191. }
  192. <srdat>D {                /* Receive Data packet */
  193.     if (decode(datalen) < 0)
  194.       errpkt("Packet decoding error");
  195.     else
  196.       ack();
  197. }
  198. <srdat>Z {                /* Receive EOF packet */
  199.     if (*rdatap == 'D')            /* Check for Discard directive */
  200.       cx = 1;
  201.     if (closof() < 0) {            /* Close the output file */
  202.     errpkt("closof");
  203.     } else {
  204.     ack();                /* Send ACK */
  205.     BEGIN srfil;            /* Wait for another file or EOT */
  206.     }
  207. }
  208.  
  209. /* GET files from a Kermit server... */
  210.  
  211. r {                    /* Start state for Get */
  212.     tinit();                /* Initialize transaction */
  213.     ginit();                /* Initialize Get */
  214.     sinit('I');                /* Send I packet */
  215.     BEGIN sipkt;
  216. }
  217. <sipkt>Y {                /* Receive ACK for I packet */
  218.     spar(rdatap);            /* Set parameters from it */
  219.     if (scmd('R',cmarg) < 0)        /* Send GET packet file filespec */
  220.       errpkt("scmd");
  221.     else
  222.       BEGIN srini;            /* Wait for S packet */
  223. }
  224.  
  225. E { return(failure = 1); }        /* Receive an Error packet */
  226.  
  227. . { errpkt("Unknown packet type"); }    /* Handle unwanted packet types. */
  228. %%
  229.